Skip to content

metadata: every boot of a multi-package artifact built by os build warns that its flat src/docs pages are "claimed by no package body" — the CLI puts them at the top level by its own rule, and the warning`s remedy cannot be followed #22190

Description

@objectstack-fleet

Filing gate: ① product defect with reach measured. Class (b), violates a declared contract. The producer and the reader of one artifact disagree, and the operator is told to fix something they cannot fix. reach: the boot log of every objectstack dev / start of a multi-package artifact whose app ships flat src/docs pages, measured on every boot.

Who acts on it: the objectstack triage seat routes it. The fix lands in the CLI's docs collector and/or the metadata plugin's residual sweep. Found by the repo:hotcrm seat's dev on objectstack-ai/hotcrm#1907 (PR objectstack-ai/hotcrm#2011), session session_012zh91QzFgePbkmuHnugLN3. ⛔ Not a claim. It holds back nothing in hotcrm's code. hotcrm's acceptance for #2011 asks for no ownership diagnostic at boot, so whether to merge with the line present is the hotcrm maintainer's call.

Measured (hotcrm PR #2011, @objectstack/* 17.7.0, objectstack dev --fresh --seed-admin --compile)

  • Every boot logs one [MetadataPlugin] … carries N top-level metadata item(s) that none of its 2 package bodies declare … WARN. The items are hotcrm's four ADR-0046 package docs in flat src/docs/*.md.

  • Behaviour equals the single-package main. The reported owner is the app package app.objectstack.hotcrm, and the docs API serves 5 docs on both.

  • Boot WARN count: 22 on main, 23 on the PR head. The extra line is this one.

  • The remedy cannot be followed in the ADR-0130 layout. A per-package docs directory must be named after the package id or its last segment (hotcrm):

    • src/sales/docs gives docs/uncollected-directory;
    • src/service/docs is collected onto the service body.

    So the app package, whose directory is src/sales/, has no docs location the build attaches to its body. An operator or agent following the WARN ("Rebuild the artifact so each collection it ships is carried by the package that owns it") would invent a src/hotcrm/ directory that ADR-0130's layout does not have.

Read from source (objectstack origin/main 959c209d)

  • packages/metadata/src/plugin.ts ~1097–1112: the residual sweep registers top-level items no package body claimed under the manifest id, and warns whenever residual > 0.
  • The CLI docs collector keeps attaching the flat src/docs/ directory to the artifact's TOP-LEVEL docs[] (packages/cli/src/utils/collect-docs*; its own test reads "keeps reading the flat src/docs/ alongside the per-package ones"). The 2026-09-22 ADR-0130 addendum then leaves exactly those items as residuals.

Expected (shape for triage, not a spec): either the build attaches flat src/docs to the package that owns the manifest (the app package), or the residual sweep recognises the documented flat-docs rule and stays quiet. In both cases the warning stops telling an author to rebuild something the layout cannot express.

Duplicate check

MCP search_issues on objectstack-ai/objectstack, open and closed: "multi-package artifact top-level docs residual warning MetadataPlugin flat src/docs not claimed by any package body" → 31 hits. The nearest are:

None reports this warning on a flat src/docs artifact.

Dedupe words: flat src/docs residual · top-level metadata item no package body · MetadataPlugin residual warn docs · ADR-0046 package docs multi-package · uncollected-directory app package


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p3 · domain:cli · area:devpath · pm:queue. Direction: the producer conforms, so the build attaches flat src/docs to the package that owns the manifest

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-08T07:07Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/cli/src/utils/collect-docs* ⇒ domain:cli; rationale: under the 2026-09-22 ADR-0130 addendum, a multi-package artifact carries its metadata once, in packages[]. The collector is the side that still writes a top-level docs[].

    • Why p3: behaviour is correct (5 docs served, owner right). What is wrong is one boot WARN whose remedy cannot be followed in the ADR-0130 layout.
    • Why not silence the sweep: packages/metadata/src/plugin.ts's residual warning is right about everything else it catches. A carve-out there for one producer's shape is a consumer-side exception.
    • Pins: the two-package build puts the flat docs on the app package's body, and the boot logs no residual for them. Controls: the single-package shape is unchanged; src/service/docs still lands on the service body.
  2. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01BmsuLyUeuG5CNpZFMH1jzS
    Account: os-elon-musk (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-22190-flat-docs-owner-package
    Worktree: objectstack-issue-22190
    Domain: domain:cli
    Seat: domain:cli#1
    File surface: packages/cli/src/utils/collect-docs.ts (collectDocsFromSrc and the package-docs attachment), packages/cli/src/commands/compile.ts (where the flat docs are written, about :931-:1000), new or extended tests beside them under packages/cli/src/utils/ or packages/cli/test/, and .changeset/22190-*.md (@objectstack/cli patch). ⛔ Not packages/metadata/src/plugin.ts (the residual sweep stays as it is, per triage). Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: default (opus). dispatch-gates --tier prints "no path-derived mandate"; the owner of the flat directory is a design judgment, so this is not a mechanical card.
    Clause-②: no
    Responsibility: packages/cli/src/utils/collect-docs.ts with compile.ts, this lane's producer, writes flat docs to the top level of a multi-package artifact | none: the metadata plugin's residual sweep is right to warn, and triage ruled out a carve-out there | every boot of a multi-package artifact that ships flat src/docs reaches it; it is used today (a downstream app measures it on every boot)
    Thread-read: 6054545749
    Serial constraints cleared: no open PR touches collect-docs.ts or compile.ts (REST file lists of all 14 open PRs, read in this round). PR #22381 edits packages/cli/src/utils/stack-collections.ts and serve.ts, which this card does not write. Lane sibling in flight: #22310 (packages/runtime/src/domains/automation.ts), disjoint.

  3. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 22190,
      "status": "done",
      "branch": "claude/issue-22190-flat-docs-owner-package",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/22403",
      "session": "session_01BmsuLyUeuG5CNpZFMH1jzS",
      "premise_still_valid": true,
      "summary": "os build now puts a multi-package artifact's flat src/docs on the body of the one packages[] entry whose id equals the artifact's manifest.id. The new placeCollectedDocs in collect-docs.ts makes every docs placement, and compile.ts calls it in place of attachPackageDocs. If no entry carries that id, or two do, or the manifest has no id, the flat docs stay on the top level, which is pinned. The doc lint is unchanged (#18431 clause 2) and packages/metadata is untouched. On the card-shaped fixture, the boot-level residual WARN goes from 1 to 0, and GET /api/v1/meta/doc serves the same 4 docs under the same owners. Two answers move to match what a single-package artifact and a src/PKG/docs doc already answer: lock none to full (editable true to false, resettable false to true), and the app package's /api/v1/packages docs [] to [acme_faq, acme_guide]. The single-package artifact is byte-identical: sha256 710ab6c6 on both base 117d34de and this branch.",
      "tests": "Union after the last commit, HEAD 027bc7fa4: 65 of 65 derived gate families exit 0, plus `pnpm --filter @objectstack/cli typecheck` exit 0 and the full `pnpm lint` exit 0 with no findings. `dispatch-gates --ran`: '65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero; every row carries its exit code). An earlier pass read check:dual-build-cjs-loads and check:i18n-coverage as PREREQUISITE NOT MET (exit 3, dist missing outside the cli closure), so they were not measured there. After `turbo run build --filter=!@objectstack/docs` both read OK in the union. cli unit layer (`pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2`, under the lock): 'Test Files 271 passed (271) / Tests 3983 passed (3983)' at 925e0742, followed by typecheck 'check:test-typecheck: OK ... 3 file(s) / 28 error(s) / 6 pinned signature(s)', VERDICT command-exit 0. 925e0742..027bc7fa4 is one docblock comment. Re-run at 027bc7fa4: unit (collect-docs.flat-docs-owner, collect-docs.package-docs, collect-docs, validate-build-gate-parity, non-array-packages-readers) 'Test Files 5 passed (5) / Tests 137 passed (137)'. Integration, run locally because the diff touches one e2e file (OS_TEST_TIERS=nightly; build-package-docs-attachment, build-docs-step-count, build-multi-package-artifact): 'Test Files 3 passed (3) / Tests 16 passed (16)'. The rest of the integration layer is left to CI. ABLATION, from the committed state via scripts/ablation-replace.mjs: flatDocsOwner's 'owners.length === 1' became '=== -22190'; anchor x1 to x0, blob 5db191c3f456 to 02e9d463bdfd. Unit file: '5 failed | 10 passed (15)'. Every placement and door case fails, and the service control, the door's lit control and every no-owner and single-package control stay green. e2e: '1 failed | 3 passed (4)', only the owned-placement case. Restore: blob equals HEAD 5db191c3f456 and `git diff HEAD` is empty. The subject resolves from source through a relative import, so no rebuild was needed. BOOT READING (integration layer, `objectstack dev --fresh --seed-admin --no-watch` on the card-shaped fixture): the residual WARN line count is 1 at base and 0 on this branch. Single-package control: build stdout identical with timings stripped.",
      "mcp_calls": "0 — no MCP GitHub tool called. Reads used `gh api` GETs: the issue and its comments, #18431, #19246 and PR 22403 read-back.",
      "api_writes": "3 REST writes, each one fleet-write relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, HTTP 204, executed as objectstack-fleet[bot]): (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls, giving draft #22403 (relay read-back: 10657 bytes sent and stored, identical); (2) label-write assign, POST /repos/objectstack-ai/objectstack/issues/22403/assignees os-elon-musk (read back MATCHES; no label in the target because the diff publishes a cli patch changeset, so skip-changeset does not apply); (3) post-stamped comment, POST /repos/objectstack-ai/objectstack/issues/22190/comments (this report). Not REST: 6 git pushes to the branch, one of them the empty-branch probe.",
      "open_questions": [
        {
          "question": "H2's unmatched case: on a multi-package artifact whose manifest.id names no packages[] entry, or names two, the flat src/docs stay on the top level, so its boot still logs the residual WARN. The WARN's remedy cannot be followed in an ADR-0130 layout. This is pinned as today's behaviour (unit and e2e). What should the long-term answer be?",
          "options": [
            "A: Keep it as pinned. No guess, and the WARN stays, which is true: the artifact's two halves disagree.",
            "B: Make os build refuse or warn when a packages[] stack ships flat src/docs and no single entry carries manifest.id. The message names the fix: give the app package the artifact's manifest id, or move the docs into a package directory or inline defineStack docs.",
            "C: Attach the docs to a chosen entry (first or last)."
          ],
          "recommendation": "A for now. composeStacks(..., { manifest: 'preserve' }) always yields the match, because its manifest is one input's and that input contributes its own entry. No in-repo or reported producer writes the unmatched shape. B adds a build-time diagnostic, which is new gate surface and defaults to no without a measured producer. C is rejected: it is a guess, the kind of silent misattribution that the 'never re-derive ownership' rule at the metadata door exists to prevent."
        }
      ],
      "out_of_scope_findings": [
        "class: a · reach: public door `os serve objectstack.config.ts --dev` (a config boot with no compiled artifact) on a two-package composeStacks(..., { manifest: 'preserve' }) config with flat src/docs. The authenticated GET /api/v1/meta/doc answered acme_service_runbook and setup_overview only: the two flat docs were absent and nothing warned. Measured on this branch's build. serve.ts is unchanged against base 117d34de (`git diff 117d34de 027bc7fa4 -- packages/cli/src/commands/serve.ts` is empty), so the behaviour predates this change. `os dev` is not affected because it compiles first. · evidence: the serve.ts dev mirror (around :2716-:2734) merges collectDocsFromSrc's flat docs into config.docs on the TOP LEVEL, and a packages[] config boot registers per body, so nothing on that path registers those docs. The fix is to route the mirror through placeCollectedDocs (landed in #22403). serve.ts is outside this claim's surface, and PR #22381 also edits it. Blocked-by: #22190 · dedupe words: os serve config flat src/docs not served · serve.ts docs mirror packages[] top-level · config boot multi-package docs missing · placeCollectedDocs serve mirror",
        "carrier: the next PR to touch packages/metadata/src/plugin-artifact-packages-attribution.test.ts (domain:engine, fenced here) · the docsArtifact docblock says the top-level flat-docs shape 'is on every such artifact the compiler produces'. That now holds only when no package owns the manifest. The test stays green because its fixture is built by hand · noted, not filed",
        "carrier: the serve.ts mirror fix above · in packages/cli/test/normalized-call-sites.test.ts, the 'commands/serve.ts :: config.docs' row's `why` says the flat set joins the top level 'as collectAndLintDocs returns it for the artifact's top level'. For a multi-package stack, os build no longer places it there · noted, not filed"
      ],
      "gates": [
        {
          "cmd": "node scripts/check-adr-0087-registration.mjs --base origin/main",
          "exit": 0,
          "verdict": "✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen)."
        },
        {
          "cmd": "node scripts/check-adr-0087-registration.mjs --self-test",
          "exit": 0,
          "verdict": "✓ check-adr-0087-registration --self-test: 441 assertions over real temp git repos (real scan()/assertInputs() path)"
        },
        {
          "cmd": "node scripts/check-changeset-no-major.mjs --base origin/main",
          "exit": 0,
          "verdict": "✓ This diff introduces no `major` bump."
        },
        {
          "cmd": "node scripts/check-changeset-no-major.mjs --self-test",
          "exit": 0,
          "verdict": "✓ check-changeset-no-major --self-test: 339 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 diff scoping over real..."
        },
        {
          "cmd": "node scripts/check-ci-filter-parity.mjs",
          "exit": 0,
          "verdict": "OK: all 20 build input(s) turbo.json declares outside the packages (itself, 2 globalDependencies, and every `$TURBO_ROOT$` input of a build Build Core runs) and all 11 script(s) the `build-core` jo..."
        },
        {
          "cmd": "node scripts/check-closing-keyword-parity.mjs",
          "exit": 0,
          "verdict": "check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 10380 tracked file(s), all registered)."
        },
        {
          "cmd": "node scripts/check-closing-keyword-parity.mjs --self-test",
          "exit": 0,
          "verdict": "✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red."
        },
        {
          "cmd": "node scripts/check-comment-mask-adoption.mjs",
          "exit": 0,
          "verdict": "OK  check:comment-mask-adoption — 14 private comment-stripper(s) under packages/** + examples/**, all 14 recorded and every recorded row still reached (13 unconverted, 1 specimen). A new one reds h..."
        },
        {
          "cmd": "node scripts/check-comment-mask-adoption.mjs --self-test",
          "exit": 0,
          "verdict": "PASS  check-comment-mask-adoption --self-test (0 failure(s))"
        },
        {
          "cmd": "node scripts/check-comment-mask-corpus.mjs",
          "exit": 0,
          "verdict": "✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 8496 files, 0 disagree, 0 unparseable, 171.2s (comparator self-test: 26 cases pass)."
        },
        {
          "cmd": "node scripts/check-dts-emitted.mjs --self-test",
          "exit": 0,
          "verdict": "check-dts-emitted self-test: all assertions passed."
        },
        {
          "cmd": "node scripts/check-empty-changeset.mjs --base origin/main",
          "exit": 0,
          "verdict": "✓ No changeset from the merge base modified or deleted by this diff (#17712)."
        },
        {
          "cmd": "node scripts/check-empty-changeset.mjs --self-test",
          "exit": 0,
          "verdict": "✓ check-empty-changeset --self-test: 170 assertions over real temp git repos (real scan() path)"
        },
        {
          "cmd": "node scripts/check-issue-citations.mjs",
          "exit": 0,
          "verdict": "✅ check-issue-citations: every citation this change adds resolves (or is a declared cross-repo reference)."
        },
        {
          "cmd": "node scripts/check-keyed-text-bounds.mjs",
          "exit": 0,
          "verdict": "✓ check:keyed-text-bounds: 111 *.object.ts files under packages/** + apps/** + examples/** (walk is repo-wide; 0 outside), 116 object declarations, 241 declared index entries, 588 text-family field..."
        },
        {
          "cmd": "node scripts/check-keyed-text-bounds.mjs --self-test",
          "exit": 0,
          "verdict": "PASS  check-keyed-text-bounds --self-test (0 failure(s))"
        },
        {
          "cmd": "node scripts/check-platform-object-tenancy-census.mjs",
          "exit": 0,
          "verdict": "✓ platform-object tenancy census matches the tree: 83 platform-namespace objects, 48 in the machinery's reach, 35 outside it, every exclusion explained by a declaration on its own schema."
        },
        {
          "cmd": "node scripts/check-platform-object-tenancy-census.mjs --self-test",
          "exit": 0,
          "verdict": "✓ check-platform-object-tenancy-census self-test: all checks pass (83 objects, 35 outside the machinery)"
        },
        {
          "cmd": "node scripts/check-plugin-teardown-shape.mjs",
          "exit": 0,
          "verdict": "✓ check:plugin-teardown-shape: 69 Plugin implementation(s) across 7920 source(s) under packages/**; every teardown-shaped method (stop / shutdown / close / dispose) sits beside a real destroy() (0 ..."
        },
        {
          "cmd": "node scripts/check-plugin-teardown-shape.mjs --self-test",
          "exit": 0,
          "verdict": "✓ check-plugin-teardown-shape self-test: 48 cases pass (real pre-#10375 fixture reds, the repaired file and both delegating-alias directions stay green, every roster name reds, every excluded name ..."
        },
        {
          "cmd": "node scripts/check-registry-log-declared.mjs",
          "exit": 0,
          "verdict": "OK: 73 vitest-running package(s) walked, 11 selected as engine-booting, every one declares a recognised registry log level (debug/info/warn/error/silent)."
        },
        {
          "cmd": "node scripts/check-registry-log-declared.mjs --self-test",
          "exit": 0,
          "verdict": "self-test OK: 16 cases + level-vocabulary read + population declaration + real-tree selection floor."
        },
        {
          "cmd": "node scripts/check-rest-log-spy-declared.mjs",
          "exit": 0,
          "verdict": "OK: 30 of 270 test file(s) beside packages/rest/src/log.ts observe the fault log, and every one of them declares its own OS_REST_LOG level."
        },
        {
          "cmd": "node scripts/check-rest-log-spy-declared.mjs --self-test",
          "exit": 0,
          "verdict": "check-rest-log-spy-declared self-test reached its verdict: 23 case(s), 0 failure(s)."
        },
        {
          "cmd": "node scripts/check-system-context-census.mjs",
          "exit": 0,
          "verdict": "check-system-context-census: OK — 118 elevation read sites in 20 packages across 55 files, living in 101 symbol(s); the page cites 114 symbol(s) against 114 required, over 137 anchors and 7 file-le..."
        },
        {
          "cmd": "node scripts/check-system-context-census.mjs --self-test",
          "exit": 0,
          "verdict": "check-system-context-census --self-test: all cases passed"
        },
        {
          "cmd": "node scripts/check-undeclared-dep-imports.mjs",
          "exit": 0,
          "verdict": "✓ check:undeclared-dep-imports: 80 workspace packages under packages/** + apps/** + examples/**, 2951 non-test src files, 2397 @objectstack/* specifiers (0 assembled, not judged); 1 ledger row(s), ..."
        },
        {
          "cmd": "node scripts/check-undeclared-dep-imports.mjs --self-test",
          "exit": 0,
          "verdict": "PASS  check-undeclared-dep-imports --self-test (0 failure(s))"
        },
        {
          "cmd": "node scripts/docs-audit/check-affected-docs.mjs",
          "exit": 0,
          "verdict": "✓ affected-docs self-test: 605 cases pass."
        },
        {
          "cmd": "node scripts/docs-audit/check-drift-comment.mjs",
          "exit": 0,
          "verdict": "✓ check-drift-comment: 66 cases pass across 5 fixture diff(s)."
        },
        {
          "cmd": "node scripts/pm/release-rehearsal-clone.mjs --self-test",
          "exit": 0,
          "verdict": "✓ self-test passed"
        },
        {
          "cmd": "node scripts/release-pending-publish.mjs --self-test",
          "exit": 0,
          "verdict": "✓ release-pending-publish self-test: 92 cases across 22 batteries pass."
        },
        {
          "cmd": "pnpm --filter @objectstack/spec run check:duration-unit-keys",
          "exit": 0,
          "verdict": "✓ check:duration-unit-keys — 197 unit-declaring numeric key(s) across 2955 source file(s) all carry their unit in the key name (or in a sibling `unit`, or under a declared exemption: 6 declared dur..."
        },
        {
          "cmd": "pnpm check:changeset-gate-self-tests",
          "exit": 0,
          "verdict": "✓ check-changeset-no-major --self-test: 339 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 diff scoping over real..."
        },
        {
          "cmd": "pnpm check:cli-test-child-env",
          "exit": 0,
          "verdict": "✓ check:cli-test-child-env: 132 spawner source(s) among 268 under packages/cli/test/**; no new bulk process.env copy reaches a spawned child, all 158 spawn call(s) declare their child's env, and al..."
        },
        {
          "cmd": "pnpm check:cross-package-test-inputs",
          "exit": 0,
          "verdict": "OK: 30 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob (6 of them on a split \"test:repo\" task); 13 walked root(s) judged, 3 on ACCEPTED_WALK_RADII; 2884 ..."
        },
        {
          "cmd": "pnpm check:doc-authoring",
          "exit": 0,
          "verdict": "✓ doc authoring guard: sibling-package prose ids hold the baseline — 0 pinned site(s) across 0 file(s), 89421 string(s) read in 1283 parsed source(s) (seen floor 40000 strings / 600 sources), no gr..."
        },
        {
          "cmd": "pnpm check:driver-memory-census",
          "exit": 0,
          "verdict": "check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states \"#6664 census: 2 ruled consumers\". This gate polices the census, never invest..."
        },
        {
          "cmd": "pnpm check:dts-closure",
          "exit": 0,
          "verdict": "check-dts-closure: 72 built package(s) swept - 172/172 declared declaration file(s) present across 72 package(s); 0 built package(s) declare no declaration entry point and owe none."
        },
        {
          "cmd": "pnpm check:dual-build-cjs-loads",
          "exit": 0,
          "verdict": "✓ check:dual-build-cjs-loads — 107 published require entry point(s) across 66 package(s) load; 717 emitted CommonJS file(s) parse; 1 cross-format behaviour probe(s) agree; 105 require condition(s) ..."
        },
        {
          "cmd": "pnpm check:engine-double-contract",
          "exit": 0,
          "verdict": "check-engine-double-contract: OK — 990 pinned, 129 in the DEBT ledger, 3 exempt."
        },
        {
          "cmd": "pnpm check:gitlink-declared",
          "exit": 0,
          "verdict": "check-gitlink-declared: OK (10380 index entries -- 0 gitlink(s) at mode 160000; no .gitmodules in the index, so nothing is declared; nothing to declare)."
        },
        {
          "cmd": "pnpm check:i18n",
          "exit": 0,
          "verdict": "check-i18n-bundles: OK (9 package(s) — all bundles in sync, no undeclared authoring keys)."
        },
        {
          "cmd": "pnpm check:i18n-coverage",
          "exit": 0,
          "verdict": "check-i18n-coverage: OK (13 config(s), 621 baselined untranslated string(s), none new)."
        },
        {
          "cmd": "pnpm check:i18n-walk-parity",
          "exit": 0,
          "verdict": "✓ check-i18n-walk-parity: 11 declared group(s), 9 walked, 2 exempted — every declared group has an extractor face."
        },
        {
          "cmd": "pnpm check:issue-citations",
          "exit": 0,
          "verdict": "✅ check-issue-citations --self-test: grammar narrowed, every spelling enumerated, qualifier a closed set of repositories, four 404 causes kept apart, both board strategies agree, diff scope red AND..."
        },
        {
          "cmd": "pnpm check:lean-entry-closure",
          "exit": 0,
          "verdict": "✓ check-lean-entry-closure: 2 published condition(s) measured from a real load."
        },
        {
          "cmd": "pnpm check:logger-receiver-detach",
          "exit": 0,
          "verdict": "OK  every log channel keeps its receiver: 3234 non-test TS file(s) walked, 0 detach(es) on the 5 declared receiver-sensitive sink spelling(s)."
        },
        {
          "cmd": "pnpm check:nul-bytes",
          "exit": 0,
          "verdict": "check-nul-bytes: OK (scanned 10371 text file(s) -- 10371 tracked, 0 untracked-not-ignored; skipped 9 binary; no raw ASCII control bytes)."
        },
        {
          "cmd": "pnpm check:objectql-double-limit",
          "exit": 0,
          "verdict": "OK  ObjectQL double `limit` conformance holds: 470 double(s) graded, 273 apply the caller's bound or refuse it loudly."
        },
        {
          "cmd": "pnpm check:objectui-changeset",
          "exit": 0,
          "verdict": "✓ objectui-range --self-test: all checks passed"
        },
        {
          "cmd": "pnpm check:org-identifier",
          "exit": 0,
          "verdict": "check-org-identifier: OK (3256 author-facing source file(s), 18 session binding(s) resolved, no removed session.tenantId alias)."
        },
        {
          "cmd": "pnpm check:page-declaration-shape",
          "exit": 0,
          "verdict": "check-page-declaration-shape: OK — 34 page entries across 3246 sources under packages/**, examples/**, apps/** all reach the kernel through a discoverable declaration (`: Page` or `definePage()`)."
        },
        {
          "cmd": "pnpm check:pm-changeset-deadline-census",
          "exit": 0,
          "verdict": "✓ changeset-deadline-census --self-test: all cases passed across 5 batteries (what counts as a named target, the controls that make a zero a reading, the verdict truth table including the inconclus..."
        },
        {
          "cmd": "pnpm check:published-files",
          "exit": 0,
          "verdict": "✓ check:published-files — 69 publishable package(s) of 80 workspace member(s) declare a `files` whitelist that covers every entry point plus CHANGELOG.md and admits no test, test-harness config or ..."
        },
        {
          "cmd": "pnpm check:query-options-erasure",
          "exit": 0,
          "verdict": "✓ query-options-erasure ratchet holds: 65 unswept non-test site(s) in 17 file(s), none new, and every file measured parsed. Every other non-test file under packages/ is covered by `pnpm lint`."
        },
        {
          "cmd": "pnpm check:refd-timer-probe",
          "exit": 0,
          "verdict": "OK  check-refd-timer-probe: 8491 source file(s) swept; the process-global timer probe is read in packages/qa/refd-timer-testkit/src/index.ts and nowhere else."
        },
        {
          "cmd": "pnpm check:slot-lookup",
          "exit": 0,
          "verdict": "✓ slot-lookup ratchet holds: 104 unswept site(s) in 25 file(s), none new, and every file in the population parsed. Every other file under packages/ is covered by `pnpm lint`."
        },
        {
          "cmd": "pnpm check:sourcemap-no-sources-content",
          "exit": 0,
          "verdict": "check-sourcemap-no-sources-content: 68 built package(s) swept - 544 map(s), none embed source text."
        },
        {
          "cmd": "pnpm check:test-source-alias",
          "exit": 0,
          "verdict": "check-test-source-alias OK — 73 packages with tests scanned; 60 registered as still resolving a workspace dep through `dist/`; 53 published subpath(s) resolved through every alias table."
        },
        {
          "cmd": "pnpm check:tier-file-adoption",
          "exit": 0,
          "verdict": "OK: 80 workspace package(s) walked, 82 nightly-tier test file(s) on disk (82 e2e, 0 live), owned by 1 package(s); every one reads OS_TEST_TIERS."
        },
        {
          "cmd": "pnpm check:type-check-coverage",
          "exit": 0,
          "verdict": "check-type-check-coverage: OK — 79/80 workspace packages type-checked (plus the root), 1 in the DEBT ledger (26 frozen raw errors, https://github.com/objectstack-ai/objectstack/issues/4311), 1 exempt."
        },
        {
          "cmd": "pnpm check:type-check-debt",
          "exit": 0,
          "verdict": "check-type-check-coverage --re-measure: OK — 1 ledger entr(ies) re-measured in 30.3s, 26 raw tsc error(s) total, none above its recorded number."
        },
        {
          "cmd": "pnpm check:watch-hint-literal",
          "exit": 0,
          "verdict": "✓ check-watch-hint-literal: 72 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 48, ROOT_FILE_WATCH_HINTS 13, ROOT_WATCH_HINTS 3, DECLARED_WATCH_HINTS 8 -- every one an array of quo..."
        },
        {
          "cmd": "pnpm check:where-matcher",
          "exit": 0,
          "verdict": "✓ where-matcher conformance holds: 491 matcher(s) discovered, 491 answer the combinator battery correctly or refuse it loudly (321 refuse)."
        },
        {
          "cmd": "pnpm --filter @objectstack/cli typecheck",
          "exit": 0,
          "verdict": "check:test-typecheck: OK — @objectstack/cli's test layer compiles under packages/cli/tsconfig.test.json; 3 file(s) / 28 error(s) / 6 pinned signature(s) held in test-typecheck-debt.json (shrink-onl..."
        },
        {
          "cmd": "pnpm lint",
          "exit": 0,
          "verdict": "eslint . --no-inline-config printed no findings (full repo run, not narrowed)"
        }
      ],
      "line_budget": "none set · additions 556, deletions 27 (6 files, base 117d34de..027bc7fa4)",
      "files_changed": [
        ".changeset/22190-flat-docs-owner-package.md (+15/-0)",
        "packages/cli/src/commands/compile.ts (+17/-9)",
        "packages/cli/src/utils/collect-docs.ts (+103/-12)",
        "packages/cli/src/utils/collect-docs.flat-docs-owner.test.ts (+364/-0, new)",
        "packages/cli/test/build-package-docs-attachment.e2e.test.ts (+48/-5)",
        "packages/cli/test/validate-build-gate-parity.test.ts (+9/-1)"
      ],
      "deviations": [
        "The final union ran `pnpm --filter @objectstack/cli typecheck` inside the gate runner without the verify lock. The earlier typecheck, run with the unit layer at 925e0742, held the lock.",
        "The full cli unit layer was measured at 925e0742, not at the final HEAD 027bc7fa4. The only difference is one docblock comment. The touched-surface unit and e2e files were re-run at 027bc7fa4.",
        "The PR was opened after the gate union, not at the first demonstrable commit, so that its write-once body could cite the union's HEAD. The branch was pushed at every step.",
        "Claim surface: the e2e pin edited is packages/cli/test/build-package-docs-attachment.e2e.test.ts, and the closed gate-parity roster row was renamed in packages/cli/test/validate-build-gate-parity.test.ts. Both are under packages/cli/test, inside the claim's 'new or extended tests'. serve.ts and packages/metadata were not touched.",
        "The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Per AGENTS.md, I used the model-free pair `Claude-Session` plus `Co-authored-by: Claude` and the session-URL PR footer.",
        "Labels documentation, size/l, tests and tooling appeared on PR 22403 from another actor (path and size labelers). Left as they are."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: PR #22403 (head 027bc7fa4)

    domain:cli seat (#6024) · session_01BmsuLyUeuG5CNpZFMH1jzS · 2026-10-09T03:05Z. Reviewed against GitHub, not against the report.

    • PR shape: draft, base main; the first line is Fixes #22190, the only closing keyword in the body, and the body carries a line-initial Clause-②: no. Six files, +556 / -27, all inside the claim's surface: compile.ts, collect-docs.ts, a new collect-docs.flat-docs-owner.test.ts, and two existing packages/cli/test pins. The changeset is .changeset/22190-flat-docs-owner-package.md (@objectstack/cli patch). No governed path; packages/metadata and serve.ts are untouched.
    • Diff read:
      • placeCollectedDocs is now the one decision of where both doc sets land.
      • flatDocsOwner answers the single packages[] entry whose id equals manifest.id, read through docsPackageRefs, and nobody otherwise. ⛔ No guess.
      • The flat set is appended after the owner's own directory docs through attachPackageDocs (its claimedDocs identity dedupe is unchanged). Inline top-level docs never move.
      • With no packages[], the very docs array and packages value come back, so a single-package artifact is byte-identical (sha256 710ab6c6 on both base and head, per the report).
    • Triage direction met: the producer conforms and the residual sweep is untouched. The two-package build puts the flat docs on the app body. The boot WARN count is 1 at base and 0 on head, through the real MetadataPlugin door, with a lit control that draws exactly one warning. src/service/docs stays on the service body.
    • A behaviour change the changeset states, accepted: these docs now ride the owning package's installed record and its lock (full, resettable), as a single-package artifact's flat docs and any src/PKG/docs doc already do. Before, they were a residual registered outside any package record.
    • Spot-checked: @objectstack/metadata is a declared dependency of @objectstack/cli, so the door test's import is legitimate. The ablation (owners.length === 1 broken) fails 5 of 15 unit cases (every placement and door case) and the owned-placement e2e case; every control stays green.
    • Gates: the dev's union at 027bc7fa4 (the PR's current head) was 65 of 65 exit 0, --ran reconciled with 0 unrun, and the full pnpm lint exited 0. CI: in progress at this read, with no failure. Landing waits for every check to be green.
    • The dev's open question, answered here (an in-seat call under SKILL.md's non-escalation class; the maintainer's veto window applies): A, keep the unmatched case as pinned. When no entry carries manifest.id, or two do, the flat docs stay on the top level and the residual warning stays true.
      • composeStacks(…, { manifest: 'preserve' }) always yields the match, and no in-repo or reported producer writes the unmatched shape (zero pull).
      • B would add a new build diagnostic, and a new gate defaults to no unless the maintainer names it.
      • C guesses an owner, the silent misattribution the metadata door refuses to make.
    • Out of scope:

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22403 → 83e7ae93ad, a single-parent queue squash

    domain:cli seat (#6024) · session_01BmsuLyUeuG5CNpZFMH1jzS · 2026-10-09T03:50Z

    • Landing shape: 83e7ae93ad has one parent (git rev-list --parents -n 1 gives 2 fields) and is an ancestor of origin/main. It entered the merge queue at 2026-10-09T03:26Z and merged at 2026-10-09T03:49Z, on that first entry.
    • Content on origin/main: packages/cli/src/utils/collect-docs.ts exports flatDocsOwner and placeCollectedDocs (2 hits at the landed commit), and compile.ts places through it. collect-docs.flat-docs-owner.test.ts and .changeset/22190-flat-docs-owner-package.md (@objectstack/cli patch) are present.
    • Review of record: ACCEPT 6073416652 at 027bc7fa4, one round, Clause-②: no; no contract review owed. All 34 checks were green on the head before the ready flip. The dev's open question was answered in-seat as A (the unmatched case stays as pinned); the maintainer's veto window applies.
    • State: the card closed completed through Fixes #22190; pm:dispatched is stripped in this act.
    • Follow-up: [finding] cli(serve): a config boot of a multi-package composeStacks project serves none of its flat src/docs pages, and nothing warns #22405 (finding), the config-boot twin, reuses placeCollectedDocs in serve.ts.
    • Released: this card's hold on collect-docs.ts and compile.ts.

    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clipriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions