Uh oh!
There was an error while loading. Please reload this page.
docs(cli): the ⛔ notes over ORGANIZATIONS_RUNTIME_PKG state the reason that survives the resolver hop - #12636
Conversation
… ORGANIZATIONS_RUNTIME_PKG The organizations package spelling is declared twice inside `packages/cli`, and four docblocks explained why with the same reason: the host-anchoring sweep in `serve-cluster-host-resolution.test.ts` resolved the load through `Serve.ORGANIZATIONS_RUNTIME_PKG` and needed a LITERAL in `serve.ts`, or the load dropped out of the swept population silently. That reason died at `1ca763b60` (#12533, PR #12582), which taught `resolveIdentifier()` to follow an import alias into a sibling module of the same package. A true prohibition carrying a false explanation is worse than no note: the next author reads it as arbitrary and steps over it. Comment-only. Each note now records the constraint, the commit that retired it, and what actually survives — the duplication is CHECKED rather than required, and whether to end it is an open maintainer-facing decision (#12579). The ⛔ in `tenancy-posture-hints.ts` against importing `Serve.ORGANIZATIONS_RUNTIME_PKG` into the shared module is untouched: its reason is #12464's coupling ruling, not the sweep. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd
📓 Docs Drift CheckThis PR changes 1 package(s): 17 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 4 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 23 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 fabc6041352099099eeeffd9f9d0163dd9872d68 && git checkout fabc6041352099099eeeffd9f9d0163dd9872d68
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin aa5994e17a47187c5a09bc82b1fc1163f250092b 40ce969b1c0e6937a40aaffb1eb37fa0114c278b && git checkout -B drift-repro aa5994e17a47187c5a09bc82b1fc1163f250092b && git merge --no-ff 40ce969b1c0e6937a40aaffb1eb37fa0114c278b
node scripts/docs-audit/affected-docs.mjs --json aa5994e17a47187c5a09bc82b1fc1163f250092b
|
Uh oh!
There was an error while loading. Please reload this page.
Part of #12579 — fork (a), the note repair. Comment-only.
⛔ Deliberately not a closing keyword. The dispatch asked for one; fork (b) — actually
single-sourcing the spelling — is maintainer-facing and is NOT in this diff, and the four
docblocks rewritten here now point at #12579 as the place that decision is open. Closing the
card would leave four notes citing a closed issue and drop the open half out of every
is:openfilter. Flip it to a closing keyword in one edit if the lane wants the card closedanyway; that direction is cheap and merging the other one is not.
What was wrong
Four docblocks carried the same explanation for the same ⛔: that
Serve.ORGANIZATIONS_RUNTIME_PKGmust stay a string literal inserve.tsbecause thehost-anchoring sweep in
serve-cluster-host-resolution.test.tsresolves the organizationsimport()through that static and, quoting the spelling test, "needs the literal in thatfile, or the load drops out of the host-anchoring sweep silently".
That was true, and measured true — #12492 attempted exactly that rewrite and the sweep's
named vacuity guard refused it by name. It stopped being true at
1ca763b60(#12533,PR #12582), which taught
resolveIdentifier()to follow an import alias into a sibling module of the same package.A true prohibition carrying a false explanation is worse than no note: the next author reads
it as arbitrary and steps over it.
Re-derived on
origin/main@0043c9224by grepping the reason's fingerprints(
drops out of the host-anchoring sweep,string LITERAL,re-export of,silent-vacuity,one more hop/one further hop,LITERAL IN THAT FILE), each reverse-checked againstORGANIZATIONS_RUNTIME_PKG, a term known present in all of these files:packages/cli/src/commands/serve.tspackages/cli/src/utils/tenancy-posture-hints.tspackages/cli/src/commands/serve-organizations-message-spelling.test.tspackages/cli/src/commands/doctor-organizations-message-spelling.test.tsserve.tsor the host-anchoring sweep … can no longer resolve which package that command'simport()names"Site 4 is the same defect, one file further along the same citation chain, and repairing three
of four would have reproduced exactly the failure ruling ① exists to refuse. It is in this diff.
Nothing else in the tree carries the reason.
serve-cluster-host-resolution.test.tssays"deliberately a duplicated LITERAL today" and "single-sourcing a spelling silently empties
the sweep" — both still true (the first is a fact about today, the second a counterfactual
about deleting the hop), so that file is untouched.
What each note says now
Each site records three things instead of one: the constraint as it stood, the commit that
retired it, and what actually survives. The dead reason is stated as history rather than
deleted — a reader who meets neither half re-derives it from the duplication and puts the
⛔ back.
tenancy-posture-hints.ts's ⛔ read on its own terms: still valid as writtenThe ⛔ there is "Do NOT close the gap by importing
Serve.ORGANIZATIONS_RUNTIME_PKGhereinstead", and its reason is "this module is read by
os doctor, and a diagnostic commandtaking a dependency on a
servecommand's export in order to spell a package name is a worsecoupling than the duplication it removes (#12464's ruling, unchanged)". That is a
coupling-direction ruling. It has nothing to do with the sweep, the hop does not touch it, and
its wording does not imply the dead reason. It is kept verbatim — including the
connective "instead", whose referent (the paragraph above it, about ending the duplication
for real) is preserved rather than removed.
What was stale in that same docblock is the two paragraphs around it: the⚠️ one carrying the
sweep reason, and "an edit to a file #12492 does not own, and which was in flight elsewhere
when this landed" — the hop landed, so that clause is now false too. Both repaired.
⭐ Ruling ⑤ — the reason that survives, measured rather than assumed
Does any reason remain for the literal to be in
serve.tsspecifically? Measured: no.serve.ts's SOURCE for a packagespelling. Everything else that reads this value reads the value:
test/serve-capability-vocabulary.test.ts(roster key), site 8 ofserve-organizations-message-spelling.test.ts(equality), doctor's leg (ii). All three arealias-safe.
serve.ts—check-route-envelope.mjs,check-wildcard-fallthrough.mjs,cross-package-test-inputs.mjs,slot-lookup-baseline.json— read it for other populations, none for a package spelling.
"resolves an alias to a literal in a REAL sibling module of packages/cli" reads the live
packages/cli/src/utils/tenancy-posture-hints.tsthroughserve.ts's own scan context, anda sibling case pins "the shape the refactor writes".
Serve.ALWAYS_ON_CAPABILITIESis already assigned from animported const, so a static sourced from an import is not itself the problem.
⇒ the honest answer, and what the notes now say: the only stated reason is false, and fork
(b) is the open question. Not "⛔ don't, because someone decided so" — that is the
arbitrary-prohibition failure this card exists to end. Two constraints are recorded as
outliving the decision either way: the static keeps its NAME (the roster pins address
Serve.ORGANIZATIONS_RUNTIME_PKG; only a spelling may move), and the gap is never closed inthe other direction.
⛔ Site 8 stays
Untouched. While there are two declarations the pin has a subject; the note now says so
explicitly and says deleting it belongs to the reversal, not to this repair.
⛔ Not taken here
The reversal itself. PR #12532
shipped the duplication deliberately with reasoning at both ends, so ending it is a
maintainer-facing call. It is now easier to decide, which was the point of doing this first.
Verification — all on
40ce969b1, the final commitProof the diff is comment-only. Both blobs of all four files transpiled with
removeComments: trueand the emitted program hashed (sha256, first 16 hex):The instrument is reverse-checked in both directions, or the equality means nothing —
in memory, against git blobs, so the working tree was never mutated:
Tests —
pnpm --filter @objectstack/cli exec vitest run --maxWorkers=2over a declaredconsumer set (the full
packages/clisuite does not finish in this container's foregroundwindow; ⛔ narrowing declared, CI runs the farm):
The four:
serve-cluster-host-resolution.test.ts(the sweep — it reads BOTH edited sourcefiles as text, so it is the one that could have gone red on a comment edit),
serve-organizations-message-spelling.test.ts,doctor-organizations-message-spelling.test.ts,test/serve-capability-vocabulary.test.ts.Typecheck —
pnpm --filter @objectstack/cli typecheck(tsc --noEmit) exit 0, and it isnot a vacuous green:
tsc --noEmit --listFileslists all four edited files (1 hit each of 1279).Gates — dependency closure built first (
pnpm --filter '@objectstack/cli^...' build,exit 0). Families from
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(16 matched + the test-file convention kind); exit codes captured before any pipe. All green,
quoting each gate's own verdict line:
check:nul-bytes— "OK (scanned 6986 text file(s) … no raw ASCII control bytes)"check:comment-mask-adoption— "OK … 20 private comment-stripper(s) … all 20 recorded"check:slot-lookup— "slot-lookup ratchet holds: 107 unswept site(s) … baseline key set verified against 0043c92: no files added"check:route-envelope,check:cross-package-test-inputs("20 package(s) read outside themselves, all declared"),check:page-declaration-shape,check:published-files,check:test-source-alias,check:type-source-resolution,check-ci-filter-parity,check-plugin-teardown-shape,check:engine-double-contract,check:where-matcher,check:query-options-erasure("none new … baseline key set verified against 0043c92"),check:type-check-coverage— all exit 0pnpm lint(eslint . --no-inline-config) — the whole repo, exit 0 in 95s. ⛔ Nonarrowing was needed, so none is claimed.
Not run locally:
check:i18n/check:i18n-coverage(needpackages/cliitself built) andcheck:type-check-debt --re-measure(needs the whole workspace closure built) — CI runs thefarm regardless.
Changeset
None, and
skip-changesetapplied instead. The rule used is AGENTS.md's: "Add achangeset for feature work … Pure bug fixes do not require a changeset." This is neither —
it is comment-only and, proven above, emits a byte-identical program, so it releases nothing.
The repo's
changeset-checkis path-agnostic, and an empty-frontmatter changeset is refusedfor new files, so the label is the mechanism here.
Generated by Claude Code