docs(runtime): repoint the C4 boundary prose at the post-#16610 state - #17706
Conversation
`action-governance-scope-divergence.test.ts` described the C4 divergence as
a standing boundary: `plugin.ts` swallowing the throw, the assertions below
pinning that boundary, and the remaining change "tracked on its own card".
`ObjectQLPlugin.resolveGovernanceMetadataService` now asks
`getServiceScoped('metadata', environmentId)` first, in the router's own
order, so the throw is no longer swallowed and the boundary is narrower
than the file said.
Comment blocks only. The executable half is byte-identical: same 282
non-comment lines, same 13 `it(`, 1 `describe(` and 40 `expect(`. The
assertions exercise the kernel's raw synchronous accessor, not the plugin,
so they stay green and stay true — the accessor is exactly the rung the
plugin now reaches for second.
Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c
Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Review of record — ACCEPTHead reviewed: Reviewed-by:
Gates, exit codes captured before any pipeThe control returns the opposite verdict on the same predicate, so the gate is live and discriminating rather than green-by-default.
CI on this head
The prose's five load-bearing claims, each measured on
|
Fixes #16613
packages/runtime/src/action-governance-scope-divergence.test.tsdescribed the C4 divergence as a standing boundary. PR #16610 (card #15252) made that description false:ObjectQLPlugin.resolveGovernanceMetadataServicenow asksctx.getServiceScoped('metadata', this.environmentId)first — the router's own order, mirroringHttpDispatcher.resolveService— and falls back to the synchronousctx.getService('metadata')only when there is no scope to name or the host has no scoped accessor. The throw is no longer swallowed into "no metadata plane at all", and the boundary that remains is narrower than the file said.This PR repoints that prose. One file, comment blocks only.
The card's own switch was run, not assumed
The card names the switch that decides whether it is live at all: "while it reads 0 the prose is still true and this card is premature; once it reads 2 the prose is false".
The premise came back LARGER than dispatched — one of the two "already repaired" readings was a line-wrap artifact
The dispatch narrowed this card from three false statements to two, on a measurement that the third was already gone. Re-driven here on the same path, that zero does not hold: the phrase is present, wrapped across a line break plus the
*comment prefix, so a line-orientedgit grepcannot see it.origin/main:345:345:364:364:357-:358, wrapped#15252number itselfReproduction of the wrap, on the merge base:
Controls, so those zeros are readings: file = 497 lines,
describe(= 1, and the same fabricated-token probe exits 1 on this path too.So all three statements the card names were live, and all three are repointed here. The half that really was already repaired is narrower than reported: the file no longer cites the number
#15252, but it still told the reader the change was "tracked on its own card" — which #16610 landed.What the prose now says
environmentId, so a boot-time audit has no scope to name and the synchronous lookup stands.packages/objectql/src/plugin-governance-scoped-metadata.test.ts(verified present, 2 hits, read-only).Proof that no behaviour changed
⛔ Not one assertion,
it(ordescribe(was changed, reordered, renamed or added.The target suite is green on the changed file: 1 file / 6 tests passed.
Verification
Roster derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, re-derived aftergit fetch origin main— identical both times. All 51 commands run, every exit code captured before any pipe, then reconciled with--ran.51 derived, 51 run, 0 NOT-MEASURED, 0 UNRUNpnpm --filter @objectstack/runtime exec vitest run --project localon the changed filepnpm --filter @objectstack/runtime run test(fulllocalproject)pnpm --filter @objectstack/runtime run typecheckcheck:test-typecheckconfirms this file's layer really compilespnpm --filter '@objectstack/runtime^...' run buildpnpm eslint . --no-inline-config(full union)The lint union was run at
f7f8af68, the final commit of this PR. The changed file appears in eslint's own--format jsonoutput aterrors=0 warnings=0; a fabricated path does not appear, so the presence is a reading.Heavy runs went through
scripts/pm/os-verify-lock.shon slotissue-16613-c4-prose; the wrapper printedVERDICT command-exit 0.Two gates first came back exit 3 (
PREREQUISITE NOT MET— NOT MEASURED, never counted green). Both were driven to a real reading rather than left as holes:pnpm check:dual-build-cjs-loadsreads built output for the whole workspace, and this worktree had only the runtime dependency closure built. Built the closure exactly aslint.ymlspells it (pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*', exit 0, 72 tasks) ⇒ re-run exit 0.pnpm check:type-check-debtthen still exited 3, and its own output named the cause:tschitMark-Compact ... allocation failureat 4033 MB against the 4096 MB ceiling my resource-disciplineNODE_OPTIONSimposed — the cap truncated it, not the diff. Re-run with the heap raised on that stated reason (box had 15 GB free, lock idle) ⇒ exit 0:5 ledger entr(ies) re-measured in 127.3s, 55 raw tsc error(s) total, none above its recorded number.The reconciliation records an exit code per family, so its zero is derived rather than claimed:
all 51 accounted famil(ies) carry one ... none of them is 3.Changeset: measured, not assumed
skip-changeset.@objectstack/runtimedoes publish, so this was measured rather than argued:Symbols zero, positive control non-zero ⇒ nothing published moves.
Clause-②: no
The diff is a comment block inside a test file. It exports nothing, declares no schema key, adds no closed-set member, and moves no accept/reject verdict; the file's executable half is byte-identical. There is no contract surface for a review to act on.
Acceptance notes
it(title still reads "C4 — BOUNDARY: env-scopedmetadatais unreachable from a boot-time audit, before any read runs". Checked rather than assumed: the case buildsnew ObjectKernel({}), which declares noenvironmentId, so the title remains true for the composition it constructs — it is exactly the remaining boundary. No change needed, and the dispatch forbids one.Generated by Claude Code