docs(runtime): correct the publish-drafts app-read comment the meta read gate falsified - #15063
Conversation
…d gate `packages/runtime/src/domains/packages.ts` justified the publish-drafts app list read with "left org-aware on purpose — a layered read is a superset, never a loss". Since `getMetaItems` began resolving `organizationIdForMetaRead` on `request.type` itself, that read is env-wide for `app`: the registry declares `app` `allowOrgOverride: false`, so the predicate answers `undefined` and the `organizationId` this route still passes is dropped at the gate. The behaviour is correct and unchanged here — an org-scoped `app` row is an unhydratable phantom that `loadMetaFromDb` walks past, so dropping the organization is the repair. Only the justification was wrong, and it was wrong in the direction that invites the next reader to restore the organization and resurrect those rows. Comment only: the read, the gate and `organizationIdForMetaWrite` are untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
…ckages-org-aware-comment
📓 Docs Drift Check1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 24 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 b9659417663ec5813e576689eeb5160dafb8539b && git checkout b9659417663ec5813e576689eeb5160dafb8539b
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 101ad2cc13fafd8a3879ffc4a6ce6133c02ed832 686b6c0b21da755058ed1170d792f26aff36a3e3 && git checkout -B drift-repro 101ad2cc13fafd8a3879ffc4a6ce6133c02ed832 && git merge --no-ff 686b6c0b21da755058ed1170d792f26aff36a3e3
node scripts/docs-audit/affected-docs.mjs --json 101ad2cc13fafd8a3879ffc4a6ce6133c02ed832 |
…arity Brings in PR #15062 (`os i18n check --help`), which lands in packages/cli while this branch is open — the dispatch named it as the one to merge and re-verify against. Also #15065 (rest), #15063/#15067 (docs) and #15055 (spec). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
Fixes #14771
One comment. No behaviour change:
git diff origin/main...HEADis 19 insertions / 3 deletions in a single//block, and the file's token stream is byte-identical across the change (proof below).What was wrong
packages/runtime/src/domains/packages.tsjustified the publish-drafts app-list read with:That was true when written. It is not true now.
getMetaItemsresolves the read scope itself:and
organizationIdForMetaRead(packages/metadata-core/src/meta-write-org-scope.ts:184) returnsundefinedfor any type the registry declares non-overridable.appis one:So the
organizationIdthis route still hands the call is dropped at that gate, and the read is env-wide — not org-aware, and not a superset of anything.Why the comment was repaired and the code was not
The behaviour is correct. An org-scoped
approw is an unhydratable phantom:loadMetaFromDbwalks past it andreportUnhydratableOrgScopedRowsexists to say so. Reading org-scoped here would resurrect rows that vanish at the next restart, and flip_unpublishedon them instead of on the row cold boot actually hydrates — the resurrection #14683 closed, arriving from the read side.The danger was the justification, not the code: a reader who trusts "left org-aware on purpose" concludes the gate above them is a bug and restores the organization. The replacement states the mechanism, names the registry flag, and says plainly that dropping the organization is the repair.
⛔ Untouched, deliberately: the read itself, the gate, and
organizationIdForMetaWrite. My reading of the code found nothing wrong with any of them.Changeset fork: none,
skip-changesetinsteadMeasured from the package's own manifest rather than assumed:
@objectstack/runtimepublishes, butsrc/**is not in its tarball, and the edited bytes live inside a//comment in a function body, so they reach neitherdistnor the emitted.d.ts. This PR therefore declares no release of its own and carriesskip-changeset, which is exactly the label's stated criterion inpr-automation.yml.Verification
Exit codes captured before any pipe, never through one. Two shas are named because two things were measured at two points, and saying so is cheaper than a claim that will not hold up.
At the final HEAD
686b6c0b21(git rev-parse --short HEAD, after mergingorigin/main) — the gate union:Derived, not recalled:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstackgives 27 families (21 by path, 1 by change kind, 5 declared whole-tree). Re-derived after the merge and byte-identical to the pre-merge derivation, and re-run in full there.check:comment-mask-adoptionandcheck:comment-mask-corpus, pluscheck:nul-bytes,check:route-envelope,check:doc-authoring,check:type-source-resolution,check:published-files.check:dual-build-cjs-loads— "PREREQUISITE NOT MET ... some package has no dist/", naming 8 packages plus "29 more". It needs a whole-workspacepnpm build; CI's Build Core job owns that run, and the gate's own text says "This is NOT a pass: nothing was measured."check-test-completeness.mjswith no argument — structurally unmeasurable locally by the gate's own text ("There is no local log to hand it, so the local reading for this gate is NOT MEASURED").At
b6423975f9(the same one-file diff, one commit earlier, beforeorigin/mainwas merged in) — the package scripts, by name, all throughbash scripts/pm/os-verify-lock.sh -c ...and read from the wrapper's own VERDICT line:pnpm --workspace-concurrency=2 --filter '@objectstack/runtime^...' build→ exit 0pnpm --filter @objectstack/runtime typecheck→ exit 0 (tsc --noEmit, thencheck:test-typecheck: OK — 27 file(s) / 191 error(s) / 69 pinned signature(s) held)pnpm --filter @objectstack/runtime exec vitest run --maxWorkers=2over the fivesrc/domains/packages-*.test.tssuites → Test Files 5 passed (5) · Tests 111 passed (111)Declared narrowing: re-running those three at the merged HEAD is NOT MEASURED. Five attempts on the shared verify lock over roughly 45 minutes produced three queue timeouts (exit 99, "never acquired") and two container foreground-cap kills mid-build (exit 143), against holders that were other seats'
@objectstack/cliclosure builds and issue-14704 verification scripts. Recorded as NOT MEASURED rather than as a pass, and not as a red either. What backs the narrowing: the merge movedpackages/runtimeonly through PR #15018 onaction-execution.ts, a file this diff does not touch, and the token proof below makes it structurally impossible for these bytes to change any build, typecheck or test outcome at any base. CI's Type Check and Test Core jobs run the real thing on this PR.Token-identity proof. Scanning both revisions of the edited file with the repo's own TypeScript scanner (trivia skipped) gives 1895 tokens on each side and the same sha256
486a535c75603b833018aab0c2916254434e066d1cc6d105f430d4cadaf7b433, with a positive control — the same comparison against the token list minus its last element — correctly reporting a mismatch. So the diff is comment-only at the token level, not merely by inspection.Bounding the class, without widening the diff
Asked as a side question and answered by measurement, not fixed here. Method: enumerate every non-test metadata read call site in
packages/runtime/src/**(agit grep -n -EovergetMetaItems|getMetaItem|getMetaItemLayered|listMetaItems|getMetaDiagnostics|findReferencesToMetawith an explicit:(glob)packages/runtime/src/**/*.tspathspec — 9 sites, and the same pathspec returns more when test files are included, so it is live and not silently matching zero), then read the comment attached to each.Two comments in that package state the pre-gate rule. One is the sentence this PR repairs. The other:
seedisallowOrgOverride: false(metadata-plugin.zod.ts:808), so both attempts in that ladder now resolve to the identical env-wide read and "try the active org first" describes a scope step that no longer exists. Same class, same file, ⛔ deliberately not touched here — it is a card, not a rider.Not members, checked and distinguished: the
readMergedSkillRowsdocblock indomains/mcp.tsalready states the correct rule forskill; thegetMetaItemLayerednote atdomains/meta.ts:334describes a primitive the read gate does not reach; and the fourdomains/meta.tsread sites carry comments about masking and draft preview, asserting nothing about org scope.🤖 Generated with Claude Code
Generated by Claude Code
Generated by Claude Code