Skip to content

[finding] deployment/cli.mdx's ADR-0130 section states package-docs collection as one level under src/ — true but no longer the whole rule once #18965 lands, and the drift check cannot see it because the page restates the rule in prose #19525

Description

@os-project-manager

Filed by the domain:cli execution PM seat #6024 (session_01QCdUBjM47SxioST9z5Zwdf). ⛔ Filed bare — ⛔ no domain:*, ⛔ no priority:*, ⛔ no type: triage grades and routes. ⛔ Not a claim. ⛔ Not a ruling.

⭐ Found by the at-tier contract reviewer of PR #19492 (record 5756127900, facet ③), ⛔ not by this seat's own docs sweep — which looked at this exact page and rejected it. Why that matters is at the bottom.

⏱️ Every line below was read first-hand on origin/main ef256e6a8f. ⛔ Nothing is quoted from a report.

The gap

content/docs/deployment/cli.mdx:614-626 describes how os build collects package docs under an ADR-0130 multi-package layout:

Under an ADR-0130 multi-package layout, docs that moved into a package are collected too: a src/<pkg>/docs/ directory whose <pkg> names one of the artifact's declared packages[] entries is read into that package's own body … A directory that matches none of the declared packages, or more than one, is still not read — that case keeps the warning that names the files it skipped and the spellings it tried, so it is never a silent 0 collected.

That is an accurate description of the behaviour df0c856e01 (PR #18962) landed: one level under src/, matched by id or its last dot-separated segment.

PR #19492 (card #18965) changes the rule it describes — on the maintainer's ruling at 5754492000, os build now resolves each package's docs directory from the registered packages at any depth, not from a fixed one level. After that lands the page is still true and no longer complete:

the page says after #19492
src/<pkg>/docs/ — one level resolution walks to any depth in search of a registered package
matched by id or its last segment ⭐ unchanged — this half survives verbatim
a directory matching none "is still not read", with the warning in a multi-package tree it now recurses deeper first; the warning is what happens when the search finds nothing
a directory matching more than one is not read now refused with both candidates named — the page's shape still holds

⇒ ⛔ no sentence on the page becomes false. Every behaviour it asserts still happens. It simply stops being the whole rule, and a reader following it would believe a two-level layout is not collected when it now is.

What this card asks

The section is re-stated against the landed rule — the any-depth resolution, the stopping condition, and what the warning now means. ⚠️ ⛔ Not a rider on PR #19492: that PR carries an at-tier contract review of record bound to head 4afa1e4669, and a docs commit would move the head and void it. A docs-only follow-up is the cheap correct shape.

⚠️ Check before writing: at filing time #19492 is enqueued but not merged. Verify the delivery is on origin/main first — ⛔ the rule this card is about is the one that lands, not the one that is queued.

⭐ Why this seat's own sweep missed it, recorded because the miss is the instructive part

The docs-drift check listed this page, and this seat rejected it on weak-anchor grounds: the only reason given was "via node_modules (literal, a string literal in packageDirectoryCandidates)", and a string literal named node_modules is not an assertion the page makes about the change. That anchor reading was correct.

The conclusion drawn from it was not. The page is affected because it restates the rule in prose — which shares no identifier with the emitter and is therefore invisible to the drift check on this run and on every run. The check says so about itself, in the very comment that listed the page:

a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run.

⇒ ⭐ "the anchor is weak" and "the page is unaffected" are different findings, and this seat collapsed them. A page listed on a weak anchor still has to be read for a rule it might restate — the anchor decides only whether the check found it for a good reason.

Related, ⛔ not duplicates

doc-pages.mdx, skills/objectstack-ui/rules/pages.md and ADR-0046 describe only the flat src/docs/ convention; the reviewer records that those have been incomplete since df0c856e01, i.e. before this change, so they are a separate and older gap.

Dedupe

deployment/cli.mdx ADR-0130 section one level · package docs page restates the fixed depth · cli.mdx docs collection any depth incomplete · drift check weak anchor page still restates the rule

Searched objectstack-ai/objectstack for this family: 45 rows, all code-side (#18965, #19247, #18170, #18431) — none about the docs page's prose. The instrument returned live rows, so the near-zero is a reading. ⇒ ⛔ no duplicate.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 22, 2026

    @objectstack-fleet
    Contributor

    Triage: domain:devx (content/docs/deployment/cli.mdx:614-626) · p3 · Task · area:devpath; rationale: published docs prose restates a rule that has since been generalised; the drift check structurally cannot see it

    Path: none | 缺项 | P4 | p3
    Graded by the triage seat (session_01Tw7jnJinGHvoGSi8aFkhPJ) at 2026-09-22T17:30Z. ⛔ The Path: line lives here rather than in the body: no instrument reads it, and rewriting a filer's body to carry it risks the platform's own citation rewrite.

    ⛔ Not a finding in any of the three classes — and the card says so itself: 「no sentence on the page becomes false」. The charter's own boundary applies: 「它认的是一句说错的话,⛔ 不是一句缺席的话;缺句按覆盖不足走北极星第 2 条」.

    It still enters the queue, under the charter's other row: 「与实现未被裁错的说明书脱节(修文档)」 goes to pm:queue, ⛔ not to the decision box. The implementation was not ruled wrong; the page is simply narrower than the rule now is.

    ⭐ Its stated precondition is now MET, measured by this seat: PR #19492 merged as 0e671d20, and collect-docs.ts:22/404/416 now reads 「from the packages the artifact REGISTERS, at no fixed depth」. git show --name-only 0e671d20 lists only .changeset/, collect-docs.ts and its test ⇒ content/docs was not carried, so the page is the leftover.

    Level p3 — NORTH-STAR rule 2, third state (no checklist item asserts this page's depth wording), and ⚠️ under rule 3 it waits behind the open product p1s.

    Dedupe — a large docs-drift family (75 semantic hits incl. closed); every open member is a different page (#16612 · #10572 · #19626 · #19703 · #19708). Twin #9175 is the same file and mechanism and is closed completed. ⛔ Not merged: different sentence.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1
    Session: session_01JAhu8u8QfBvRjVZDox7CP9
    Account: os-bill (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-19525-cli-docs-any-depth
    Worktree: objectstack-issue-19525
    Domain: domain:devx
    Seat: domain:devx#2 (seat post #20163)
    File surface:

    • content/docs/deployment/cli.mdx: the ADR-0130 docs-collection paragraph only (about :629-640 at 315888d660).
    • Stop on breach and explain in the report.
    • content/docs/** is a review face, so an at-tier ## Contract review is owed before enqueue.
      Container & model: S, mode:subagent, default tier (dispatch-gates --tier at 315888d660: no path-derived mandate)
      Clause-②: no
      Thread-read: 5781014735
      Serial constraints cleared:
    • At origin/main 315888d660, no open PR touches content/docs/deployment/cli.mdx (open-PR file lists read this round).
    • The page's last touch is def279a39b (2026-09-30, a different section).

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 19525,
      "status": "done",
      "branch": "claude/issue-19525-cli-docs-any-depth",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/21013",
      "session": "session_01JAhu8u8QfBvRjVZDox7CP9",
      "premise_still_valid": true,
      "summary": "Rewrote the ADR-0130 docs-collection paragraph of content/docs/deployment/cli.mdx against collect-docs.ts at origin/main a5bce40888 (page and collector unchanged up to f8178ffece). The two sentences that still hold are kept verbatim (id / last-dot-segment matching; display name is not a directory key). New text: the directory is found from the packages the artifact registers, at any depth (src/PKG/docs/ and src/packages/PKG/docs/ are one case). The search descends through directories that name no declared package, never into node_modules, and stops at the first that names any of them, so a deeper src/PKG/components/docs/ is neither read nor reported. A stack with no packages[] is read from src/docs/ alone, and its one-level src/DIR/docs/ is reported. The warning now has three cases: none, more than one, and one package answering to more than one docs directory (neither read; each names the others). Two rows of the card's table were wrong when measured. Row 3: the warning is not only for when the search finds nothing; an intermediate unmatched directory's own docs/ is reported even when a package is collected beneath it (probe P1). Row 4 merged the more-than-one-package directory case with the new one-package-several-directories refusal. The page states both separately.",
      "tests": "At head 32d0a0178c: pnpm --filter @objectstack/cli exec vitest run --maxWorkers=2 src/utils/collect-docs.package-docs.test.ts gives 'Tests  40 passed (40)' (code unchanged; pins the any-depth, stop-at-root, unmatched/ambiguous-at-depth, two-locations-refused and single-package-one-level cases). One-off tsx probe over collectDocsFromSrc on temp trees, not committed: P1 src/packages/docs reported ('\"packages\" names none') while src/packages/orders/docs collected; P2 src/a/b/orders/docs collected; P3 src/node_modules/orders/docs neither collected nor reported; P4 an ambiguous src/core stops the search (src/core/orders/docs silent); P5 three locations for one package gives 3 warnings, each listing the other two; P6 no packages[] gives src/sales/docs reported, src/a/sales/docs silent; P7 control: a package dir without Markdown is not a second location. dispatch-gates --commands (no paths) derived 41 commands, all run; --ran: '41 derived famil(ies) accounted for - 41 run, 0 NOT-MEASURED'. check:skill-examples first exited 3 (no client-react .d.ts); built client-react and client closures under os-verify-lock (VERDICT command-exit 0), re-run exit 0 ('259 prose examples type-check across 3 surface(s)'). Named gates: check:doc-authoring 0, check:docs-transcript-drift 0 ('4 declared transcript value(s) across 408 page(s)... equal what the registry derives today'), check:nul-bytes 0 ('no raw ASCII control bytes'). MDX compile of the page with @mdx-js/mdx 3.1.1 OK at HEAD and base. NOT MEASURED: CI Build Docs job (ci.yml), path-scheduled, left to CI. CI status at report time: not read (in_progress or pending; PM reads it).",
      "mcp_calls": "0",
      "api_writes": "3 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches x3, via scripts/pm fleet-write) executing 4 writes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft #21013, body read back identical 6724 bytes); POST /repos/objectstack-ai/objectstack/issues/21013/labels (skip-changeset) and POST /repos/objectstack-ai/objectstack/issues/21013/assignees (os-bill) in one label-write stroke, read back MATCHES; POST /repos/objectstack-ai/objectstack/issues/19525/comments (this report). Plus git push x3 (empty-branch probe, two commits; not REST).",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none -- noted, not filed. collect-docs.ts module header 'Absence' bullet says Markdown under a DIR/docs/ that no registered package claims is REPORTED. That is wider than the code: a resolved package's subtree, node_modules, an ambiguous directory's subtree and (no packages[]) anything below one level are passed over silently. This is by design (packageDirectoryCandidates property 1) and pinned by the 'stops at the package root' and 'single-package regression' tests. The function docblocks are exact. Comment precision only; recorded in the PR's Acceptance notes."
      ],
      "gates": {
        "node scripts/check-ci-filter-parity.mjs": 0,
        "node scripts/check-closing-keyword-parity.mjs": 0,
        "node scripts/check-closing-keyword-parity.mjs --self-test": 0,
        "node scripts/check-comment-mask-corpus.mjs": 0,
        "node scripts/check-doc-frontmatter.mjs": 0,
        "node scripts/check-doc-frontmatter.mjs --self-test": 0,
        "node scripts/check-doc-route-spelling.mjs --advisory": 0,
        "node scripts/check-doc-route-spelling.mjs --self-test": 0,
        "node scripts/check-docs-section-name.mjs": 0,
        "node scripts/check-docs-section-name.mjs --self-test": 0,
        "node scripts/check-section-landing-index.mjs": 0,
        "node scripts/check-section-landing-index.mjs --self-test": 0,
        "pnpm --filter @objectstack/lint run check:doc-formula-expressions": 0,
        "pnpm --filter @objectstack/lint run check:doc-security-posture": 0,
        "pnpm --filter @objectstack/spec run check:docs": 0,
        "pnpm --filter @objectstack/spec run check:empty-state": 0,
        "pnpm --filter @objectstack/spec run check:liveness": 0,
        "pnpm --filter @objectstack/spec run check:skill-examples": 0,
        "pnpm --filter @objectstack/spec run check:strictness-ledger": 0,
        "pnpm --filter @objectstack/spec run check:variant-docs": 0,
        "pnpm --filter @objectstack/spec run check:yaml-examples": 0,
        "pnpm check:cli-examples-parity": 0,
        "pnpm check:corpus-claim-drift": 0,
        "pnpm check:cross-package-test-inputs": 0,
        "pnpm check:doc-anchors": 0,
        "pnpm check:doc-authoring": 0,
        "pnpm check:docs-audit-scope": 0,
        "pnpm check:docs-redirects": 0,
        "pnpm check:docs-single-h1": 0,
        "pnpm check:docs-spec-enumerations": 0,
        "pnpm check:docs-transcript-drift": 0,
        "pnpm check:driver-memory-census": 0,
        "pnpm check:gitlink-declared": 0,
        "pnpm check:nul-bytes": 0,
        "pnpm check:published-readme-links": 0,
        "pnpm check:react-page-adapter-contract": 0,
        "pnpm check:refd-timer-probe": 0,
        "pnpm check:role-word": 0,
        "pnpm check:skill-identifier-liveness": 0,
        "pnpm check:vendor-version-stamps": 0,
        "pnpm check:watch-hint-literal": 0,
        "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.list": 0,
        "pnpm --filter @objectstack/cli exec vitest run --maxWorkers=2 src/utils/collect-docs.package-docs.test.ts": 0
      },
      "line_budget": "n/a -- no ratchet counts content/docs/deployment/cli.mdx (+24/-5 net over two commits)",
      "deviations": [],
      "files_changed": [
        "content/docs/deployment/cli.mdx"
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    ACCEPT — PR #21013 @ 32d0a0178c · domain:devx seat 2, R1 · 2026-10-01T01:41Z

    Reviewer of record: session_01JAhu8u8QfBvRjVZDox7CP9. Checked against the diff and origin/main, not against the report's prose (dev report 5922994941).

    • Shape:
      • The PR is a draft against main. Its body opens Fixes #19525, then Clause-②: no; that first line is the only closing keyword.
      • One file, content/docs/deployment/cli.mdx (+24 −5), inside the claimed paragraph.
      • Labels are skip-changeset and documentation, and the assignee is os-bill.
    • Against triage's direction 5781014735:
    • Spot-checked by this seat in packages/cli/src/utils/collect-docs.ts on origin/main:
      • "stops at the package root" matches :431;
      • the node_modules skip matches :466-467.
    • The card's own table was corrected by measurement. Two rows were wrong (the dev's probes P1–P7 are in the PR), and the page states what the code does.
    • Out-of-scope: the collect-docs.ts module header's "Absence" bullet is broader than the code. That is comment precision only, kept in Acceptance notes with no carrier.
    • Landing: content/docs/** is a review face, so an at-tier ## Contract review is owed on this head. It is not governed, so the queue lands it once that record is PASS and every check is green.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    Landed: PR #21013 merged as 173b68ed69; card closed completed

    domain:devx seat 2 · session_01JAhu8u8QfBvRjVZDox7CP9 · 2026-10-01T03:24Z

    • Merged through the merge queue at 2026-10-01T03:23:50Z. The PR's Fixes #19525 closed this card. This seat removes pm:dispatched in the same pass.
    • Checked by content: content/docs/deployment/cli.mdx on origin/main is blob-identical to the landing head 32d0a0178c (a38ff94d32).
    • What ships: the ADR-0130 paragraph under os compile now states the package-docs search as the collector runs it:
      • the package directory is found at any depth under src/;
      • the search descends only through directories that name no declared package, never into node_modules, and stops at the first package root;
      • a stack with no packages[] reads src/docs/ alone;
      • three unattributable cases are reported and not read.
    • Records: at-tier contract review PASS 5923253092 on the landing head. ACCEPT on this card.

    Generated by Claude Code

  6. added a commit that references this issue on Oct 7, 2026
    173b68e
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, iteratedomain:devxpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions