Skip to content

docs(adr): record the command-surface contracts as ADR-0020–0026 - #440

Merged
Kuldeep2822k merged 17 commits into
docs/435-adr-backfill-storagefrom
docs/436-adr-backfill-cli
Oct 12, 2026
Merged

Kuldeep2822k merged 17 commits into
docs/435-adr-backfill-storagefrom
docs/436-adr-backfill-cli

Conversation

@Kuldeep2822k

@Kuldeep2822k Kuldeep2822k commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Description

Third batch of the ADR backfill from #436 — the command surface's behavior contracts. Seven ADRs covering what the v0.6.0 audit round and the post-1.0.0 batch established about how the CLI must behave, each previously documented only in PR bodies and review threads.

New ADRs:

  • ADR-0020 — Readiness and scheduling contracts: one shared prerequisite gate so next, plan and dashboard cannot disagree; the two-case "Blocked by prerequisites" report (unmet vs. unresolvable); due and blocked sets made disjoint; archived topics out of readiness and blocked reporting but kept in the graph so they never read as missing; quarantined notes never reported as blocked. Checked against src/application/get-next-topics.ts.
  • ADR-0021 — The assessment surface: only supplied pillars written (minted zeros pinned mastery low and hid dependents); corrupt stored values refused, not clamped into an unlock; non-scalars refused (Number(String([1])) is 1); exact-palee_id-wins resolution; the availability delta computed the way plan computes readiness; the Feynman hint computed from the pillar table.
  • ADR-0022 — Adoption contracts: a hand-written depends_on survives first adoption; batch filters refused in single-file mode with per-pattern accounting; single-file --dry-run previews; --undo with the PALEE_OWNED_KEYS contract and the --drop-title opt-in rationale; the verified rollback journal.
  • ADR-0023 — migrate --relabel-ties as the migration surface: the surface ruling (why migrate and not adopt/validate); "give the pass a route, not retract the promise"; the adjacency rule; the three counted refusals; existence-based vanished classification; rename detection by path not id; one derived set printed and written.
  • ADR-0024 — Exit codes and the machine-readable error contract: one classifier (containment → 3, provider kinds mapped with 401/403 → 2), process.exitCode over process.exit so piped JSON is complete, parsed-options JSON detection — and the honest note that the classifier swap fixed a class of bug rather than a reachable misreport.
  • ADR-0025 — The application layer and the CLI boundary: the use-case table, policy stays in the CLI while the predicate is shared, and "due" as two first-class axes (date and graph).
  • ADR-0026 — Test discipline: proven-dead guards by neutralization, equal-work comparisons replacing wall-clock bounds, which side of a policy change moves (and that it is stated), hand-computed expected values, negative controls measured before committing.

Also updates the ADR index, the VitePress sidebar, and the CHANGELOG.

Stacked on #439 (the storage batch) so each PR's diff shows only its own ADRs.

Type of Change

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation updates
  • refactor: Code refactoring without feature/bug changes
  • perf: Performance improvement
  • test: Adding or updating tests
  • ci: CI/CD workflow changes

Checklist

  • npm run docs:build renders the new ADRs and sidebar entries
  • npm test passes (1907 pass / 0 fail / 2 platform skips — no code touched, run to confirm nothing regressed)
  • ADR index, sidebar and CHANGELOG entries consistent across the stack

Merging this stack: merge bottom-up. Once the base PR lands on main, retarget this one's base to main (gh pr edit 440 --base main) — GitHub only arms the closing keyword on a default-branch merge, so the issue stays open until then. Deleting each branch after its merge auto-retargets the PRs above it.

Closes #436

@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0384b80a-9151-414b-832b-79984ca33473

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Oct 11, 2026
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/435-adr-backfill-storage branch from c0f804d to fdce766 Compare October 12, 2026 02:09
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/436-adr-backfill-cli branch from 7316a92 to b2ebd69 Compare October 12, 2026 02:09
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/435-adr-backfill-storage branch from fdce766 to 6733b45 Compare October 12, 2026 02:22
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/436-adr-backfill-cli branch from b2ebd69 to 163cdf5 Compare October 12, 2026 02:22
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/435-adr-backfill-storage branch from 6733b45 to b675e3d Compare October 12, 2026 03:26
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/436-adr-backfill-cli branch from 5113060 to f25daaf Compare October 12, 2026 03:26
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/435-adr-backfill-storage branch from b675e3d to ecfdbf6 Compare October 12, 2026 03:44
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/436-adr-backfill-cli branch from 5465180 to 8a29cc7 Compare October 12, 2026 03:44
Third backfill batch from #436. Covers the CLI behavior contracts the
audit round found living only in PR bodies and review threads:

- ADR-0020: readiness and scheduling — one shared prerequisite gate
  (next, plan and dashboard cannot disagree), the two-case 'Blocked by
  prerequisites' report, due and blocked sets made disjoint, archived
  topics out of readiness AND blocked reporting but in the graph,
  quarantined notes never reported as blocked
- ADR-0021: the assessment surface — only supplied pillars written,
  corrupt stored values refused not clamped, non-scalars refused,
  exact-id-wins resolution, the availability delta computed the way
  plan computes readiness, the Feynman hint from the pillar table
- ADR-0022: adoption — a hand-written depends_on survives first
  adoption, batch filters refused in single-file mode with per-pattern
  accounting, single-file dry-run previews, --undo with the
  PALEE_OWNED_KEYS contract and the --drop-title opt-in rationale, the
  verified rollback journal
- ADR-0023: migrate --relabel-ties — the surface ruling (migrate, not
  adopt or validate), 'give the pass a route', the adjacency rule, the
  three counted refusals, existence-based vanished classification,
  rename detection by path, one derived set printed and written
- ADR-0024: exit codes and the machine-readable error contract — one
  classifier with the containment->3 and provider mappings,
  process.exitCode over process.exit, parsed-options JSON detection,
  and the honest note that the swap fixed a class, not a reachable bug
- ADR-0025: the application layer — the use-case table, policy stays in
  the CLI while the predicate is shared, and 'due' as two first-class
  axes
- ADR-0026: test discipline — proven-dead guards, equal-work
  comparisons over wall-clock bounds, which side of a policy change
  moves, hand-computed expected values, negative controls

Claims checked against src/application/get-next-topics.ts and
src/cli/exit-codes.ts plus the PR evidence. Closes #436.
'docs/02-1' was shorthand; the promise about dry-run not modifying
files lives in docs/02-1-topic-management-commands.md, and the full
name is what a reader can follow.
The table claimed src/application/resolve-topic-query.ts exporting
matchesTopicQuery. No such file or function exists — the resolver
stayed in the CLI layer as src/cli/topic-query.ts exporting
resolveTopicQuery, called by review, assess, progress and session.
The PR body (#400) described the extraction in those terms but the
shipped code kept it in the CLI; the ADR records what shipped, and
the fix makes the 'policy stays in the CLI' section consistent with
its own table (and with ADR-0021, which already used the real name).
The ADR credited 'tieStillHolds', which does not exist in the
codebase. The function that re-derives the predecessor decision
from the bytes about to be written is predecessorIntact
(src/cli/migrate.ts:323) — exported so the predicate has a test
that can fail, exactly as the ADR describes.
The ADR said a note skipped by the write-time recheck 'leaves the
exit code alone'. The shipped code is the opposite: the recheck
branch does stale++ AND hadConflict = true, and hadConflict maps
to ExitCode.Conflict (4) with 'Re-run to retry' — pinned by
test/cli-migrate-relabel-ties.test.ts:617 ('drift under the pass
is a conflict, not a success'). The sentence described the
derivation-time refusals' behaviour; separate the two cases and
state each exit code accurately.

Also in ADR-0025: #404's figures are approximate ('~561 ms',
'~224 ms'); carry the tildes.
- ADR-0024: 'Seven handlers' was a transposition — the source commit
  (09a1ffe) says nine handlers hard-coded ExitCode.Unexpected while
  five routed through exitCodeFor.
- ADR-0026: the SM-2 rounding expected value (2.5568) does not come
  from q=5 on the default 2.5 ease (that is 2.6); the test starts
  from a deliberate 2.456789, so +0.1 gives 2.556789, which rounds
  half-up to 2.5568. State the full derivation instead of the
  shorthand.
Three sources carry three numbers (#226's measured 333439/6067 =
55.0×, the test comment's 'about 20x', the assertion's '< small *
5'). Name the measured pair so the claim is independently checkable.
…n ADR-0026

#226's 55× is the corrected-vs-quadratic ratio; the test comment's
'about 20x' is the memo-less large-leg-vs-small ratio. Name both and
the 5× bound they clear, so a reader comparing ADR to test does not
read a mismatch that is not one.
@Kuldeep2822k
Kuldeep2822k force-pushed the docs/436-adr-backfill-cli branch from 8a29cc7 to a21d76c Compare October 12, 2026 03:58
…-0027–0028

Fourth and final backfill batch from #437.

- ADR-0027: the AI provider adapter and its network boundary — the
  injected Transport seam, test-connection as the only network call
  (enforced by test/ai-network-boundary.test.ts), the reserved-space
  refusals measured against Node's serialized form (fe80::/10 as
  fe[89ab] with fec0 outside, IPv4-mapped literals unwrapped because
  the hostname arrives as ::ffff:a9fe:a9fe, ::1 exempted first,
  .internal refused, RFC 1918 permitted by design), loopback-only
  plain HTTP, refused redirects, the streaming 256 KiB bound with
  cancellation, and credential handling (never argv, masked on show,
  PALEE_API_KEY precedence, the Windows 'location, not ACL' ruling
  with its recorded trade-offs)
- ADR-0028: the four Phase-2 designs recorded as Proposed, not
  decided — #24 provider abstraction, #70 deterministic recommendation
  engine, #206 downgrade-only AI chain verification, #224 per-edge
  policy — plus the external bug-ledger gap (Supervisor ruling 3 of
  2026-09-25 cited from a shared/bug-ledger.md that was never
  committed)

Claims checked against src/ai/provider.ts. Closes #437.
'*Why Rejected (for now)**' had one opening and two closing
asterisks; every other alternative in the backfill uses
'*Why Rejected*:'.
The H1 is 'Phase-2 Design Directions'; the status lives in the
Status line, as it does for ADR-0013, whose index entry has no
suffix either. Keep the index matching the file headers.
The git-log verification is only true as of the moment it runs;
say so, so the sentence cannot silently become false the day the
ledger is committed.
The ADR described only the link-local arm. The code's test is
/^fe[89ab]/ || /^f[cd]/ || /^ff/ — unique-local (fc/fd) and
multicast (ff) are refused too, and the sentence as written left a
reader unaware of both. Describe the full test.

Also drop the '(Proposed)' suffix from the sidebar entry: the
Status is in the page body, and README + H1 carry no suffix.
docs(adr): record the AI provider boundary and Phase-2 designs as ADR-0027–0028
@Kuldeep2822k
Kuldeep2822k merged commit 46bd31c into docs/435-adr-backfill-storage Oct 12, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant