docs: record 0.1.1 as the published release status - #94
Conversation
The npm dist-tag `latest` and the only git tag are both `0.1.1`, but the docs still asserted `0.1.0` as the current published state — including `docs/README.md`'s "Current readiness", which declares itself the single source of truth for release status. A reader checking release status got a stale answer from the one place that promises an accurate one. `docs/README.md` now records `0.1.1` as the current release and the first one published through the OIDC pipeline (so it carries build provenance), keeping the reason `0.1.0` could not be. The echoing passages in `README.md`, `CLAUDE.md`/`AGENTS.md`, DEC-7, and the product spec's release-gate preamble keep the durable manual-bootstrap/OIDC narrative but no longer pin a version that rots — they defer to `docs/README.md` for the current release, so only one file moves each time crew publishes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAdcHxgLQztc5RhBRC4ag6
dichovsky
left a comment
There was a problem hiding this comment.
Two reviewers ran per .github/ISSUE_TRIAGE.md: the general code reviewer, and — the diff being docs-only — a documentation-accuracy reviewer verifying the new prose against the code it describes and against the authority order, in place of the TypeScript reviewer. No security reviewer: the diff touches none of src/store/, src/process.ts, src/which.ts, src/fs-safe.ts, src/setup/, or the Launcher.
No CRITICAL. No HIGH. 2 MEDIUM, 6 LOW. Both reviewers independently landed on the same MEDIUM, and it concerns a clause this PR introduces.
Verified clean
Fact-checked against the live registry, not just the repo:
npm view @dichovsky/crew@0.1.1 --json→_npmUser: "GitHub Actions <npm-oidc-no-reply@github.com>",dist.attestations.provenance.predicateType = https://slsa.dev/provenance/v1. So "first one published through the OIDC pipeline, so it carries build provenance" is TRUE.npm view @dichovsky/crew@0.1.0 --json→disthas noattestationskey. So "0.1.0carries no CI provenance" is TRUE.publish.yml:22-24(id-token: write) and:96-105(npm publish --provenanceon both branches) corroborate.docs/README.md:69"six gates" still matches the six rows atproduct-spec.md:126-133.- Every relative link and anchor in the six changed files resolves.
product-spec.md:108[docs/README.md](../README.md)→docs/README.md(correct; the root README would be../../README.md).#release-gates→## Release gates. diff CLAUDE.md AGENTS.mddiffers on exactly the two pre-existing title lines; the edited paragraph is byte-identical in both.- Scope: all six hunks trace to #38. No adjacent-code improvements,
git diff --checkclean. - Rot resistance holds: after the change,
docs/README.md:62is the only prose assertion of a current published version anywhere in the repo. The remaining0.1.xstrings are historical/procedural boundary statements,CHANGELOG.md(dated history by construction),package.json(the artifact's own version), anddocs-site/generated/facts.json(generated frompackage.json, pinned bytests/unit/docs-facts.test.ts:80-92). The PR's out-of-scope claim forpublishing.md,live-smoke-checklist.md:76-77, andtesting-strategy.md:254-256was checked and is correct.
MEDIUM 1 — the extended "no separate copy" rule is falsified by its own paragraph
docs/design/product-spec.md:107-108, new text:
Other documents reference it and must not keep a separate copy — release status included, which docs/README.md owns. crew has shipped to npm. Because npm's OIDC Trusted Publishing…
Two defects. The antecedent of "which" is ambiguous — read naturally it says docs/README.md owns the release-gate list, contradicting the sentence's own opening claim that this document is canonical for it. And having just forbidden a separate copy of release status, the next three sentences are one, as are decisions.md:27-31, CLAUDE.md:29-33, AGENTS.md:29-33, testing-strategy.md:254-256, publishing.md:10-20, and live-smoke-checklist.md:76-79. docs/README.md:48-49 grants the summarize-and-defer carve-out to AGENTS.md and CLAUDE.md only, so the rest have no cover under the new rule.
The rule is faithful in direction — docs/README.md:48-49 already claims single-source ownership of release status, so nothing is invented — but it is overbroad as written. The fix is to own the volatile fact (the current published version) rather than the whole publishing narrative, which is also what #38 actually fixed.
MEDIUM 2 — the rewording half-turns the SRS's release-status pointer
docs/design/srs.md:12-13 (same pointer at :1205, :1215-1216) routes release status to the product-spec:
Release status is deliberately not repeated in this document; see the product-spec release-gate table.
After this diff, product-spec.md:108 disclaims exactly that subject. A reader following the SRS — authority level 2 — lands on a document saying the subject isn't its. Nothing dangles yet (product-spec still carries the prose), but pointer and target now disagree. Narrowing MEDIUM 1 resolves this too, and is the right direction: editing the SRS to accommodate a level-below document would be backwards.
No authority-order violation otherwise — none of the six changed files sits in the authority order, no ADR states release status, and srs.md:63 ("@dichovsky/crew, published") names no version and stays true.
LOW
docs/README.md:62-66— "The first release,0.1.0, could not:" elides its verb across a tense shift and colons into a because-clause. The paragraph also states twice each that0.1.0lacks provenance and that OIDC starts at0.1.1.docs/README.md:66-68— thepublish.ymlsummary omits the pre-releasenextdist-tag branch (publish.yml:93-105) and the already-published preflight skip (:75-91). Nothing stated is false. One consequence: "the current published release" is unqualified, and a futurenextpre-release would be published but not current.0.1.1is the currentlatest" would be tighter.docs/README.md:48-49— still names onlyAGENTS.mdandCLAUDE.mdas documents that defer here;product-spec.md:108now defers too and is unlisted.product-spec.md:108-111— rewrap residue: line 108 is 102 chars, line 110 is 63, in a paragraph otherwise wrapping at 87–93. Passesformat:check(Prettier'sproseWrapdefaults topreserve), but visible editing residue.docs/README.md:51-62— the feature-complete paragraph immediately precedes "0.1.1is the current published release", whileCHANGELOG.md:7-27still has Little Coder / pi / opencode under[Unreleased]. The juxtaposition pre-dates this PR, but "is the current published release" reads more like a claim about shipped feature content than the old wording did.docs/release/publishing.md:57— "Re-cuttingv0.1.0is safe … so the Release still validates the pipeline end-to-end" is now moot, since0.1.1validated it with a real publish. Not a current-version claim, so outside #38; adjacent rot.
Disposition
MEDIUM 1 and 2 concern text this PR introduces and share one fix, so the implementer is taking a pass to narrow that clause to the current published version. LOW 1 is being folded in as it is the same paragraph. The rest are left: LOW 2–5 are pre-existing or stylistic and outside #38's scope, and LOW 6 belongs to a separate cleanup.
One finding is a distinct problem rather than a defect in this diff, and is being filed as its own issue per .github/ISSUE_TRIAGE.md:253-256 rather than folded in: docs/release/publishing.md:35-64's "Cutting a release" checklist has no step to update docs/README.md's readiness paragraph. Steps 1–7 cover CI, smoke evidence, the gate table, package.json + CHANGELOG.md, the GitHub Release, and verification — but not the document that declares itself the single source of truth for release status. That omission is why #38 was filed, and it regenerates the same issue at 0.1.2.
Generated by Claude Code
The previous commit told other documents not to keep a separate copy of "release status". That claim was too wide in both directions. Its "which" read as binding to the release-gate list, so the sentence appeared to hand docs/README.md ownership of the very list the same sentence calls canonical here — and `docs/design/srs.md` routes release status to this section, so a level-4 document was disclaiming a subject a level-2 document assigns it. The rule also outlawed its own paragraph: the publishing narrative is restated, legitimately, in decisions.md, CLAUDE.md/AGENTS.md, testing-strategy.md, publishing.md, and live-smoke-checklist.md, none of which fall under the summarize-and-defer carve-out docs/README.md grants. Narrow the clause to the fact that actually rots — the current published version — which is what #38 was about. The publishing narrative stays freely restatable, the SRS pointer stays honest, and docs/README.md remains the single place naming a version. Also rewrap the paragraph back into the file's band after the earlier edit, and drop a doubled statement of 0.1.0's missing provenance from docs/README.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DAdcHxgLQztc5RhBRC4ag6
|
Fix pass taken and re-checked. MEDIUM 1 and 2 resolved by one edit.
The semicolon gives the clause its own independent subject, so nothing binds back to the release-gate list — killing the ambiguous antecedent. And it claims ownership of one volatile fact rather than the whole subject "release status", so the paragraph no longer falsifies its own rule three sentences later, and the restatements in LOW 1 folded in (same paragraph).
All three links, the release-gate-table reference, and the LOW 4 fixed as a consequence: the release-gates paragraph rewraps to 63–93 chars (was 102 on LOW 2, 3, 5, and 6 were left deliberately: pre-existing or stylistic, and outside #38's scope. Re-check on
|
| Command | Exit | Result |
|---|---|---|
npm run typecheck |
0 | clean |
npm run lint |
0 | clean |
npm run format:check |
0 | "All matched files use Prettier code style!" |
npm run build |
0 | dist/ + dist/ui-assets/main.js |
npx vitest run tests/unit/docs-facts.test.ts |
0 | 2 passed |
npm run test:coverage |
1 | 1395 passed, 3 skipped, 2 failed — byte-identical to the pre-fix run and to the stashed-clean-tree proof; the same two uid-0 doctor.test.ts cases (:319, :373). Nothing new. |
Coverage thresholds remain unevaluated locally (vitest suppresses the table on a non-zero exit); CI is authoritative, and the diff still touches no src/** or bin/** file.
origin/main was re-fetched and is still 97d7f88; the rebase reported up to date.
Note on the earlier red check
The publish dry-run failure on 378a4e7 (job) was a GitHub Actions infrastructure outage, not a defect in this branch: Failed to resolve action download info. Error: Service Unavailable, retried twice and given up before the runner ever checked out the repository. No step of the job ran. Both checks have re-queued against 0fb71ae.
Nothing CRITICAL or HIGH was found at any point, and both MEDIUMs are closed, so the PR is moving out of draft. One finding was filed separately rather than folded in: #95, the release runbook's "Cutting a release" checklist never updates docs/README.md — the process gap that generated #38 in the first place.
Generated by Claude Code
Closes #38
docs/README.md's "Current readiness" section declares itself "the single source of truth for release status" (:48-49), and it recorded0.1.0as the published state.0.1.1shipped on 2026-07-13. Five other passages echoed the same stale claim.Published state, verified directly rather than from the issue body:
npm view @dichovsky/crew dist-tags→latest: 0.1.1;versionsis exactly["0.1.0","0.1.1"];0.1.1published2026-07-13T15:51:28Z.git tag -l 'v*'→v0.1.1, the only tag.package.jsonversion is0.1.1.CHANGELOG.md:29-33records[0.1.1] — 2026-07-13as the first release through the automated OIDC pipeline, carrying build provenance, with no functional CLI changes.One delta against the issue body, noted rather than silently absorbed: it cites
README.md:47; the line is:49(:45-47is the Node-floor paragraph).What changed and why
Every one of the six passages already carried the
0.1.0-manual-bootstrap /0.1.1-onward-OIDC narrative correctly. The defect was that each also asserted0.1.0as the current published state. Only that assertion is removed.docs/README.mdis the one file permitted to name a concrete current version, because it is the declared source of truth for release status and is expected to move each release. The other five are reworded to state the durable fact without pinning a version that rots — which is the Acceptance's stated goal.docs/README.md:62-660.1.1as the current published release and the first through the OIDC pipeline, so it carries provenance; keeps why0.1.0could not (OIDC can only attach to an existing package) and that it therefore carries no CI provenance. Links topublish.yml, the release-gate table, andpublishing.mdare unchanged, as is the1.0.0-reserved sentence.README.md:490.1.0is published to npm." → "crew is published to npm." The install code block is untouched.CLAUDE.md:29,AGENTS.md:290.1.0is published to npm." → "The package is published to npm." Both paragraphs already defer todocs/README.mdfor release status, and they remain byte-identical to each other, as before.docs/design/decisions.md:27-31(DEC-7)0.1.0is published:" → "The package is published to npm: the first publish (0.1.0) was …". The naming rationale,@dichovsky/crew, and the1.0.0parenthetical are unchanged.docs/design/product-spec.md:107-1100.1.0) has shipped to npm." → "crew has shipped to npm", with the "must not keep a separate copy" principle extended to release status and pointed atdocs/README.md.Two wording notes for a reviewer:
CLAUDE.md/AGENTS.mdkeep "The first publish was a one-time manualnpm publish" without re-naming0.1.0. Adding "(0.1.0)" would push the line past the files' ~90-char wrap and force a reflow of an otherwise-unchanged seven-line paragraph in two files. That detail still lives in DEC-7 anddocs/README.md.product-spec.md, "the first release (0.1.0) was published once by hand" rather than "the first publish … was published", to avoid a publish/published repetition the rewording would otherwise introduce. Same fact.Verification
Tests: none added — claiming the docs-only exemption. The diff is six Markdown files and zero code, which
CONTRIBUTING.md("tests are not applicable for docs-only changes") and.github/ISSUE_TRIAGE.mdboth grant.Run under Node
24.18.0(CI's pinned version) on the branch as pushed. Every command was run twice — once by the implementer, once independently — with identical results:npm run typecheckweb/+docs-site/)npm run lintnpm run format:checknpm run builddist/+dist/ui-assets/main.js(88.4kb)npx vitest run tests/unit/docs-facts.test.tsnpm run test:coveragetests/unit/docs-facts.test.tswas run standalone because it is the guard that reads project facts. It takes the version frompackage.json(:82-92), not from prose, sodocs-site/generated/facts.json:4already read0.1.1and needed no regeneration.Pre-existing-failure proof (performed, not assumed). The two failures are
tests/integration/commands/doctor.test.ts:319("degrades a raw filesystem read failure in project roles instead of aborting doctor") and:373("degrades unreadable roles and teams directories to whole-listing warnings"). Bothchmod 000a directory and expect the read to fail; this sandbox runs as uid 0, which ignores mode bits, so the reads succeed and the expectedINVALID_CONFIGwarnings never fire. Proven bygit stash push -u, confirminggit status --porcelainempty at97d7f88, re-running that file on the clean tree for the identical 2 failed / 31 passed, thengit stash pop. A Markdown-only edit cannot influence them, and CI is neither root nor affected.Coverage thresholds were NOT evaluated locally. Because
test:coverageexited non-zero, vitest suppressed the coverage table — the 95% statements/branches/functions/lines numbers were never printed, and no claim is made about them. This PR's CI run is authoritative. The diff touches nosrc/**orbin/**file, so coverage cannot have moved.Branch was cut from and rebased onto
origin/main@97d7f88; the pre-push rebase was a no-op —mainhad not moved. No force-push.Contract impact
None.
product-spec.mdanddecisions.mdsit outside the authority order indocs/README.md:9-12(they are build-packet and index documents), and the other four files are not contract documents at all. No ADR is amended, noFR-*/NFR-*is added, renumbered, or given new meaning, and no CLI grammar rule, record type, error code, command, or flag moves.package.jsonis not touched, so nothing here can influence a futurenpm publish.CURRENT_SCHEMA_VERSIONstays 7.Out of scope
Deliberately untouched:
docs/release/publishing.md,docs/release/live-smoke-checklist.md:76-77,docs/design/testing-strategy.md:254-256— all name0.1.0/0.1.1in a purely historical frame ("0.1.0was a one-time manual publish,0.1.1+ publish from CI") and none claims a current version, so none rots. Listed because a reviewer might expect them in the diff.product-spec.md:124-131) and the "SQLite-stress and Security-review gates are closed" sentence at:112-113— ADR-0009 stress coverage claims exceed what stress.yml actually runs #37's territory, and that issue istriage/plan-readyawaiting a human decision.CHANGELOG.mdstill has an[Unreleased]section carrying Little Coder, pi, and opencode, so the eight-Participant roster described indocs/README.md's readiness paragraph is ahead of what0.1.1actually shipped. Nothing here claims0.1.1contains them — the new wording makes no claim about its feature content — and resolving that mismatch is a separate question this change does not answer.Related open PRs
#91 (
docs/adr-cross-reference-drift) also touchesdocs/design/decisions.md. Checked at file level, not from PR prose: #91 edits the "Structural decisions" paragraph (:13-18) and the Console-decisions section (:124-135); this PR edits DEC-7 (:24-31). No line overlap, so a conflict is unlikely, but they must not both be merged without a rebase check. #91's other three files (docs/adr/0011-*.md,docs/adr/0014-*.md,docs/adr/README.md) are not touched here.#85 (
docs/cli-contract-json-surface-drift) touchesdocs/design/cli-contract.mdanddocs/design/architecture.md— no overlap with this PR.Generated by Claude Code