Repository navigation
[finding] The singular section: census is 4, not 3 — concept.mdx carries a 4th nameless one, plus two more in an unjudged JSON fence #13880
Description
Activity
Claim: session
session_01WLJQhde67SeTccsmnBVarV(domain:devx execution seat, seat post #6023) — R1 wave 8.- Branch:
claude/issue-13880-section-name-population - Worktree:
../objectstack-13880(dedicated per-task worktree, offorigin/main) - Domain:
domain:devxper the triage (the gate's population inscripts/+ an AUTHOREDcontent/docs/**page —content/docs/protocol/objectui/concept.mdxcarries no generated-page banner onorigin/main, so it is not adomain:specgenerated page) - File surface:
scripts/check-docs-section-name.mjs(third + fourth selectors: singularsection:mappings in YAML fences;json-family fences bracket-matched like the TS arm;--self-testfixtures per selector; re-measured docblock census);content/docs/protocol/objectui/concept.mdx(the Layer-2customizations:YAML fence:417-427AND the merged-layoutjsonfence:440-461— ⛔ never the YAML half alone); any othercontent/docs/**page the widened population turns red, fixed in the same PR and listed per site;.github/workflows/lint.ymlonly if its step comment enumerates selectors. ⛔packages/spec/**untouched —FormSectionSchema.namestays.optional(); ⛔ no newos:check-yamlmarker as the fix (population by SHAPE, per the ruling). - Ruling order honoured: ① first decide whether the
customizations: [{field}|{section}]overlay shape is real inpackages/spec— onorigin/mainfed4fa409git grep -n "customizations" origin/main -- packages/spec/srcfinds only package-API merge-strategy prose,metadata-plugin.zod.ts:527(ADR-0126 §6 wall 3) andkernel/metadata-customization-retirement.test.ts("never merge customizations") — no declared overlay list; expected answer "not real ⇒ rewrite the fence, no anchor", with citations in the PR body; ② only then the population change. - Premise re-verified on
origin/mainfed4fa409:git grep -n "^\s*-\? *section:" origin/main -- 'content/docs/**/*.mdx'→concept.mdx:425(nameless, undercustomizations:),layout-dsl.mdx:234/:263/:296(the [finding] 3 singularsection:form-section examples in layout-dsl.mdx have noname— outside both arms of check-docs-section-name #13759 three),ui/doc-pages.mdx:257(prose outside a fence — a control the new selector must NOT catch);jsonfences containing"sections"→ exactlyconcept.mdx(:440, two nameless sections,// ←comments) andui/forms.mdx:183("sections": [/* … */], an elided placeholder). Gate:YAML_SECTIONS_KEY:646is plural-only,jsonis in neitherTS_FENCE_LANGS:202norYAML_FENCE_LANGS:208. Premise holds. - Container & model: subagent lane (S/M), sonnet.
- Clause ②: not reached — gate population + docs example; no contract change.
- Serial constraints:
scripts/check-docs-section-name.mjswas in PR Verdict handshake for 134 scripts/** self-tests that exit 0 on an early return #14479's surface — merged (9acddde94), no hazard; no in-flight PR of this seat touchesconcept.mdx. Changeset:scripts/**+content/docs/**only ⇒ no changeset,skip-changesetlabel.
Generated by Claude Code
- Branch:
- added a commit that references this issue
on Sep 2, 2026 os-dev-report
{ "issue": 13880, "status": "done", "branch": "claude/issue-13880-section-name-population", "pr": "https://github.com/objectstack-ai/objectstack/pull/14558", "premise_still_valid": true, "summary": "Answered the triage's prior question first: the customizations: overlay-diff list concept.mdx's Layer 2 example taught is not a declared shape (only customizations key in packages/spec is tenant.zod.ts's free-form z.record; FormViewSchema is .strict(); the three-layer merge engine it narrates is the paper metadata-customization protocol retired in @objectstack/spec 17, #13135/ADR-0049, tombstoned in MetadataPluginConfig.customizationPolicies/mergeStrategy, ADR-0126 section 6 wall 3: upgrades never merge customizations). Per the ruling, rewrote the fence into a Callout (same register as the steps: ghost layout-dsl.mdx already removed) naming the real mechanism (a per-org overlay write on the view metadata type, allowOrgOverride: true, ADR-0005) rather than adding an anchor to a fictional example. Added the two selectors the population question needed: (3) a singular YAML section: mapping at any nesting (document root or sequence-item value), widening YAML_SECTIONS_KEY from sections\\s*: to sections?\\s*:; (4) a sections: [...] array inside json/jsonc/json5 fences, bracket-matched with the same comment-masked matcher the TS arm uses (tolerates the // <- comments and JSON5 trailing commas concept.mdx's own merged-layout fence carries). Widened gate on the unmodified corpus measured 4 findings (matching the card's 4-not-3): concept.mdx :307 (Server Response json, a 5th site the issue itself hadn't named), :426 (the Layer 2 singular section:), :443/:451 (Final Merged Layout json, two sections). Fixed all four in this PR: :307 and the Final Merged Layout section got name: contact_information; the Billing-Info section (an artifact of the removed fictional Layer 2) was dropped from the merged output rather than named; the Layer 2 fence became the Callout. Widened gate is now green over the full 404-file corpus (22 TS literals, 22 YAML mappings including layout-dsl.mdx's 3 already-named singular sites from #13759, 2 JSON literals). ui/forms.mdx:183's elided sections placeholder is judged as zero entries, not skipped and not fabricated as a nameless section. ui/doc-pages.mdx:257 prose confirmed outside any fence, does not enter the population. No schema change: FormSectionSchema.name stays .optional(). No other content/docs/** page turned red under the widened corpus sweep.", "tests": "node scripts/check-docs-section-name.mjs --self-test -> 85 cases pass (real temp trees on disk; both new selectors driven RED and GREEN at both singular-section cardinalities, the JSON elided-placeholder and comment/trailing-comma tolerance, every new floor/anchor refusal exercised) -- re-run clean at final merge HEAD 38c73232d. node scripts/check-docs-section-name.mjs -> before-fix widened run on unmodified concept.mdx: 4 findings (:307,:426,:443,:451); after-fix: 0 nameless form-section examples, 404 docs files, 1180 TS-family fences / 22 literals, 13 YAML fences / 22 mappings, 148 json-family fences / 3 sections arrays / 2 literals -- clean at final HEAD too. pnpm --filter @objectstack/spec run check:yaml-examples -> concept.mdx: 0 tagged / 9 untagged (down from 0/10, one fewer untagged fence). Full derived gate list (node scripts/pm/dispatch-gates.mjs --commands, 39 commands) run at 45312b3fb -- all 39 green; three needed a one-time dependency build first (@objectstack/spec, @objectstack/formula, @objectstack/lint, @objectstack/client-react) since check:doc-formula-expressions / check:doc-security-posture / check:skill-examples each reported PREREQUISITE NOT MET (exit 3, not a finding) before the build. check:pm-dispatch-gates run detached (node scripts/pm/check-dispatch-gates.mjs) under heavy shared-verify-lock contention from sibling dispatch PRs (repeated queue-timeout exit 99 before it finally acquired) -- command-exit 0, dispatch-gates self-test: 1240 cases pass. Re-derived the same 39-command list at final merge HEAD 38c73232d (git log confirms no incoming commit touches scripts/check-docs-section-name.mjs or content/docs/protocol/objectui/**) and re-ran check-docs-section-name.mjs + its self-test there -- still green; the other 38 were not re-run post that second merge since nothing they read moved. A pnpm-lint-narrowed ESLint pass over just the two touched files was attempted 3 times and never completed -- each attempt queued behind other agents' heavy jobs and hit the 540s acquisition budget (queue-timeout, exit 99, NOT MEASURED, never ran); not one of the 39 derived commands, and CI's required Lint & Repo Gates job runs full pnpm lint regardless.", "mcp_calls": 0, "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
ACCEPT — PR #14558 merged to
mainas2a2653619(out of the merge queue 14:18:54Z;added_to_merge_queue13:54:14Z). Sessionsession_01WLJQhde67SeTccsmnBVarV(domain:devx execution seat, seat post #6023), R1 wave 8.Close-out probes on
origin/main2a2653619(verify worktree; the merge commit is the probed head):scripts/check-docs-section-name.mjs:JSON_FENCE_LANGS(:253,json/jsonc/json5) routed through the sharedsweepBracketMatchedFence(file, block, kind, …)(:770, called forjsonat:855and fortsat:860— one bracket-matcher, two arms); the singular-section:YAML selectorYAML_SECTIONS_KEY = /(^|[^A-Za-z0-9_$.])sections?\s*:/m(:753, gate at:833); census floorsFLOOR_YAML_FENCES(:316) …FLOOR_JSON_SECTION_LITERALS(:342) andJSON_CENSUS_ANCHORS(:326, anchored onconcept.mdx) present, enforced at:939+.content/docs/protocol/objectui/concept.mdx:contact_informationnamed at:117(YAML),:308(Server Response JSON) and:461(merged layout JSON); the Layer-2 box row reads "Org overlay: a full FormView write" (:393) and the formercustomizations:YAML fence is the<Callout type="warn">at:419.- Merge stat: 2 files,
+469 −94(concept.mdx53 lines, the script 510) — the YAML and JSON halves ofconcept.mdxfixed together, never the YAML half alone.skip-changeset,size-l.
Against triage 5486760083: population widened by SHAPE (two more selectors, each with self-test fixtures and a re-measured census); ⛔
packages/spec/**untouched (FormSectionSchema.namestays.optional()); ⛔ no newos:check-yamlmarker as the fix. All held. Zero rework.pm:dispatchedremoved with this comment; the card closes via the PR'sFixes #13880.
Generated by Claude Code
Found while implementing #13759 (the three singular
section:sites inlayout-dsl.mdx).Filed separately, not folded in: the triage ruling on #13759 fenced the population question
out of that PR, and this finding is exactly that question wearing a concrete example.
The measurement
Re-running the #13759 census with the same
yamlparser and the sameclassifyYamlFencethe #11887 arm uses, on
8c6a7fc0b, over all ofcontent/docs/**, with no marker filter:The population is 4, not the 3 the #13759 card recorded. #13759 fixed its three; the
concept.mdxone is untouched and still live.Why the card counted 3 — the census was scoped by MARKER, not by shape
Not drift, and not a fourth that appeared since:
- section:is present atconcept.mdx:425in
af01080e3itself, the commit the card measured on. Two control runs separate thehypotheses:
YAML_SECTIONS_KEYpre-filter(
/(^|[^A-Za-z0-9_$.])sections\s*:/m) yields 0, not 3 — so the card did not use it;grepfor the marker yields exactly the card's 3:os:check-yaml FormSectionSchema key=sectionappears 3 times incontent/docs/**, all inlayout-dsl.mdx.So the card's population was "fences carrying the singular
key=sectionmarker", and it wasreported as "the singular population across all of
content/docs/**".concept.mdxcarriesno
os:check-yamlmarkers at all (check:yaml-examplesreports it as0 tagged / 10 untagged), so it is invisible to that scoping.Why it is not a copy of the #13759 edit
The
concept.mdxsite is a different enclosing shape and needs a decision #13759 did not take:example. A
customizations:sequence of{ field | section }overlay entries isdeclared nowhere in
packages/spec— the onlycustomizationsin the authorable surfaceis
tenant.zod.ts'sz.record(z.string(), z.unknown()), a free-form record. Whether thisfence teaches a real shape at all is the prior question; giving it a
namepolishes anexample that may want removing or rewriting instead. Compare the
steps:callout alreadyon
layout-dsl.mdx, which removed a phantom rather than repairing it.directly below (
concept.mdx:440) is a ```json fence carrying two more namelesssections (
"label": "Contact Information", `"label": "Billing Info"`) inside a real`"sections": [ ... ]` array. `json` is in neither `TS_FENCE_LANGS` nor `YAML_FENCE_LANGS`,
so both arms of `check-docs-section-name` pass over it. Fixing the YAML half alone would
teach an anchor that vanishes from the merged output shown two paragraphs later.
Why the population question is the real subject
check-docs-section-namejudgessections:sequences in both arms. This finding adds twomore shapes that carry form sections and that neither arm reaches — a singular
section:mapping, and a
sections:array in ajsonfence — which is the same drift #10830 and #11887each closed one selector at a time. Deciding the gate's population means deciding which keys
and which fence languages introduce a form section, together with how the
os:check-yamlmarker vocabulary is read. That is a triage call, not a dev call, and it is the one #13759
deliberately deferred.
Sites, for whoever picks this up:
content/docs/protocol/objectui/concept.mdx:426- section:undercustomizations:,label: Billing Infocontent/docs/protocol/objectui/concept.mdx:444"label": "Contact Information"content/docs/protocol/objectui/concept.mdx:452"label": "Billing Info"⛔ Not a schema change either way:
FormSectionSchema.namestays.optional()(#10709,reaffirmed #10830).
Back-links: #13759, #11887, #10830, #10709