Skip to content

test(metadata): #19246 does not reproduce — a packages[] artifact's top-level-only docs DO register - #19375

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-19246-toplevel-docs-registration
Sep 20, 2026
Merged

os-project-manager merged 1 commit into
mainfrom
claude/issue-19246-toplevel-docs-registration

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #19246

Verdict: the card does not reproduce

#19246 was filed NOT MEASURED, on a static reading taken twice independently (review flag D of 5747199582, and the #18431 dev): that a multi-package artifact's top-level-only docs register nowhere at boot. This round booted it. They register.

Both static readings were correct about the two places they looked, and wrong about the conclusion drawn from them:

  • resolveArtifactPackageOrder (packages/core/src/artifact-packages.ts) does return package bodies only when packages is present — confirmed, unchanged.
  • packages/runtime/src/app-plugin.ts does not register collections.docs — confirmed, its only docs mention is the APP_CATEGORY_KEYS presence list.

Neither file is the registrar. The registrar is MetadataPlugin._parseAndRegisterArtifact's residual sweep (packages/metadata/src/plugin.ts), which runs after the package walk and registers every top-level (type, name) slot that no package body claimed, stamped with the artifact's own manifest identity. Neither reading reached it.

The measurement

Fixture — the card's own e2e multi fixture (packages/cli/test/build-package-docs-attachment.e2e.test.ts, replicated outside that claimed directory), two packages with different namespaces, a flat src/docs/pkgdocs_index.md and a package-directory src/orders/docs/ord_playbook.md, each carrying a distinct marker string written into exactly one file on disk.

os build emitted the shape under test:

top-level docs:                       ['pkgdocs_index']     # THE SUBJECT
packages[com.example.pkgdocs.core]:   []
packages[com.example.pkgdocs.orders]: ['ord_playbook']      # THE LIT CONTROL

Boot — os dev --fresh -p PORT on that artifact, real process, real kernel (29 plugins), better-sqlite3 driver, seeded dev admin.

Query — GET /api/v1/meta/doc as an authenticated caller (both docs' effective audience is org, so an anonymous caller is filtered to [] by design — that empty answer is a fake zero, not a reading):

{"type":"doc","items":[
  {"name":"ord_playbook","label":"Orders Playbook","_packageId":"com.example.pkgdocs.orders",...},
  {"name":"pkgdocs_index","label":"Index","_packageId":"com.example.pkgdocs.core","_packageVersion":"1.0.0",...},
  {"name":"setup_overview","label":"Setup overview","_packageId":"com.objectstack.setup",...}
]}

With ?include=content, pedigree holds in both directions: pkgdocs_index carries MARKER-flat-doc-18431 (written only into src/docs/pkgdocs_index.md) and ord_playbook carries MARKER-package-doc-18431 (written only into src/orders/docs/ord_playbook.md). Neither item is an echo of the other, and a third doc from the platform's own com.objectstack.setup package rode along as an unplanned second control.

Instrument absence arm — the same fixture rebuilt with src/docs/ deleted, booted on a second port and queried identically, returns ord_playbook and setup_overview and not pkgdocs_index. The query can report a missing doc, so the presence above is a reading rather than a shape that always answers yes.

The boot says it out loud. The residual sweep is not silent — it warns, naming the count, the owner it fell back to and a remedy:

[MetadataPlugin] artifact 'ARTIFACT_PATH' carries 1 top-level metadata item(s) that none of its 2 package bodies declare. They were registered under the artifact's own manifest id ('com.example.pkgdocs.core') because no package in the artifact claims them, so every door will report that id as their owner. Rebuild the artifact so each collection it ships is carried by the package that owns it.

That remedy was checked rather than assumed: moving src/docs/pkgdocs_index.md to src/core/docs/ and rebuilding puts the doc on the core body (2 collected (2 from 2 package directories)) and the top-level docs key disappears from the artifact. The warning is actionable.

What this PR lands

One regression pin, in packages/metadata/src/plugin-artifact-packages-attribution.test.ts — the existing home for this door's attribution pins, whose load() harness drives the real _parseAndRegisterArtifact. Four cases: a premise guard on the fixture shape, the measurement (lit control asserted first, in the same load, with marker pedigree on both), the absence arm, and the warning.

No production code changes. packages/cli/src/utils/collect-docs.ts was not touched — the fence held, and nothing the measurement showed needed it.

The fixture's docs half is positioned by hand and the test header says why: composeStacks(…, { manifest: 'preserve' }) is not the producer for this one key — os build's docs collector places docs after composition, per #18431's ruling — so composing a docs-carrying stack would produce the additive both-places shape, which is precisely not the shape under test. The placement is the one read off the real build above.

Reverse verification

Both legs run from the committed state, with the mutation proved on disk by anchor/injection counts and blob hash, and restored byte-identically (git hash-object back to the HEAD blob, git diff HEAD empty).

leg mutation result
baseline none 11 passed / 11
narrow ablation the residual sweep's guard if (carriesPackages) { forced false, package walk untouched 3 failed / 11 — registers BOTH …, says out loud …, and the pre-existing keeps a top-level item that NO package body declares

The narrow leg is the discriminating one. The new registers BOTH case goes red while the absence arm stays green (with the sweep off, the doc-absent world is unchanged) and the control ord_playbook keeps registering through the package walk — so the pin fails on the subject, not on the harness. A blunter first leg (replacing the call itself, which throws) took 8 of 11 down and is recorded here only as the reason the narrow one was run.

Local verification

  • pnpm --filter @objectstack/metadata exec vitest run --maxWorkers=2 src/plugin-artifact-packages-attribution.test.ts — 11 passed (11), at 2cc69a66.
  • Gate families derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack against this tree (1 changed path, +130/-0) and run: 50 of 51 green.
  • pnpm check:dual-build-cjs-loads answered PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/ (13 packages unbuilt in this worktree). NOT MEASURED, not a failure and not a pass; it needs a whole-repo pnpm build, and this diff is one test file that changes no dist/.
  • Whole-farm scans (pnpm lint and the CI-shell job steps dispatch-gates lists as unmeasurable locally) are CI's run, not this branch's.

Changeset

skip-changeset. Measured, not assumed: @objectstack/metadata ships files: ["dist","README.md","CHANGELOG.md"]; a symbol unique to the new test (pkgdocs_index) has 0 hits across those paths, while the positive control — a string from plugin.ts that does ship — has 4. A src/*.test.ts file publishes nothing.

Clause-②: no

Acceptance notes

维护者速读(草稿)

改了什么 — 只加了一个测试。没有改任何生产代码。

为什么改 — #19246 是一张「没人实测过」的卡:两位评审各自静态读代码,都得出「多包制品的顶层 docs 在启动时哪里都没注册」。这一轮真的把它跑起来了:用卡里点名的 e2e fixture 编译出制品、启动真实服务、带登录态查 /api/v1/meta/doc,顶层那篇 doc 在,并且同一次查询里那篇「一定会注册」的分包 doc 作为对照也在。两位评审看的两个文件都没错,只是注册它的既不是那两个文件,而是 packages/metadata 里的 residual sweep。所以卡的结论被推翻,这个 PR 把这次测量钉成回归测试,免得下一个人得出第三次静态结论。

风险与代价(含回滚) — 风险接近零:新增的是测试文件,不进任何 npm 包(已实测 files[] 里零命中)。回滚就是 revert 这一个提交。代价是往一个已有测试文件里加了约 130 行。

席位意见 — (留空)

你要做的 — 确认一件事就够了:#19246 应当以「不复现」关闭,而不是继续当 bug 排期。另外 #18431 在 hotcrm 上的 clause-5 验收会看到一条启动 warning(顶层 docs 无包认领),那是设计如此、且有可执行的补救,不是缺陷。


Generated by Claude Code

…s register

#19246 was filed NOT MEASURED, on a static reading taken twice independently:
that a multi-package artifact's top-level-only `docs` — the flat `src/docs/`
that #18431's ruling keeps at the top level — register nowhere at boot.

Measured instead of read. `os build` on the #18431 e2e fixture emits top-level
`docs: ['pkgdocs_index']` with the package doc `ord_playbook` on the orders
body alone; booting that artifact and asking `GET /api/v1/meta/doc` as an
authenticated caller returns BOTH, `pkgdocs_index` stamped with the artifact's
own manifest id. The registrar is `MetadataPlugin._parseAndRegisterArtifact`'s
residual sweep, which neither reading reached.

The new block pins that measurement against the same real door: the body doc
as the lit control, the top-level-only doc as the subject, an absence arm that
proves the instrument can report a missing doc, and the door's own warning.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QCdUBjM47SxioST9z5Zwdf
@os-project-manager os-project-manager added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 20, 2026 — with Claude
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing 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): node scripts/docs-audit/affected-docs.mjs --json ada701220b14d31c44b14cd531b50ca8ccaf233e → packageMentionDocs.

@github-actions github-actions Bot added the tests label Sep 20, 2026

Copy link
Copy Markdown
Collaborator Author

Seat grading — ACCEPT. The card does not reproduce, and the correction is the deliverable.

⭐ This is the outcome the dispatch named as complete: "if it does NOT reproduce, that is a finding worth writing down too — and it is a complete, acceptable outcome for this round." ⛔ No defect was manufactured to justify the round, and ⛔ the repro was not quietly widened until something broke.

What the seat verified independently on origin/main, ⛔ not taken from the report

claim check result
the registrar neither reading reached packages/metadata/src/plugin.ts _parseAndRegisterArtifact at :894, carriesPackages at :974, the if (carriesPackages) residual sweep at :1013, its warning at :1039 — present as described
static reading 2 was right about itself app-plugin.ts registers collections.docs 0 times — and mentions collections 33 times, so that grep was live, ⛔ not a dead zero
static reading 1 was right about itself core/src/artifact-packages.ts resolveArtifactPackageOrder present
scope GET /pulls/19375/files 1 file, +130/−0, packages/metadata/**
the fence held diff scanned packages/cli/src/utils/collect-docs.ts untouched — it was claimed by PR #19352 at dispatch time
CI both layers 0 failed runs, 0 failed suites

⭐ Why two independent readings agreed and were both wrong

Both were correct about the files they read. resolveArtifactPackageOrder really does walk bodies only when packages is present; app-plugin.ts really does register no collections.docs. The conclusion was wrong because the registration happens in a third file neither reading opened.

⇒ ⭐ agreement between two static readings is only evidence when they looked in different places. These looked at the same two, so the second reading added confidence without adding coverage. That is the same failure shape as a lit control that certifies the instrument but not the question (#18755).

⚠️ This is also the argument for how the card was written. It was filed NOT MEASURED, with "reproduce first" as the deliverable, rather than as a defect. Had it been filed as a defect, the likely outcome was a dev "fixing" a registration path that was never broken.

The measurement, and the fake zero it caught

Booted the card's own two-package fixture through a real os build + os dev --fresh, then asked the live surface. Authenticated GET /api/v1/meta/doc returned both the top-level-only pkgdocs_index and the lit control ord_playbook, each stamped with its own _packageId and each carrying a marker written into exactly one file on disk.

Two things make that a measurement rather than a green light:

  1. an absence arm that can show absence — src/docs deleted, rebuilt, rebooted → the same query returned 2 docs with pkgdocs_index gone. ⇒ the query is capable of reporting a missing doc, so its earlier "present" was not a query that always says yes.
  2. ⭐ the dev found and recorded a fake zero of its own: anonymous GET returns items: [] by audience design. It named that as a fake zero rather than reporting it. ⛔ An unauthenticated empty answer here would have "confirmed" the card.

The ablation closes it: forcing the residual sweep's carriesPackages guard false turned the two new cases red (plus a pre-existing orphan case) while the control kept registering and the absence arm correctly stayed green; restore proven by blob hash back to 0bdb14843b86 with an empty git diff HEAD.

⭐ The pin is what makes a negative result durable

+130/−0 in packages/metadata/src/plugin-artifact-packages-attribution.test.ts. ⛔ A non-reproduction reported only in prose decays the moment someone edits that path — the next reader gets a third static reading. This one leaves a measurement that goes red if the registration ever does break the way the card predicted.

Disposition of #19246

The card is not reproduced. Its two static readings are corrected on the card itself, and the pin carries the correction forward. ⛔ It was never a defect, so nothing is "fixed" — the round discharged the question it was filed to ask.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] a multi-package artifact's top-level-only docs appear to register nowhere at boot (NOT MEASURED — reproduce first)

2 participants