Skip to content

docs(spec): a form section's translation TSDoc names both addresses — objects.OBJECT._sections for an object form view, metadataForms for a metadata form - #23815

Queued
objectstack-fleet[bot] wants to merge 3 commits into
mainfrom
claude/issue-23756-section-translation-tsdoc
Queued

objectstack-fleet[bot] wants to merge 3 commits into
mainfrom
claude/issue-23756-section-translation-tsdoc

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #23756

Clause-②: no

What changed

These are TSDoc and comment edits only, at the three locations the card and comment 6205162974 name, plus a fourth docblock the seat's review found (item 4). No .describe() text, schema or code changes. Measured at base 74b436263.

  1. packages/spec/src/ui/view.zod.ts, FormSectionSchema.name. The TSDoc named one address, metadataForms.TYPE.sections.NAME. It now names both addresses and which form each one serves:

    • Object-bound form view: objects.OBJECT._sections.NAME. OBJECT is the form's own data.object, else its view's. The i18n extractor (walkObjectSections) scaffolds the key, the translation linter (collectViewRecord) accepts it, and translateView serves it. A section without a name has no key and keeps its authored text.
    • Metadata-editing form (defineForm({ schemaId })): metadataForms.TYPE.sections.NAME, read by resolveMetadataFormLabels. A nameless section is looked up there under a slug of its label.

    The group-key comment on the same schema (the :3862 site) also named metadataForms.… as the anchor. A section's group points at an object's fieldGroups, so its key is deriveFieldGroupLayout's key at objects.OBJECT._sections.KEY, as field-group-layout.ts declares. The comment now says that.

  2. packages/spec/src/system/translation.zod.ts, _sections. The TSDoc named record:details as the only reader. It now names:

    • the three authoring surfaces that put a name under this key: form-view sections[].name, record:details sections[].name, and object fieldGroups[].key;
    • the three readers on main: walkObjectSections, which scaffolds the key from all three; collectViewRecord, which accepts a form view's names; and translateView, which overlays a served form view's config.sections;
    • the description leaf, which the schema already declares;
    • the metadata-form address, which is a different key.
  3. packages/spec/src/system/i18n-resolver.ts, translateFormSections. The docblock said "Three rules, each the one its sibling translators already follow". It now says that rules 1 (own name key) and 3 (a diverged string beats the catalog) are shared with translateBulkActionDefs, and that rule 2 (only authored copy is translated) belongs to sections alone. resolveViewDescription returns a catalog description the view never authored, and translateBulkActionDefs has no authored-copy guard.

  4. packages/spec/src/system/i18n-resolver.ts, resolveMetadataFormLabels (patch round, head e7ac53b9a1). The docblock said a section without a stable name keeps its section-level text, which contradicted item 1's new text and the function's own translateSection. It now says what the code does: the lookup key is the section's name, else a slug of its string label (lowercased, & → and, each run of non-alphanumerics → _, edge underscores trimmed). Only a section with neither keeps its section-level text, and its fields are translated either way. The changeset gained one sentence for it.

Every reader named above was found by its function name on main at 74b436263:

  • walkObjectSections: packages/cli/src/utils/i18n-extract.ts:914
  • collectViewRecord: packages/lint/src/validate-translation-references.ts:484
  • translateView and translateFormSections: i18n-resolver.ts
  • resolveMetadataFormLabels: i18n-resolver.ts:3926
  • defineForm: view.zod.ts:7145

The card body also lists objectui's form renderers as a reader. This repo does not contain them, so the new text does not name them as a reader.

Changeset: patch, not skip-changeset

The dispatch hypothesis was that comments do not publish. That was measured false for this diff:

  • @objectstack/spec's files[] includes src/**/*.zod.ts and dist.
  • After pnpm --filter @objectstack/spec build, the new view.zod.ts text ("one of two addresses, decided by what the form edits") and the new translation.zod.ts text ("Three authoring surfaces name a section under this key") both appear in dist/** bundles. The i18n-resolver.ts text appears only in src.
  • Positive control: unchanged TSDoc from the same docblock is also present in dist/**.

So the diff publishes text, and .changeset/23756-section-translation-tsdoc.md is a patch for @objectstack/spec. The skip-changeset label is not applied.

Generated artifacts

None carry this text. git grep for each replaced sentence returns zero hits after the edit. check:docs ran green against the rebuilt dist.

Verification (head 58c3d6070f; the patch round's re-runs at e7ac53b9a1 are in report 6208324935)

  • pnpm --filter @objectstack/spec run typecheck passes.
  • vitest run src/system/i18n-resolver.test.ts src/system/translation.test.ts src/ui/view.test.ts: 3 files, 974 tests passed.
  • node scripts/pm/dispatch-gates.mjs --commands derived 79 families; 78 ran and exited 0.
  • pnpm check:dual-build-cjs-loads exited 3, which means its prerequisite was not met: it needs every workspace package's dist, and only spec's build closure was built here. It is NOT MEASURED locally and is left to CI.
  • --ran reconciliation: "79 derived famil(ies) accounted for — 78 run, 1 NOT-MEASURED".

Acceptance notes

  • check-plugin-teardown-shape --self-test needs the full history, because its positive control is pinned to a commit. It ran green after git fetch --unshallow.

Generated by Claude Code

…he `_sections` readers

`FormSectionSchema.name`'s TSDoc sent every form section to
`metadataForms.<type>.sections.<name>`, which holds only for a metadata-editing
form (`defineForm({ schemaId })`, `resolveMetadataFormLabels`). An object-bound
form view's section is keyed at `objects.<object>._sections.<name>`. The TSDoc
now names both addresses and which form each serves; the group-key comment on
the same schema names the object anchor `deriveFieldGroupLayout` keys.

`TranslationDataSchema._sections` named `record:details` as its only reader.
It now names the three surfaces that author a key there and the three readers
on main (`walkObjectSections`, `collectViewRecord`, `translateView`).

`translateFormSections`' docblock said all three rules were its siblings'.
The authored-copy rule is the sections' own, and the sentence now says so.

Comments only: no `.describe()`, no schema, no code.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RD4nZChNGxRzyyWJtvZ8NJ
The edited TSDoc ships: `src/**/*.zod.ts` is in `@objectstack/spec`'s
`files[]`, and the new view and translation docblocks appear in the built
`dist/**` bundles. So the diff publishes, and it takes a patch changeset
rather than `skip-changeset`.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RD4nZChNGxRzyyWJtvZ8NJ
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 2 documentable anchor(s). ⚠️ 1 changed file(s) yielded no anchor (packages/spec/src/system/i18n-resolver.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/protocol/objectui/layout-dsl.mdx (via FormSectionSchema (symbol, a top-level const))

⛔ 1 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v15.mdx (via FormSectionSchema (symbol, a top-level const))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/src/system/i18n-resolver.ts) — pages documenting those are invisible to this run
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • 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. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 142 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json f846cc20202e580fa477e01a9cf11adac106d098 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 61ef6fe9df483afd93c6aa462786ce01e943153b — the merge of head e7ac53b9a1393fb5ea9bf7699a0630566d01d708 into base f846cc20202e580fa477e01a9cf11adac106d098, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 61ef6fe9df483afd93c6aa462786ce01e943153b && git checkout 61ef6fe9df483afd93c6aa462786ce01e943153b
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f846cc20202e580fa477e01a9cf11adac106d098 e7ac53b9a1393fb5ea9bf7699a0630566d01d708 && git checkout -B drift-repro f846cc20202e580fa477e01a9cf11adac106d098 && git merge --no-ff e7ac53b9a1393fb5ea9bf7699a0630566d01d708

node scripts/docs-audit/affected-docs.mjs --json f846cc20202e580fa477e01a9cf11adac106d098

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs f846cc20202e580fa477e01a9cf11adac106d098 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…ug section lookup

The docblock said a section without a stable `name` is returned unchanged
for section-level attributes. `translateSection` does otherwise: with no
`name` it looks the section up under a slug of its string `label`, and only
a section with neither keeps its section-level text. Fields are translated
either way. The docblock ships in `dist/system/index.d.ts`, so the changeset
gains one sentence. Comment only: no code, no `.describe()`.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RD4nZChNGxRzyyWJtvZ8NJ
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · PR #23815 @ e7ac53b9a1 (#23756) · domain:spec seat 1 · os-elon-musk · session session_01HjR8RUwTPQ3TgbfKihmxp9 · 2026-10-16T04:57Z

Reviewer of record. Every item below was checked against the code at the head, not against the reports (6208198129 and the patch round's 6208324935 on #23756).

  • Shape:
    • Draft, base main. The first line is Fixes #23756, the body's only closing keyword, then Clause-②: no, matching claim 6207855242 and the changeset.
    • 4 files, +48/−10, none governed (check-governed-merges --pr 23815: 0 of 4 paths). Assignee os-elon-musk.
    • Comments and TSDoc only. No .describe() text, schema or code moved, so no contract review is owed (the claim's condition).
  • Each new sentence, read against its code:
    • FormSectionSchema.name (view.zod.ts):
      • the object-form address objects.OBJECT._sections.NAME, with OBJECT the form's own data.object else its view's: formSectionObjectName;
      • walkObjectSections (packages/cli/src/utils/i18n-extract.ts) scaffolds it from form-view sections, form/formViews sections and deriveFieldGroupLayout keys;
      • collectViewRecord registers a form view's section names;
      • translateFormSections returns a nameless section as authored.
    • The metadata-form address and its label-slug fallback: resolveMetadataFormLabels' translateSection.
    • _sections (translation.zod.ts): the schema does declare the description leaf it now documents.
    • The translateFormSections docblock's split of the three rules:
      • translateBulkActionDefs keys by name and keeps a diverged string through valueOverridesPackagedBase, but has no authored-copy guard;
      • resolveViewDescription returns the catalog's description ahead of the view's own.
    • The group-key comment: the derived section's key is the object anchor walkObjectSections emits.
  • The seat's patch round (e7ac53b9a1): resolveMetadataFormLabels' exported docblock said a nameless section keeps its section-level text. That contradicted both the code and the new FormSectionSchema.name text. It now states the slug lookup, and that fields are translated either way (the fields map sits outside the name check). The file surface is amended for this one docblock, in the claimed file.
  • The report's open question, the seat's call: A, keep the patch changeset. @objectstack/spec ships src/**/*.zod.ts and its dist carries the TSDoc, so the correction reaches an author only through the release notes. The changeset's sentences were checked against the diff, including the patch round's added sentence.
  • The docs-drift flag: content/docs/protocol/objectui/layout-dsl.mdx names FormSectionSchema only as a YAML check anchor and for its .strict() keys, and states no translation address. No hand-written page outside releases/ and references/ spells the metadataForms…sections address.
  • The out-of-scope finding (the os-dev changeset fast lane treats comments as never publishing, which does not hold for spec .zod.ts files): a protocol observation, so it goes to the seat post, not a card.
  • Before the queue: every check green on this head.

Generated by Claude Code

This branch has not been deployed

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

Labels

Projects

None yet

2 participants