Development record
The status-line badge is true at every stop
Press Release
The status-line badge always reads one of three states, a question to the human is refused until the mode is set, and the answer resets it.
"The badge was set by whichever agent remembered," said a product thinker who had watched it read managed while an agent waited on them. "Now an agent cannot ask me anything until it has said which of us it is asking, and the moment I answer the badge goes back. It is the one signal I have that something is waiting; now it is true."
Why This Matters
itd-200 shipped the badge and the mode verb; the state is whatever the agent last set, so it lags, sticks or never changes, and two captures already sit on it (a default that reads bare "abcd"; a colour that bleeds past the badge). Ruled 2026-09-21: the verb stays the setter, because the agent knows whom it addresses; the guard enforces it; abcd resets it on the next human message.
Mechanism
We expect a question refused until the mode is set, and a reset on the answer, to make the badge true at every stop, because the two moments the badge must change are the two moments the harness already sees; shown wrong if a stop is still observed with the badge reading managed.
Scope Conditions
None stated.
What's In Scope
- Three states, never bare:
abcd-managed,waiting on the product thinker,waiting on the technical facilitator; an unmanaged repository shows nothing. - The guard: a question to the human through the host's question tool is refused while the mode reads managed; the refusal names the two settings and the verb.
- The setter:
abcd mode product-thinker|facilitatorsets the state; the line changes on its next render. - The reset: the prompt hook resets the mode to managed when the next human message arrives after a question, and says so on stderr once.
- The paint: the line's colour ends at the badge (closes iss-2609170709035405); the default state closes iss-2609170627427239.
What's Out of Scope
- Deriving the addressee from the question's text (the agent names it).
- Any state beyond the three.
Decisions
Ruled by the product thinker on 2026-09-21, in the interview that filed and planned this intent (adr-2609212115255771 records the vocabulary rulings it rests on):
- The verb sets the state, enforced by the guard on the question tool; the agent is reminded to choose the product thinker or the technical facilitator (ruled 2026-09-21).
- abcd resets the mode to managed on the next human message.
Open Questions
None open.
Acceptance Criteria
- Given an abcd-managed repository, when the status line renders, then it reads exactly one of
abcd-managed,waiting on the product thinker,waiting on the technical facilitator, never a bareabcd; an unmanaged repository shows nothing. - Given the mode reads managed, when an agent calls the host's question tool, then the guard refuses the call naming the two settings and
abcd mode. - Given
abcd mode product-thinkerorfacilitator, when the line next renders, then it shows the corresponding state. - Given a question was asked and the next human message arrives, when the prompt hook runs, then the mode is reset to managed and one line on stderr says so.
- Given the line, when it renders, then its colour ends at the badge.
Audit Notes
Fidelity review — receipt rcp-68f6cce6a701 (verifier intent-auditor claude-fable-5-1).
Provenance: intent-auditor@claude-fable-5-1 · rubric_hash sha256:effa65b3e9e88ff29433b443ec2be159522a8b0b71cf1434526514aa61edb13e · prompt_hash sha256:dc8f6a33e6a1e0d65927ac2c34bc3c74f642e9c3849476ecf308bb9ad2e7eb11 Input attestations: commit:c1c05edeb (spc-2609212139593041 close, itd-2609212130146198 ships); tree audited at 52c2236a55830421c2af5fa58f5a196c4eb7fdd5@-;
Acceptance rollup: MET 4 · MET_WITH_CONCERNS 1 · NOT_MET 0 · INCONCLUSIVE 0
Per-criterion verdicts:
- ac-1 — MET: badgeWord maps the three states to
abcd-managedand mode's two WaitingOn phrases, an unknown or empty state falls back to the managed word (never bare), TestBadgeNeverReadsABareTag holds all five inputs to the three labels; the CLI renders abcd's row only where ahoy.Managed, otherwise the previous command or nothing (TestStatuslineUnmanagedRunsThePreviousCommand, TestStatuslineWithNoPreviousCommandPrintsNothing); all pass at BASE evidence: internal/core/statusline/badge.go:62 — "var badgeWord = map[State]string{ StateManaged: "abcd-managed"," evidence: internal/core/statusline/badge.go:121 — "s = StateManaged word = badgeWord[StateManaged]" evidence: internal/core/statusline/render_test.go:253 — "func TestBadgeNeverReadsABareTag" evidence: internal/surface/cli/statusline.go:106 — "managed := rootErr == nil && ahoy.Managed(root) if !managed || set.Disabled {" evidence: internal/surface/cli/statusline_test.go:116 — "func TestStatuslineWithNoPreviousCommandPrintsNothing" - ac-2 — MET_WITH_CONCERNS: the hook manifest matches the question tool beside the shell tool, questionGate exits 2 on a managed mode with one stderr line naming
abcd mode product-thinker,abcd mode facilitator, the product thinker and the technical facilitator (TestGuardRefusesAQuestionWhileManaged). Concern: the refusal is issued only where the badge shows AND the verb could set the state — no local tier, or a tier the verb cannot write, lets the question run ungated with a loud line (the guard's fail-open-loud contract, iss-2609260100382261), so a managed repository without its local tier is not refused evidence: hooks/hooks.json:26 — ""matcher": "Bash|AskUserQuestion"" evidence: internal/surface/cli/guard_question.go:45 — "const questionRefusal = "Blocked by the abcd guard (question tool): the mode reads managed" evidence: internal/surface/cli/guard_question.go:80 — "fmt.Fprintln(stderr, questionRefusal) return &exitError{Code: 2}" evidence: internal/surface/cli/guard_question.go:66 — "if err != nil || !ahoy.Managed(root) || !mode.HasTier(root) { return nil" evidence: internal/surface/cli/guard_question.go:77 — "if err := mode.CanSet(root); err != nil { return questionFailOpen(" evidence: internal/surface/cli/guard_question_test.go:44 — "func TestGuardRefusesAQuestionWhileManaged" - ac-3 — MET:
abcd mode product-thinker|facilitator|managedwrites the store and the nextabcd statuslinerender carries the matching label; TestModeVerbSetsTheLine drives all three through the CLI evidence: internal/surface/cli/mode.go:35 — "facilitator(the loop is parked on the facilitator" evidence: internal/surface/cli/guard_question_test.go:256 — "func TestModeVerbSetsTheLine" evidence: internal/core/mode/mode.go:150 — "func (s State) WaitingOn() string" - ac-4 — MET: an admitted question writes the question_open marker; the UserPromptSubmit hook calls resetModeOnAnswer before the rules work, ResetOnAnswer writes Managed then clears the marker and the front door prints exactly one stderr line; a hand-set mode with no marker is left alone (TestPromptHookResetsTheModeAfterAQuestion) evidence: internal/core/mode/question.go:112 — "func ResetOnAnswer(repoRoot string) (bool, error)" evidence: internal/surface/cli/cli.go:1421 — "resetModeOnAnswer(cmd.ErrOrStderr(), cwd)" evidence: internal/surface/cli/guard_question.go:113 — "abcd mode: the question was answered, so the mode is reset to managed" evidence: internal/surface/cli/guard_question_test.go:174 — "func TestPromptHookResetsTheModeAfterAQuestion"
- ac-5 — MET: the badge closes with SGR 39;49 on the badge itself, not at the row's end and not a full reset, and no later element carries an escape; TestBadgeColourEndsAtTheBadge asserts all three, and iss-2609170709035405 is resolved on it evidence: internal/core/statusline/badge.go:104 — "const reset = "\x1b[39;49m"" evidence: internal/core/statusline/badge.go:146 — "return "\x1b[" + fg.sgr(38) + ";" + bg.sgr(48) + "m" + text + reset" evidence: internal/core/statusline/render_test.go:283 — "func TestBadgeColourEndsAtTheBadge"
Gap audit:
- honoured:
- the two captures the intent names are closed by the delivery: the bare
abcddefault and the colour bleeding past the badge evidence: .abcd/work/issues/resolved/iss-2609170627427239-the-status-line-badge-s-default-state.md:12 — "no state renders the bare tool name" evidence: .abcd/work/issues/resolved/iss-2609170709035405-the-status-line-paints-everything-after.md:12 — "the badge's colour ends at the badge" - the reset writes the state before it clears the marker, so a failure between the two retries on the next message rather than parking the badge evidence: internal/core/mode/question.go:101 — "The state is written before the marker is removed"
- a mode the human set by hand is not clobbered by their next message: the reset acts only on an open question marker evidence: internal/core/mode/question.go:10 — "Without the marker the prompt hook // changes nothing, so a state the human set by hand" evidence: internal/surface/cli/guard_question_test.go:198 — "A human who sets the hat by hand keeps it across their next message."
- the badge's word carries the meaning and the role labels are mode's own vocabulary, so badge and notice name the same person evidence: internal/core/statusline/render_test.go:644 — "func TestRoleBadgeWordsAreTheModeVocabulary" evidence: internal/surface/cli/guard_question_test.go:281 — "func TestBadgeAndNoticeNameTheSamePerson"
- the two captures the intent names are closed by the delivery: the bare
- diverged:
- the press release says an agent cannot ask the human anything until it has said whom it is asking; the delivery gates only the host's question tool, so a stop that asks in prose at the end of a turn is ungated and the badge can still read managed at that stop — the Mechanism's own falsifier — while the intent's scope confines the guard to the question tool evidence: .abcd/development/intents/shipped/itd-2609212130146198-the-status-line-badge-is-true-at-every.md:23 — "Now an agent cannot ask me anything until it has said which of us it is asking" evidence: internal/surface/cli/guard_question.go:30 — "var questionTools = []string{"AskUserQuestion"}" evidence: .abcd/development/intents/shipped/itd-2609212130146198-the-status-line-badge-is-true-at-every.md:40 — "a question to the human through the host's question tool is refused while the mode reads managed"
- the guard refuses only where the verb it names could run: a managed repository without its local tier, or with one the verb cannot write, lets the question through loudly evidence: internal/surface/cli/guard_question.go:59 — "the guard's fail-open-loud contract"
- missing: (none)
Grounds
- pursued: the badge is how the product thinker tells an agent is waiting on them, and today it is set by memory; we expect a guarded verb and an automatic reset to make it true at every stop; shown wrong if a stop is still seen with the badge reading managed
Frontmatter
| id | itd-2609212130146198 |
|---|---|
| type | intent |
| lifecycle | shipped |
| kind | standalone |
| severity | minor |
.abcd/development/intents/shipped/itd-2609212130146198-the-status-line-badge-is-true-at-every.md
open on GitHub ↗ · commit history ↗
References4
- adr-2609212115255771Phases and milestones are retired: sequencing is dependencies rendered as status, the checkpoint is the derived releaserelated
- itd-200A managed repository shows it is managed, and whose answer the loop is waiting on, in the host's status linebuilds on
- itd-201Every question abcd's agents put to a human is asked one at a time, in plain language, with options that widenrelated
- itd-2609212137129937abcd's text names the product thinker or the technical facilitator, never the maintainerrelated
Referenced by5
- iss-2610262034582374itd-2609212130146198 has the guard refuse a question while the mode reads managed; the board's surface page has the guard admit abcd's chipped question and set the state from it.related
- iss-2610262036376499The badge intent refuses a question to the human while the mode reads managed; the guard chapter says abcd's question is never refused on the mode.related
- iss-2610262045007603itd-201 asks which hat the human wears before the mode is set; itd-2609212130146198 refuses every question while the mode reads managedrelated
- itd-2609212137129937abcd's text names the product thinker or the technical facilitator, never the maintainerbuilt on by
- spc-2609212139593041the-status-line-badge-is-true-at-every-stop-an-abcd-managedimplemented by
mentions5
- dcn-26092100000000012026-09-21 — Phases and milestones are retired, and the word roadmap with them (product thinker, at an interactive interview after an independent research pass; adr-2609212115255771 supersedes adr-9). Sequencing is dependencies plus the lifecycle shelves, rendered as a Now / Next / Later status block on the `abcd` board and the site (itd-2609212103568351), never stored; the checkpoint is the derived release plus each intent's acceptance criteria, with an optional `target_release` the cut reports and moves forward (itd-2609212103572513); the unit below a spec is the step, a section not a family (itd-2609212103565953); an issue carries no spec by design; the batch is the run's internal order; one page maps the families (itd-2609211913453478). itd-24 becomes release retrospectives; itd-34 drops its phase rule. Same interview: `build` is the verb a person types and `implement` the loop (itd-2609201916151817 decision 8), the loop takes an issue key (decision 10), only the loop writes a verdict (decision 9); the person's command list is grouped with an agents block behind `--agent` (itd-146), every verb opens with a does/writes/refuses sentence (itd-2609212113220149), modes become flags and five checks one lint (itd-2609212130136102, breaking); the status-line badge is guarded and reset (itd-2609212130146198); a new capture or draft is matched and linked at filing, never refused (itd-2609212137116617); abcd's text names the product thinker or the technical facilitator and never the maintainer (itd-2609212137129937, captured for the run, no sweep today); the lab conventions become `abcd lab` (itd-2609212137128014); a managed repository's site goes live by one verb behind a provider seam (itd-2609061543533170).
- iss-2609170627427239The status-line badge's default state reads 'abcd', which says the tool is present but not that this repository is managed by it; make the managed-and-nobody-waiting badge read 'abcd-managed' in an abcd-managed repository, so the word on the row states the fact the badge exists to show, alongside the facilitator and product-thinker states.
- iss-2609170709035405The status line paints everything after the badge in the terminal's plain foreground, so the repository name, the branch, the model, the context percentage and the intent and issue counts all carry the same weight and the row reads as one undifferentiated run. Give the elements two tones: a softer grey for the repository and branch names and for the itd and iss counts (the standing facts, glanced at rarely), and a darker colour for the model and the context figure (the two that change and get read). The badge keeps its own pair; the split is the one the previous hand-written status line already drew, and it must keep the rest of the row legible on the status surface's dim background.
- iss-2609260100382261The question gate can refuse a legitimate question forever: in a managed checkout whose .abcd/.work.local/ exists but is not writable, HasTier reads true and the absent mode file reads managed, so the guard exits 2 on the host's question tool, while the remedy it names, abcd mode facilitator, fails with permission denied. HasTier tests presence, not writability, though its comment says it gates on the verb being able to set the state.
- iss-2609290000171068itd-2609212130146198's press release promises that an agent cannot ask the human anything until it has said whom it is asking, but the delivered guard (criterion 2) covers only the host's question tool: a stop that asks in prose at the end of a turn is not gated, so the badge can still read abcd-managed while an answer is owed, which is the Mechanism's own falsifier. The intent's scope confines the guard to the question tool, so the press release overclaims; either the promise narrows to the tool or a stop-time gate closes the prose path. Found by the fidelity audit at 52c2236a5 (internal/surface/cli/guard_question.go questionTools).