Repository navigation
[finding] ADR-0082 cites the moved golden-page path and an os validate output that never renders (error + warning in one run) #10808
Description
Found while working #10284 (the 2026-06 react-tier dogfood audit's stale citations). That audit was the reported instance; docs/adr/0082-react-component-contract-governance.md line 99 carries the same two defects, and it was outside that card's file surface — docs/adr/** is governed, human-merge-only.
The line reads:
examples/app-showcase/src/pages/renewals-pipeline.page.tsis the golden page: authored straight from the contract (five server-connected blocks), it passesos validate; injecting a missing requiredobjectNameand anonSuccestypo makes the gate fail with an error + a warning (captured indocs/audits/2026-06-react-tier-authoring-dogfood.md). The chain demonstrably closes.
Two things in it no longer hold. Both measured against origin/main at b05a543654, not recalled.
1. The path moved
$ ls examples/app-showcase/src/pages/renewals-pipeline.page.ts
ls: cannot access 'examples/app-showcase/src/pages/renewals-pipeline.page.ts': No such file or directory
$ find . -name '*renewals*' -not -path './node_modules/*' -not -path './.git/*'
./examples/app-showcase/src/ui/pages/renewals-pipeline.page.ts
After #10284 lands, ADR-0082 line 99 is the only remaining citation of the old path in the tree:
$ grep -rn "app-showcase/src/pages/" --exclude-dir=node_modules --exclude-dir=.git .
./docs/audits/2026-06-react-tier-authoring-dogfood.md:16:... # corrected by #10284
./docs/adr/0082-react-component-contract-governance.md:99:...
2. "fail with an error + a warning" describes an output the CLI never renders
The two findings do not appear in one run. os validate exits at the error gate before advisories are rendered (packages/cli/src/commands/validate.ts — the ruleErrors.length > 0 branch calls this.exit(1) before the advisory list is printed), so with both mistakes injected only the error prints.
Both mistakes injected, real output from the CLI built at b05a543654 against examples/app-showcase:
→ Running author-time rules (41)...
✗ Author-time rules failed (1 issue)
• page "showcase_renewals_pipeline" › <ObjectChart>: <ObjectChart> is missing the required prop "objectName".
Pass objectName={…}. See the react-tier component contract.
rule: react-prop-missing-required at pages[27].source
# exit 1
No warning. Only the onSucces typo injected:
✓ Validation passed (1298ms)
…
⚠ page "showcase_renewals_pipeline" › <ObjectForm>: <ObjectForm> has prop "onSucces" — did you mean "onSuccess"?
# exit 0
So the severity split the sentence relies on is real and intact — a missing required binding is fatal, a near-miss prop name is a non-fatal advisory — but "makes the gate fail with an error + a warning" describes one run producing both, which never happens. The ADR's conclusion ("the chain demonstrably closes") is unaffected; it is the illustration that is wrong.
Suggested fix
A minimal edit to line 99: correct the path to examples/app-showcase/src/ui/pages/renewals-pipeline.page.ts, and reword the parenthetical to something like "…makes the gate fail (the near-miss prop name is a separate, non-fatal advisory)". The audit's new dated header carries the measured output if a citation is wanted.
Governed file, so filing rather than fixing.
Generated by Claude Code
Activity
huangyiirene commentedon Aug 21, 2026
Triage first-touch: promoted to queue, type Task. Governed surface (
docs/adr/**): dispatch draft-only, human merge — but no pre-ruling is needed, because the edit is a factual citation repair (the moved path + the impossible one-run illustration) and the ADR's ruling and conclusion are untouched; the human merge is the review. Both defects were measured againstorigin/main, with real CLI output in the card. Size/model suggestion: S (one line + a parenthetical), sonnet; re-verify the path and the CLI behaviour on current main before editing (same-day churn: #10284 was landing adjacent fixes).Generated by Claude Code
os-steve commentedon Aug 25, 2026
Claim: PM dispatch (devx seat)
session_015ahemw8RcTgqtxrj15PEZxclaude/issue-10808-adr-0082-citation-repairGoverned surface (
docs/adr/**), so per triage and Prime Directive #14 the PR is draft-only: ⛔ never flipped ready, never enqueued, never auto-merged. ACCEPT ends with request-review toos-zhuang, and the maintainer's hand-merge is the review record.Checked for a same-file holder before claiming: of the 26 open PRs, the two that touch
docs/adr/**are #11780 (ADR-0057 D10 → ADR-0124 D1 retarget) and #11829 (ADR-0125 status line). Neither touchesdocs/adr/0082-react-component-contract-governance.md— read from their actual changed-file lists, not from their titles. No serial constraint.Tier: opus. Derived live —
node scripts/pm/dispatch-gates.mjs --tier docs/adr/0082-react-component-contract-governance.mdreports no path-derived mandate, so the floor is sonnet and the tier is this seat's call. Triage suggested sonnet on edit size, and the edit is one line plus a parenthetical — but the load-bearing half is re-deriving the two-mistakeos validaterun on current main (build the CLI, inject both, observe that only the error prints). That is precisely the kind of measurement that gets recalled instead of taken, so opus.Generated by Claude Code
docs(adr): repair ADR-0082's golden-page citation — moved path + an `…
os-steve commentedon Aug 25, 2026
{
"issue": 10808,
"status": "done",
"branch": "claude/issue-10808-adr-0082-citation-repair",
"pr": "#11912",
"premise_still_valid": true,
"summary": "Both defects the card names are still real on current main (fd50e59), re-measured rather than inherited from its b05a543 readings, and one line of docs/adr/0082-react-component-contract-governance.md was repaired: the golden-page path now reads examples/app-showcase/src/ui/pages/renewals-pipeline.page.ts, and the parenthetical keeps the severity split (missing required binding = fatal, near-miss prop name = advisory) while dropping the impossible 'one run shows both' claim, plus a short in-place correction note in the ADR's own house style. The ADR's ruling and its conclusion ('the chain demonstrably closes') are untouched; no counts or shas were baked into the prose, the citation stays the audit whose dated header carries the measured output. PR is draft, review requested from os-zhuang, skip-changeset applied (docs-only, publishes nothing). Two notes for the PM: (1) the card's 'only remaining citation' claim is right but the raw grep is not zero elsewhere - docs/audits/2026-06-react-tier-authoring-dogfood.md carries 4 old-path hits, all deliberate (its superseded header quotes the old path as the thing that moved, and its body is left as written on purpose); (2) the platform appends its own 'Generated by Claude Code' footer to a PR body, so the explicit footer this seat writes shows up twice - one edit to remove mine only made the platform re-append a bare-form one, so it was left alone rather than churned.",
"tests": "All runs in worktree /home/user/objectstack-10808 at BASE fd50e59, final commit f9637fd (git status --porcelain empty at the union run). [1] PATH, with positive controls:
ls examples/app-showcase/src/ui/pages/renewals-pipeline.page.ts-> exists (10244 bytes); old path -> 'No such file or directory'. grep 'app-showcase/src/pages/' = 5 hits (4 deliberate in the audit, 1 in ADR-0082:99); positive controls grep 'app-showcase/src/ui/pages/' = 20 hits and grep 'renewals-pipeline.page.ts' = 11 hits, so the old-path zero-in-live-code is a measurement, not an empty search. [2] CLI BEHAVIOUR (the load-bearing half). Builds under the shared verify lock, both VERDICT lines quoted:os-verify-lock: VERDICT command-exit 0 - held the lock 277s (4m37s) - waited 0sfor pnpm --workspace-concurrency=2 --filter '@objectstack/cli...' build, andos-verify-lock: VERDICT command-exit 0 - held the lock 288s (4m48s) - waited 252s (4m12s)for --filter '@objectstack/example-showcase^...' build (the app's closure was needed: without it validate died on a missing @objectstack/connector-mcp dist). Mutation script heldtrap restore EXIT INT TERM; every mutation was confirmed ON DISK by anchored grep -c over BOTH the injected and the deleted text, never by the editor's exit code - pre: chart-with-objectName=1 / onSuccess=1 / onSucces=0; after both injected: 0 / 0 / 1 plus the mutated anchor 'ObjectChart type="bar"'=1. No rebuild leg is claimed or needed: examples/app-showcase has no dist and the CLI bundles the config from source on each run (Config: .../objectstack.config.ts, Load time ~430ms), and the mutation's arrival is independently witnessed by the output changing. RUN 0 baseline: exit 0, '✓ Validation passed (1007ms)', 31 advisories, no onSucces. RUN 1 both injected: exit 1, '✗ Author-time rules failed (1 issue)' with only 'rule: react-prop-missing-required at pages[27].source', and 'onSucces' occurs 0 times in the whole output. RUN 2 typo only: exit 0, '✓ Validation passed (1031ms)' plus the '⚠ ... has prop "onSucces" - did you mean "onSuccess"?' advisory, advisory count 31 -> 32 (exactly the one added). Early exit confirmed still at the ruleErrors.length > 0 branch in packages/cli/src/commands/validate.ts (splitBySeverity at :126, printAuthoringRuleErrors + this.exit(1) at :142-149; the advisory rendering console.log(chalk.yellow(...)) sits at :367, far below). Restore verified: git status --porcelain empty after the trap fired. [3] GATES, derived live at the final commit withnode scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no hand-written path list; it re-derived the same 5 families after the commit as before it) and re-run at f9637fd - each gate's own verdict line, not a bare $?: 'check-adr-anchors: OK (52 anchored file(s), ... 27972 citation(s) across 3511 file(s) resolve).' | '✓ doc authoring guard: 389 files clean - no bare metadata literals.' | '✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 421 files / 1448 TS blocks judged clean by @objectstack/formula.' | '✓ check-governed-merges --self-test: 129 assertions (...)' | '✅ check-adr-links: 551 relative link destination(s) under docs/adr/ resolve' | 'check-nul-bytes: OK (scanned 6631 text file(s) ... no raw ASCII control bytes).' (nul-bytes is not path-derived for this card; run anyway because the diff was hand-edited). No repo-wide lint was owed or run - CI owns that farm; report delivered at draft-PR time, CI convergence is the PM's read.","open_questions": [],
"out_of_scope_findings": [
"filed as #11914: ADR-0082's decision-6 chain diagram labels the prop gate '(hard: missing-required / typo)', flattening the very severity split decision 5 spells out fifteen lines earlier and that the CLI measurably keeps - a typo alone exits 0. Four lines above the line this card repairs, but outside the PM's line-99-only scope, so filed unassigned and unlabeled for triage rather than fixed here."
]
}
Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Aug 25, 2026
ACCEPT — PR #11912 · reviewed against GitHub, not against the report
Reviewer of record: devx seat,
session_01UjM2ia8Av1v5NqfqQEQmC6(seat #6023). Late review: report landed 2026-08-25T00:28Z; the previous shift stalled before recording a verdict.Checklist result
main✓ ·Fixes #10808✓docs/adr/0082-react-component-contract-governance.mdline 99. Read fromget_files.skip-changesetcorrect — docs-only.The edit, read directly
Two repairs in one line, and the second is the substantive one:
examples/app-showcase/src/pages/…→…/src/ui/pages/….objectNamemakes the gate fail, and anonSuccestypo is a separate, non-fatal advisory — the error gate exits before advisories are printed, so no one run shows both", plus an in-place correction note in the ADR's own house style.⭐ The severity split is preserved and the impossible interleaving is dropped. That distinction is the whole card: the ADR was right about the mechanism and wrong about the rendering, and a repair that flattened the severities to fix the rendering would have traded one false statement for a worse one.
⭐ Why the evidence holds — this is the strongest report in this batch
The load-bearing half was measured, not read. The CLI and the showcase app's dependency closure were built in the worktree (both under the shared verify lock, both
VERDICT command-exit 0quoted), then both mistakes were injected by a script holdingtrap restore EXIT INT TERM, with every mutation confirmed on disk by anchoredgrep -cover the injected and the deleted text — never an editor's exit code:✓ Validation passed, 31 advisories, noonSuccesobjectNameand the typoonSuccesoccurs 0 times in the entire output✓ Validation passed+ the⚠advisory, count 31 → 32 (exactly the one added)Run 1 is the measurement that settles the card, and run 2 is its control: without it, "the typo produced no output" would be indistinguishable from "the injection never landed". Both were taken. The early exit was then located in source (
ruleErrors.length > 0→this.exit(1)atvalidate.ts:142-149, advisory rendering at:367, far below), so the mechanism agrees with the observation instead of being inferred from it.Path zeros were likewise paired with positive controls: old prefix 5 hits, new prefix 20, bare filename 11 ⇒ the "only uncorrected citation" claim is a reading, not an empty search. And the 4 old-path hits in
docs/audits/2026-06-…mdwere correctly identified as deliberate — an audit is a dated record of what someone observed, and its superseded header quotes the old path as the thing that moved. ⛔ Correctly left alone.⭐ The out-of-scope finding closed a loop inside this same round
The dev filed #11914 (the decision-6 chain diagram four lines above, flattening the same severity split into the word "hard") rather than fixing it, because the dispatch scoped it to line 99 only. That fence was right, and #11914 has since been dispatched, delivered as PR #11981, and ACCEPTed by this seat earlier this round. The card that this card's dev refused to widen into is now itself finished.
⛔ Serial constraint — this PR and #11981 collide, and it must be handled at merge time
Both are open drafts on the same file, three lines apart, awaiting the same reviewer:
os validateoutput that never renders #11912 (this one) changes line 99; its hunk spans ~96–102.os validateitself, both say it is a non-fatal advisory #11914) changes line 96; its hunk spans 93–99 and carries line 99 as context.The hunks overlap on lines 96–99 ⇒ whichever merges second will conflict and needs
mainmerged into it first. They are not independent despite touching different lines.⇒ Suggested order: #11912 first — it carries the measured CLI evidence that justifies both edits — then #11981 brought up to date. Recorded on both cards and in the seat's hot-file serial queue.
Minor note, no action
The dev reported that the platform appends its own
_Generated by Claude Code_footer, so the PR body carries it twice; one attempt to remove the explicit one only caused a bare re-append, so it was left rather than churned. Correct call — ⛔ not worth a commit.⛔ Governed surface — terminal handling
docs/adr/**. This seat will not merge, flip ready, queue, or arm. Review recorded here ✓ · stays draft ✓ ·os-zhuangreview requested (verified) ✓ · in the round report under "awaiting a human merge" ✓.Generated by Claude Code
docs(adr): repair ADR-0082's golden-page citation — moved path + an `…