Repository navigation
/forms/:name publishes current_user but not features, so a features.* predicate still resolves differently there than inside an app #6262
Description
Activity
Triage:
pm:blocked+domain:ui+bug.Blocked-by: #6110
Rationale: real asymmetry with a fail-open consequence — a
features.*predicate faults on/forms/:nameandvisibleWhendefaults visible: one authored text, two verdicts, the same class as #6110 itself one scope root over. Same route component as in-flight PR #6261 ⇒ blocked behind #6110; on its close re-verify on the merged ref (the gap is recorded inFormPage.tsx's own comment there).Not P0: unmeasured whether any shipped form-view metadata authors
features.*— measuring that is the claim's first step. Fork clause: if nothing does and the honest fix becomes "form views may not namefeaturesat all", that is a contract question — stop and send back to triage instead of wiring. Otherwise this stays a wiring fix: fillfeaturesfromgetAuthConfig()followingAppContent's own pattern —ExpressionProvideralready documents{}as the deliberate pre-load state, so matching in-app semantics (not inventing stricter pre-load behaviour) keeps parity the goal.
Generated by Claude Code
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Aug 25, 2026 - addedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchand removed
on Aug 25, 2026 os-support-ai commented
on Aug 25, 2026 CollaboratorMore actionsUnlock scan + the card's own open measurement, now taken —
pm:blocked→pm:queue+pm:retriagedomain:ui@ objectui execution seat, PM sessionsession_011SfZeFWrhGLHmfq61xbz4q. Labels moved in one stroke;pm:retriageis attached alongside, ⛔ nothing removed but the dischargedpm:blocked.1. The block is discharged — and it was never going to discharge itself
Blocked-by: #6110(recorded in a comment on this card, not the body). #6110 closed 2026-08-25T06:35:50Z — 7½ hours before this reading — and nothing returned this card to the queue. It satpm:blockedon a closed upstream, which is the state that makes a card permanently invisible to the Bug-first order.⚠️ Worth recording for the lane: three of the fourpm:blockedBugs indomain:uicarry noBlocked-by:line in the body. This repo's convention puts them in comments — a body-only grep reports "no blocker" for cards that plainly have one, and I nearly filed that as a finding before checking the comments. Any unlock sweep here must read comments as well as bodies.2. ⛔ Do NOT dispatch this as a wiring fix — the card's own unmeasured question is now measured
The body's "Not yet measured" section is the load-bearing one:
Whether any shipped form-view metadata actually authors a
features.*predicate. If nothing does, this is a latent asymmetry rather than a live break, and the honest fix may be to decide that form views may not namefeaturesat all — which is a contract question, not a wiring one.Measured on
origin/main@c38162d7c, acrossapps/examples/content/over.json/.yml/.yaml/.mdx:probe reading control — do authored visibleWhenpredicates exist in this population at all?18 occurrences. The search finds authored predicates ✅ target — any authored predicate naming features.*?3 raw hits, and all three are false positives ❌ control 2 — is features.findable at all with this pattern?yes, many hits under packages/✅The three target hits, individually:
content/docs/utilities/runner.mdx:12— the English word "features" in a sentence.content/docs/utilities/vscode-extension.mdx:8— same, English prose.examples/schema-catalog/.../code-preview.json:14—data.features.map(...)inside a JavaScript source string being displayed by a code-preview widget. Not a predicate; not even schema.
So: zero authored
features.*predicates exist in this repo. The asymmetry is latent, not a live break — exactly the branch the card said would change its shape.3. Why
pm:retriagerather than a dispatchDispatching the wiring fix would mean building an
/auth/configfetch on a route that makes none, plus deciding what a predicate sees before that fetch resolves — the card notesExpressionProviderdocuments{}as the deliberate pre-load state, so a naive fetch introduces a visible-then-hidden flash on every load of this route. That is real machinery, and the measurement above says it would serve zero current consumers.The card's own preferred alternative — form views may not name
featuresat all — narrows a public contract's accept set, which is the maintainer floor, ⛔ not a seat call and ⛔ not mine to grade.⛔ I am not re-grading this card.
pm:queueis restored because the block is genuinely discharged;pm:retriageis attached because the measurement that the card itself said would decide its class has now come in and points away fromBug/wiring. Triage's call, with the evidence above as input. Thepm:queue+pm:retriagepair is the designed combination here: visible to the right queue, ⛔ skipped by dispatch while the dissent is open.
Generated by Claude Code
Maintainer ruling recorded — Option B: declared narrowing; the spec half is filed and this card waits on it
Provenance: maintainer, 2026-08-27, PM chat decision-inbox batch 2 (adjudication session
session_01DKWDdUJ2XNRESVVWUvcpnh), verbatim: 「同意」 — accepting the triage recommendation B (2026-08-25T14:59Z facet block); fallback C not needed.Ruled: form-view predicates may NOT name
features.*— the exclusion becomes part of the declared predicate vocabulary for form views, rejected loudly at authoring time, so the latent two-routes-two-verdicts trap dies at the author's desk instead of in front of a user. The measured basis stands: zero authoredfeatures.*predicates repo-wide (18-hit positive control), so nothing breaks today. ⛔ Option A (parity wiring for zero consumers) is declined.Execution: the narrowing lands in
packages/spec— filed as objectstack-ai/objectstack#12665 (fix-at-destination; the spec lane owns that surface; Clause-②: yes since it narrows a published accept set, and the maintainer ruling here is the authority that floor requires). This card records the objectui-side asymmetry and closes when the spec narrowing lands and the exclusion is re-verified on this repo's surfaces.State:
needs-user-decision→pm:blocked,Blocked-by: objectstack-ai/objectstack#12665.
Generated by Claude Code
Unblocked →
pm:queue(domain:spec seat, sessionsession_01JvjTCjJQn9zSTXEhUKgT7s). The blocking card objectstack#12665 is CLOSED: the ruled Option-B narrowing merged in objectstack#12849 — form-view predicates naming thefeatures.root are now refused loudly at parse (section/field/nested/per-option,sections+ legacygroups,visibleOnaliases, all form types includingsplit), with app-context surfaces pinned unchanged.Premise updates for whoever picks this up:
- The day-of zero-consumer reading was re-verified at dispatch time (objectui
origin/main@38a123cac, 2026-08-28): 18-hit positive control on authoredvisibleWhen, zero authoredfeatures.*form-view predicates — nothing on this side is broken by the narrowing. - What closes this card is the objectui-side re-verification, and it needs the spec bump: the refusal reaches objectui through the next released
@objectstack/specthat carries objectstack#12849 (same unlock family as objectui#6620). Once the dependency is bumped, verify a form-viewfeatures.*predicate is refused at the authoring/publish door on this side's surfaces, confirm theFormPage.tsxgap comment from PR fix(console,plugin-form): bind the host predicate scope on the two unbound authored-predicate evaluators #6261 can now point at the contract refusal instead of an open asymmetry, and close. - The wiring alternative (fetching
/auth/configon/forms/:name) stays declined per the ruling — do not revive it here.
Generated by Claude Code
- The day-of zero-consumer reading was re-verified at dispatch time (objectui
pm:queue→pm:on-hold. Caught while selecting this card for dispatch; it is not dispatchable yet, and the queue label was saying it is.Why the state was wrong. The 2026-08-28T04:56Z unblock comment is correct that objectstack#12665 is closed and the ruled Option-B narrowing merged in objectstack#12849. But it also states what actually closes this card: "the refusal reaches objectui through the next released
@objectstack/specthat carries objectstack#12849", and "Once the dependency is bumped, verify…". The work here is a re-verification of a refusal that is not installable on this side yet — there is nothing a dev can measure today.This lane's rule for cross-repo unlocks is explicit that "upstream merged" is not the criterion:
跨仓解锁的判据是「消费方可安装」,不是「上游已合并」…… 未发版 ⇒ 转
pm:on-hold+Restart-when:加消费方安装面判据,⛔ 不回pm:queue—— 回队烧掉的派发注定以 premise-false 收场。A dispatch from
pm:queuewould have burned a full dev cycle to arrive at "the dependency isn't bumped, nothing to verify". That is the premise-false ending the rule exists to prevent, and it is the second time today this lane has been saved by reading a thread to its last comment rather than trusting the label.Restart-when:
@objectstack/specas resolved by this repo's lockfile refuses a form-view predicate naming thefeatures.root at the authoring/publish door — i.e. the installed package rejects it, not merely that objectstack#12849 is merged. The probe is an install-surface one: against the installed@objectstack/spec, author a form-viewvisibleWhennamingfeatures.*and confirm it is refused; a positive control in the same shape (an authored predicate that must still pass) proves the probe is live rather than blind.The version bump itself is a human/release action, so this hold has a real firing condition rather than an open-ended wait.
Everything measured stays measured — the restart needs no new analysis. Zero authored
features.*form-view predicates repo-wide, re-verified atorigin/main@38a123cacon 2026-08-28 with an 18-hit positive control on authoredvisibleWhen. Nothing on this side breaks when the narrowing arrives.Unchanged on restart: Option A (parity wiring for zero consumers) stays declined per the maintainer's 2026-08-27 ruling — ⛔ do not revive it. The remaining work when this fires is the three-step verification the 04:56Z comment already spelled out, including pointing
FormPage.tsx's PR #6261 gap comment at the contract refusal instead of an open asymmetry.No re-grading and no
domain:*change: this is a pm-state correction on adomain:uicard by the seat that owns that lane, not a dissent with triage.
Generated by Claude Code
4 remaining items
- added and removed
on Sep 24, 2026 objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsClaim: PM loop round 1 —
domain:uiexecution seat 4
Session:session_01BP8CMtACxTdLjqR6rhd33C
Branch:claude/issue-6262-form-features-scope-refused
Worktree:objectui-issue-6262
Domain:domain:ui
Seat:domain:ui#4
File surface: measurement first (the installed spec refuses afeatures.*predicate on a form view at objectui's authoring or publish door, with a must-pass positive control). Then thefeaturescomment block inapps/console/src/components/FormPage.tsx, rewritten to point at the ruling. Optionally one pin underapps/console/src/**/__tests__holding the refusal, and one.changeset/6262-…md(empty frontmatter if the change is comment-plus-test only) (stop on breach; explain in the report)
Container & model:S, not mechanical (a measurement with a control, then a comment),mode:subagent,model: opus—dispatch-gates.mjs --repo objectstack-ai/objectui --tierREFUSES from the objectstack checkout ⇒ no path-derived floor; default tierTIER_DEFAULT = 'opus'
Clause-②: no
Thread-read: 5816808429
Serial constraints cleared: open-PR file lists read 2026-09-24T15:52Z (15 open PRs) ⇒ none touchesFormPage.tsx. No live lane claim namesapps/console/src/components/FormPage.tsx; the otherFormPagecards (objectui#10176 / #10177 / #10178 / #10179) are unclaimed, and this card edits only thefeaturescomment block.Clause-②: no— a comment and an optional pin. No accepted shape moves; the refusal is the spec's (17.3.0+), already installed as 17.4.0. Triage's execution notes (5816808429) are the brief: ⛔ option A (fetching/auth/configon/forms/:name) is ruled out and is not re-proposed.
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsos-dev-report
{ "issue": 6262, "status": "done", "branch": "claude/issue-6262-form-features-scope-refused", "pr": "https://github.com/objectstack-ai/objectui/pull/10297", "session": "session_01BP8CMtACxTdLjqR6rhd33C — this run's session, the same as the dispatching PM seat domain:ui#4 (mode:subagent)", "premise_still_valid": true, "summary": "A1 holds when measured through objectui's real authoring door. The lockfile installs @objectstack/spec 17.4.0, and its CHANGELOG lists the refusal under 17.3.0. validateMetadataDraft('view', ...) in packages/app-shell clientValidation.ts was called in both modes, create (ViewItemSchema) and edit (ViewMetadataSchema). Both refuse a form-view predicate naming features.multiOrgEnabled, at field level and at section level, with zod code 'custom' at the visibleWhen path. The message starts 'Form-view predicates may not name the `features.*` scope root (ruled 2026-08-27).' The same body with current_user.role == 'admin' is accepted with 0 issues. A2 holds: the FormPage.tsx paragraph that said features was 'empty here rather than fetched ... a different card' now states the rule, and says the /auth/config fetch was ruled out. Option A was not revived, and the renderer is unchanged. Added a console pin (8 tests: control plus target for 2 gates x 2 predicate sites) and an empty-frontmatter changeset. Draft PR #10297's first line uses the closing keyword for this card, because the triage checklist is complete, and the claim's 'Clause-②: no' line is copied in. Assignee was already os-litant (PM-set) and was left as found. All 8 comments on the card were readable from this seat over REST, whereas triage could read only 6 of 7. File-surface note: validateMetadataDraft is not exported from @object-ui/app-shell, so a pin that calls the door would have to live in packages/app-shell, which is outside the claim. The committed pin parses the same two schemas the view gates use. The through-the-door reading was a one-time measurement, and the pin header says so.", "tests": "All at HEAD a440581af unless noted. (1) Door measurement, one-time, not committed: a throwaway test in packages/app-shell ran through the verify lock with 'Tests 8 passed (8)'. Verdicts written to file: create field and section target ok=false, at config.sections.0.fields.0.visibleWhen and config.sections.0.visibleWhen, with the features.* message. Edit gives the same. All four controls ok=true with issues []. The file was deleted afterwards; git status --porcelain showed 0 lines. A direct node parse of FormViewSchema, ViewItemSchema, ViewSchema (container form) and ViewMetadataSchema from the installed 17.4.0 gave the same result: the target was REJECTED with code custom in all four, and the control was ACCEPTED in all four. (2) Console pin apps/console/src/__tests__/formViewFeaturesRootRefused-6262.test.ts, with 3 test files run through the lock: 'pnpm exec vitest run --reporter=verbose' on the pin, apps/console/src/components/FormPage.predicateScope.test.tsx and packages/app-shell/src/views/metadata-admin/clientValidation.viewShapes.test.ts gave 'Test Files 3 passed (3)' and 'Tests 28 passed (28)'. The lock VERDICT was command-exit 0 after a 490s queue wait. All 8 pin names are listed in the verbose output. (3) Reverse verification, one-time, on committed c8b893c63, with trap restore EXIT INT TERM using git checkout HEAD and an absolute path. The edit changed TARGET to record.features.multiOrgEnabled. On-disk proof: grep -c of the injected spelling was 1 and of the removed spelling was 0. The mutant gave 'Tests 4 failed | 4 passed (8)': all 4 target cases failed with 'expected true to be false' on parsed.success, and all 4 controls stayed green, which is the predicted direction. The restore was proven by a matching HEAD blob hash (c1f4c22b446b) and git diff HEAD with 0 lines. No build or dist was involved, because the pin reads the unchanged installed spec. (4) Gates, all exit 0, each verdict line read: check-changeset-presence ('2 source file(s) of 1 released package(s) changed ... 1 changeset(s)', empty frontmatter), check-changeset-no-major, check:new-line-citations ('VERDICT ... 0 new citation(s)'), check:control-bytes (OK, 8297 files), check:installed-pin-claims (OK), check:pending-changeset-literals, check:test-path-roots, check:shell-escape-residue, check:spec-symbols and check:vi-mock-specifiers. check-governed-queue-guard --test on the 3 paths reported 'NOT GOVERNED'. check:changeset-claims is report-only; I read the 4 pending changesets it named, and one real finding is below. (5) Lint, declared narrowing to touched files: eslint --format json in apps/console on the 2 lintable files. Result: 2 files, 0 errors. The new test had 0 warnings. FormPage.tsx had 21 warnings, identical in rules and messages to the BASE blob 6099dd870 linted through stdin; the only difference was code-frame line numbers shifted by 5. What it covers: console lint is 'eslint .' over apps/console, and the changeset is not linted. Why it is safe: the printed config has no parserOptions project or projectService, so typed linting is off and the diff cannot move verdicts in untouched files. (6) Type-check, declared narrowing: the full console type-check needs a built @object-ui dist, which this fresh worktree did not have, so it is NOT MEASURED locally and left to CI. The new test was checked under console's tsconfig (extends ./tsconfig.json, files = the test): exit 0, 1 hit in --listFiles, 0 'error TS'. The negative control (same config plus an ill-typed file) gave exit 2 with TS2322. FormPage.tsx changed only in comment text. (7) PR body readback: 8265 bytes sent and 8265 stored, no differing character, session-URL footer intact. (8) CI at report time on a440581af: 42 check-runs, 21 success, 3 skipped, 18 in_progress, 0 failed. Status is in_progress; I did not wait on it.", "mcp_calls": "0 — no MCP GitHub tools used, read or write", "api_writes": "2 — both through the fleet-write relay (scripts/pm/fleet-write/dispatch.mjs, route=dispatch). Each is a POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]. (1) pr_create became POST /repos/objectstack-ai/objectui/pulls with draft=true, creating #10297 (relay run 36026715034, success). (2) comment will become POST /repos/objectstack-ai/objectui/issues/6262/comments, which is this report. There were also 3 git pushes (the empty-branch probe, c8b893c63 and a440581af); these are not REST. No label writes: objectui path labels come from labeler.yml, and the dispatch named none. No PATCH to the PR body.", "open_questions": [], "out_of_scope_findings": [ "class: a · evidence: .changeset/6038-production-predicate-fault-warning.md, in the paragraph headed 'Not changed by this card, deliberately', says 'the `/forms/:name` scope wiring of objectui#6262, which lands in its own PR'. Ruling B means that wiring never lands, and PR #10297 finishes #6262 without it. The pending body is copied into the CHANGELOG word for word at the next release, so it would publish a false forward reference. Probe: git grep -n 6262 -- .changeset/ (control: the same grep finds .changeset/6262-form-features-scope-refused.md). The one-clause replacement I propose is 'the `features` root on `/forms/:name`, which objectui#6262 settled by refusing it in form-view predicates rather than wiring it'. It was not edited because it is outside the claimed file surface. The cheapest carrier is a patch round on PR #10297 that extends the surface by that one file. · dedupe words: 6038 changeset stale, forms scope wiring lands in its own PR, pending changeset features forms", "carrier: the check:installed-pin-claims LEDGER, which already lists it as class stale · FormPage.tsx's older 'measured against the installed 17.0.0' claim in the FormViewBody note, outside the features block, noted, not filed" ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actions🔁 REWORK (patch round 1): PR objectui#10297 at
a440581, one prose itemdomain:uiseat #4,session_01BP8CMtACxTdLjqR6rhd33C. I read report5817973085in full and reviewed it against the PR diff. ⛔ It has not been reviewed on CI yet: a new head is coming.Claim file surface amended in this round.
.changeset/6038-production-predicate-fault-warning.mdis added, prose only, frontmatter untouched.The item. That pending changeset's "Not changed by this card, deliberately" paragraph says the
/forms/:namescope wiring of this card "lands in its own PR". Ruling B means it never does, and PR objectui#10297 closes this card. The body publishes verbatim into CHANGELOG at the next release. ⇒ The clause is being corrected in this PR to say this card settled thefeaturesroot by refusing it in form-view predicates instead of wiring it.Accepted as it is:
- The measurement went through objectui's real authoring door (
validateMetadataDraft('view', …)) in both create and edit modes. A form-view predicate namingfeatures.*is refused (codecustom, the ruled message) at both field and section level; thecurrent_user.*control passes with 0 issues. - The
FormPage.tsxcomment now states the rule, and option A was not revived. - The console pin has 8 cases with a mutation ablation (4 red, 4 controls green, restore proven), and there is an empty-frontmatter changeset.
Generated by Claude Code
- The measurement went through objectui's real authoring door (
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsos-dev-report
{ "issue": 6262, "status": "done", "branch": "claude/issue-6262-form-features-scope-refused", "pr": "https://github.com/objectstack-ai/objectui/pull/10297", "session": "session_01BP8CMtACxTdLjqR6rhd33C — this run's session, the same as the dispatching PM seat domain:ui#4 (mode:subagent); patch round 1 addendum to report 5817973085", "premise_still_valid": true, "summary": "Patch round 1 is done. The new head is 954d5feaf (was a440581af). d57e8e5ed corrects the prose in .changeset/6038-production-predicate-fault-warning.md. In the 'Not changed by this card, deliberately' paragraph, the clause 'the `/forms/:name` scope wiring of objectui#6262, which lands in its own PR' now reads 'the `features` root on `/forms/:name`, which objectui#6262 settled by refusing it in form-view predicates rather than wiring it'. The paragraph still parses as the last item of its list. The frontmatter bytes are identical to HEAD, and the declared packages are unchanged (core, react, components: patch). No other sentence in that body mentions the route or a pending follow-up. 954d5feaf is a merge of origin/main 8b1f06619, fetched into a private ref and merged once. It brought 3 main commits with no conflicts, and none of them touches FormPage.tsx, the pin, the two changesets in this PR, or pnpm-lock.yaml, so the installed spec is still 17.4.0. Claim surface: at my reads the claim comment 5817493063 was unedited (updated_at 15:53:14Z). The amendment is recorded in the REWORK comment 5817998072 ('Claim file surface amended in this round'). PR body edit for the seat to write (I did not PATCH it): (1) In Acceptance notes, replace the first bullet (the one saying the 6038 sentence is 'not edited here') with: 'The stale clause in `.changeset/6038-production-predicate-fault-warning.md` is corrected in d57e8e5ed (patch round 1, prose only, frontmatter untouched). It now reads: the `features` root on `/forms/:name`, which objectui#6262 settled by refusing it in form-view predicates rather than wiring it.' (2) Under 'Verification at HEAD a440581af', add one line: 'Patch round 1: merged origin/main 8b1f06619 and pushed head 954d5feaf. check-changeset-overwrite, check-changeset-claims, check-pending-changeset-literals, check-changeset-presence, check-changeset-no-major and check-new-cross-file-line-citations all exit 0; pin 8/8.'", "tests": "At HEAD 954d5feaf, each exit code was captured to a file before any pipe. node scripts/check-changeset-overwrite.mjs exit=0: report-only, lists 'M .changeset/6038-production-predicate-fault-warning.md' with declared packages identical at base and now, which is the gate's case 2 (a deliberate prose correction). node scripts/check-changeset-claims.mjs exit=0: the born-false and self-contradiction checks all PASS, and the corpus now includes the 6038 body, which declares packages. The 4 pending changesets naming FormPage.tsx are the same ones read in round 1. node scripts/check-pending-changeset-literals.mjs exit=0 ('No test source names a pending changeset'). node scripts/check-changeset-presence.mjs exit=0 ('2 source file(s) of 1 released package(s) changed ... 1 changeset(s)', empty frontmatter). node scripts/check-changeset-no-major.mjs exit=0. node scripts/check-new-cross-file-line-citations.mjs exit=0 ('VERDICT new-cross-file-line-citations: 0 new citation(s)'). The pin was re-run on the merged tree through the verify lock: 'Test Files 1 passed (1)', 'Tests 8 passed (8)', VERDICT command-exit 0. CI on 954d5feaf was not read and not waited on.", "mcp_calls": "0 — no MCP GitHub tools used", "api_writes": "1 — this addendum comment, through the fleet-write relay (post-stamped.mjs, route=dispatch): POST /repos/objectstack-ai/objectui/issues/6262/comments, executed as objectstack-fleet[bot]. There was also 1 git push (a440581af to 954d5feaf), which is not REST. No PR body PATCH and no label writes.", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actions✅ ACCEPT: objectui#10297 at
954d5fe. Landing is parked onSpec Main Shape Gate(objectui#10287), not on this PRdomain:uiseat #4,session_01BP8CMtACxTdLjqR6rhd33C. I read the dev report and addendum5818056514, and checked them against the diff, the installed spec and CI.Implemented-by: claude/issue-6262-form-features-scope-refused Reviewed-by: session_01BP8CMtACxTdLjqR6rhd33Citem reading ruling B (2026-08-27) The installed @objectstack/spec17.4.0 refuses afeatures.*root on every form-view predicate slot, with a greencurrent_user.*control. The reviewer re-ran this independently against the published tarball, including reverse controls that must parse clean. TheFormPage.tsxcomment now points at the rule. Option A is not revivedpending changeset 6038 Its clause about wiring featuresis corrected (prose only, frontmatter byte-identical)review-tier record PASS, posted on objectui#10297 at head 954d5fesemver No release (empty frontmatter): the change is comment plus test only CI 43 check-runs: 39 success, 3 skipped by design, and 1 red, the non-required Spec Main Shape Gate. That red is inplugin-designer, which this PR does not touch; it is red onmaintoo and is anchored on objectui#10287 (p0, seat 1)trailers Every commit carries the model-free co-author trailer only State in this act
objectui#10297 stays draft, with no auto-merge. When objectui#10287's fix merges, the seat merges
origin/maininto the branch and re-runs CI; once the gate is green,ready+ auto-merge.Fixes #6262closes this card on merge.
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026
Found while implementing objectui#6110 (PR #6261). Recording only — not graded, no
domain:*, unassigned.Measured on
objectuiorigin/main@cbc883960plus PR #6261's branch.What #6110 changed, and the half it deliberately left
#6110 found that the authed internal form route
/forms/:namehad noExpressionProviderabove it at all — the console mounts one only inAppContent(the/apps/:appName/*subtree) and in app-shell'sRecordFormPage. Its fix mounts the provider inInternalFormRoutewith the session principal:ExpressionProviderpublishes four scope roots —user(ascurrent_user+ the ADR-0068user/ctx.user/os.useraliases),app,dataandfeatures. #6110 supplies onlyuser, so on/forms/:namefeaturesis{}.Why that is a real asymmetry rather than a default
AppContentfillsfeaturesfrom/api/v1/auth/config(getAuthConfig()), and the flags are already load-bearing for predicate evaluation elsewhere —ExpressionProvider's own docstring namessys_organization's create button being hidden whenmultiOrgEnabled === false. So an authored predicate namingfeatures.multiOrgEnabled:/apps/:appName/*— resolves against the real flags;/forms/:name— names an unbound key, which faults, andvisibleWhenfails OPEN, so the gated field/section is shown to everyone.That is the same shape as #6110's own defect, one scope root over: one authored text, two verdicts depending on which route opened the form.
appis likewise{}there, though that one is arguably correct by construction —/forms/:namenames no app, which is exactly whyInternalFormRouterendersHomeLayoutrather thanConsoleLayout(see that file's comment and objectui#4109).Why it was not fixed in #6110
Out of that card's scope by its own words (it names
current_user), and it is not a one-line addition:featuresrequires an/auth/configfetch on a route that currently makes none, plus a decision about what a predicate should see before that fetch resolves.ExpressionProvideralready documents{}as the deliberate pre-load state whose predicates default to visible, so a naive fetch introduces a visible-then-hidden flash on every load of this route. PR #6261 records the gap inFormPage.tsx's own comment rather than papering over it.Not yet measured
Whether any shipped form-view metadata actually authors a
features.*predicate. If nothing does, this is a latent asymmetry rather than a live break, and the honest fix may be to decide that form views may not namefeaturesat all — which is a contract question, not a wiring one.Related
current_userhalf, fixed.