docs: correct prune counting and crew ui reporting in the CLI contract - #115
Draft
dichovsky wants to merge 1 commit into
Draft
docs: correct prune counting and crew ui reporting in the CLI contract#115dichovsky wants to merge 1 commit into
dichovsky wants to merge 1 commit into
Conversation
The CLI contract is authority level 3 and the surface it describes is a declared stable contract, so a wrong statement in it is load-bearing: a reader who believes Task-linked Messages only ever vanish with their Task mis-models retention, and one who scripts around "crew reports whether the browser opened" is building on output no code emits. The doctor comment is a source comment contradicting the function eighteen lines below it, in the one file a contributor reads to learn what doctor reports. No behavior changes: the code is correct on all three points and no FR-* requires otherwise, so the prose is the side that moves. Closes #66 Closes #88 Closes #90
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #66
Closes #88
Closes #90
docs/design/cli-contract.mdis authority level 3 and the surface it describes is a declared stable contract, so a wrong statement in it is load-bearing. Two of the three drifts here are exactly that: a reader who believes a Task-linked Message only ever disappears together with its Task mis-models retention (messages_deletedis the fieldEXAMPLES.mdrecommends scripting against), and a reader who scripts around "crew reports whether it opened the browser" is building on output no code emits. The third is a source comment insrc/doctor.tsthat contradicts the function twenty lines below it, in the one file a contributor reads to learn whatdoctorreports.All three reproduce on
main@09e67cd, verified against the code rather than taken from the issue bodies. Per the authority order indocs/README.mdthe code is the correct side of each: noFR-*/NFR-*requires the documented behavior —FR-K02/FR-K04(srs.md:709-718) specify prune eligibility and "report deletion counts" without prescribing how the counts partition, and noFR-U01–FR-U11mentions the browser opener at all. So this is a documentation/comment correction with no behavior change.What changed and why
cli-contract.md:605-612messages_deletedsentence said "(Task-linked ones plus standalone read Messages)".pruneState(src/store/maintenance.ts:166-190) has notask_id IS NULLpredicate on step 4 —DELETE FROM messages WHERE read_at IS NOT NULL AND created_at < ?(:183-185) removes every remaining old read Message, including ones still linked to a Task that survived the prune (too new, or a sibling Message on it is still unread, perELIGIBLE_TASKSat:155-157). The sentence now describes both halves of the sum and states the consequence a script author needs: an old read Message can disappear while its Task stays.cli-contract.md:772-776crew uiprints "whether it opened the browser" and that--no-open"reports that the browser was not opened".renderUiStarted(src/format.ts:315-333) prints exactly two lines —Console listening at <url> (workspace <path>)and the secret-token warning — and neither mentions the browser;--no-openonly skips the opener call (src/ui/index.ts:118-124) and emits nothing of its own. The bullet now states the two lines actually printed and that nothing reports the browser outcome.cli-contract.md:387-393crew uisection's human-output bullet is where a reader looks for opener behavior, so the silent-failure-by-design fact lands here:runUiawaits the opener inside atry/catch {}that swallows the failure so a deadopen/xdg-opencannot kill a running Console (src/ui/index.ts:118-124). Nothing was printed about it before and nothing is now — that was undocumented, not just unstated.cli-contract.md:378-381resolvePort(src/ui/index.ts:54-61) throwsUSAGEfor a non-decimal or out-of-range value; an unavailable port surfaces fromstartUiServerasLAUNCH_FAILED(:100-108), never a fallback bind (FR-U03). Both are now named, matching the meaning table at:484, which PR #85 had already corrected on theLAUNCH_FAILEDside. The section's closing "introduces no new error code" claim (:432-433) stays true — both codes are pre-existing.src/doctor.ts:89-93collectParticipantFindingsdoc comment ended "Version is not a doctor finding — it is surfaced bycrew setup."collectVersionFloorFindings(:114-143) pushes awarnfinding withcode: 'VERSION_FLOOR'anddetails{ target, detected, minimum, verified_on }(:131-141) — confirmed present and emitted at currentmain, not inferred from the issue. The comment now scopes this function to presence and points at the function that does report version drift. Comment only: no change tocollectParticipantFindings' behavior, return value, or any finding it emits.Deltas against the issue bodies — noted rather than silently absorbed
cli-contract.md:584-585; the text sits at:604-605on currentmain(six PRs merged into the file's neighbourhood on 2026-08-06). An audit of a sibling PR reported that:604already read the corrected form. It does not —:604read the defective form the issue quotes, verbatim, and the diff here shows it being removed. CLI contract: messages_deleted is described as counting standalone read Messages, but prune deletes every old read Message #66 reproduces in full.task_id IS NULLpredicate. The other half also went undocumented: step 2 (DELETE FROM messages WHERE task_id IN (...),maintenance.ts:174) carries nocreated_atfilter, so Messages on a pruned Task are removed whatever their age, entirely independent of the Message cutoff. The replacement states that explicitly rather than only fixing the half the issue names.:768-769onmain→:772-776after this change. PR docs: correct CLI contract drift on the --json surface #85 touched this bullet and then reverted its edit (its own body records the revert as the resolution of a HIGH review finding), so the text is byte-identical to what CLI contract: the crew ui section describes browser reporting no code emits and omits its failure codes #88 quotes.LAUNCH_FAILEDis not raised for "a port that is merely unavailable" in general — it is the fallback for any non-CrewErrorthrown bystartUiServer, withEADDRINUSEthe motivating case (src/ui/index.ts:100-108). The wording added ("fails asLAUNCH_FAILEDwhen the server cannot bind") describes the bind failure without over-narrowing the code to that one cause.:92line number, thewarnseverity, and all fourdetailskeys. No delta.grep -n "standalone" docs/design/cli-contract.md→ no hits after the change;grep -rn "not a doctor finding\|surfaced by \crew setup`" src/ docs/→ no hits;grep -rn "whether it opened the browser|reports that the browser" docs/ README.md EXAMPLES.md→ no hits.docs/design/data-model.md:527-531` already described step 4 correctly ("the remaining old read Messages") and is untouched — the two level-3 documents now agree.Wrapping: Prettier is
proseWrap: "preserve"and never reflows Markdown, soformat:checkpasses either way and wrapping is hand-maintained. New lines are 90-93 columns, inside the file's existing band. Theprune_resultparagraph was re-wrapped end-to-end because the inserted clause would otherwise have left a 21-column orphan line; the word-level diff shows the--vacuumtail is re-wrapped only, with no content change. No other paragraph was touched.Verification
Tests: none added or updated — claiming the docs-only/comment-only exemption explicitly. The diff is one Markdown file plus a comment-only hunk in
src/doctor.ts;CONTRIBUTING.mdand.github/ISSUE_TRIAGE.mdboth grant that exemption, and it is stated here as they require. Proven, not assumed, that nothing guards what changed:grep -rn "cli-contract" tests/returns one hit,tests/unit/format-edge.test.ts:214, a comment about timestamp rendering that reads no doc file.tests/unit/docs-facts.test.tsderivesdocs-site/generated/facts.jsonfromsrc/platforms/registry.ts,src/store/schema.ts,src/cli.ts,package.json,vitest.config.ts, and ADR H1 headings — nevercli-contract.mdand never asrc/doctor.tscomment — so no regeneration was needed, and the suite is run below to prove it.Run on the final pushed tree (rebase onto
origin/main@09e67cdwas a no-op — the branch was already on the tip), Nodev24.19.0, uid501(not root):npm run typechecknpm run lintnpm run format:checknpm run builddist/+dist/ui-assets/npm run build:docsnpx vitest run tests/integration/commands/doctor.test.ts tests/integration/commands/doctor-edge.test.ts tests/unit/docs-facts.test.tsnpm run test:coverageThe doctor suites were run despite the change being a comment, because the diff touches
src/doctor.ts. Both files pass here: this machine is uid 501, so the twochmod 000tests that fail for root elsewhere are not in play.Pre-existing-failure proof (performed, not assumed). The single failure is
tests/integration/package/pack-smoke.test.ts—TypeError: Cannot read properties of undefined (reading 'files')at:40, i.e.npm pack --jsonno longer returns the array shape the test destructures. This box runs npm12.0.2. Proven bygit stash push -u -- docs/design/cli-contract.md src/doctor.ts, confirminggit status --porcelainshowed only the untrackednode_modulessymlink andgit diff origin/main --statwas empty, then re-running that file on the clean tree: identical failure, same line, same message.git stash poprestored the change. A Markdown-and-comment edit cannot influence annpm packoutput shape, and CI pins its own npm.Coverage thresholds were NOT evaluated locally.
test:coverageexited non-zero, so vitest suppressed the coverage table and no claim is made about the 95% numbers. This PR's CI run is authoritative. The onlysrc/**change is a doc comment, which cannot move a coverage number.Out of scope
Deliberately untouched, owned by other issues or concurrent PRs:
docs/design/data-model.md:527-531— already correct on step 4; no edit needed, and docs: reconcile architecture.md and data-model.md with the shipped code #111 is open against that file.EXAMPLES.md:182-184, which CLI contract: messages_deleted is described as counting standalone read Messages, but prune deletes every old read Message #66 cites as the script pattern relying onmessages_deleted— the recommendation itself is sound; only the contract's description of the field was wrong.src/ui/index.ts,src/ui/server.ts,src/format.ts,src/platforms/*— cited as evidence for CLI contract: the crew ui section describes browser reporting no code emits and omits its failure codes #88/Doctor: collectParticipantFindings comment says version is not a doctor finding, which VERSION_FLOOR falsifies #90 and read, never edited. All three claims resolve in the docs/comment.docs/design/srs.md— checked for a governingFR-*on each claim (there is none) and not modified; docs: close seven SRS drifts against the code they govern #112 is open against it.FR-*/NFR-*id, CLI grammar rule, record type, error code, command, or flag is added, removed, or given new behavior. No ADR is amended.CURRENT_SCHEMA_VERSIONis untouched.Cross-PR dependency: none. No out-of-scope file needed to change for any of the three fixes.
Related open PRs
None touching the same files.
gh pr list --state open --json number,title,filesshows #110, #111, #112, #113, #114 open; none includesdocs/design/cli-contract.mdorsrc/doctor.ts. The nearest neighbours are #111 (docs/design/data-model.md, the document this change is being reconciled with — it is already correct on the prune step and is not edited here) and #112 (docs/design/srs.md, consulted read-only for the authority check).