docs(rest): correct the single-project fallback comment to the environments prefix - #16543
Conversation
…nments prefix The comment on `resolveRequestEnvironmentId`'s step 3 described the bare `/api/v1/data/...` fallback as taking effect when there is "no `/projects/<id>` prefix". ADR-0006 v4's second addendum (D2) renamed that scoped URL family to `/environments/:environmentId` with no alias and no dual-spelling interval, so the sentence names a prefix that no longer resolves. Prose only: the executable scoped-base construction in this file already spells `/environments/:environmentId` at 28 sites. The edit is a same-line substitution and leaves the file's line count unchanged, so the absolute line anchors that `content/docs/permissions/system-context.mdx` holds into this file do not move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YFY46JydE1gMxQG1TqBcMZ
📓 Docs Drift CheckThis PR changes 1 package(s): 6 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
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): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 258527c9b17a62869721cc5f66d1ab6525f66335 && git checkout 258527c9b17a62869721cc5f66d1ab6525f66335
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 70e77ec3b566b92d7c6551637d6bc746fb840bb6 83e61be2987efb89e789688152329015bfd46774 && git checkout -B drift-repro 70e77ec3b566b92d7c6551637d6bc746fb840bb6 && git merge --no-ff 83e61be2987efb89e789688152329015bfd46774
node scripts/docs-audit/affected-docs.mjs --json 70e77ec3b566b92d7c6551637d6bc746fb840bb6
|
Refs #15858 (item 1) · Part of #15858 (item 1 of the two the card names).
#15858 stays open for item 2 — the reason is below, and it is a real fork, not an oversight.
What this changes
One line of prose in
packages/rest/src/rest-server.ts, on step 3 ofresolveRequestEnvironmentId:ADR-0006 v4's second addendum (D2, executed 2026-08-28) renamed the scoped URL family to
/environments/:environmentIdwith no alias and no dual-spelling interval, so the sentence named a prefix that no longer routes.content/docs/api/environment-routing.mdxsays the same to callers: "there is no alias, so the old spelling does not resolve."The placeholder spelling
<id>is this file's own local convention, kept deliberately — the sibling comment on the scoped discovery route already writes/environments/<id>.Prose only. The executable scoped-base construction in this file already spells
/environments/:environmentIdat 28 sites, and the measurement below shows the edit moves no shipped byte.Item 2 is deliberately untouched
The card's other sentence — the
'platform'virtual-id docblock, which describes addressing the control plane "through the regular project URL shape (/projects/platform/...)" — is not edited here. Transliterating it to/environments/platform/...without first knowing whether that shape is still addressed at all would swap a known-stale sentence for one that may be equally stale while merely looking current, and a wrong reference that resolves is worse than one that dangles.What this repository can answer, and does, is only half the fork. Measured at
7a5592f5a:environmentId === 'platform'inrest-server.tsif (environmentId === 'platform') return this.protocol;, exactly the control-plane short-circuit the docblock describes!== 'platform'in the same fileenvironmentId === 'zzz-absent-virtual-id', same file, same predicate family/platform/URL-shaped literal in any packagesrcThere is also a live pin:
packages/rest/src/rest-env-resolution.test.tsasserts "keeps the'platform'guard — the reserved id is never handed to getOrCreate", driving it throughparams: { environmentId: 'platform' }, i.e. through a route parameter.⇒ The mechanism is live in this repo and pinned. ⛔ That does not settle the fork: whether any host still addresses it — the cloud repository's wiring — is out of this tree's reach. #15861 is the already-open reading request to the cloud seat on this exact ADR-0006 boundary and is the natural place for the answer to arrive.
Verification
node scripts/pm/dispatch-gates.mjs --commandswith no paths, letting it derive the change set from the merge base. Its own Reconciliation line reads 42 families,--commandsprinted exactly 42, and 41 exited 0.pnpm check:dual-build-cjs-loads, which exited 3 —PREREQUISITE NOT MET("this gate reads built output, and some package has no dist/"). ⛔ That is NOT MEASURED, not a pass. It is declared to CI, which builds the whole tree. See the byte-identity measurement below for why its verdict here cannot differ from its verdict onmain.pnpm --filter @objectstack/rest typecheck— green (tsc --noEmitpluscheck:test-typecheck: 0 files / 0 errors).pnpm --filter @objectstack/rest exec vitest run --maxWorkers=2 src/rest-env-resolution.test.ts— 20 passed (20), the suite covering the very method this comment sits in.check-system-context-census— green with no repair. That file anchors intorest-server.tsby absolute line number immediately below the edited line, so the edit was made line-count neutral on purpose: the file is 13442 lines before and after, and no anchor moved. The gate's--fixwas never needed.Why there is no changeset
Measured, not asserted.
@objectstack/restpublishes["dist","README.md","CHANGELOG.md"], so the question is whether this comment reachesdist. It does not, and the same file supplies both controls:dist/index.jsdist/index.cjs.d.ts/.d.cts//comment in the same method//comment lines surviving into the bundle at allprojects/platform, a block comment in this same fileresolveRequestEnvironmentId, a runtime identifier from this moduleesbuild keeps leading block comments and drops line comments inside function bodies, so this file has one comment that ships and one that does not — and the edited one is the one that does not.
sourcesContentis absent from the sourcemap, so the source text does not ship there either.The decisive check: rebuilding the package with only this file reverted to
7a5592f5aproduces byte-identical output, all four published artifacts:The mutation was proven to land on disk first (blob
d2957e407…vs5153c8e4d…, old-spelling count 1, new-spelling count 0), and the restore leg was verified by blob hash and an emptygit diff HEAD, then rebuilt.⇒ This diff publishes nothing, which is the
skip-changesetcriterion exactly. The label is applied.验收备注
Filed, not repaired here — #16538. While locating the two sentences, a third site in this same file turned out to carry the same retired ADR-0006 spelling in executable code, which corrects a premise of this family: the card states, and triage endorses, "This is prose only." That is true of the two sentences; it is not true of the file.
registerDiscoveryEndpointshas two siblingunscopedBasecomputations eleven lines apart. The MCP one strips/\/(environments|projects)\/:environmentId$/; the auth one strips only/\/projects\/:environmentId$/. SinceisScopedis true only when the base contains/environments/:environmentId, the auth regex can never match on the branch it guards, so a scoped discovery document advertisesroutes.authwith the scope still attached and an unsubstituted:environmentId— while the comment two lines above it states "Auth is a control-plane concern, so use the unscoped base." All three existing pins onroutes.authassert the unscoped base, where the branch never runs, which is why it is green today.It is filed rather than repaired here because it is executable and changes an advertised route value, so it needs a behavioural test — a new verification surface outside this card's prose-only scope, and repairing it here would falsify the very classification this PR is graded under.
Noted, not filed: nothing else.
Docs-drift rows — verified, ⛔ no docs edited
docs-drift-checklisted six hand-written pages plus one release-owned page against this diff. Verdict: CLEAN — none of the seven states anything this diff falsifies, and two rows are demonstrably spurious. ⛔ Nocontent/docs/**file was edited, andcontent/docs/releases/v17.mdxwas read only.The diff corrects a retired
/projects/URL spelling to the current one. The direct test is therefore whether any listed page states that retired spelling:/projects/resolveRequestEnvironmentId/api/v1api/client-sdk.mdxapi/metadata-api.mdxapi/plugin-endpoints.mdxkernel/contracts/metadata-service.mdxkernel/services-checklist.mdxprotocol/objectui/concept.mdxreleases/v17.mdx(read-only)The control discriminates: every page yields
/api/v1hits and most yield the word "project", so the grep reads the files and finds URL prose — and still returns a real zero for the retired segment.Two spurious rows, named:
resolveRequestEnvironmentId— the one anchor genuinely tied to the changed line — appears on zero of the seven pages. The row that named it is spurious on every page.content/docs/protocol/objectui/concept.mdxscores zero on all four anchors (getView,meta.getView,/view/:object/:type,resolveRequestEnvironmentId). Nothing connects it to this diff at all.The surviving anchors are about a different surface that merely co-inhabits this 13,442-line file:
client.meta.getView('account', 'list'),MetadataService.getView, andGET /ui/view/:object/:typeare the view metadata surface. The changed line is about environment resolution for bare/api/v1/data/...URLs. Same file, unrelated concerns.client-sdk.mdxdoes nameX-Environment-Id(step 2 of the very chain this comment documents) — already in the current spelling, so it is not falsified either.The structural argument stands behind all of it: this diff changes zero emitted bytes (measured above), so it cannot falsify documented behaviour by construction.
Grading
no— graded from the delivered diff. One comment line, no routing, contract or metadata change; the byte-identity measurement above is the evidence. ⇒ noneeds:contract-review.main. ⛔ Not flipped ready, ⛔ not enqueued.🤖 Generated with Claude Code
https://claude.ai/code/session_01YFY46JydE1gMxQG1TqBcMZ
Generated by Claude Code