docs(rest): the ?type= diagnostics comment describes today's tree, and names the inner gate it sits above - #15619
Conversation
…d names the inner gate it sits above The call-site comment beside `GET /meta/diagnostics`'s `?type=` arm asserted that `getMetaItems` applies no registry gate of its own, so the scope of a sweep is decided at the door, per type, by the caller. That was measured and true when it was written. #14683 put `organizationIdForMetaRead(request.type, request.organizationId)` inside `getMetaItems`, after the canonical fold, and the sentence has been false since. The design question the card opens — is the door-side predicate defence in depth, or is it now redundant? — is answered KEEP, from two measurements rather than a preference: * the VALUE is redundant. Both sites fold the identical string through the identical map (`canonicalMetaUrlType` at the door; the same function inside `getMetaItems` via `canonicalizeMetaRequestType` -> `canonicalMetaType`), so `f(t, f(t, o)) === f(t, o)`. Measured: swapping the door's predicate for a raw `diagnosticsCtx?.tenantId` leaves rest-server-meta-read-org-scope.test.ts 30/30 green. * but the two gates are not in the same TRUST DOMAIN. `getMetaDiagnostics` is not a member of `MetadataProtocol` — not required, not optional — which is why the door reaches it through `(p as any)` and 501s when it is absent. The inner gate therefore belongs to one implementation of an undeclared extension, while the door-side predicate holds for every `RestProtocol` a host can mount. Comments only; no observable behaviour moves, on either branch. The harness the card names is corrected in the same pass: its header carried the same falsified sentence and an ablation recipe ("swap the predicate for a raw ctx?.tenantId and that assertion, and only it, turns red") that no longer discriminates. Measured 30/30 green under that mutation, and 6 failed / 24 passed under the mutation that drops the organization -- which is what the file does still pin. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
📓 Docs Drift Check
What this run could not see
Coarse fallback — 13 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
⛔ Correction — this PR is RED, and my ACCEPT did not say soI posted the ACCEPT for this PR on #15034 ( The ACCEPT stands on substance — the comment text, the KEEP ruling on the inner gate, and the comments-only verification are unaffected. What was wrong was the implication that the PR was therefore ready. It is not, and it has not been since before I reviewed it. ⛔ It has not been flipped ready and has not been enqueued. The failure, read from the log
All ten are in Pair them in order: +44 on every pair, counts equal at five and five. So the reading is a uniform line shift — this PR's added comment lines pushed the elevation-read sites down, and The gate names its own remedy, and its self-test proves it distinguishes the two cases ( A repair is dispatched. ⭐ What this seat got wrong, generalisedI verified that both changed files' diffs were comments-only and treated that as evidence the change was inert. It is not:
This repository anchors documentation into This is the sixth time this seat has carried a claim about a PR's colour that it did not re-read. The rule I had already written — "parked, green, awaiting tier" is THREE claims, and the middle one is a CI reading with a timestamp — is correct and I did not apply it here. The one thing that went right is that the re-read happened before an enqueue, not after.
|
… after the +44 comment shift The `?type=` diagnostics comment added 44 lines above every `isSystem` read site in `packages/rest/src/rest-server.ts`, and row 50 of the system-context census anchors that file by line number, so all five citations rotted by exactly 44. Repaired with the gate's own `node scripts/check-system-context-census.mjs --fix`, which REFUSED ZERO files: per-file the page's distinct anchor count still equalled the lines the file offers, so the rewrite is a pure shift, not a guessed mapping. Verified rather than assumed: the full census JSON at the merge-base and at this head differs in exactly five `line` fields, each +44 -- same sites, same order, same receivers, same text counts. No elevation read site arrived or vanished. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
Green. Flipped ready and enqueued.All 37 check runs completed, every one success or skipped. ⭐ The +44 hypothesis held, and it was tested properlyI handed the repair a hypothesis derived from arithmetic on a log and told it to trust the gate over me. It tested rather than adopted, and the way it tested is the part worth keeping:
⭐ And the reason that was necessary rather than pedantic:
Comparing the content at each anchor would have looked like a match no matter which of the four it landed on. Comparing the whole census structure is what actually proves no elevation read site arrived or vanished. The comment diff this PR was accepted for is untouched.
|
Fixes #15034
Comments only. No observable behaviour moves, on either branch of the design question — the whole diff is comment text, proven mechanically below.
The design question, answered: KEEP — defence in depth
The card's first unit of work is a deliberate answer, not a merge resolution. Answered from two measurements rather than a preference, and the two point in opposite directions — which is the finding.
1. The VALUE is redundant, and measured to be
Both applications fold the identical string through the identical map:
canonicalMetaUrlType(diagnosticsType);getMetaItemsfolds withcanonicalizeMetaRequestType→canonicalMetaType→ the samecanonicalMetaUrlType, one statement before its own gate.getMetaDiagnosticssetstargetTypes = [request.type]on the?type=arm and passes that same raw segment down, sof(t, f(t, o)) === f(t, o)and the inner application is the algebraic no-op. There is no path reachable from this arm that hands the inner gate a type the door has not already folded.Ablation M1 — swap the door's predicate for a raw
diagnosticsCtx?.tenantId. Predicted direction stated first: stays green, because the inner gate re-folds.Green. The door-side predicate buys nothing at runtime today.
2. But the two gates are not in the same TRUST DOMAIN — and that is why it stays
getMetaDiagnosticsis not a member ofMetadataProtocol— not required, not optional (packages/spec/src/api/protocol.zod.ts, the interface declaresgetMetaItems/getMetaItem/saveMetaItemplus a list of optional members; this is on neither list). That is exactly why the door reaches it through the(p as any)cast and answers 501NOT_IMPLEMENTEDwhen a kernel does not implement it, and whypackages/clientdocuments it as "501s on kernels withoutgetMetaDiagnostics".⇒ The inner gate belongs to ONE implementation of an UNDECLARED extension. The door-side predicate sits on the REST boundary and holds for every
RestProtocola host can mount. Delete it and a REST door's tenant scope becomes a function of which kernel is mounted.⭐ And the sharpest part: no pin can see that happen, because the harness boots the bundled implementation — M1 is the proof. So the DELETE branch is worse than the card's cost asymmetry estimated: it is not merely "owes one more pin", it is "owes a pin that cannot be written in this package".
The comment now carries this reason, per the acceptance criterion for the KEEP branch. No pin change owed.
Which site is which — established here, by symbol
The card and the routing notes cite two different anchors and they are two different things. Measured on the merged ref
ba426b0f091, unedited:origin/maindiagnosticsOrganizationId = organizationIdForMetaRead(:4808?type=computation// getMetaItems applies NO registry gate of its own::4757// organizationIdForMetaRead(canonicalMetaUrlType(:5536GET /meta/:type/:name/referencesTriage's verified anchor for "the comment" was
:5531, which on today's ref is:5536— the references door, not this card's site. Both sites quote the same string and both assert the same falsified clause, which is how they came to be conflated. The site this card is about is:4757.Inner gates re-verified on my own merged ref:
packages/metadata-protocol/src/protocol.ts:6958(plural, #14683) and:7583(singular overlay read, #14908).⭐ This call site sits above exactly ONE of them, not two.
getMetaDiagnosticsonly ever callsgetMetaItems; the singulargetMetaItemgate is under the by-name read door and this arm never reaches it. The comment says so.The harness is corrected too, because M1 falsified it as well
packages/rest/src/rest-server-meta-read-org-scope.test.ts— the file the card's acceptance criteria name as the ready-made harness — carried the same falsified sentence in its header, plus an ablation recipe that M1 measured false:It does not turn red. Same fate as #14677's ablation B, for the same reason. Its inline
PREDICTED DIRECTIONnote said the same thing and is corrected with it.Ablation M2 — what the file does still discriminate: drop the organization the
?type=arm passes. Predicted red, and red:Taken in scope under the bounded in-place rule, all four conditions checked: same defect class and the same sentence; mechanical, with M1 as the pinning evidence; 33/33 open PR heads measured, 0 hits on this file or on
rest-server.ts(git, against each head's own merge-base — extends the dispatch note'srest-server.ts-only scan); same gate family, no new verification surface.Ablation hygiene
Both legs: predicted direction stated before running · mutation proven on disk by counting both the removed text and an injected marker (a zero-hit edit would have exited 0 and read as a clean run) · restored under a
trapwith absolute paths · restore proven by blob-hash equality against the HEAD blob and an emptygit diff HEAD, empty hash treated as failure:Resolution path, stated:
packages/rest's vitest config aliases onlyplugin-hono-serverandservice-datasource, so@objectstack/metadata-protocolresolves throughdist/— registered inKNOWN_UNALIASED_TEST_IMPORTSunder@objectstack/rest. A source-only mutation of the inner gate would have measured nothing, so the closure was built first and the artifact checked before any reading:grep -coverpackages/metadata-protocol/dist/index.jsreturns 2 occurrences oforganizationIdForMetaRead(request.type, request.organizationId)— both inner gates live in the artifact the suite actually resolves. The mutated file itself (rest-server.ts) is source-resolved through a relative import, so no rebuild was owed for the mutation legs.typecheckis on the other axis — its tsconfigpathsredirects the same specifier to source.Verification
Union re-derived from the real changed paths with
scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstackon a tree the tool does not call stale (the first derivation reported STALE TREE, 4 commits behind; fast-forwarded toba426b0f091and re-derived). 31 families run; the ratchet families re-run after that round's final commit, atd993d6c1e42, all exit 0. (The repair round below re-derives and re-runs on the new head — that sentence describes the first round only.)Artifact-roster families were run rather than read as cleared:
check:error-code-casingandcheck:filter-alias-parityboth scoresilentfor every card, and both are green here.typecheckcoverage was verified, not assumed:packages/rest/tsconfig.jsonexcludes**/*.test.ts, sotsc --noEmitalone says nothing about the harness edit.--listFilesconfirmsrest-server.tsis in thetscprogram (1 hit) andrest-server-meta-read-org-scope.test.tsis in thetsconfig.test.jsonprogram (1 hit).No observable behaviour moves — mechanically checked, not asserted: every added and removed line in this diff is a comment line.
Repair round — the census gate's line anchors
The first push was red on one required context,
Lint & Repo Gates, and on one gate inside it:check-system-context-census. Its--self-testleg passed; the corpus leg reported 10 problems, all onpackages/rest/src/rest-server.ts— five[anchor-is-not-a-read-site](4972, 6386, 6634, 7065, 7258) and five[site-without-a-row](5016, 6430, 6678, 7109, 7302), pairing at a uniform +44.Cause.
content/docs/permissions/system-context.mdxrow 50 anchors that file by line number, and this PR's comment adds a net 44 lines above everyisSystemread site in it — hunks+7,+25and+12, all above:4755. Every citation below the insertion rotted by exactly 44.That it is a pure shift was verified against the tree, not inferred from the log. The whole census JSON, re-derived at the merge base and at this head, differs in exactly five
linefields, each +44:Nothing else moved — same sites in the same order, same receivers, same package and file lists, same text counts. No elevation read site arrived or vanished. (Line-content identity alone would not have shown this: four of the five lines are the same string, so the census diff is the load-bearing evidence, not the
sed -ncomparison.)Repair: the gate's own
--fix, never a hand-edited line number.⭐
--fixREFUSED ZERO files. Per the gate's header that sentence is the whole point: the refusal is the gate's only signal that a site arrived or vanished, so a clean rewrite is what separates a pure re-anchor from a population change that merely happened to be shifted at the same time. The diff is one table row, five numbers, nothing else.Gate exit code: 1 before, 0 after. Both legs green after the repair:
Union re-derived and re-run on the repair head (
a8cfb760115). The first derivation again reported STALE TREE (5 commits behindorigin/main, 3 of the gate-deriving scripts changed in that range), so the family list was re-derived a second time from a tree atorigin/maincarrying this change set. Both derivations agree: 73 runnable families, 62 matched by path. All 73 exit 0 ata8cfb760115, exit codes captured after redirection, never through a pipe.Six needed a second pass and none was a finding:
check:doc-formula-expressions,check:doc-security-posture,check:dual-build-cjs-loads,check:type-check-debtfirst answered exit 3 PREREQUISITE NOT MET — the workspace closure was unbuilt. Re-run afterturbo run build --filter='./packages/*' --filter='./packages/*/*'(the command lint.yml uses): all four exit 0.check:skill-examplesanswered exit 1 for the same reason in different words (packages/client-react/distheld no declarations). After the build: exit 0, 257 prose examples type-check.check:docs-audit-scopeanswered exit 1 on the pre-existingcheck:skill-examplesleavespackages/spec/.examples-build/behind, andcheck:docs-audit-scopethen fails its own self-test in the same working tree #15446 / check:docs-audit-scope (affected-docs --self-test) answers a finding's exit 1 on an unbuilt workspace — the contract-declaration case flips with the build state, where its siblings exit 3 PREREQUISITE NOT MET #15328 defect, not on this diff:check:skill-examplesleavespackages/spec/.examples-build*/behind,walkSourceFilesskips onlynode_modules,distand.turbo, so 233 gitignored byproduct files enter the walk and the live pin "every contract declaration admitted is a packages/spec API declaration" fails. Proven not ours: the same commit in a fresh worktree passes 568/568, and the polluted tree passes again once the byproduct directories are removed.A standing tax on this file, worth knowing before the next edit
system-context.mdxcitespackages/rest/src/rest-server.tsat eight absolute line numbers —:1553,:1582,:1585and row 50's five. The file is 12,864 lines, so any diff that changes the line count above:7302— comments included — rots at least one citation and reds this gate. It has happened before: the gate's own header recordsrest-server.tsdisplaced+3/+11by a merge, and a sibling file's shift "cost a patch round". The repair is one command, not a hand-written row, provided the diff neither adds nor removes anisSystemread site; if it does,--fixrefuses by design and a human writes the row.Changeset
skip-changeset, applied at PR-open time. The rule is.github/workflows/pr-automation.yml, Check Changeset step, route 2 — "it releases nothing". This diff is comment text plus a test file plus a docs line-number re-anchor: no public surface, no behaviour, nothing a consumer can observe.changeset-checkcarries no paths filter, so it does not skip for this diff on its own; the label is the mechanism. Confirmed still applied on the repair head, and theCheck Changesetrun reportsskipped.Fences honoured
packages/specread only ·packages/rest/src/error-response.tsuntouched (single writer, #14704, held by PR #15452) ·content/docs/releases/untouched ·protocol.tsuntouched — the enumeration finding below is filed, not edited, and PR #15592 is open on that file. The repair round's only new path iscontent/docs/permissions/system-context.mdx, which is hand-written docs and not a governed surface.Generated by Claude Code