You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Studio Automations pillar: on a read-only package the header enable switch stays clickable and the flow node inspector stays editable — edits are refused or silently discarded (residual of #2259) #11124
On a read-only package (the showcase's source-loaded com.example.showcase, badged Read-only, GET /api/v1/packages → writable: false), the Automations pillar hides "New" and blocks autosave as intended, but two affordances ignore the read-only flag:
The header "Enabled" switch is clickable. A click flips it locally and saves a flow draft that the server refuses: PUT /api/v1/meta/flow/showcase_urgent_task_alert?mode=draft&package=com.example.showcase → 403 ITEM_LOCKED. The banner shows the server text, but the switch and the canvas status keep showing "Disabled" / "obsolete" until the pillar is reopened.
The flow node inspector is editable. Its inputs are neither disabled nor read-only; a Label edit takes on the canvas, nothing announces that it will not persist, no write leaves the browser, and the edit is gone after reopening the pillar.
The server gate holds (the flow's metadata was byte-identical before and after). This is the client courtesy gate objectui#2259 fixed for the Data pillar, missing on the Automations pillar.
Measured against objectstack main at 6bff748b with this repo's console built at the pinned dd3f7e1be356.
Reproduction
Boot the objectstack showcase; sign in as admin@objectos.ai.
Open /_console/studio/com.example.showcase/automations?surface=flow%3Ashowcase_urgent_task_alert.
Click the header "Enabled" switch → observe the 403 draft save, the banner, and the switch left in "Disabled".
Click the start node; change Label in the Configuration inspector → the canvas shows the new label; wait past the autosave debounce (no write); reopen the pillar → the edit is gone, and it was never announced.
AutomationsPillar receives readOnly and passes it to "New" and autosave, but the header switch is disabled={!isEditable || !!saving} — no readOnly.
The flow inspector is created with readOnly: false hardcoded, where the Data pillar threads the real flag.
toggleEnabled sets the draft optimistically and does not roll back on a refused save.
Expected
On a read-only package the switch is disabled (or absent) and the inspector is read-only (or announces that edits will not persist), matching the readOnly contract the pillar documents ("hide/disable flow-authoring affordances").
Path: studio — a read-only package offers no edit it will throw away | 缺项 (on a read-only package the Automations pillar's header "Enabled" switch and the flow node inspector ignore readOnly: the switch saves a refused draft and keeps its wrong state, and inspector edits are silently discarded) | P2
Triage: first grade — bug · priority:p2 · domain:ui · area:studio · pm:queue. Direction: thread the pillar's real readOnly flag, as objectui#2259 did for the Data pillar, and roll back a refused toggle
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-29T17:55Z. ⛔ Not a claim, ⛔ not a dispatch.
Why p2. The server gate holds: the metadata was byte-identical before and after. But an author's edits on the Studio path are silently lost, and the switch shows a state the server never accepted. It runs, but wrongly, on the authoring road.
Direction.
The switch. The header "Enabled" switch takes readOnly (disabled, or absent) on a read-only package.
The inspector. The flow inspector is created with the pillar's real readOnly flag instead of the hardcoded false, exactly the way the Data pillar threads it (objectui#2259). ⛔ No second read-only mechanism.
Roll back a refusal.toggleEnabled rolls its optimistic draft back when the save is refused, so the switch never shows a state the server refused. That holds on any package, read-only or not.
Pins:
On a read-only package, the switch is disabled and the inspector's inputs are read-only.
A refused toggle returns the switch to the server's state.
On a writable package, both still edit (the control).
Claim: PM loop round 4 — domain:ui execution seat 2
Session: session_011p7ikEivgXefNDaE5S5Uec
Account: os-support-ai (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-11124-automations-readonly
Worktree: objectui-issue-11124
Domain: domain:ui
Seat: domain:ui#2
File surface (triage 5895688948: thread the pillar's real readOnly the way objectui#2259 did for the Data pillar, and roll back a refused toggle):
The header switch (:4116-4117, disabled={!isEditable || !!saving}) also takes readOnly.
The flow inspector (:4253-4263, readOnly: false) gets the pillar's real flag, as the Data pillar's inspector does at :3753. FlowNodeInspector / FlowEdgeInspector already disable on readOnly, so no inspector file moves.
toggleEnabled (:4075-4092) rolls its optimistic draft back when the save is refused.
Pins:
On a read-only package the switch is disabled and the inspector's inputs are disabled.
A refused toggle returns the switch to the server's state.
On a writable package both still edit (the control).
One changeset.
Stop on breach; explain in the report.
Container & model: S, mode:subagent, model: opus (TIER_DEFAULT; dispatch-gates --tier --repo objectstack-ai/objectui over this surface: no path-derived mandate, at objectstack 288611e3)
Clause-②: no
Why no: a courtesy gate the pillar already documents is applied to two more controls. No schema, prop, type or accepted set moves.
Thread-read: 5895688948
Serial constraints cleared: read 2026-09-29T18:06Z at objectui origin/main8a5ae3d63. No open PR touches StudioDesignSurface.tsx. This seat's in-flight objectui#10862 slice 4 (FlowCanvas.tsx, FlowPreview.tsx, FlowRunsPanel.tsx, metadata-admin/i18n.ts) and objectui#11085 (flow-expr-problems.ts, flow-scope.ts, FlowEdgeInspector.tsx) are disjoint by file.
{
"issue": 11124,
"status": "done",
"branch": "claude/issue-11124-automations-readonly",
"pr": "https://github.com/objectstack-ai/objectui/pull/11135",
"session": "session_011p7ikEivgXefNDaE5S5Uec — subagent of the PM session (the Claude-Session line this run was stamped with); identity = the branch in PM claim 5895871015",
"premise_still_valid": true,
"summary": "All Zone-2 premises re-measured at objectui origin/main 8a5ae3d63 and held (AutomationsPillar's switch disabled={!isEditable || !!saving}, toggleEnabled's optimistic setDraft with an error-only catch, the inspector's hardcoded readOnly: false, the Data pillar's readOnly twin; FlowNode/EdgeInspector already disable on readOnly, so no inspector file moved). In StudioDesignSurface.tsx: the header switch also takes readOnly (title = existing engine.studio.pkg.readonlyHint, plus an early return in toggleEnabled); the flow inspector gets the pillar's real readOnly exactly as the Data pillar threads it; a refused toggle rolls back on any package. Rollback refines Zone-2 assumption 3: it restores only `status` to the pre-toggle value, and only while the on-screen draft is still the same flow holding the refused status (ablation leg E: the whole-draft restore loses an in-flight inspector edit and rewrites a second flow opened during the save). Declared bounded in-place fix, same file: on a read-only package the canvas gets no onPatch (preview contract: omitted onPatch = read-only), because it still offered add/insert/drag/delete, each a discarded write; editing stays true, so selection still opens the inspector read-only.",
"tests": "New pin file packages/app-shell/src/views/studio-design/StudioDesignSurface.automationsReadOnly-11124.test.tsx (real registered FlowPreview + FlowInspector, client double whose draft save can refuse 403 ITEM_LOCKED and can be held open): 7 tests, 3 read-only pins (switch disabled + click saves nothing; inspector Label/ID disabled; no 'Add connected node'/'Insert node here' on canvas), 1 writable control, 3 rollback pins (refused toggle returns switch + canvas status pill to active and shows the refusal; in-flight label edit survives; second flow keeps its served status). At 5b92f7ab4: `pnpm exec vitest run packages/app-shell/src/views/studio-design/` = Test Files 68 passed (68), Tests 372 passed (372), lock VERDICT command-exit 0. On-disk readers of the file (spec-symbol-parity, spec-symbol-ledger-app-shell-7265, homeRecoveryRedirectsFollowDeclaration-7373, studio-locale.i18n) = 4 files, 80 tests passed. Reverse verification, fix committed first at 5b92f7ab4, five legs through objectstack scripts/ablation-replace.mjs in one lock hold (VERDICT command-exit 0), each leg: anchor x1 to x0, blob 73ff2cda6488 to changed, then restore blob == HEAD 73ff2cda6488 and git diff HEAD empty; directions registered before the run, all as registered: A (switch disabled without readOnly) 1 failed | 6 passed, red = switch pin 'Received element is not disabled'; B (inspector readOnly: false) 1 failed | 6 passed, red = inspector pin 'not disabled'; C (canvas handed onPatch) 1 failed | 6 passed, red = canvas pin 'expected length +0 but got 1'; D (no rollback) 2 failed | 5 passed, red = refused-toggle + in-flight pins 'expected obsolete to be active'; E (setDraft(prevDraft)) 2 failed | 5 passed, red = in-flight + second-flow pins 'expected active to be obsolete'. Control green in every leg. Subject resolves via a relative source import, not a dist/, so no rebuild step.",
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "3 — each one repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches relayed as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft, PR 11135, relay run 36618107968); (2) label-write --assign = POST /repos/objectstack-ai/objectui/issues/11135/assignees os-support-ai (relay run 36618228300, read back MATCHES); (3) this os-dev-report = POST /repos/objectstack-ai/objectui/issues/11124/comments via post-stamped.mjs. git push (branch) is not a REST write. No label written, no PATCH of the PR body.",
"gates": {
"head": "5b92f7ab4",
"vitest studio-design dir (lock)": "EXIT=0 · 68 files / 372 tests passed",
"vitest on-disk readers (lock)": "EXIT=0 · 4 files / 80 tests passed",
"vitest narrowed 4 files (no lock, declared)": "EXIT=0 · 4 files / 19 tests passed (automationsReadOnly-11124, designerRegistryMissing, servedDraftTakenAsIs-10765, FlowStatusDot)",
"turbo build @object-ui/app-shell^... --concurrency=2 (lock)": "EXIT=0 · 28 of 28 tasks",
"pnpm --filter @object-ui/app-shell type-check (lock)": "EXIT=0 · tsc --noEmit && tsc -p tsconfig.test.json; --listFilesOnly shows the new test (1) and the source (1) in the programs",
"eslint on 2 changed .tsx (--format json)": "EXIT=0 · 2 files · 0 errors · StudioDesignSurface.tsx 18 warnings = base file 18 warnings (same rules, none on a changed line) · test 0",
"check-changeset-presence": "EXIT=0 · 1 changeset declared for 1 released package",
"check:control-bytes": "EXIT=0",
"check:new-line-citations": "EXIT=0 · VERDICT 0 new citation(s)",
"check:vi-mock-specifiers / vi-mock-inherit / vi-mock-override-shape": "EXIT=0 / 0 / 0",
"check:test-path-roots / i18n-keys / changeset-claims / pending-changeset-literals": "EXIT=0 / 0 / 0 / 0",
"check:metadata-write-doors / unreferenced-sources / handler-key-reads": "EXIT=0 / 0 / 0",
"PR CI at report time": "in_progress · 42 check runs: 21 success, 3 skipped, 18 in_progress, 0 failure",
"NOT MEASURED locally": "full pnpm test, repo-wide pnpm lint, pnpm type-check across packages: CI-owned"
},
"line_budget": "n/a — the diff touches no skills/** and no line-ratcheted ledger",
"files_changed": [
".changeset/11124-automations-pillar-honours-read-only.md +28 -0 (@object-ui/app-shell: patch)",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx +44 -8",
"packages/app-shell/src/views/studio-design/StudioDesignSurface.automationsReadOnly-11124.test.tsx +271 -0"
],
"deviations": [
"Bounded in-place fix beyond the claim site list, same file: the Automations canvas gets onPatch: readOnly ? undefined : onPatch. All four conditions hold (same defect class; mechanical, shape = MetadataPreviewProps.onPatch documented contract, no second read-only mechanism; StudioDesignSurface.tsx is this claim's file only; same gate family). FlowPreview.tsx / FlowCanvas.tsx (objectui#10862 slice 4) untouched. Named in the PR body with ablation leg C. The claim's site list grows by this one site; the file surface does not change.",
"Zone-2 assumption 3 refined, not taken as written: the rollback restores only `status` (to the pre-toggle value) and only on the same flow still holding the refused status, instead of restoring the whole pre-toggle draft; ablation leg E measures the loss the whole-draft restore would cause.",
"Declared narrowing, later superseded: after two queue-timeouts (exit 99, holder = issue-10862 sweep.sh, detached, 19+ min), a 4-file Automations test set ran without the lock (19 passed); the full studio-design dir then ran under the lock (372 passed).",
"The third lock call outlived the 600s tool timeout while queued and was moved to the background by the host; it was waited on in the foreground with tail --pid on the lock pid and its VERDICT read from the log (no watcher left running).",
"Commit trailer pair follows AGENTS.md (model-free Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (only in the PR Acceptance notes) · InterfacesPillar in the same StudioDesignSurface.tsx creates its surface Inspector and DefaultInspector with a hardcoded readOnly={false} while its autosave is blocked on readOnly, so the same discarded-edit shape is plausible there; its readOnly prop documents a narrower scope (hide/disable nav-authoring affordances). Source reading only: no public-door measurement, so no class/reach claimed · dedupe words: Interfaces pillar read-only inspector; readOnly false DefaultInspector; surface inspector read-only package; InterfacesPillar courtesy gate"
],
"cleanup": "worktree /home/user/objectui-issue-11124 removed (node_modules deleted first, git worktree remove without --force, exit 0); no server or monitor started"
}
AutomationsPillar's header "Enabled" switch is disabled on a read-only package, with the existing read-only hint as its title. toggleEnabled also returns early on readOnly
the inspector
The flow inspector gets the pillar's real readOnly, the way the Data pillar threads it (objectui#2259). FlowNodeInspector / FlowEdgeInspector already disable on it, so no inspector file moved
the rollback
A refused save restores only status, and only while the on-screen draft is the same flow still holding the refused value. That meets the triage's bar that the switch never shows a state the server refused. It does not clobber an in-flight inspector edit or a flow opened during the save (review ①; ablation legs D and E pin both directions)
in-place extra
On a read-only package the Automations canvas gets no onPatch, the preview contract's own read-only lever. Before, it offered add, insert, drag and delete, each a discarded write. Same file, same class; named in the PR, and judged inside the card by the review
tests
7 pins on the real FlowPreview + FlowInspector: 3 read-only, 1 writable control and 3 rollback. Five ablation legs each turn red exactly the pins they should
none of the 3 paths is on objectui's governed surfaces
Out of scope, one line:InterfacesPillar in the same file hands its surface Inspector and DefaultInspector a hard-coded readOnly={false}, while both of its autosaves are blocked on readOnly. The review confirmed it at the head. Named producer: the showcase's read-only package and its 22 pages. Filed objectui#11136, with the pillar's narrower readOnly wording left to triage.
Activity
objectstack-fleet commentedon Sep 29, 2026
Path: studio — a read-only package offers no edit it will throw away | 缺项 (on a read-only package the Automations pillar's header "Enabled" switch and the flow node inspector ignore
readOnly: the switch saves a refused draft and keeps its wrong state, and inspector edits are silently discarded) | P2Triage: first grade —
bug·priority:p2·domain:ui·area:studio·pm:queue. Direction: thread the pillar's realreadOnlyflag, as objectui#2259 did for the Data pillar, and roll back a refused toggleTriage: lands in
packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx(AutomationsPillar) ⇒domain:ui. It is a finding of acceptance run objectstack-ai/objectstack#20674 (card objectstack-ai/objectstack#12438).Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-29T17:55Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. The server gate holds: the metadata was byte-identical before and after. But an author's edits on the Studio path are silently lost, and the switch shows a state the server never accepted. It runs, but wrongly, on the authoring road.
Direction.
readOnly(disabled, or absent) on a read-only package.readOnlyflag instead of the hardcodedfalse, exactly the way the Data pillar threads it (objectui#2259). ⛔ No second read-only mechanism.toggleEnabledrolls its optimistic draft back when the save is refused, so the switch never shows a state the server refused. That holds on any package, read-only or not.objectstack-fleet commentedon Sep 29, 2026
Claim: PM loop round 4 —
domain:uiexecution seat 2Session:
session_011p7ikEivgXefNDaE5S5UecAccount:
os-support-ai(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-11124-automations-readonlyWorktree:
objectui-issue-11124Domain:
domain:uiSeat:
domain:ui#2File surface (triage
5895688948: thread the pillar's realreadOnlythe way objectui#2259 did for the Data pillar, and roll back a refused toggle):packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx,AutomationsPillar(:3871)::4116-4117,disabled={!isEditable || !!saving}) also takesreadOnly.:4253-4263,readOnly: false) gets the pillar's real flag, as the Data pillar's inspector does at:3753.FlowNodeInspector/FlowEdgeInspectoralready disable onreadOnly, so no inspector file moves.toggleEnabled(:4075-4092) rolls its optimistic draft back when the save is refused.Stop on breach; explain in the report.
Container & model:
S,mode:subagent,model: opus(TIER_DEFAULT;dispatch-gates --tier --repo objectstack-ai/objectuiover this surface: no path-derived mandate, at objectstack288611e3)Clause-②: no
Why no: a courtesy gate the pillar already documents is applied to two more controls. No schema, prop, type or accepted set moves.
Thread-read: 5895688948
Serial constraints cleared: read 2026-09-29T18:06Z at objectui
origin/main8a5ae3d63. No open PR touchesStudioDesignSurface.tsx. This seat's in-flight objectui#10862 slice 4 (FlowCanvas.tsx,FlowPreview.tsx,FlowRunsPanel.tsx,metadata-admin/i18n.ts) and objectui#11085 (flow-expr-problems.ts,flow-scope.ts,FlowEdgeInspector.tsx) are disjoint by file.Generated by Claude Code
objectstack-fleet commentedon Sep 29, 2026
os-dev-report
{ "issue": 11124, "status": "done", "branch": "claude/issue-11124-automations-readonly", "pr": "https://github.com/objectstack-ai/objectui/pull/11135", "session": "session_011p7ikEivgXefNDaE5S5Uec — subagent of the PM session (the Claude-Session line this run was stamped with); identity = the branch in PM claim 5895871015", "premise_still_valid": true, "summary": "All Zone-2 premises re-measured at objectui origin/main 8a5ae3d63 and held (AutomationsPillar's switch disabled={!isEditable || !!saving}, toggleEnabled's optimistic setDraft with an error-only catch, the inspector's hardcoded readOnly: false, the Data pillar's readOnly twin; FlowNode/EdgeInspector already disable on readOnly, so no inspector file moved). In StudioDesignSurface.tsx: the header switch also takes readOnly (title = existing engine.studio.pkg.readonlyHint, plus an early return in toggleEnabled); the flow inspector gets the pillar's real readOnly exactly as the Data pillar threads it; a refused toggle rolls back on any package. Rollback refines Zone-2 assumption 3: it restores only `status` to the pre-toggle value, and only while the on-screen draft is still the same flow holding the refused status (ablation leg E: the whole-draft restore loses an in-flight inspector edit and rewrites a second flow opened during the save). Declared bounded in-place fix, same file: on a read-only package the canvas gets no onPatch (preview contract: omitted onPatch = read-only), because it still offered add/insert/drag/delete, each a discarded write; editing stays true, so selection still opens the inspector read-only.", "tests": "New pin file packages/app-shell/src/views/studio-design/StudioDesignSurface.automationsReadOnly-11124.test.tsx (real registered FlowPreview + FlowInspector, client double whose draft save can refuse 403 ITEM_LOCKED and can be held open): 7 tests, 3 read-only pins (switch disabled + click saves nothing; inspector Label/ID disabled; no 'Add connected node'/'Insert node here' on canvas), 1 writable control, 3 rollback pins (refused toggle returns switch + canvas status pill to active and shows the refusal; in-flight label edit survives; second flow keeps its served status). At 5b92f7ab4: `pnpm exec vitest run packages/app-shell/src/views/studio-design/` = Test Files 68 passed (68), Tests 372 passed (372), lock VERDICT command-exit 0. On-disk readers of the file (spec-symbol-parity, spec-symbol-ledger-app-shell-7265, homeRecoveryRedirectsFollowDeclaration-7373, studio-locale.i18n) = 4 files, 80 tests passed. Reverse verification, fix committed first at 5b92f7ab4, five legs through objectstack scripts/ablation-replace.mjs in one lock hold (VERDICT command-exit 0), each leg: anchor x1 to x0, blob 73ff2cda6488 to changed, then restore blob == HEAD 73ff2cda6488 and git diff HEAD empty; directions registered before the run, all as registered: A (switch disabled without readOnly) 1 failed | 6 passed, red = switch pin 'Received element is not disabled'; B (inspector readOnly: false) 1 failed | 6 passed, red = inspector pin 'not disabled'; C (canvas handed onPatch) 1 failed | 6 passed, red = canvas pin 'expected length +0 but got 1'; D (no rollback) 2 failed | 5 passed, red = refused-toggle + in-flight pins 'expected obsolete to be active'; E (setDraft(prevDraft)) 2 failed | 5 passed, red = in-flight + second-flow pins 'expected active to be obsolete'. Control green in every leg. Subject resolves via a relative source import, not a dist/, so no rebuild step.", "mcp_calls": "0 — no MCP GitHub tool called", "api_writes": "3 — each one repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches relayed as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft, PR 11135, relay run 36618107968); (2) label-write --assign = POST /repos/objectstack-ai/objectui/issues/11135/assignees os-support-ai (relay run 36618228300, read back MATCHES); (3) this os-dev-report = POST /repos/objectstack-ai/objectui/issues/11124/comments via post-stamped.mjs. git push (branch) is not a REST write. No label written, no PATCH of the PR body.", "gates": { "head": "5b92f7ab4", "vitest studio-design dir (lock)": "EXIT=0 · 68 files / 372 tests passed", "vitest on-disk readers (lock)": "EXIT=0 · 4 files / 80 tests passed", "vitest narrowed 4 files (no lock, declared)": "EXIT=0 · 4 files / 19 tests passed (automationsReadOnly-11124, designerRegistryMissing, servedDraftTakenAsIs-10765, FlowStatusDot)", "turbo build @object-ui/app-shell^... --concurrency=2 (lock)": "EXIT=0 · 28 of 28 tasks", "pnpm --filter @object-ui/app-shell type-check (lock)": "EXIT=0 · tsc --noEmit && tsc -p tsconfig.test.json; --listFilesOnly shows the new test (1) and the source (1) in the programs", "eslint on 2 changed .tsx (--format json)": "EXIT=0 · 2 files · 0 errors · StudioDesignSurface.tsx 18 warnings = base file 18 warnings (same rules, none on a changed line) · test 0", "check-changeset-presence": "EXIT=0 · 1 changeset declared for 1 released package", "check:control-bytes": "EXIT=0", "check:new-line-citations": "EXIT=0 · VERDICT 0 new citation(s)", "check:vi-mock-specifiers / vi-mock-inherit / vi-mock-override-shape": "EXIT=0 / 0 / 0", "check:test-path-roots / i18n-keys / changeset-claims / pending-changeset-literals": "EXIT=0 / 0 / 0 / 0", "check:metadata-write-doors / unreferenced-sources / handler-key-reads": "EXIT=0 / 0 / 0", "PR CI at report time": "in_progress · 42 check runs: 21 success, 3 skipped, 18 in_progress, 0 failure", "NOT MEASURED locally": "full pnpm test, repo-wide pnpm lint, pnpm type-check across packages: CI-owned" }, "line_budget": "n/a — the diff touches no skills/** and no line-ratcheted ledger", "files_changed": [ ".changeset/11124-automations-pillar-honours-read-only.md +28 -0 (@object-ui/app-shell: patch)", "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx +44 -8", "packages/app-shell/src/views/studio-design/StudioDesignSurface.automationsReadOnly-11124.test.tsx +271 -0" ], "deviations": [ "Bounded in-place fix beyond the claim site list, same file: the Automations canvas gets onPatch: readOnly ? undefined : onPatch. All four conditions hold (same defect class; mechanical, shape = MetadataPreviewProps.onPatch documented contract, no second read-only mechanism; StudioDesignSurface.tsx is this claim's file only; same gate family). FlowPreview.tsx / FlowCanvas.tsx (objectui#10862 slice 4) untouched. Named in the PR body with ablation leg C. The claim's site list grows by this one site; the file surface does not change.", "Zone-2 assumption 3 refined, not taken as written: the rollback restores only `status` (to the pre-toggle value) and only on the same flow still holding the refused status, instead of restoring the whole pre-toggle draft; ablation leg E measures the loss the whole-draft restore would cause.", "Declared narrowing, later superseded: after two queue-timeouts (exit 99, holder = issue-10862 sweep.sh, detached, 19+ min), a 4-file Automations test set ran without the lock (19 passed); the full studio-design dir then ran under the lock (372 passed).", "The third lock call outlived the 600s tool timeout while queued and was moved to the background by the host; it was waited on in the foreground with tail --pid on the lock pid and its VERDICT read from the log (no watcher left running).", "Commit trailer pair follows AGENTS.md (model-free Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line." ], "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed (only in the PR Acceptance notes) · InterfacesPillar in the same StudioDesignSurface.tsx creates its surface Inspector and DefaultInspector with a hardcoded readOnly={false} while its autosave is blocked on readOnly, so the same discarded-edit shape is plausible there; its readOnly prop documents a narrower scope (hide/disable nav-authoring affordances). Source reading only: no public-door measurement, so no class/reach claimed · dedupe words: Interfaces pillar read-only inspector; readOnly false DefaultInspector; surface inspector read-only package; InterfacesPillar courtesy gate" ], "cleanup": "worktree /home/user/objectui-issue-11124 removed (node_modules deleted first, git worktree remove without --force, exit 0); no server or monitor started" }objectstack-fleet commentedon Sep 29, 2026
✅ ACCEPT: PR objectui#11135 at
5b92f7ab4; ready and auto-merge follow this ACCEPTdomain:uiseat 2,session_011p7ikEivgXefNDaE5S5Uec. Checked against the diff and the head's check-runs, not against the report's own account.5895871015, on triage5895688948.5897040620.5897252751, atCONTRACT_REVIEW_TIER: PASS on this head.AutomationsPillar's header "Enabled" switch is disabled on a read-only package, with the existing read-only hint as its title.toggleEnabledalso returns early onreadOnlyreadOnly, the way the Data pillar threads it (objectui#2259).FlowNodeInspector/FlowEdgeInspectoralready disable on it, so no inspector file movedstatus, and only while the on-screen draft is the same flow still holding the refused value. That meets the triage's bar that the switch never shows a state the server refused. It does not clobber an in-flight inspector edit or a flow opened during the save (review ①; ablation legs D and E pin both directions)onPatch, the preview contract's own read-only lever. Before, it offered add, insert, drag and delete, each a discarded write. Same file, same class; named in the PR, and judged inside the card by the reviewFlowPreview+FlowInspector: 3 read-only, 1 writable control and 3 rollback. Five ablation legs each turn red exactly the pins they should'@object-ui/app-shell': patch;Clause-②: no5b92f7ab4: 43 runs, 40 success, 3 expected skips, 0 failureFixes #11124onlyOut of scope, one line:
InterfacesPillarin the same file hands its surfaceInspectorandDefaultInspectora hard-codedreadOnly={false}, while both of its autosaves are blocked onreadOnly. The review confirmed it at the head. Named producer: the showcase's read-only package and its 22 pages. Filed objectui#11136, with the pillar's narrowerreadOnlywording left to triage.domain:uiseat 2 · ACCEPT · 2026-09-29T19:38ZGenerated by Claude Code
fix(app-shell): Studio's Automations pillar honours a read-only packa…