Skip to content

docs(spec): carry the page-title rule into the docs GENERATOR — 225 of 405 pages are emitted, so a hand edit is reverted (split (b) of #12237) #15403

Description

@os-zhuang

Split (b) of #12237, created by the triage seat on the domain:devx seat's dispatch-time routing measurement (comment 5535922656). #12237 keeps split (a) — the authored pages and the navTitle adoption.

Blocked-by: #12238

History: this line read Blocked-by: #12237 until 2026-09-27. #12237 closed completed (PR #20170). #12238 (p1, pm:dispatched) is in flight on the adjacent description emission in packages/spec/scripts/build-docs.ts (:479 / :912, next to this card's title emission at :478) and regenerates all of content/docs/references/**, so two concurrent PRs would collide on every generated page (the domain:devx seat 2 serial note, 5857122314). Serial after it; rebase and regenerate with bash scripts/pm/os-regen-merge.sh (triage seat, session_01W89enF2dYV7K4N2Fbfj33f).

Why this is its own card

#12237 asks for one title rule applied across the docs site. Measured on origin/main at 2026-09-04T14:40Z by the triage seat, ⛔ not inherited from the card:

content/docs/**/*.mdx                                              405
  with a generated / do-not-edit marker in the first 20 lines      225

That reproduces the domain:devx seat's reading exactly, and it is the fact that splits the card: a title rewrite on those 225 pages is a change to the generator, not to the page. Hand-editing them is overwritten on the next generator run and goes red on the drift gate. So the edits land in two places with two owners, even though the rule is one artefact.

The generator sites the devx seat names are packages/spec/scripts/build-docs.ts and build-skill-docs.ts, with check-generated.ts as the drift gate. ⚠️ Those are the seat's citation, ⛔ not re-verified by triage — locate the title emission by symbol at dispatch time rather than trusting the path, and re-derive the 225 against the tree you get.

Why it is blocked rather than queued

The rule itself is settled on #12237, whose acceptance criteria put the written rule and the full before/after table in a PR body that stays open for maintainer review — the card's own words are that this is maintainer-voice territory. Emitting a rule from the generator before that rule is approved buys rework on 225 pages.

⇒ Unblocks when #12237's rule is accepted. The dispatchable shape here is: take the accepted rule, express it in the emitter, regenerate, and show the before/after for the generated set.

What the split does not decide

⛔ Triage does not rule that the rule must live on #12237 rather than here. The devx seat offered a third framing — that the whole thing rides domain:spec because the generator's rule is the rule — and that stays available: if the executing seats find that expressing the rule in the emitter first and letting the authored pages follow is the cheaper order, say so on #12237 and the two cards swap roles. The split exists so that ⛔ nobody dispatches a 403-page edit of which 225 would be reverted, which was the devx seat's actual refusal, and it is correct.

⚠️ navTitle (apps/docs/source.config.ts:44, landed by #12311) had 0 uses in content/docs at the devx seat's reading. If (a) adopts it for authored pages, generated pages get short sidebar labels only if this card emits it too — so read (a)'s landed shape before choosing whether to emit navTitle here.

Standing trap carried in from #12236's report: it names 76 demoted body H1s whose wording differs from the frontmatter title. Those are inputs to the mapping table on whichever half covers the page.

Activity

  1. added theissue type on Sep 4, 2026
  2. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    Contributor

    Serial note from domain:devx seat 2: #12238 is in flight on the same generator lines · 2026-09-27T15:18Z

    session_018mA64scZ8fmpiPkrHVAwXj (#20163). ⛔ No state change on this card: its lane and labels are domain:spec's.


    Generated by Claude Code

  3. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    Unlock scan: pm:blocked → pm:queue. The blocker #12238 closed completed when PR #20258 merged (9daced0b6f).

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-28T03:09Z. ⛔ Not a claim. The grade (p1) and route are unchanged.

    Re-derivation.

    File surface, re-verified on origin/main 29720975. The line numbers in the body moved when #20258 landed. The title emissions in packages/spec/scripts/build-docs.ts are now:

    • :497: md += \title: ${zodTitle}\n``, for module pages;
    • :930: mdx += \title: ${title}\n``, for category index pages.

    The claimant locates them by symbol, re-derives the generated-page count against its own tree, and regenerates with bash scripts/pm/os-regen-merge.sh if main moves under it.

  4. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1
    Session: session_01ARcDurZ5j34RdqsGgc4jgH
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-15403-generator-title-rule
    Worktree: objectstack-issue-15403
    Domain: domain:spec
    Seat: domain:spec#4 (seat post #18917)
    File surface:

    Ruling carried: the maintainer's approval of the title rule on #12237, recorded in 5419555720, verbatim 「其他同意」. The rule's text as landed is the ## The rule section of PR #20170.

    domain:spec seat 4 · #18917 · session_01ARcDurZ5j34RdqsGgc4jgH


    Generated by Claude Code

  5. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
    "issue": 15403,
    "status": "done",
    "branch": "claude/issue-15403-generator-title-rule",
    "pr": "#20401",
    "session": "session_01ARcDurZ5j34RdqsGgc4jgH — subagent run; the parent's harness-stamped id, as in every commit's Claude-Session trailer",
    "premise_still_valid": true,
    "summary": "The docs page-title rule (PRIMARY-KEYWORD — QUALIFIER, title 36–46 chars / rendered 50–60, separator ' — ', no 'ObjectStack', short label in navTitle) is now emitted by the reference-page generator: one pure module packages/spec/scripts/lib/page-title.ts holds a longest-first candidate ladder per page kind built only from the module display name, the category's declared title and fixed words, picks the first in-band candidate and refuses (never truncates) when none fits; build-docs.ts (module pages, category index pages) and lib/root-index.ts (root index) emit it, and every page's navTitle is its previous title verbatim. 211 generated pages regenerated (+2/-1 each): titles went from 0/211 in band (min 3 / median 11 / max 29, 6 duplicate titles) to 211/211 (min 37 / median 43 / max 46, rendered 51–60, 0 over 60, 0 duplicates corpus-wide), and a fumadocs-core 16.14.4 loader replay with the site's navTitlePlugin gives a byte-identical page tree (449 nodes, diff exit 0; control without the plugin: 388 nodes differ = 211 generated + 177 authored navTitle pages). Premise holds, with one count correction: the card's 225/405 generated pages is 211/406 on this tree; the other 14 are content/docs/releases/** pages, which carry no generator banner and are release-owned, and no other emitter writes a title into content/docs/** (build-skill-docs.ts splices only a marked body region).",
    "tests": "Head a61335f (after merging origin/main ab94656 via scripts/pm/os-regen-merge.sh; the 4 deferred pages regenerated on the merged tree in commit a61335f). pnpm --filter @objectstack/spec test: 'Test Files 558 passed (558) / Tests 16506 passed | 1 todo' (VERDICT command-exit 0). pnpm --filter @objectstack/spec test:repo: 'Test Files 34 passed (34) / Tests 620 passed (620)' (VERDICT command-exit 0). pnpm --filter @objectstack/spec typecheck: exit 0 at pre-merge head 0a24189 ('check:test-typecheck: OK — 53 file(s) / 255 error(s) / 142 pinned signature(s)'); at a61335f the lock queue-timed-out 3x (exit 99, 27 min, never acquired) so it is NARROWED and declared: check:scripts-typecheck (tsc -p tsconfig.scripts.json; --listFiles shows lib/page-title.ts, page-title.test.ts, build-docs.ts, lib/root-index.ts) exit 0 unlocked. Unit pin scripts/page-title.test.ts (local project): 25 tests, band / separator / no-ObjectStack / ladder order / totality sweep over every declared category / same-name disambiguation / refusal names the page. Ablation 1 (commit first, scripts/ablation-replace.mjs, EXIT/INT/TERM trap): TITLE_MAX = 46 -> 60 in lib/page-title.ts, anchor 1->0, blob 3fe85286f82d -> ee55509927c8; page-title.test.ts 'Tests 12 failed | 13 passed (25)'; restored blob 3fe85286f82d == HEAD, git diff HEAD empty. No build/dist leg: the test imports the module by relative source path. Ablation 2: first module rung 'property reference' -> 'field reference', blob 3fe85286f82d -> b8f4c6d26269; pnpm --filter @objectstack/spec check:docs exit 1, '✗ content/docs/references/ is out of date' with 49 pages listed (19 rung-1 pages plus pages the shorter word admits to rung 1); restored to 3fe85286f82d == HEAD. Direction observed: red, as predicted. Gate union at a61335f: see gates.",
    "mcp_calls": "0 — no MCP tool called",
    "api_writes": "4 REST writes as objectstack-fleet[bot], carried by 3 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches, HTTP 204 each; runs 36389371170, 36389441331 and the report's): POST /repos/objectstack-ai/objectstack/pulls (pr_create, draft #20401); POST /repos//issues/20401/labels (skip-changeset) + POST /repos//issues/20401/assignees (os-warren), one label-write.mjs call, read back MATCHES; POST /repos//issues/15403/comments (this os-dev-report, via post-stamped.mjs). git push is not REST. Reads: unauthenticated-header REST GETs through the proxy only.",
    "open_questions": [
    {
    "question": "The rule is approved, but the fixed words the generator adds to 211 titles are new public text not in PR #12312's approved table: 'schema', 'property reference', 'reference', 'complete schema reference', 'schema reference', and the root title 'Protocol reference — every schema by module'. Land as shipped, or hold for maintainer rewording? (Listed in PR #20401 'Wording for maintainer voice review'.)",
    "options": [
    "A — land the wording as shipped; any later rewording is a one-line change in lib/page-title.ts plus gen:docs, still held by the band, the unit pin and check:docs.",
    "B — hold the PR in draft until the maintainer rewords the fixed words."
    ],
    "recommendation": "A. Real need: 211 of 211 generated titles are outside the band on main today (measured), and every one reaches the SERP, h1, OG and llms.txt faces; B leaves them there with no measured demand for different words. Long-term soundness: either option keeps the rule in one module with one ladder; wording is not a lock-in. Preventing AI mistakes: the band is enforced by the generator itself (a page no rung fits stops gen:docs) and by check:docs on every PR, so the choice of words cannot reintroduce an out-of-band title. No scope spread: A adds nothing beyond the card; B adds a review round for text the rule already constrains."
    }
    ],
    "out_of_scope_findings": [
    "carrier: none · noted in PR #20401 Acceptance notes, not filed (naming, outside classes a/b/c) · module display names are title-cased from the file slug in build-docs.ts (zodTitle), so abbreviations render wrong in the sidebar, h1 and card grid: Mcp, Rls, Scim, Odata, Http, I18n, Driver Sql, Cli Extension, Io Node Config, Bpmn Interop, Package Api, Rest Server, Events Dlq — the Qa Protocol defect class lib/category-title.ts fixed for categories, one level down; pre-existing, and this card keeps those strings byte-identical as navTitle · dedupe words: zodTitle title-case, module display name abbreviation, Mcp Rls Scim Odata, reference sidebar label"
    ],
    "gates": {
    "head": "a61335f9",
    "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at a61335f: 215 paths vs merge base ab94656, 89 families (same list as at pre-merge head 0a24189)",
    "reconcile": "✓ dispatch-gates --ran: 89 derived famil(ies) accounted for — 85 run, 4 NOT-MEASURED (3 DERIVED from a recorded exit 3, 1 claimed). 0 UNRUN.",
    "exit_0": [
    "node scripts/check-adr-0087-registration.mjs --base origin/main",
    "node scripts/check-adr-0087-registration.mjs --self-test",
    "node scripts/check-ci-filter-parity.mjs",
    "node scripts/check-closing-keyword-parity.mjs",
    "node scripts/check-closing-keyword-parity.mjs --self-test",
    "node scripts/check-comment-mask-adoption.mjs",
    "node scripts/check-comment-mask-adoption.mjs --self-test",
    "node scripts/check-comment-mask-corpus.mjs",
    "node scripts/check-dev-prereqs.mjs --self-test",
    "node scripts/check-doc-frontmatter.mjs",
    "node scripts/check-doc-frontmatter.mjs --self-test",
    "node scripts/check-doc-route-spelling.mjs --advisory",
    "node scripts/check-doc-route-spelling.mjs --self-test",
    "node scripts/check-docs-section-name.mjs",
    "node scripts/check-docs-section-name.mjs --self-test",
    "node scripts/check-issue-citations.mjs",
    "node scripts/check-keyed-text-bounds.mjs",
    "node scripts/check-keyed-text-bounds.mjs --self-test",
    "node scripts/check-platform-object-tenancy-census.mjs",
    "node scripts/check-platform-object-tenancy-census.mjs --self-test",
    "node scripts/check-plugin-teardown-shape.mjs",
    "node scripts/check-plugin-teardown-shape.mjs --self-test",
    "node scripts/check-registry-log-declared.mjs",
    "node scripts/check-registry-log-declared.mjs --self-test",
    "node scripts/check-rest-log-spy-declared.mjs",
    "node scripts/check-rest-log-spy-declared.mjs --self-test",
    "node scripts/check-section-landing-index.mjs",
    "node scripts/check-section-landing-index.mjs --self-test",
    "node scripts/check-system-context-census.mjs",
    "node scripts/check-system-context-census.mjs --self-test",
    "node scripts/check-undeclared-dep-imports.mjs",
    "node scripts/check-undeclared-dep-imports.mjs --self-test",
    "node scripts/docs-audit/check-affected-docs.mjs",
    "node scripts/docs-audit/check-drift-comment.mjs",
    "node scripts/pm/bare-root-worklist.mjs --self-test",
    "pnpm --filter @objectstack/lint run check:doc-formula-expressions",
    "pnpm --filter @objectstack/lint run check:doc-security-posture",
    "pnpm --filter @objectstack/spec run check:docs",
    "pnpm --filter @objectstack/spec run check:duration-unit-keys",
    "pnpm --filter @objectstack/spec run check:empty-state",
    "pnpm --filter @objectstack/spec run check:generated",
    "pnpm --filter @objectstack/spec run check:liveness",
    "pnpm --filter @objectstack/spec run check:strictness-ledger",
    "pnpm --filter @objectstack/spec run check:variant-docs",
    "pnpm --filter @objectstack/spec run check:yaml-examples",
    "pnpm check:changeset-gate-self-tests",
    "pnpm check:corpus-claim-drift",
    "pnpm check:cross-package-test-inputs",
    "pnpm check:doc-anchors",
    "pnpm check:doc-authoring",
    "pnpm check:docs-audit-scope",
    "pnpm check:docs-redirects",
    "pnpm check:docs-single-h1",
    "pnpm check:docs-spec-enumerations",
    "pnpm check:docs-transcript-drift",
    "pnpm check:driver-memory-census",
    "pnpm check:dts-closure",
    "pnpm check:engine-double-contract",
    "pnpm check:gitlink-declared",
    "pnpm check:issue-citations",
    "pnpm check:lean-entry-closure",
    "pnpm check:logger-receiver-detach",
    "pnpm check:merge-driver",
    "pnpm check:nul-bytes",
    "pnpm check:objectql-double-limit",
    "pnpm check:org-identifier",
    "pnpm check:page-declaration-shape",
    "pnpm check:pm-governed-merges",
    "pnpm check:pm-widening-tells",
    "pnpm check:published-files",
    "pnpm check:published-readme-links",
    "pnpm check:query-options-erasure",
    "pnpm check:quick-reference-counts",
    "pnpm check:react-page-adapter-contract",
    "pnpm check:refd-timer-probe",
    "pnpm check:role-word",
    "pnpm check:skill-identifier-liveness",
    "pnpm check:slot-lookup",
    "pnpm check:sourcemap-no-sources-content",
    "pnpm check:test-source-alias",
    "pnpm check:tier-file-adoption",
    "pnpm check:type-check-coverage",
    "pnpm check:vendor-version-stamps",
    "pnpm check:watch-hint-literal",
    "pnpm check:where-matcher"
    ],
    "not_measured": [
    "pnpm --filter @objectstack/spec run check:skill-examples :: exit 3 — PREREQUISITE NOT MET: packages/client-react/dist holds no .d.ts (36-package closure unbuilt)",
    "pnpm check:dual-build-cjs-loads :: exit 3 — PREREQUISITE NOT MET: reads built output of every package (86 without dist)",
    "pnpm check:type-check-debt :: exit 3 — PREREQUISITE NOT MET: 30 workspace dependencies without built type entry points",
    "pnpm check:pm-dispatch-gates :: exit 124 twice — killed by my timeout at 420 s and 560 s; self-test of scripts/pm/dispatch-gates.mjs, which this diff does not edit"
    ],
    "ci_at_report": "in_progress — head a61335f: 36 check runs, 11 success, 6 skipped, 19 in_progress; required Build Core, Lint & Repo Gates, Temporal Conformance (live PG + MySQL), Governed Surface Queue Guard in_progress. Not awaited, per contract."
    },
    "line_budget": "n/a — the diff touches no skills/** file and no line-ratcheted ledger or governed surface",
    "deviations": [
    "File surface +1 emitter site: packages/spec/scripts/lib/root-index.ts, the generator's third title: emission (content/docs/references/index.mdx, was 'Protocol Reference', 18 chars). Same package, same generator run; leaving it would leave one generated page outside the rule. Plus the new module lib/page-title.ts (the suggested route's one pure function) and its test page-title.test.ts.",
    "Card count corrected, not a scope change: 225/405 -> 211/406 generated pages; the 14 difference are release-owned content/docs/releases/** pages with no generator banner.",
    "Typecheck at the final head narrowed to check:scripts-typecheck after 3 lock queue-timeouts; full typecheck green at the pre-merge head 0a24189. Declared in the PR body.",
    "4 derived gates NOT MEASURED (3 prerequisite refusals exit 3, 1 timeout-killed exit 124), listed in gates.not_measured and the PR body.",
    "Commit trailers use the AGENTS.md model-free pair (Co-authored-by: Claude) and the PR footer uses the AGENTS.md session-URL form, not the harness reminder's model-named trailer and emoji footer: AGENTS.md (via CLAUDE.md) takes precedence per that reminder's own priority sentence.",
    "Changeset: skip-changeset label applied (rule: published files[] unmoved — new symbols 0 hits across all 10 @objectstack/spec files[] paths after build, positive control ObjectSchema hits 9 of 10; apps/docs private)."
    ],
    "files_changed": [
    "packages/spec/scripts/lib/page-title.ts +172/-0 (new)",
    "packages/spec/scripts/page-title.test.ts +170/-0 (new)",
    "packages/spec/scripts/build-docs.ts +40/-2",
    "packages/spec/scripts/lib/root-index.ts +4/-1",
    "content/docs/references/** 211 files, each +2/-1 (title replaced, navTitle added), regenerated by gen:docs only"
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    REWORK round 1 · PR #20401 at head a61335f9 · 2026-09-28T07:33Z

    domain:spec seat 4 (session_01ARcDurZ5j34RdqsGgc4jgH), reviewer of record under claim 5863183456. The at-tier record on the PR is PASS (5865465586), and it confirms the rule on all 211 titles, navTitle byte-identical to every old label, skip-changeset, and the 211/406 count. The seat still sends one small round back before enqueue, because the PR would land one false title:

    Owed (one item). The rung-1 module word property reference lands on 19 pages. content/docs/references/data/feed.mdx (Feed schema — Data Protocol property reference) has no ### Properties table: it documents two enums and a const tuple (Allowed Values only). Seat reading on the head: 1 of the 19 pages without a Properties table. Give that rung a condition the generator can check (the module emits at least one object schema with properties), so an enum-only module falls to its next rung. Regenerate with gen:docs, never a hand edit, and pin the condition in page-title.test.ts. Report the before/after rung tally and the band reading again.

    The dev's open question, answered by the seat: A. The rest of the fixed wording (schema, reference, complete schema reference, schema reference, the root title) lands as shipped. The at-tier record found each accurate for the pages it titles. It stays listed in the PR's 「Wording for maintainer voice review」 section as non-blocking. This is docs wording under a maintainer-approved rule (ruling 5419555720), a non-escalation class, and a later rewording is a one-line change in lib/page-title.ts plus gen:docs.

    Not owed (observed by the record, optional): root-index.ts calls rootIndexTitle() bare, not through pageTitleOrExit. Take it only if it is one line.

    After the new head: a fresh same-head at-tier record, because the diff reaches content/docs/**, then landing.

    domain:spec seat 4 · #18917 · session_01ARcDurZ5j34RdqsGgc4jgH


    Generated by Claude Code

  7. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
    "issue": 15403,
    "status": "done",
    "round": "REWORK round 1 (spec: comment 5865474678; record 5865465586)",
    "branch": "claude/issue-15403-generator-title-rule",
    "pr": "#20401",
    "head": "1ba9d84c",
    "session": "session_01ARcDurZ5j34RdqsGgc4jgH — subagent run; the parent's harness-stamped id, as in every commit's Claude-Session trailer",
    "premise_still_valid": true,
    "summary": "The property reference rung is now conditional: it is offered only when at least one of a module page's schemas renders a ### Properties table. The check is rendersPropertiesTable() in packages/spec/scripts/lib/schema-section.ts, built on declaresProperties(). That is the one expression the section renderer now also uses for its root and union-arm branches. build-docs.ts passes the answer as a required documentsProperties field of the title input. data/feed.mdx (two enums, no property table) moved from 'Feed schema — Data Protocol property reference' (46) to 'Feed schema — Data Protocol reference' (37 / rendered 51), and no other title moved. Rung tally, before -> after: module pages 19 / 102 / 60 / 15 -> 18 / 103 / 60 / 15 (rungs 1–4); category index pages 11 / 3 and root 1 are unchanged. All 18 rung-1 pages render a Properties table; the 14 module pages that render none are all on rungs 2–4. Band reading at 1ba9d84: 211/211 generated titles in 36–46 (min 37 / median 43 / max 46), rendered 51–60, 0 over 60, 211 with ' — ', 0 with ObjectStack, 406 distinct titles across all 406 content/docs pages, 211 navTitle each equal to origin/main's title. Page-tree replay: 449 nodes, identical to origin/main df3ba16 (diff exit 0). The control without navTitlePlugin differs in 388 nodes. origin/main was merged once more with scripts/pm/os-regen-merge.sh; the two deferred pages (security/permission, security/rls) were regenerated on the merged tree. main has since moved 1 commit (dcd3bce, #20398, touching 3 generated pages); a driverless merge-tree of it with 1ba9d84 exits 0 (clean). Not merged again. The optional rootIndexTitle() routing was not taken because it is more than one line (reason in pr_body_delta).",
    "tests": "At head 1ba9d84. pnpm --filter @objectstack/spec test: 'Test Files 561 passed (561) / Tests 16546 passed | 1 todo' (VERDICT command-exit 0). pnpm --filter @objectstack/spec test:repo: 'Test Files 35 passed (35) / Tests 634 passed (634)' (VERDICT command-exit 0). Unit pin at 41b0f68: page-title.test.ts + schema-section.test.ts 'Tests 84 passed (84)'. page-title.test.ts is now 41 tests. It adds the data/feed row (properties: false), the condition pin (the same name with the fact flipped: rung 1 present / absent), a totality sweep for property-less pages (name + category 16–43), the named refusal below 16, and an 11-shape table asserting that rendersPropertiesTable equals the renderer's own '### Properties' emission for every renderSchemaSection branch. Predicate vs renderer over every published schema: 1523 JSON Schemas under packages/spec/json-schema, 1219 true, 0 disagreements. Ablation 3 (commit first, scripts/ablation-replace.mjs, EXIT/INT/TERM trap): '...(documentsProperties ? [' -> '...(true ? [' in lib/page-title.ts, anchor 1->0, blob 38277b23f728 -> 90e0cbe18d3b. page-title.test.ts 'Tests 3 failed | 38 passed (41)': the Feed row, the condition pin, and the short property-less refusal. Restored to 38277b23f728 == HEAD blob, git diff HEAD empty. No dist leg: the test imports by relative source path. check:scripts-typecheck (tsc -p tsconfig.scripts.json, which holds every edited file) exit 0, 0 'error TS'. check:docs exit 0 and check:generated exit 0 ('All 15 generated artifacts are up to date'), both within the gate union. Control-byte self-scan of the 4 edited source files: none.",
    "mcp_calls": "0 — no MCP tool called",
    "api_writes": "1 REST write this round, as objectstack-fleet[bot] via one relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches, HTTP 204): POST /repos//issues/15403/comments (this os-dev-report, via scripts/pm/post-stamped.mjs). git push (4 commits: 41b0f68, 0ea42f4, 23f0d0b, 1ba9d84) is not REST. No PR body PATCH, no new PR, no label or assignee write. Reads: header-less REST GETs through the proxy only.",
    "pr_body_delta": [
    {
    "find": "| module page | NAME schema — CATEGORY property reference | name + category + 29 |",
    "replace": "| module page | NAME schema — CATEGORY property reference, offered only when the page renders a ### Properties table | name + category + 29 |"
    },
    {
    "find": "The module rungs overlap end to end and cover every name + category length from 7 to 43; the longest pair on the tree is 41 (Schemaless Node Config in Automation Protocol).",
    "replace": "The module rungs overlap end to end and cover every name + category length from 7 to 43; the longest pair on the tree is 41 (Schemaless Node Config in Automation Protocol). The first module rung is conditional: property reference is offered only when at least one of the page's schemas renders a ### Properties table (rendersPropertiesTable in lib/schema-section.ts, built on declaresProperties, the one expression the section renderer itself branches on). A page without one, such as the enum-only data/feed, starts at the second rung; without the first rung the ladder covers name + category lengths 16 to 43, and the shortest property-less pair on the tree is 17 (Feed in Data Protocol)."
    },
    {
    "find": "Rung usage on this tree: module pages 19 / 102 / 60 / 15 (rungs 1–4), category index pages 11 / 3, root index 1.",
    "replace": "Rung usage on this tree: module pages 18 / 103 / 60 / 15 (rungs 1–4), category index pages 11 / 3, root index 1. All 18 rung-1 pages render a ### Properties table; the 14 module pages that render none are all on rungs 2–4."
    },
    {
    "find": "| references/ai/agent.mdx | Agent | Agent schema — AI Protocol property reference | 45 / 59 |\n",
    "replace": "| references/ai/agent.mdx | Agent | Agent schema — AI Protocol property reference | 45 / 59 |\n| references/data/feed.mdx | Feed | Feed schema — Data Protocol reference | 37 / 51 |\n"
    },
    {
    "find": "Rewording any of them is a one-line change in lib/page-title.ts plus gen:docs; the band, the unit test and check:docs hold the result either way.",
    "replace": "Rewording any of them is a one-line change in lib/page-title.ts plus gen:docs; the band, the unit test and check:docs hold the result either way. Non-blocking: the seat answered land-as-shipped in comment 5865474678 on #15403, and property reference is now claimed only by pages that render a property table."
    },
    {
    "find": "- packages/spec/scripts/build-docs.ts: the two emission sites (module pages, category index pages), located by symbol.\n",
    "replace": "- packages/spec/scripts/build-docs.ts: the two emission sites (module pages, category index pages), located by symbol.\n- packages/spec/scripts/lib/schema-section.ts: declaresProperties() (an object that declares properties, the one spelling of that condition, now also used by the renderer's root and union-arm branches) and rendersPropertiesTable() (whether a schema renders at least one ### Properties table), read by the module-page title. Rendered output unchanged: regenerating moved exactly one page, data/feed.mdx, and only its title: line.\n"
    },
    {
    "find": "Head a61335f9 (after merging origin/main at ab946560; the four generated pages that merge deferred were regenerated on the merged tree in their own commit).",
    "replace": "Head 1ba9d84c, REWORK round 1: 41b0f683 (the conditional rung), 0ea42f45 (data/feed.mdx regenerated), then a merge of origin/main at df3ba164 whose two deferred pages, security/{permission,rls}.mdx, were regenerated on the merged tree in 1ba9d84c. Round 0 was head a61335f9."
    },
    {
    "find": "- pnpm --filter @objectstack/spec test: 558 files, 16506 passed, 1 todo.",
    "replace": "- pnpm --filter @objectstack/spec test: 561 files, 16546 passed, 1 todo."
    },
    {
    "find": "- pnpm --filter @objectstack/spec test:repo: 34 files, 620 passed.",
    "replace": "- pnpm --filter @objectstack/spec test:repo: 35 files, 634 passed."
    },
    {
    "find": "- pnpm --filter @objectstack/spec typecheck: exit 0 at the pre-merge head 0a241893 (tsc --noEmit, check:scripts-typecheck, check:test-typecheck: 53 files / 255 errors / 142 signatures held in the ledger). At a61335f9 the verify lock timed out three times in a row (27 minutes queued, never acquired), so the check there is narrowed and declared: check:scripts-typecheck (tsc -p tsconfig.scripts.json, the program holding all four files this diff edits plus the 411 src/ files they import) exit 0, run unlocked. The merge brought only main's own src/ changes; CI's TypeScript Type Check runs the full set.",
    "replace": "- Type check: check:scripts-typecheck (tsc -p tsconfig.scripts.json, the program holding every file this diff edits, page-title.test.ts included) exit 0 at 1ba9d84c. The full spec typecheck was green locally at round 0's pre-merge head 0a241893, and Type Check · workspace ran it green in CI on a61335f9."
    },
    {
    "find": "Gates derived by node scripts/pm/dispatch-gates.mjs --commands over this diff,",
    "replace": "Gates derived by node scripts/pm/dispatch-gates.mjs --commands over this diff at 1ba9d84c (216 paths, the same 89 families as round 0),"
    },
    {
    "find": " - NOT MEASURED, timed out: check:pm-dispatch-gates. Its self-test of scripts/pm/dispatch-gates.mjs, which this diff does not edit, did not finish in a 420 s and then a 560 s window on the shared box.",
    "replace": " - NOT MEASURED, timed out: check:pm-dispatch-gates. Its self-test of scripts/pm/dispatch-gates.mjs, which this diff does not edit, did not finish in a 420 s and then a 560 s window on the shared box. Not re-run in round 1; Lint & Repo Gates ran it green in CI on a61335f9."
    },
    {
    "find": "- Ablation 2, check:docs sees the emission: the first module rung's property reference changed to field reference (blob 3fe85286f82d to b8f4c6d26269). check:docs exited 1 with 49 pages out of date: the 19 rung-1 pages, plus the pages the shorter word lets onto rung 1. Restored the same way.\n",
    "replace": "- Ablation 2, check:docs sees the emission: the first module rung's property reference changed to field reference (blob 3fe85286f82d to b8f4c6d26269). check:docs exited 1 with 49 pages out of date: the 19 rung-1 pages, plus the pages the shorter word lets onto rung 1. Restored the same way.\n- Ablation 3, the rung condition is pinned: ...(documentsProperties ? [ changed to ...(true ? [ in lib/page-title.ts (anchor 1 to 0, blob 38277b23f728 to 90e0cbe18d3b). page-title.test.ts went 3 failed / 38 passed: the data/feed row, the condition pin, and the short property-less refusal. Restored to 38277b23f728 = HEAD blob, git diff HEAD empty.\n- The predicate agrees with the renderer on every published schema: over all 1523 JSON Schemas under packages/spec/json-schema/, rendersPropertiesTable(name, schema) equals whether renderSchemaSection(name, schema) emits a ### Properties heading: 1219 true, 0 disagreements. The unit pin holds the same agreement shape by shape (11 JSON Schema shapes covering every renderer branch).\n"
    },
    {
    "find": "- The card body's 225 / 405 reading included 14 releases/** pages (see Measured); nothing here depends on them.",
    "replace": "- The card body's 225 / 405 reading included 14 releases/** pages (see Measured); nothing here depends on them.\n- api/protocol.mdx renders 6 ### Properties tables with no rows (object schemas declaring an empty properties). Pre-existing renderer output; that page is on rung 2 and carries non-empty tables as well. Noted, not filed.\n- The optional routing of rootIndexTitle() through pageTitleOrExit was not taken: pageTitleOrExit lives in build-docs.ts, so routing it means passing the title into renderRootIndex (its input type and the root-index.test.ts fixtures), more than one line. The root title is a fixed 43-character string pinned by the unit test."
    },
    {
    "find": "| references/data/feed.mdx | Feed | Feed schema — Data Protocol property reference | 46 / 60 | = before |",
    "replace": "| references/data/feed.mdx | Feed | Feed schema — Data Protocol reference | 37 / 51 | = before |"
    }
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted in pr_body_delta Acceptance notes, not filed (renderer polish, outside classes a/b/c) · api/protocol.mdx renders 6 '### Properties' tables with no rows (object schemas declaring an empty properties). This is pre-existing renderSchemaSection output, not a title question: that page is on rung 2 and carries non-empty tables too · dedupe words: empty Properties table, properties {}, api/protocol reference page, header-only table"
    ],
    "gates": {
    "head": "1ba9d84c",
    "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 1ba9d84: 216 paths vs merge base df3ba16, 89 families (identical list to round 0)",
    "reconcile": "✓ dispatch-gates --ran: 89 derived famil(ies) accounted for — 85 run, 4 NOT-MEASURED (3 DERIVED from a recorded exit 3, 1 claimed). 0 UNRUN.",
    "exit_0": [
    "node scripts/check-adr-0087-registration.mjs --base origin/main",
    "node scripts/check-adr-0087-registration.mjs --self-test",
    "node scripts/check-ci-filter-parity.mjs",
    "node scripts/check-closing-keyword-parity.mjs",
    "node scripts/check-closing-keyword-parity.mjs --self-test",
    "node scripts/check-comment-mask-adoption.mjs",
    "node scripts/check-comment-mask-adoption.mjs --self-test",
    "node scripts/check-comment-mask-corpus.mjs",
    "node scripts/check-dev-prereqs.mjs --self-test",
    "node scripts/check-doc-frontmatter.mjs",
    "node scripts/check-doc-frontmatter.mjs --self-test",
    "node scripts/check-doc-route-spelling.mjs --advisory",
    "node scripts/check-doc-route-spelling.mjs --self-test",
    "node scripts/check-docs-section-name.mjs",
    "node scripts/check-docs-section-name.mjs --self-test",
    "node scripts/check-issue-citations.mjs",
    "node scripts/check-keyed-text-bounds.mjs",
    "node scripts/check-keyed-text-bounds.mjs --self-test",
    "node scripts/check-platform-object-tenancy-census.mjs",
    "node scripts/check-platform-object-tenancy-census.mjs --self-test",
    "node scripts/check-plugin-teardown-shape.mjs",
    "node scripts/check-plugin-teardown-shape.mjs --self-test",
    "node scripts/check-registry-log-declared.mjs",
    "node scripts/check-registry-log-declared.mjs --self-test",
    "node scripts/check-rest-log-spy-declared.mjs",
    "node scripts/check-rest-log-spy-declared.mjs --self-test",
    "node scripts/check-section-landing-index.mjs",
    "node scripts/check-section-landing-index.mjs --self-test",
    "node scripts/check-system-context-census.mjs",
    "node scripts/check-system-context-census.mjs --self-test",
    "node scripts/check-undeclared-dep-imports.mjs",
    "node scripts/check-undeclared-dep-imports.mjs --self-test",
    "node scripts/docs-audit/check-affected-docs.mjs",
    "node scripts/docs-audit/check-drift-comment.mjs",
    "node scripts/pm/bare-root-worklist.mjs --self-test",
    "pnpm --filter @objectstack/lint run check:doc-formula-expressions",
    "pnpm --filter @objectstack/lint run check:doc-security-posture",
    "pnpm --filter @objectstack/spec run check:docs",
    "pnpm --filter @objectstack/spec run check:duration-unit-keys",
    "pnpm --filter @objectstack/spec run check:empty-state",
    "pnpm --filter @objectstack/spec run check:generated",
    "pnpm --filter @objectstack/spec run check:liveness",
    "pnpm --filter @objectstack/spec run check:strictness-ledger",
    "pnpm --filter @objectstack/spec run check:variant-docs",
    "pnpm --filter @objectstack/spec run check:yaml-examples",
    "pnpm check:changeset-gate-self-tests",
    "pnpm check:corpus-claim-drift",
    "pnpm check:cross-package-test-inputs",
    "pnpm check:doc-anchors",
    "pnpm check:doc-authoring",
    "pnpm check:docs-audit-scope",
    "pnpm check:docs-redirects",
    "pnpm check:docs-single-h1",
    "pnpm check:docs-spec-enumerations",
    "pnpm check:docs-transcript-drift",
    "pnpm check:driver-memory-census",
    "pnpm check:dts-closure",
    "pnpm check:engine-double-contract",
    "pnpm check:gitlink-declared",
    "pnpm check:issue-citations",
    "pnpm check:lean-entry-closure",
    "pnpm check:logger-receiver-detach",
    "pnpm check:merge-driver",
    "pnpm check:nul-bytes",
    "pnpm check:objectql-double-limit",
    "pnpm check:org-identifier",
    "pnpm check:page-declaration-shape",
    "pnpm check:pm-governed-merges",
    "pnpm check:pm-widening-tells",
    "pnpm check:published-files",
    "pnpm check:published-readme-links",
    "pnpm check:query-options-erasure",
    "pnpm check:quick-reference-counts",
    "pnpm check:react-page-adapter-contract",
    "pnpm check:refd-timer-probe",
    "pnpm check:role-word",
    "pnpm check:skill-identifier-liveness",
    "pnpm check:slot-lookup",
    "pnpm check:sourcemap-no-sources-content",
    "pnpm check:test-source-alias",
    "pnpm check:tier-file-adoption",
    "pnpm check:type-check-coverage",
    "pnpm check:vendor-version-stamps",
    "pnpm check:watch-hint-literal",
    "pnpm check:where-matcher"
    ],
    "not_measured": [
    "pnpm --filter @objectstack/spec run check:skill-examples :: exit 3 — PREREQUISITE NOT MET (client-react closure unbuilt)",
    "pnpm check:dual-build-cjs-loads :: exit 3 — PREREQUISITE NOT MET (every package's dist)",
    "pnpm check:type-check-debt :: exit 3 — PREREQUISITE NOT MET (30-package type closure unbuilt)",
    "pnpm check:pm-dispatch-gates :: claimed — not re-run; killed at 420 s and 560 s (exit 124) in round 0; scripts/pm/dispatch-gates.mjs not edited"
    ],
    "ci_at_report": "head 1ba9d84: 35 check runs, 31 success, 3 skipped, 1 in_progress. Required: Test Core, TypeScript Type Check, Dogfood Regression Gate, Temporal Conformance, Build Core, Governed Surface Queue Guard success; Lint & Repo Gates in_progress. Not awaited."
    },
    "line_budget": "n/a — no skills/** file, no line-ratcheted ledger, no governed surface",
    "deviations": [
    "File surface +1 this round: packages/spec/scripts/lib/schema-section.ts. It gains declaresProperties() + rendersPropertiesTable(), and its three inline 'object with properties' checks now call declaresProperties(). The rung condition is the renderer's own; rendered output is unchanged (regeneration moved only data/feed.mdx's title line; 0/1523 predicate-renderer disagreements).",
    "Without the property rung, the module ladder covers name + category 16–43 (not 7–43). A future property-less module shorter than that is refused by name, per the refusal-not-truncation design, rather than titled; the shortest on the tree is 17. Stated in lib/page-title.ts and pinned in page-title.test.ts. No padding wording was invented, because the seat's spec was 'falls to its next rung'.",
    "Optional rootIndexTitle() -> pageTitleOrExit routing not taken: it needs the title threaded into renderRootIndex's input and root-index.test.ts fixtures, which is more than one line.",
    "Not merged a second time: origin/main moved 1 commit (dcd3bce) after the round's merge. A driverless merge-tree is clean (exit 0), so the later lander re-merges.",
    "Full spec typecheck not re-run locally this round: check:scripts-typecheck covers every edited file. CI 'TypeScript Type Check' is success on 1ba9d84.",
    "The merge commit 23f0d0b carries git's default merge message (os-regen-merge.sh step 1), the same shape as round 0's 9da41ce."
    ],
    "files_changed": [
    "packages/spec/scripts/lib/schema-section.ts (this round: +declaresProperties, +rendersPropertiesTable, 3 renderer checks now call declaresProperties)",
    "packages/spec/scripts/lib/page-title.ts (this round: required documentsProperties input; first module rung conditional; docblock)",
    "packages/spec/scripts/build-docs.ts (this round: passes documentsProperties = schemas.some(rendersPropertiesTable))",
    "packages/spec/scripts/page-title.test.ts (this round: 25 -> 41 tests)",
    "content/docs/references/data/feed.mdx (this round: title line only, via gen:docs)",
    "content/docs/references/security/{permission,rls}.mdx (merge regeneration: main's body rows + this branch's title/navTitle)",
    "PR total vs origin/main df3ba16: 216 files — 5 scripts files + 211 generated pages (each +2/-1 in frontmatter)"
    ]
    }


    Generated by Claude Code

  8. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
    "issue": 15403,
    "status": "done",
    "round": "landing lap: merge origin/main + regenerate only (record 5866297461 PASS on 1ba9d84)",
    "branch": "claude/issue-15403-generator-title-rule",
    "pr": "#20401",
    "head": "2da3e2394d3c0f5604c000a891d8b9665313fb72",
    "session": "session_01ARcDurZ5j34RdqsGgc4jgH — subagent run; the parent's harness-stamped id, as in every commit's Claude-Session trailer",
    "premise_still_valid": true,
    "summary": "Merge and regeneration only. bash scripts/pm/os-regen-merge.sh merged origin/main 2c31070 into 1ba9d84 as ce03af2. It deferred exactly the three generated pages both sides changed (data/object, kernel/metadata-plugin, ui/action) and staged main's side of each. No hand-written file conflicted, and the tree was not left in MERGE state (no MERGE_HEAD) when the generators ran. gen:schema + gen:docs on the merged tree produced 2da3e23 (those three pages only). No file under packages/spec/scripts/** and no authored page was touched in the lap. No title or navTitle moved: 0 of 211 titles and 0 of 211 navTitles differ from 1ba9d84, and every navTitle still equals origin/main's title. The three pages keep their Properties-table counts (12 / 8 / 4, unchanged), so no rung changed. Band reading on 2da3e23: 211/211 generated titles in 36–46 (min 37 / median 43 / max 46), rendered 51–60, 0 over 60, 211 with ' — ', 0 with ObjectStack, 406 distinct titles across 406 pages. Rungs: modules 18/103/60/15, category indexes 11/3, root 1. 0 rung-1 pages lack a Properties table. The page-tree replay has 449 nodes and is identical to origin/main (diff exit 0). origin/main has since moved one more commit (7db1332, #20405: 9 files, none under content/docs/references or packages/spec/scripts). The driverless merge-tree probe could not run: the shared bare clone did not see the new object, so that probe is NOT MEASURED. The GitHub REST read at report time was PR 20401 mergeable: true (mergeable_state 'blocked', i.e. review/draft, not a conflict). Not merged again.",
    "scripts_numstat": {
    "before (df3ba16...1ba9d84)": [
    "48\t3\tpackages/spec/scripts/build-docs.ts",
    "191\t0\tpackages/spec/scripts/lib/page-title.ts",
    "4\t1\tpackages/spec/scripts/lib/root-index.ts",
    "36\t5\tpackages/spec/scripts/lib/schema-section.ts",
    "256\t0\tpackages/spec/scripts/page-title.test.ts"
    ],
    "after (2c31070...2da3e23)": [
    "48\t3\tpackages/spec/scripts/build-docs.ts",
    "191\t0\tpackages/spec/scripts/lib/page-title.ts",
    "4\t1\tpackages/spec/scripts/lib/root-index.ts",
    "36\t5\tpackages/spec/scripts/lib/schema-section.ts",
    "256\t0\tpackages/spec/scripts/page-title.test.ts"
    ],
    "identical": true
    },
    "regenerated_vs_merge": "Pages whose bytes differ from what the lap's merge produced before regeneration: exactly 3 — content/docs/references/data/object.mdx, kernel/metadata-plugin.mdx, ui/action.mdx. Pre-regeneration index = main's side, staged by step 2; after gen:docs only these three were MM, and the other 208 pages are byte-identical to both the index and merge commit ce03af2. Staged vs ce03af2 (the branch's bytes, which the driver kept): +3/-11, body lines only, no title/navTitle line. Staged vs origin/main: only the three pages' title/navTitle lines (Object -> 'Object schema — Data Protocol reference'; Metadata Plugin -> 'Metadata Plugin — Kernel Protocol reference'; Action -> 'Action schema — UI Protocol property reference'), each exactly as at 1ba9d84.",
    "tests": "On 2da3e23. pnpm --filter @objectstack/spec check:docs exit 0 ('✅ 226 generated files in sync with packages/spec'). pnpm --filter @objectstack/spec check:generated exit 0 ('✓ All 15 generated artifacts are up to date'). pnpm --filter @objectstack/spec test: 'Test Files 563 passed (563) / Tests 16577 passed | 1 todo' (VERDICT command-exit 0). pnpm --filter @objectstack/spec test:repo: first attempt exit 99 (queue-timeout, never acquired: not a measurement); the retry on the same slot gave 'Test Files 35 passed (35) / Tests 634 passed (634)' (VERDICT command-exit 0).",
    "mcp_calls": "0 — no MCP tool called",
    "api_writes": "1 REST write, as objectstack-fleet[bot] via one relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches): POST /repos//issues/15403/comments (this os-dev-report, via scripts/pm/post-stamped.mjs). git push of ce03af2 + 2da3e23 is not REST. No PR body write.",
    "open_questions": [],
    "out_of_scope_findings": [],
    "gates": {
    "head": "2da3e239",
    "ran": [
    "pnpm --filter @objectstack/spec check:docs :: exit 0",
    "pnpm --filter @objectstack/spec check:generated :: exit 0",
    "pnpm --filter @objectstack/spec test :: exit 0",
    "pnpm --filter @objectstack/spec test:repo :: exit 0"
    ],
    "scope": "Per the lap order: merge + regeneration only, with check:docs, check:generated, spec test and test:repo. The dispatch-gates union was not re-run this lap because the diff's source files are byte-identical to round 1 (scripts numstat identical); only generated pages moved."
    },
    "line_budget": "n/a",
    "deviations": [
    "origin/main advanced to 7db1332 after the lap's merge. Not merged again: the order was one merge. That commit touches no generated page and no spec script, and GitHub reports the PR mergeable. The local driverless merge-tree probe could not see the new object, so it is NOT MEASURED.",
    "The merge commit ce03af2 carries git's default merge message (os-regen-merge.sh step 1), as in the earlier laps."
    ],
    "files_changed": [
    "ce03af2c merge of origin/main 2c31070 (main's own files; the branch's 3 overlapping generated pages were deferred by the driver)",
    "2da3e239 content/docs/references/data/object.mdx, kernel/metadata-plugin.mdx, ui/action.mdx: regenerated on the merged tree",
    "PR total vs 2c31070: 216 files — the same 5 packages/spec/scripts files (numstat identical) + 211 generated pages"
    ]
    }


    Generated by Claude Code

  9. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
    "issue": 15403,
    "status": "done",
    "round": "landing lap 2: merge origin/main + regenerate only (record 5866297461 PASS on 1ba9d84, carried to 2da3e23 by Regen-provenance 5867040613)",
    "branch": "claude/issue-15403-generator-title-rule",
    "pr": "#20401",
    "head": "1773c29a7ee45e553c98faf06162520772d00cc0",
    "session": "session_01ARcDurZ5j34RdqsGgc4jgH — subagent run; the parent's harness-stamped id, as in every commit's Claude-Session trailer",
    "premise_still_valid": true,
    "summary": "Merge and regeneration only. bash scripts/pm/os-regen-merge.sh merged origin/main 0283cb9 into 2da3e23 as a0e8590. There was no conflict in any non-generated file: git completed the merge itself, and main's overlap with the branch's five scripts files is none. The driver deferred five generated pages both sides changed (automation/schemaless-node-config, data/analytics, index, integration/connector, system/auth-config), and step 2 staged main's side of each. The tree was not in MERGE state (no MERGE_HEAD) when gen:schema + gen:docs ran on the merged tree; the result was committed as 1773c29 (those five pages only). No title or navTitle moved: 0 of 211 titles and 0 of 211 navTitles differ from 2da3e23, and every navTitle equals origin/main's title. integration/connector went from 19 to 15 Properties tables because of main's retirement of the connector resilience family, but it stays on rung 3, where the Properties condition does not apply. The other three module pages keep their counts. Band reading on 1773c29: 211/211 generated titles in 36–46 (min 37 / median 43 / max 46), 0 rendered over 60, 211/211 with ' — ', 0 with ObjectStack, 407 distinct titles across 407 content/docs pages (main added one authored page). Rungs: modules 18/103/60/15, category indexes 11/3, root 1. 0 rung-1 pages lack a Properties table. The page-tree replay has 450 nodes and is identical to origin/main (diff exit 0). origin/main has since moved one more commit (24b7085, #20421), which touches no generated reference page and no spec script. Not merged again.",
    "scripts_numstat": {
    "before (2c31070...2da3e23)": [
    "48\t3\tpackages/spec/scripts/build-docs.ts",
    "191\t0\tpackages/spec/scripts/lib/page-title.ts",
    "4\t1\tpackages/spec/scripts/lib/root-index.ts",
    "36\t5\tpackages/spec/scripts/lib/schema-section.ts",
    "256\t0\tpackages/spec/scripts/page-title.test.ts"
    ],
    "after (0283cb9...1773c29)": [
    "48\t3\tpackages/spec/scripts/build-docs.ts",
    "191\t0\tpackages/spec/scripts/lib/page-title.ts",
    "4\t1\tpackages/spec/scripts/lib/root-index.ts",
    "36\t5\tpackages/spec/scripts/lib/schema-section.ts",
    "256\t0\tpackages/spec/scripts/page-title.test.ts"
    ],
    "identical": true
    },
    "non_references_diff": "Three-dot patch of the PR outside content/docs/references: 2c31070...2da3e23 vs 0283cb9...1773c29 is byte-identical (cmp exit 0). The five scripts blobs are identical at both heads, and page-title.ts / page-title.test.ts are absent at both merge bases.",
    "regenerated_vs_merge": "Pages whose bytes differ from what the lap's merge produced before regeneration: exactly the 5 deferred pages. Before regeneration the index held main's side, staged by step 2. After gen:docs only those five were MM, and the other 206 generated pages are byte-identical to both the index and merge commit a0e8590. Staged vs origin/main: only each page's title/navTitle lines, equal to 2da3e23's (Schemaless Node Config — Automation Protocol; Analytics schema — Data Protocol reference; Protocol reference — every schema by module; Connector — Integration Protocol reference; Auth Config schema — System Protocol reference). Staged vs a0e8590: +52/-265, body lines only, no title/navTitle line.",
    "tests": "On 1773c29, each under scripts/pm/os-verify-lock.sh. check:docs: CHECK_DOCS_EXIT=0 ('✅ 226 generated files in sync with packages/spec'). check:generated: CHECK_GENERATED_EXIT=0 ('✓ All 15 generated artifacts are up to date'). Those two ran in one lock call whose last part asserted both exits are 0; VERDICT batch-last-exit 0. pnpm --filter @objectstack/spec test: 'Test Files 564 passed (564) / Tests 16640 passed | 1 todo' (VERDICT command-exit 0). pnpm --filter @objectstack/spec test:repo: 'Test Files 36 passed (36) / Tests 655 passed (655)' (VERDICT command-exit 0).",
    "mcp_calls": "0 — no MCP tool called",
    "api_writes": "1 REST write, as objectstack-fleet[bot] via one relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches): POST /repos//issues/15403/comments (this os-dev-report, via scripts/pm/post-stamped.mjs). git push of a0e8590 + 1773c29 is not REST. No PR body, label or assignee write.",
    "open_questions": [],
    "out_of_scope_findings": [],
    "gates": {
    "head": "1773c29a",
    "ran": [
    "pnpm --filter @objectstack/spec check:docs :: exit 0",
    "pnpm --filter @objectstack/spec check:generated :: exit 0",
    "pnpm --filter @objectstack/spec test :: exit 0",
    "pnpm --filter @objectstack/spec test:repo :: exit 0"
    ],
    "scope": "Per the lap order: merge + regeneration only; the PR's non-references patch is byte-identical to the reviewed head, so the dispatch-gates union was not re-run."
    },
    "line_budget": "n/a",
    "deviations": [
    "origin/main advanced to 24b7085 (#20421) after the lap's merge. Not merged again: the order was one merge, and that commit touches no generated reference page and no spec script. GitHub's mergeable was still computing ('unknown') at report time.",
    "The merge commit a0e8590 carries git's default merge message (os-regen-merge.sh step 1), as in the earlier laps."
    ],
    "files_changed": [
    "a0e8590e merge of origin/main 0283cb9 (main's own files; the branch's 5 overlapping generated pages were deferred by the driver)",
    "1773c29a content/docs/references/{automation/schemaless-node-config,data/analytics,index,integration/connector,system/auth-config}.mdx: regenerated on the merged tree",
    "PR total vs 0283cb9: 216 files — the same 5 packages/spec/scripts files (patch identical) + 211 generated pages"
    ]
    }


    Generated by Claude Code

  10. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    Review: ACCEPT · PR #20401 at head 1773c29a7ee45e553c98faf06162520772d00cc0 · 2026-09-28T11:26Z

    domain:spec seat 4 (session_01ARcDurZ5j34RdqsGgc4jgH), reviewer of record under claim 5863183456. The readings below were taken on GitHub or on the tree by this seat.

    check reading
    Shape Draft, base main. Body line 1 Fixes #15403; Clause-②: no stands alone. skip-changeset: the record judges it right, because the diff publishes nothing from a released package.
    Scope 216 files, +957/−220. Five are under packages/spec/scripts/ (build-docs.ts, lib/page-title.ts new, lib/root-index.ts, lib/schema-section.ts, page-title.test.ts new). The other 211 are generated pages under content/docs/references/**, each moving only its title: line and gaining a navTitle: equal to main's old title.
    Rework REWORK round 1 (5865474678), the property reference rung condition, is held on every regenerated page. The round-0 question (the fixed words: land as shipped or hold) was answered A by the seat in 5865474678. The record judges the wording accurate, and the PR keeps it listed for the maintainer's reading, non-blocking.
    Contract review At-tier record PASS 5866297461 on 1ba9d84c. It is carried forward over two pure-regeneration hops, each re-run by this seat on the committed trees: 5867040613 (1ba9d84c → 2da3e239) and 5868765660 (2da3e239 → 1773c29a). The PR's diff outside content/docs/references/** is byte-identical across both hops.
    Title band at this head From the dev report 5868744813: 211/211 generated titles are 36–46 characters, 0 render over 60, 211/211 carry ' — ', and there are 407 distinct titles across 407 pages. The page-tree replay is identical to origin/main.
    CI at this head 32 success, 3 skipped, all on the roster (check-expected-skips.mjs --pr 20401, exit 0). mergeable_state: clean. origin/main dbddf02c is one commit past the merge base (driver-turso, no reference page), and git merge-tree is clean.
    Governed / size Not governed (check-governed-merges.mjs --branch, 0 of 216 paths; the --pr form hit the page-2 403), 1177 changed lines.

    Acceptance notes (non-blocking, carried from the PR's own section):

    • Module display names are title-cased from the file slug (Mcp, Rls, Scim, Odata, …). This defect class predates this PR; it was fixed for category titles by lib/category-title.ts. These strings are now each page's navTitle, which this card keeps byte-identical → Acceptance notes, carrier: none (fixing it changes nav labels, which is its own decision).
    • api/protocol.mdx renders six empty ### Properties tables, a pre-existing renderer output → Acceptance notes, carrier: none.

    Landing next: ready + auto-merge through the relay. At MERGED, this card closes by Fixes. ⚠️ Any spec PR that regenerates a reference page and lands first will dequeue this one. The next lap would again be pure regeneration, carried by a third hop.

    domain:spec seat 4 · #18917 · session_01ARcDurZ5j34RdqsGgc4jgH


    Generated by Claude Code

  11. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    Contributor

    Landed: PR #20401 → main e4d3f2ca696f4b388286c0dfdda23e50c850ca92 · 2026-09-28T11:49Z

    domain:spec seat 4 (session_01ARcDurZ5j34RdqsGgc4jgH), landing record for claim 5863183456. ACCEPT 5868926712, on the at-tier PASS 5866297461 carried forward over two pure-regeneration hops (5867040613, 5868765660). Queue path: ready and auto-merge at 11:25Z, added_to_merge_queue at 11:28Z, merged at 11:49Z.

    domain:spec seat 4 · #18917 · session_01ARcDurZ5j34RdqsGgc4jgH


    Generated by Claude Code

  12. added a commit that references this issue on Sep 29, 2026
    e4d3f2c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationdomain:specpriority:p1High: required for production / M2

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions