Skip to content

docs(ui,protocol,lint): a form SECTION visibleWhen binds current_user — retire the claim from the three prose sites #13074 left unswept - #13532

Merged
os-project-manager merged 2 commits into
mainfrom
claude/issue-13077-current-user-section-prose
Aug 30, 2026
Merged

docs(ui,protocol,lint): a form SECTION visibleWhen binds current_user — retire the claim from the three prose sites #13074 left unswept#13532
os-project-manager merged 2 commits into
mainfrom
claude/issue-13077-current-user-section-prose

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #13077

A form-view section visibleWhen binds current_user today. That was re-measured and landed for the schema text and the field-rule lint message in PR #13074, but three hand-written sites still taught the retired claim. Text only — no schema, no verdict, no runtime behaviour moves.

H1 first: the claim was verified before any prose was trimmed

The card is an explicit relay and marks itself unverified, so nothing here was trimmed on its word. Verified at source in objectui, not from #13074's prose:

  • apps/console/src/components/FormPage.tsx:1855 calls isSectionVisible(sec, values, loaded.record, predicateScope), and isSectionVisible forwards that scope to evalFieldPredicate (objectui#6110). It used to pass undefined.
  • packages/plugin-form/src/ObjectForm.tsx:1271 copies an authored section visibleWhen onto the section-divider pseudo-field the renderer evaluates with the scope bound (objectui#6111); SplitForm / ModalForm / DrawerForm carry the same line.
  • packages/components/src/renderers/form/__tests__/predicate-scope-parity-6010.test.tsx pins the section surface at parity with the field surface.

⇒ the retired claim is still present at all three sites and still wrong. H1 confirmed, not falsified.

H3: measured and falsified — #13074 did not take these

#13074's "four stale text sites" are FormSectionSchema.visibleWhen, SelectOptionSchema.visibleWhen, SELECT_OPTION_EDITABILITY_GUIDANCE, and the field-rule message in packages/lint/src/validate-expressions.ts. Its only content/docs changes are the generated references/ui/view.mdx and references/data/field.mdx. None of this card's three files were in it — and its section-3 target is packages/lint/scripts/check-doc-formula-expressions.mjs, a different file from the src/ one #13074 corrected.

H2: the gate epilogue is the load-bearing half — confirmed, and the reason is on the record

The gate's own JSDoc had already been re-measured and says so explicitly: "(#12914 tracks the message text that describes the mechanism)". The mechanism text was the deferred item, and it is the one an author reads at refusal time. The two .mdx edits are the wider blast radius; the epilogue is the half that teaches the wrong rule at the moment someone is already stuck.

The three files

  • content/docs/ui/views.mdx listed "section-level predicates (objectui#6111)" as a surface that still evaluates the predicate unbound — naming as evidence the very PR that bound it.
  • content/docs/protocol/objectui/layout-dsl.mdx carried the claim at four sites, where the card recorded three: a code comment inside an os:check block, the binding-root table row, the paragraph under it, and the "two limits" prose. All four re-measured together.
  • packages/lint/scripts/check-doc-formula-expressions.mjs still said a faulting field-level visibleWhen is simply fail-OPEN. Under a scope-publishing host it RESOLVES instead: hidden in that one form while no server-side gate evaluates a field-level visibleWhen at all, so every other reader still returns the value — a silent enforcement gap, the worse of the two. The fault-open leg is kept, not replaced — it is still what happens where no host publishes a scope. The verdict is untouched.

Both replacement texts carry the two qualifications the correction needs, so "sections bind current_user" cannot be misread as an authorization primitive: the binding is client-side only, and the scope belongs to the host, so it is empty on the public /f/:slug route.

Two in-place fixes named rather than left silent

Both are the same defect class in the same declared files, with the correct form pinned by #13074's landed text:

  1. The same views.mdx sentence also listed /forms/:name as unbound. That route renders inside InternalFormRoute, which publishes the session principal and binds normally — only the public /f/:slug is mounted outside any provider. The same stale half appeared in layout-dsl.mdx's caveat paragraph. Both corrected.
  2. layout-dsl.mdx's "two limits" prose said an object-level field rule does not bind the scope. Reworded to say its write-path evaluator binds record / previous / parent — true, and it keeps the lint refusal's grounding intact without straying into Three more consumers of the "no current_user at section level" claim go stale the moment #12914 lands — one of them is a live runtime detector, not prose #13072's section 1, which is domain:engine and untouched here.

The epilogue is now pinned, and the pin is proven able to fail

The epilogue was a plain string nobody read: deleting the re-measured clause broke no assertion and turned no gate red — exactly how the stale claim outlived its sibling. A --self-test case now asserts both outcomes plus the surviving fault-open leg. It scopes itself to the real epilogue via lastIndexOf, so it cannot satisfy itself from its own literal, and it pins the extension-less sectionFields spelling that #5017's receiver scan requires of a string.

Ablation (implementation committed first; mutation confirmed on disk by grep counts, not by an exit code):

pre-mutation  'renderer RESOLVES it': 1
post-mutation 'renderer RESOLVES it': 0   'renderer re-evaluates it': 1   -> MUTATION CONFIRMED ON DISK
self-test on mutated tree: EXIT=1
  X REPORT - the field-rule epilogue names BOTH outcomes, not just the fault-open one
  X check:doc-formula-expressions self-test: 1 case(s) failed
restore: git checkout HEAD -- ABSOLUTE_PATH; git diff HEAD empty; marker count back to 1

No build/dist is involved — the gate runs from source — so no rebuild leg applies.

Gates — union re-run at 8ae8385bf, verdict lines quoted

check:doc-formula-expressions self-test: 58 cases passed   (was 57; +1 new pin)
check:doc-formula-expressions: 22 record-scoped formula example(s) across 426 files / 1451 TS blocks judged clean
check:doc-formula-expressions (field-level `*When`, #11407): 14 predicate(s) judged clean; 6 skipped as undeterminable
check:skill-examples: 260 prose examples type-check across 3 surface(s) - every marked block parsed
check:role-word: Scanned 225 .md/.mdx file(s); Ledger 43 baselined file(s) - unchanged, nothing re-baselined

Also green: check:doc-authoring, check:doc-anchors, check:docs-single-h1, check:doc-security-posture, check:docs (spec), check:yaml-examples, check:docs-audit-scope, check:docs-redirects, check:published-files, check:published-readme-links, check:react-page-adapter-contract, check:slot-lookup, check:page-declaration-shape, check:keyed-text-bounds, check:cross-package-test-inputs, check:test-source-alias, check:type-source-resolution, check:undeclared-dep-imports, check:changeset-gate-self-tests, check:objectui-changeset, check:pm-half-states, check-doc-frontmatter, check-docs-section-name, check-doc-route-spelling, check-comment-mask-adoption, check-section-landing-index, check-plugin-teardown-shape, check-ci-filter-parity, check-empty-changeset, check-changeset-no-major, check-adr-0087-registration, release-rehearsal-clone --self-test.

Both convention-triggered obligations for editing a gate script ran green: bare-root-worklist.mjs --self-test (51 live rows, none stale/missing/contradicted) and check:pm-dispatch-gates (976 cases).

NOT MEASURED, neither red nor green: check-test-completeness.mjs and scripts/pm/check-half-states.mjs both exit 3 — this container has no real GITHUB_TOKEN, so nothing was swept.

check:role-word went red on the first pass and the fix is mine, not a baseline change: my replacement prose used the ADR-0090 D3 reserved word. Reworded to current_user.positions, which is what these predicates actually test. The shrink-only baseline is untouched.

Note for review: pnpm lint (repo-wide ESLint) was not run locally. The diff is two .mdx files, one .mjs gate script and one changeset; CI runs the farm regardless.


Generated by Claude Code

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • 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.

Coarse fallback — 0 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 57827b617e1f6f38a684b5b1daf56c8a7455cb81packageMentionDocs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Aug 30, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 30, 2026 17:19
@os-project-manager
os-project-manager added this pull request to the merge queue Aug 30, 2026
Merged via the queue into main with commit b2dea86 Aug 30, 2026
35 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13077-current-user-section-prose branch August 30, 2026 17:41
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/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Two docs pages and one lint gate epilogue still teach the retired "no current_user at section level" claim (prose half, split from #13072)

2 participants