Skip to content

docs(ui): re-take the react-block-needs-record-context transcript from os validate; the close-out census reads 0 author-time ids over 200 - #24313

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-22161-close-out
Oct 18, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-22161-close-out

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #22161
Clause-②: no

The close-out slice of the card. It does two things. It takes the census the close condition asks for, as a reading on main. It also re-takes the one stale docs transcript that slice 15's landing (6136999237) carried to this slice. The census reads 0 author-time packages/lint ids firing a hint or fix: over 200 characters, so this PR closes the card. The domain:cli half is a separate card: #22841 remains open, and nothing here touches it.

Claim: 6248840553. It is the newest Claim: on the card and it names this branch. I checked that before any edit.

Cross-lane declaration: content/docs/ui/react-pages.mdx belongs to domain:devx by the domain table. This one transcript block is carried here by triage 6109231286 and slice 15's landing 6136999237. Nothing else in content/docs/** is touched.

The close condition, read on main

The condition (triage 6219576699): "no author-time packages/lint id fires a hint or fix: over 200 characters, item 3's slice has landed, and the close-out slice's carries are done." Item 3's slices 11–21 have landed; slice 21 landed as 9c74d4098d. The carries are the transcript below and this census.

All readings are on main at 21070a2f0 (this branch's base), in objectstack-ai/objectstack. main then moved to 30da04f8e, and the branch merges it. None of those 3 commits touches packages/lint, packages/cli, packages/formula, packages/sdui-parser or packages/spec/src: git diff --quiet 21070a2f0 HEAD over those paths exits 0. So the reading also holds at this PR's head.

Instrument 1: a fire census over the whole lint suite. It is a copy of slice 21's preload. Array.prototype push / unshift / map / filter / forEach / find / findIndex / some / every / flatMap / concat / slice hooks record every finding-shaped object the suite handles: a string rule and message, plus hint, fix, where, path and severity. My copy drops slice 21's "must carry a hint" filter, so it also counts ids that fire without one. It runs as scratch tooling and is never committed.

  • Run: packages/lint, 144 files / 6857 tests passed, VERDICT 0 (verify lock, slot issue-22161-co). That gives 4379 distinct finding rows.
  • 240 ids fire. 239 carry a hint or fix: string. One of those is expression-invalid's empty hint, which is by design: the CLI prints no fix: line for it. relationship/missing-reference carries none.
  • Over 200: 3 ids, all outside the condition. They are the repo-gate ids in lint-startup-registry-verdict.ts: startup-open-vocabulary-verdict 972, startup-verdict-assertive-wording 972 and startup-source-unparseable 254.
  • Author-time ids over 200: 0. 237 author-time ids fire (8 of them are the spec's functional-completeness.ts ids, which the lint suite runs). The longest hint is 200, from approval-approvers-may-resolve-empty (GROUP_ONLY_FIX). Next come 199 (sharing-rule-unlowerable-condition, semantic-role-field-unprovisioned), 198 (flow-bare-dollar-reference, filter-preset-comparand) and 197 (rls-predicate-over-budget). No hint has a line break.
  • Controls. Two known ids must be seen, and both are: react-block-needs-record-context (5 distinct hints, longest 195) and the card's own field-no-consumers (16 distinct, longest 175). The instrument also records over-200 text when it fires: the 3 repo-gate ids are recorded at 972 / 972 / 254. Slice 21's preload, unmodified, reads the same suite as 4376 rows / 239 ids with the same 3 over 200. My copy adds exactly the 3 hint-less relationship/missing-reference rows.

Instrument 2: a static floor over the source. It is a TypeScript AST walk of every hint: / fix: property in packages/lint/src's 97 non-test files. For each site it counts the characters the source fixes, whatever the fixture: string literals, template heads and spans, + chains, and same-file string constants. Calls and parameters count 0, so each reading is a floor.

  • 281 sites. Only 2 have fixed text over 200: lint-startup-registry-verdict.ts:743 and :769, the two 972-character repo-gate hints.
  • The two instruments agree where they can be compared. GROUP_ONLY_FIX reads 200 in both.

Census-invisible ids (exported or named, never fired by the suite). I enumerated the ids statically: the values at every rule: position (literals, and identifiers resolved to string constants) together with every exported id-shaped string constant. That gives 249 ids, of which 233 fire. The 7 jsx-* ids also fire, through the one template-literal id site (validate-jsx-pages.ts:66). The 16 that do not fire:

  • 9 are packages/cli's, not packages/lint's. packages/lint holds only their RULE_EXPLANATIONS entries; the ids are emitted in packages/cli (utils/collect-docs.ts, lint/hook-body-lowering.ts, utils/picklist-references.ts). They are docs/duplicate-name, docs/frontmatter-tags, docs/nav-target, docs/uncollected-directory, hook-body/bundled-fallback, hook-body/extraction-failed, hook-body/not-lowerable, hook-body/unparseable and picklist-reference-unverified. They are the domain:cli half.
  • 1 is emitted by packages/spec: view/row-color-unresolvable-value (functional-completeness.ts). Its fix: is 59 fixed characters plus the field name.
  • 1 is not an id: condition. It is an alias-map value quoted in a comment in validate-expressions.ts.
  • 5 are packages/lint ids the suite never fires, read from source:
    • authoring-rule-threw (runtime-gate.ts): a fully static hint of 131 characters.
    • relationship/association-inline-edit: a static fix: of 54.
    • rollup/missing-summary: a fix: of 27 fixed characters plus the child object and field names.
    • chart-config-missing: no emit site. The id is kept so suppressWarnings entries keep parsing.
    • react-prop-deprecated: the hint is the react-blocks contract's own deprecation note. On main the contract (REACT_BLOCKS, 4 blocks) declares 0 deprecated interactions, so the id cannot fire. Its sibling's notes (REACT_RETIRED_OVERLAY_PROPS, 2 entries) are at most 129.

At the public door. os validate on examples/app-showcase, unmodified, built CLI at 21070a2f0: exit 0, Running author-time rules (49), 64 warnings, 64 fix: lines from 5 rule ids. The longest are 200 (approval-approvers-may-resolve-empty) and 199 (field-no-consumers).

The transcript

content/docs/ui/react-pages.mdx, in the record:*-blocks section, holds the bare fence at :360–:365. Three of its four lines no longer matched what the rule prints:

  • the verdict line: the one-sentence message ("…which reads its record from a record page's context; a kind:'react' page mounts none, so the block renders empty") replaces the old two-clause one;
  • the fix: line: it now opens with Instead: and no longer says "On a react page bind the record yourself:" (slice 15's one-line shape);
  • the rule: line: the path is pages[28].source (it was pages[27]), and the line now carries the pointer "os explain react-block-needs-record-context for why a record block renders empty on a react page".

How it was taken: from a real run, not by hand. I built the showcase's dependency closure (turbo run build --filter=@objectstack/example-showcase^..., 63 tasks, VERDICT 0). Then I planted RecordHighlights on the showcase renewals page, the page this transcript has always been taken from. The plant swapped the view-mode ObjectForm for RecordHighlights objectName="showcase_account" recordId={sel}, through scripts/ablation-replace.mjs in wrap mode. That mode checks that the anchor hits exactly once and that the blob changed, and it restores by absolute path. Then I ran node ../../packages/cli/bin/run.js validate from examples/app-showcase. The run exited 1 with Author-time rules failed (1 issue). The four lines from ✗ through rule: were copied byte for byte out of that log into the fence, by a script that asserts each line's prefix. The page restore is proven: blob fd28f319b1 equals HEAD's, git diff HEAD is empty and the status is clean.

My first attempt was a no-op. Its replacement contained the anchor text, so ablation-replace refused (anchor count 1 → 1), the command never ran, and the page was restored. The second attempt used the anchor above.

The fence, its language-less info string and the surrounding prose are unchanged. pnpm check:docs-transcript-drift is not this block's judge. Its header pins only the registry-derived author-time rule count, in blocks declared transcript=KIND. This block is a bare fence, and its Author-time rules failed (1 issue) is a different sentence the gate deliberately does not match. --list shows 4 declared values across 417 pages, all ok (49 = 49), and none is this block. The edited page compiles through @mdx-js/mdx.

Verification

Final head 609c99c07 (this branch's commit eb0e3b839 plus a clean merge of origin/main 30da04f8e). Exit codes were captured before any pipe.

  • Derived gates. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths, at 609c99c07: 40 families over 1 path since merge base 30da04f8e. That is identical to the PM's derivation. All 40 were run one by one and all exit 0.
    • check:skill-examples first exited 3 (PREREQUISITE NOT MET: packages/client-react was unbuilt), so it measured nothing. I built that package directly and re-ran the gate: 262 marked examples type-check, exit 0.
    • --ran: "40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN", exit 0.
    • For every family CI runs, this PR's own check-runs are the reading.
  • Not owed locally: check:dev-prereqs and check:skill-frame-freshness, since the diff touches neither a packages/spec build input nor the four-axis frame files. Nor is any package test or typecheck, since the diff touches no package.
  • Control characters: grep -naP over the changed file and this body finds nothing (exit 1).

Acceptance notes

  • The next transcript on the same page is off by one page index. The react-prop-missing-required block at :402–:407 says at pages[27].source. The same planted-run method (ObjectChart's objectName removed on the renewals page) prints pages[28].source. Its verdict, fix: and rule: lines are otherwise byte-identical to the page. The block is outside this claim's file surface, which names the record-context block only, so it is left as written. A one-token docs edit takes it. Not filed: it is index drift in an elided example, and no defect class applies.
  • The 200-character bound is measured over fixtures and the showcase, as in slices 11–21. Some fix lines interpolate author names. The card's own field-no-consumers prints 199 on the showcase, against 175 in the suite, because its line quotes the first carrier path. A longer object or field name pushes it past 200. The static floor names 10 author-time sites whose fixed text is 150–200 and which interpolate. The highest is field-group-shadowed at 192.
  • os explain was not run. This slice changes no explanation.

Generated by Claude Code

…m os validate

The react-pages transcript of the record-context refusal predated the
one-line message and fix shape: its verdict line, its fix line and its
rule line (no os explain pointer, pages[27]) were no longer what the CLI
prints. The four lines are now the real output of os validate on the
showcase with <RecordHighlights> planted on the renewals page, taken on
main at 21070a2; the fence and the surrounding prose are unchanged.

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

Copy link
Copy Markdown
Contributor Author

席位核对 (seat check) · PR #24313 · #22161 close-out · domain:spec seat 2 · zhuangjianguo · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-18T11:17Z

ACCEPT at head 609c99c079993f2b0fba0c7a5815e65a2ec73438 (claim 6248840553, report on #22161). It lands once every check on this head is green. No contract review is owed: the diff is one content/docs/** prose file (a face outside the contract review), Clause-②: no, and it is not governed.

item reading
Shape Draft, base main. The body's line 1 is Fixes #22161, line 2 is Clause-②: no; no other closing keyword. skip-changeset is on the PR: content/docs/** ships in no package. 1 file, +3/-3.
The close condition (triage 6219576699) The census on main (21070a2f0, report): 240 ids fire. 3 are over 200, all repo-gate ids in lint-startup-registry-verdict.ts, which are outside the condition. 0 author-time ids over 200. The controls are seen (react-block-needs-record-context 195, field-no-consumers 175). A second instrument, a static floor over 281 hint sites, agrees. Item 3's slices have all landed (slice 21 → 9c74d4098d). The domain:cli half, #22841, is closed. So Fixes is right.
The transcript, checked line by line against origin/main The verdict line matches validate-react-page-props.ts:1083–:1084 ("which reads its record from a record page's context; a kind:'react' page mounts none, so the block renders empty"). The fix: line matches :1085 (Instead: ${REACT_RECORD_BLOCK_ALTERNATIVES[...]}). The rule: line carries the os explain pointer slices 11–21 added. The block was taken from a real os validate run on a planted page, with the restore proven by blob hash.
Cross-lane content/docs/ui/react-pages.mdx is domain:devx's. The declaration is in the PR body, and the seat posts the seat-post note to #6023 in this act.
Out of scope Both Acceptance notes. The neighbouring react-prop-missing-required transcript (:402–:407) prints pages[27] where main now prints pages[28]; the misleading test says that does not mislead, since it is one stale index in an elided example. The 200-character bound is measured over fixtures and the showcase, and long names can pass it.
Landing After every check on this head is green: pr_ready then automerge_enable. The merge closes #22161.

Generated by Claude Code

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

Labels

documentation Improvements or additions to documentation size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants