What it is
Quitting mid-onboarding is specified to discard everything (spec 06 §2.1
"Interruption"), but the way it plays out reads as a lost answer rather than a
deliberate discard, and the loop does not actually stop when the listener
leaves.
From .dev/dev.log, a run against a fresh MURMUR_HOME (2026-08-26):
13:04:52 host: This is murmur's first run ... Three short questions ...
13:04:52 host: Who's listening? ...
13:04:58 tui: command received: /quit
13:04:58 host: What do you want on the air? ...
13:04:58 host: How do you like to be talked to? ...
13:04:58 host: stopped before the broadcast.
Two things, one seam:
-
The questions keep coming after the listener has left. runFirstRun's
loop (src/first-run.ts:110-113) calls ask() for all three questions
unconditionally; only the read short-circuits, because the quit latch
resolves every later read to ''. So Q2 and Q3 are put to someone who has
already quit — both landed in the same second as the /quit above. The
quit check is after the loop (src/first-run.ts:118), not inside it.
-
Nothing says the answer was dropped. The listener typed a real answer to
Q1, then quit, and the only closing word is "stopped before the broadcast."
The next boot starts again from Q1 — correct per spec, but indistinguishable
from murmur having failed to remember. This is what the report was: "I
answered one question and it didn't remember."
Restarting from the top is NOT the defect and should not be changed here: spec
06 §2.1 says Ctrl-C during onboarding exits without writing anything and the
next run is still a first run, and src/first-run.ts:115-118 implements that
deliberately ("leaving is not answering"). Whether a half-finished onboarding
should ever resume is a separate product decision, not part of this issue —
if it is ever taken, it changes the spec first.
Spec
specs/spec06/06-persona-onboarding.md §2.1 — the input primitive and the
Interruption rule. The contract is satisfied on "writes nothing"; it is silent
on continuing to ask, and on telling the listener where they stand.
Done when
Where it is not
Not the first-run trigger. isFirstRun was right to fire here — the run used a
fresh MURMUR_HOME (/tmp/murmur-demo, created 13:03:23); the real home's
~/.murmur/data/memory/persona.md was untouched.
What it is
Quitting mid-onboarding is specified to discard everything (spec 06 §2.1
"Interruption"), but the way it plays out reads as a lost answer rather than a
deliberate discard, and the loop does not actually stop when the listener
leaves.
From
.dev/dev.log, a run against a freshMURMUR_HOME(2026-08-26):Two things, one seam:
The questions keep coming after the listener has left.
runFirstRun'sloop (
src/first-run.ts:110-113) callsask()for all three questionsunconditionally; only the read short-circuits, because the quit latch
resolves every later read to
''. So Q2 and Q3 are put to someone who hasalready quit — both landed in the same second as the
/quitabove. Thequit check is after the loop (
src/first-run.ts:118), not inside it.Nothing says the answer was dropped. The listener typed a real answer to
Q1, then quit, and the only closing word is "stopped before the broadcast."
The next boot starts again from Q1 — correct per spec, but indistinguishable
from murmur having failed to remember. This is what the report was: "I
answered one question and it didn't remember."
Restarting from the top is NOT the defect and should not be changed here: spec
06 §2.1 says Ctrl-C during onboarding exits without writing anything and the
next run is still a first run, and
src/first-run.ts:115-118implements thatdeliberately ("leaving is not answering"). Whether a half-finished onboarding
should ever resume is a separate product decision, not part of this issue —
if it is ever taken, it changes the spec first.
Spec
specs/spec06/06-persona-onboarding.md§2.1 — the input primitive and theInterruption rule. The contract is satisfied on "writes nothing"; it is silent
on continuing to ask, and on telling the listener where they stand.
Done when
/quit(or Ctrl-C) during onboarding stops the question loop at once —no further question is put to the listener after the latch fires.
that the next boot starts over, instead of only "stopped before the
broadcast."
the quit, none after, and the closing line present.
Where it is not
Not the first-run trigger.
isFirstRunwas right to fire here — the run used afresh
MURMUR_HOME(/tmp/murmur-demo, created 13:03:23); the real home's~/.murmur/data/memory/persona.mdwas untouched.