Repository navigation
The app bar's Edit app pencil hides for system apps and read-only packages #12615
Description
Source
Walked on objectui main 8415d9f11: inside the Setup app (/apps/com.objectstack.setup/dashboard/system_overview) the app bar's right group shows the pencil "Edit app" linking to /studio/com.objectstack.setup/interfaces?surface=dashboard:system_overview; inside HotCRM (a read-only code package) the same pencil links to its Studio dashboard surface. packages/app-shell/src/layout/AppHeader.tsx renders it for every app. Studio then opens the read-only posture (objectui#12453) with nothing editable — the pencil promises an edit it cannot deliver, and for the system app it offers to edit the console's own Setup surface.
Target
- The pencil renders only when the current app belongs to a writable package and the caller holds the authoring capability; otherwise it is absent (not disabled): a read-only package's app gets no pencil, the system apps (Setup, Studio, Account) never.
- The sidebar entry menu's "Design" / "Edit in Studio" entries (objectui#12520 lineage) follow the same rule.
File surface
packages/app-shell/src/layout/AppHeader.tsx, SidebarItemMenu.tsx, the package-posture read the Studio landing already uses (packages-io.ts), tests beside.
Acceptance
- Tests: no pencil for
com.objectstack.setup; no pencil for a package whose posture is read-only; the pencil for a writable package. - Screenshots of the Setup app bar and a writable app's bar at 1280 px.
pnpm --filter @object-ui/app-shell testgreen.
Constraints
- The capability check is the one objectui#5521's home cover cards use (
canAuthorMetadata).
Evidence
Screenshots on the temporary branch claude/console-home-login-design-20261016 of objectstack-ai/objectui (commit 01244b886, never merged): app-bar-hotcrm-edit-pencil.jpg.
Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-16 second review pass: objectui main 8415d9f11, HotCRM 63db83e2, the vite console on :5180 against objectstack serve --dev on :4001, the Studio pillars and all 43 Setup pages walked in the maintainer's browser pane at 1024 × 768 (en) with a 1280 × 900 re-check (zh). The maintainer asked for every finding to be filed, verbatim: 「全部立卡」.
Activity
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 1
Session:
session_01Vk15bz8xHtKGUfXfCm16h4Account:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12615-edit-app-pencil-postureWorktree:
objectui-issue-12615Domain:
domain:uiSeat:
domain:ui#3File surface:
packages/app-shell/src/layout/AppHeader.tsx(the app bar's Edit app pencil only:canDesignInStudio/studioDesignPathand the button they draw; ⛔ not the/homesearch entry objectui#12601 is changing),packages/app-shell/src/layout/SidebarItemMenu.tsx(the Design / Edit in Studio entries), the package-posture read inpackages/app-shell/src/views/studio-design/packages-io.ts(reused; hoisted to a shared helper only if both callers need it),appStudioRoutePathinpackages/app-shell/src/utils/only if the gate belongs there, tests beside each, and one.changeset/12615-*.md(stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuiover the three named paths: no path-derived mandate)Clause-②: no (the posture is read inside the shell; if the fix needs a new exported prop or type, the dev measures the built declaration closure and this line is corrected)
Responsibility:
@object-ui/app-shellAppHeaderdraws the pencil on workspace admin +canAuthorMetadataalone, without the owning package's posture | none covers the affordance: the server refuses the write, and Studio opens its read-only posture with nothing editable, so the risk is a dead-end promise, not data | every workspace admin holding the authoring capability, on any app of a read-only package or a system app; reached today on the Setup app and on HotCRM (the card's walk)Thread-read: none
Serial constraints cleared:
AppHeader.tsxis also claimed by objectui#12601 (seat 1, claim6209656150, "the search entry on/homeonly"), a different region; whichever lands second mergesmainfirst. No open PR touchesAppHeader.tsx,SidebarItemMenu.tsxorpackages-io.ts(6 open objectui PRs' file lists read 2026-10-16T07:23Z). Queued objectui#12605 (the same app bar's left side) waits behind this card.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 12615,
"status": "done",
"branch": "claude/issue-12615-edit-app-pencil-posture",
"pr": "#12652",
"session": "session_01Vk15bz8xHtKGUfXfCm16h4 — this run's id as the relay derived it from the container (CLAUDE_CODE_REMOTE_SESSION_ID); mode:subagent, so it is the dispatching seat's",
"premise_still_valid": true,
"summary": "A new hook, useStudioDesignGate (packages/app-shell/src/hooks/useStudioDesignGate.ts, not exported from the package), now gates the app bar's Edit app pencil, the app switcher's Studio row (which takes the pencil's target) and the sidebar menu's Design entry. Each one shows only for a workspace admin holding manage_metadata, and only when the package the Studio link opens is in fetchPackages' list with writable: true. Otherwise it is absent, never disabled, and it is also absent while the list is still loading or after the read fails. All five hypotheses held on origin/main 79c1996. H3: Setup, Studio and Account have scope 'system', so the server judges them read-only (READ_ONLY_PACKAGE_SCOPES) and parsePackages leaves them out of the list; they drop out with no app-id list. H4: no provider or cache holds the package list, so the gate costs one GET /api/v1/packages per package asked about, only for principals who pass the capability check, shared in flight between the bar and the sidebar rows; both cost cases are pinned. objectui#12601 landed during the run; origin/main was merged twice, and the second merge auto-merged AppHeader.tsx cleanly, keeping both intents.",
"tests": "Final head f599de6, every run under os-verify-lock with OS_VERIFY_LOCK_SLOT=12615. (1) pnpm exec vitest run --maxWorkers=2 over 108 files: every test file that names AppHeader, ConsoleLayout, UnifiedSidebar, SidebarItemMenu or PageView, plus console/home/tests, across packages/app-shell and apps/console. Result: 'Test Files 108 passed (108)', 'Tests 802 passed (802)', VERDICT command-exit 0. (2) The new files: AppHeader.editAppFollowsPackagePosture-12615 (no pencil and no switcher row for com.objectstack.setup; none for a writable:false package, an unlisted package or a flat-shape system row; CONTROL: pencil and row for a writable base; absent while pending, drawn after; absent after a failed read; the two cost pins) and SidebarItemMenu.designFollowsPackagePosture-12615 (no Design for Setup or a read-only package; CONTROL: Design for a writable base; a favorite judged by its own package; the principal half; studioPathPackageId round-trip). (3) Ablation at 690835c (the hook file is byte-identical at f599de6), run with node ../objectstack/scripts/ablation-replace.mjs: the anchor 'return packages.some((pkg) => pkg.id === packageId && pkg.writable);' became 'return true;' (anchor x1 to x0, blob 0f8d83a07af5 to 06d12c72b15b). Result: 'Tests 7 failed | 9 passed (16)'. Exactly the seven posture cases went red, as predicted. Restore was proven: blob equals HEAD and git diff HEAD is empty. The tests import source by relative path, so no dist build sat between the mutation and the run. (4) Eight existing harnesses were updated to serve a writable fixture and to let the verdict settle. Six AppHeader harnesses now hold one adapter object per file. A fresh adapter per render re-keys the shared feeds (adapterKey) on every commit, which hung any case that awaited with the bar mounted: measured 34,700 commits in 60 s with no new request, and the hang persisted with the gate stubbed to identity, so the cause is the harness, not the gate.",
"gates": "Local, on f599de6, each exit code captured before any pipe: pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build exited 0; pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json, whose include is src//*.test.ts(x); not counted with --listFiles) exited 0; pnpm exec eslint on the 13 changed .ts/.tsx files exited 0 with 0 errors (32 pre-existing warnings); node scripts/check-changeset-presence.mjs exited 0; pnpm check:new-line-citations exited 0 ('0 new citation(s)'). The i18n family was not run because no locale file changed. No --ran reconciliation: objectui has no dispatch-gates.mjs, so the list is the dispatch's hand-derived one, re-derived for this diff. CI on PR 12652 head f599de6 at report time: 35 check-runs. Success: Build Docs, Changeset Bump Policy, Changeset Claim Re-read, Changeset Declaration, Changeset Fixed Group Check, Changeset Overwrite Report, Governed Surface Queue Guard, Line Citation Gate, label. Skipped: Test (coverage), Test (coverage shard), dependabot. in_progress: Build & E2E, Bundle Analysis, Lint, Live E2E (informational), Repo Gates, Test (dist pins), Test (shard 1/16 through 16/16), Type Check.",
"mcp_calls": "0",
"api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write as objectstack-fleet[bot]: (1) pr_create on objectstack-ai/objectui = POST /repos/objectstack-ai/objectui/pulls (draft forced) + POST /repos//issues/12652/assignees ['os-elon-musk'], read back as 10040 bytes identical with the assignee listed; (2) this os-dev-report = POST /repos//issues/12615/comments. Plus git push of the branch (not REST). No label writes, no card writes.",
"open_questions": [
{
"question": "PageView's 'Edit in studio' pencil (objectui#12540, the same 12520 lineage) still gates only on isAdmin && canAuthorMetadata. On a read-only package's page it stays drawn, while the app bar pencil on the same route is now hidden. PageView.tsx is outside this claim's file surface, so it was left alone (stop on breach). Does the card's target 2 ('Design / Edit in Studio entries') mean this door?",
"options": [
"A: a patch round on this claim that adds PageView.tsx and its two PageView Edit-in-studio tests to the surface; the fix is one line, useStudioDesignGate(appStudioRoutePath(activeApp, true, { type: 'page', name: pageName })), plus the fixture/settle updates the bar's tests needed",
"B: the seat routes it as a separate card",
"C: leave it, reading target 2 as the sidebar's Design entry and the app switcher row, both of which are done"
],
"recommendation": "A, because it is the same defect class and the same gate, already pinned, with no new verification surface; until then the pencils disagree on one route. Card PR 12652 says 'Fixes #12615'; if the seat reads target 2 as including PageView, the PR text needs 'Part of #12615' instead, written by the seat."
}
],
"out_of_scope_findings": [
"class: a · reach: UI door /apps/PACKAGE/page/NAME for an admin author on a read-only package; the 'Edit in studio' pencil (page-edit-in-studio-button) is drawn because PageView gates on isAdmin && canAuthorMetadata only. Read from source, not measured in a browser. Same family as this card, so it should merge into this card's family rather than get a single-point card (see open_questions) · dedupe words: PageView Edit in studio read-only package; page-edit-in-studio-button posture; useStudioDesignGate PageView",
"carrier: none (承接者:无) · noted, not filed: test-harness trap. AppHeader harnesses whose useAdapter stub returns a fresh object per render loop forever (the shared feeds re-key on adapterKey) as soon as a case awaits with the bar mounted. This PR fixes it in the six harnesses it touched; untouched ones (e.g. AppHeader.sidebarTrigger-12429) still carry the stub but read synchronously, so they are dormant. Plausibly the cause of the unexplained hang the 12198 harness notes; observation only"
],
"files_changed": [
".changeset/12615-edit-app-pencil-posture.md",
"packages/app-shell/src/hooks/useStudioDesignGate.ts",
"packages/app-shell/src/layout/AppHeader.tsx",
"packages/app-shell/src/layout/SidebarItemMenu.tsx",
"packages/app-shell/src/layout/tests/AppHeader.editAppFollowsPackagePosture-12615.test.tsx",
"packages/app-shell/src/layout/tests/SidebarItemMenu.designFollowsPackagePosture-12615.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.appBarLeftGroup-12461.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.appIdentity-12201.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.centeredSearch-12472.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.designInStudioNeedsAuthoring-10899.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.pageRouteNoAuthoringHandles-12198.test.tsx",
"packages/app-shell/src/layout/tests/SidebarItemMenu-12427.test.tsx",
"packages/app-shell/src/layout/tests/SidebarItemMenu.designOpensStudio-12520.test.tsx",
"packages/app-shell/src/layout/tests/UnifiedSidebar.favoritesMenu-12427.test.tsx"
],
"line_budget": "n/a: no skills/ file and no governed ledger touched (diff vs origin/main: 14 files, +868/-96)",
"deviations": [
"Narrowed suite, declared: @object-ui/app-shell has more than 1,400 test files, so the local run covered the 108 files that render the gated components plus console/home; the full package suite is left to CI's 16 shards. The list came from a source grep, so it cannot see a test that reaches these components through another module.",
"Screenshots: NOT MEASURED. Reason: the sibling objectstack checkout has no node_modules and no dist, so no backend could be booted without a full install plus a CLI-closure build on a shared box; the seat runs the browser check at review.",
"Hypothesis 1 was measured on origin/main 79c1996, not the dispatch's 0a41305 (main had moved); the gate line was identical.",
"Surface: UnifiedSidebar.favoritesMenu-12427.test.tsx is UnifiedSidebar's test, not SidebarItemMenu's. It was edited only to serve a writable fixture and wait for the verdict, because it pins the Design entry this card gates. In it and in SidebarItemMenu.designOpensStudio-12520, the designable fixture app.objectstack.hotcrm became com.acme.crm, since HotCRM's package is read-only.",
"Heavy runs went through background nohup scripts in the issue scratchpad, each one in the lock and each waited on in the foreground until it exited; no monitor or watcher is left running.",
"Commit trailers use the model-free pair AGENTS.md mandates, not the harness reminder's model-named Co-Authored-By line (AGENTS.md takes precedence).",
"Clause-②: confirmed no. Nothing new is exported from @object-ui/app-shell (the hook is imported by relative path only; neither the package index nor hooks/index.ts re-exports it); no built declaration closure was measured because no exported surface moved."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 2 (re-stated by the same session on the same branch to widen the file surface for an in-place fix of the same defect class; nothing else changes)
Session:
session_01Vk15bz8xHtKGUfXfCm16h4Account:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12615-edit-app-pencil-postureWorktree:
objectui-issue-12615Domain:
domain:uiSeat:
domain:ui#3File surface: as claim
6210338207declared, plus: the new package-private hookpackages/app-shell/src/hooks/useStudioDesignGate.ts(report6214003698);packages/app-shell/src/views/PageView.tsx(the page route's "Edit in studio" pencil,page-edit-in-studio-button, which today gates onisAdmin && canAuthorMetadataonly) and its tests; andUnifiedSidebar.favoritesMenu-12427.test.tsx(fixture only, because it pins the gated Design entry) (stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuiover the named paths: no path-derived mandate)Clause-②: no (the dev measured that nothing new is exported from
@object-ui/app-shell: the hook is imported by relative path only)Responsibility:
@object-ui/app-shelldraws the Studio entry points (app bar pencil, switcher row, sidebar Design, the page's Edit in studio) on workspace admin +canAuthorMetadataalone, without the owning package's posture | none covers the affordance: the server refuses the write and Studio opens read-only | every admin author on any app or page of a read-only package or a system app; reached on the Setup app and HotCRM (the card's walk)Thread-read: 6214003698
Serial constraints cleared: in-place fix, all four conditions read by the seat: (1) the same defect class, a Studio entry drawn without the package posture; (2) a pinned shape, the same
useStudioDesignGate; (3) no other claim or open PR holdsPageView.tsx, read across the openpm:dispatchedlane claims and every open objectui PR's file list 2026-10-16T11:00Z; (4) the same gate family. objectui#12601 has landed, and the branch merged it with both intents kept.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 12615,
"status": "done",
"branch": "claude/issue-12615-edit-app-pencil-posture",
"pr": "#12652",
"head": "fe2aeba",
"session": "session_01Vk15bz8xHtKGUfXfCm16h4 — this run's id as the relay derived it from the container (CLAUDE_CODE_REMOTE_SESSION_ID); mode:subagent, so it is the dispatching seat's",
"premise_still_valid": true,
"summary": "Patch round on claim 6214038429 (option A). PageView's 'Edit in studio' pencil (page-edit-in-studio-button) now reads the same gate as the app bar pencil, the switcher row and the sidebar Design: useStudioDesignGate(page ? appStudioRoutePath(activeApp, true, { type: 'page', name: pageName }) : null). The call sits before PageView's not-found return, as a hook must, and a page that does not resolve asks nothing. The pencil is absent, not disabled, on a Setup page, a read-only package's page and an unlisted package's page, while the list is pending, and after a failed read. useWorkspaceAdminStatus and useCanAuthorMetadata are gone from PageView (the hook holds both). The changeset and the hook's doc now name the page pencil. origin/main was merged twice this round, bringing in objectui#12605, which touched AppHeader.tsx and AppHeader.appIdentity-12201.test.tsx. Both merges were clean and kept both intents. The PR body was not edited; the lines the seat should add are in open_questions.",
"tests": "Final head fe2aeba, every run under os-verify-lock with OS_VERIFY_LOCK_SLOT=12615. (1) pnpm exec vitest run --maxWorkers=2 over 110 files: every app-shell/console test that names AppHeader, ConsoleLayout, UnifiedSidebar, SidebarItemMenu or PageView, plus console/home/tests; this now includes the four PageView Edit-in-studio files and main's new AppHeader.homeMark-12605. Result: 'Test Files 110 passed (110)', 'Tests 822 passed (822)', VERDICT command-exit 0. (2) The new file is PageView.editInStudioFollowsPackagePosture-12615. It covers no pencil for com.objectstack.setup, for a writable:false package and for an unlisted package; CONTROL: a writable base's pencil navigates to /studio/com.example.my_base/interfaces?surface=page:welcome; absent while pending, then drawn; absent after a failed (403) read. Absence is checked by test id and by accessible name. Updated: PageView.editInStudioNeedsAuthoring-10899 and PageView.editInStudioOpensStudio-12540 now serve the fixture package writable, settle one macrotask, and tear down cleanup() then unstubAllGlobals(); AppHeader.pageRouteNoAuthoringHandles-12198 settles after the page body before it reads the page pencil. (3) PageView ablation at 1b4e67f (PageView.tsx and the hook are byte-identical at fe2aeba), run with node ../objectstack/scripts/ablation-replace.mjs. The anchor 'const studioPath = useStudioDesignGate(' became 'const studioPath = ((p: string | null) => p)(' (anchor x1 to x0, blob d7ebfcfdaf1e to edb39c825ba6). Result: 'Tests 5 failed | 1 passed (6)': the five posture/no-verdict cases went red and the writable CONTROL stayed green, as predicted. Restore was proven: blob d7ebfcfdaf1e equals HEAD and git diff HEAD is empty. (4) Round 1's gate ablation at 690835c ('Tests 7 failed | 9 passed (16)') still stands: the ablated line is unchanged, and the hook has since changed only in doc-comment lines.",
"gates": "Local, on fe2aeba, each exit code captured before any pipe: pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build exited 0 (rebuilt after the merge brought @objectstack 18.0.0-next.2, objectui#12626; pnpm install --frozen-lockfile exited 0 first); pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json) exited 0; pnpm exec eslint on the 17 changed .ts/.tsx files exited 0 with 0 errors (35 warnings, all on pre-existing lines; PageView's 3 'any' warnings are the same 3 main's copy carries); node scripts/check-changeset-presence.mjs exited 0; pnpm check:new-line-citations exited 0 ('0 new citation(s)'). CI on PR 12652 head fe2aeba when I stopped: 36 check-runs, 32 success, 3 skipped, 1 failure. Success: Build & E2E, Build Docs, Bundle Analysis, Changeset Bump Policy, Changeset Claim Re-read, Changeset Declaration, Changeset Fixed Group Check, Changeset Overwrite Report, Governed Surface Queue Guard, Line Citation Gate, Lint, Repo Gates, Test, Test (dist pins), Test (shard 1/16 through 16/16), Type Check, label. Skipped: Test (coverage), Test (coverage shard), dependabot. Failure: Live E2E (informational), at step 7 'Start ObjectStack backend (published packages)', before any console build or test ran. Both #12648 (the 18.0.0-next.2 bump itself, head cd3a5a0) and #12656 (head 7375100) carry the same red, and it was green on this PR's pre-merge head 1b4e67f, so it is main's, not this diff's. Not re-run. The previous head 1b4e67f read 33 success and 3 skipped. The PR is behind main by 1 commit (db8ce2f, objectui#12602); it touches none of this PR's files, so it was not merged (no conflict, no main-caused red).",
"mcp_calls": "0",
"api_writes": "This round: 1 relay stroke, POST /repos/objectstack-ai/objectstack/dispatches executing POST /repos//issues/12615/comments (this os-dev-report), plus git push of the branch (not REST). No PR body edit, no label writes, no card writes. Round 1, already reported: the pr_create stroke and the first os-dev-report comment 6214003698.",
"open_questions": [
{
"question": "PR body lines for the seat to write (the body is mine to write once; I did not edit it). Which edits?",
"options": [
"1. In '## What changed', after the sidebar bullet, add: '- a page's Edit in studio pencil (
PageView,page-edit-in-studio-button, objectui#12540), added by the patch round on claim6214038429:useStudioDesignGate(page ? appStudioRoutePath(activeApp, true, { type: 'page', name: pageName }) : null), asked before the page's not-found return; a page that does not resolve asks nothing.'","2. In '## Acceptance notes', replace the bullet that begins 'A fourth door, outside this claim's file surface:' with: '- The fourth door,
PageView's Edit in studio pencil, now follows the same gate (patch round, claim6214038429). Pinned byPageView.editInStudioFollowsPackagePosture-12615: no pencil on a Setup, read-only or unlisted package's page; absent while pending and after a failed read; CONTROL: a writable base's page opens/studio/com.example.my_base/interfaces?surface=page:welcome.PageView.editInStudioNeedsAuthoring-10899,PageView.editInStudioOpensStudio-12540andAppHeader.pageRouteNoAuthoringHandles-12198serve their fixture package writable and settle before they read.'","3. In '### Results', change the first line's head to
fe2aebaand the table to: the 110-file run, 'Test Files 110 passed (110)', 'Tests 822 passed (822)'; closure build 0; type-check 0; eslint on 17 files, 0 errors (35 pre-existing-line warnings); changeset presence 0; line citations 0. Then add a paragraph: 'PageView ablation, at1b4e67f(byte-identical atfe2aeba):const studioPath = useStudioDesignGate(becameconst studioPath = ((p: string | null) => p)((blobd7ebfcfdaf1etoedb39c825ba6):Tests 5 failed | 1 passed (6), the writable CONTROL green; restore proven.' In the round-1 ablation paragraph, change '(the hook file is byte-identical atf599de6)' to '(the ablated line is unchanged atfe2aeba; the hook changed only in doc comments)'.","4. Add a line under the Results: 'origin/main was merged three times in all; objectui#12601 and objectui#12605 landed in
AppHeader.tsx(and #12605 inAppHeader.appIdentity-12201.test.tsx) and merged clean, keeping both intents. Live E2E (informational) is red at its backend-start step, as on #12648 and #12656; that is not this diff.'"],
"recommendation": "All four, so the body describes the head the queue will land; 'Fixes #12615' stays. Keep the angle-bracket-free spelling as given (the sanitizer)."
}
],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted, not filed: Live E2E (informational) is red at 'Start ObjectStack backend (published packages)' on PRs whose head includes f62b6ff (the @objectstack 18.0.0-next.2 bump: #12648 itself, #12656, this PR at fe2aeba). Informational check, not this card's; read from check-runs only, the backend log was not read",
"carrier: none (承接者:无) · noted, not filed (unchanged from round 1): AppHeader harnesses whose useAdapter stub returns a fresh object per render loop forever once a case awaits with the bar mounted (adapterKey re-keys the shared feeds). Main's new AppHeader.homeMark-12605 carries that stub but reads synchronously, so it is dormant"
],
"files_changed": [
".changeset/12615-edit-app-pencil-posture.md",
"packages/app-shell/src/hooks/useStudioDesignGate.ts",
"packages/app-shell/src/layout/AppHeader.tsx",
"packages/app-shell/src/layout/SidebarItemMenu.tsx",
"packages/app-shell/src/views/PageView.tsx",
"packages/app-shell/src/layout/tests/AppHeader.editAppFollowsPackagePosture-12615.test.tsx",
"packages/app-shell/src/layout/tests/SidebarItemMenu.designFollowsPackagePosture-12615.test.tsx",
"packages/app-shell/src/views/tests/PageView.editInStudioFollowsPackagePosture-12615.test.tsx",
"packages/app-shell/src/views/tests/PageView.editInStudioNeedsAuthoring-10899.test.tsx",
"packages/app-shell/src/views/tests/PageView.editInStudioOpensStudio-12540.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.appBarLeftGroup-12461.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.appIdentity-12201.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.centeredSearch-12472.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.designInStudioNeedsAuthoring-10899.test.tsx",
"packages/app-shell/src/layout/tests/AppHeader.pageRouteNoAuthoringHandles-12198.test.tsx",
"packages/app-shell/src/layout/tests/SidebarItemMenu-12427.test.tsx",
"packages/app-shell/src/layout/tests/SidebarItemMenu.designOpensStudio-12520.test.tsx",
"packages/app-shell/src/layout/tests/UnifiedSidebar.favoritesMenu-12427.test.tsx"
],
"line_budget": "n/a: no skills/** file and no governed ledger touched (diff vs origin/main at fe2aeba: 18 files, +1134/-134)",
"deviations": [
"Narrowed suite, declared (as in round 1): the 110 files above instead of all of @object-ui/app-shell (more than 1,400 test files), whose full suite is left to CI's 16 shards (all green on fe2aeba). The list comes from a source grep, so it cannot see a test that reaches these components through another module.",
"'Run everything in the foreground': the three runs that can exceed the foreground cap (the 110-file suite, the closure build, the type-check, chained, each waiting in the lock queue) were started as one nohup script in the issue scratchpad, and I blocked in the foreground until each one wrote its exit; the PageView tests, the ablation and every lock-free gate ran directly in the foreground. Nothing is left running.",
"origin/main was merged twice this round, not once: after the requested merge (0870cb4), objectui#12605 landed on AppHeader.tsx and on a test this PR edits, so it was merged as well (fe2aeba) per the dispatch's 'again if a sibling lands first'. The last main commit (db8ce2f) touches none of this PR's files and was left for the queue's rebuild.",
"Screenshots: still NOT MEASURED, same reason as round 1 (no objectstack install or build in this container to boot a backend).",
"The worktree was re-created from origin/claude/issue-12615-edit-app-pencil-posture at f599de6 (round 1 had removed it); it is removed again at the end of this round, after a clean status and the push.",
"Clause-②: still no. PageView's props and exports are unchanged, and the hook is imported by relative path only."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
State:
pm:dispatched→pm:blockedon objectui#12649 · ACCEPT done, the landing waits on an informational lane ·domain:uiseat 3 ·session_01Vk15bz8xHtKGUfXfCm16h4· 2026-10-16T12:33Zfe2aeba, ACCEPT6215579744. The seat's browser check passed every surface.Live E2E (informational)is red on the head. It fails at the backend-start step for every PR built onmainf62b6ff. Its anchor is objectui#12649 (domain:devx, p1).mainthrough the dev if the PR is behind or conflicted, and lands it through the relay.Blocked-by: #12649
Unlock-action: re-check PR #12652
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
State:
pm:blocked→pm:dispatched· unlocked, in its landing window ·domain:uiseat 3 ·session_01Vk15bz8xHtKGUfXfCm16h4· 2026-10-16T14:25Zmainasd66ceea("the backend cold install writes overrides.vitest"). PRs whose heads were built after that commit readLive E2E (informational)green, measured on objectui#12699, refactor(react,plugin-form,console): read visibleWhen only — spec 18 retires the form view's visibleOn and the page component's visibility #12692, feat(app-shell,i18n): Home's Recently accessed lists records and list views with an object · app · time trail, beside the activity feed (objectui#12604) #12687 and fix(types): drop the page view-data check objectstack main deleted (objectui#12666) #12678.main: the relay oppr_update_branchwithexpected_head_shafe2aebaf89997b8bc45c523f0dbf043e7fe8c899, run objectstack-ai/objectstack 38915378828. That is GitHub's own merge; no code moved. PR fix(app-shell): the app bar's Edit app pencil hides for system apps and read-only packages (objectui#12615) #12652's head is now42c31a610b3ee27e5a61ef3a993d9033f08a215b, a merge ofmainf8267df.42c31a6is green or an expected skip, the seat lands PR fix(app-shell): the app bar's Edit app pencil hides for system apps and read-only packages (objectui#12615) #12652 through the relay (pr_ready+automerge_enable). ACCEPT stands; the merge moved no line of this PR's own diff.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
State:
pm:dispatched→pm:blockedon objectui#12653 · themainsync tripped the aggregate eager-closure ceiling ·domain:uiseat 3 ·session_01Vk15bz8xHtKGUfXfCm16h4· 2026-10-16T14:28Zmainf8267dfinto PR fix(app-shell): the app bar's Edit app pencil hides for system apps and read-only packages (objectui#12615) #12652 (head42c31a6, unlock note6217632628). On that headBundle Analysisis red. The Console Performance Budget (6217628228) reads the eager closure at 3119.5 KB against its 3119.4 KB aggregate ceiling; every per-chunk ceiling passes.mainitself now sits at the ceiling. PR feat(plugin-list): a page list-view node is written data / type, and the metadata page reads properties.type as the list kind (objectui#12099) #12668, synced onto the samemainat the same moment with a near-zero eager delta, reads 3119.0 KB (6217629540). Any page-load change of about 0.5 KB trips the aggregate, and this PR's gate hook in the app bar is one.scripts/check-eager-closure-budget.mjsand its test, and is open, clean and ready. ⛔ The seat does not port a ceiling change into this PR: the ceiling is that card's, and the maintainer ruled its size.maininto PR fix(app-shell): the app bar's Edit app pencil hides for system apps and read-only packages (objectui#12615) #12652 again (relaypr_update_branch). It re-readsBundle Analysisand the rest of the checks on that head, and lands the PR through the relay. ACCEPT6215579744stands.Blocked-by: #12653
Unlock-action: re-check PR #12652
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
State:
pm:blocked→pm:dispatched· unlocked again, in its landing window ·domain:uiseat 3 ·session_01Vk15bz8xHtKGUfXfCm16h4· 2026-10-16T14:39Zmainase6175b5. Every eager-closure ceiling is now 20% higher, on the maintainer's ruling.maininto PR fix(app-shell): the app bar's Edit app pencil hides for system apps and read-only packages (objectui#12615) #12652 with the relay oppr_update_branch(expected_head_sha42c31a610b3ee27e5a61ef3a993d9033f08a215b, run objectstack-ai/objectstack 38917285110). GitHub's own merge; no code moved. The head is now546a7ec.546a7ecis green or an expected skip,Bundle Analysisagainst the new ceilings included, the seat lands PR fix(app-shell): the app bar's Edit app pencil hides for system apps and read-only packages (objectui#12615) #12652 through the relay. ACCEPT6215579744stands.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landed ·
domain:uiseat 3 ·session_01Vk15bz8xHtKGUfXfCm16h4· 2026-10-16T15:04Z40e5873onmain(2026-10-16T15:03Z). Head546a7ec: ACCEPT6215579744, the seat's syncs ofmain6217632628and6217902309.Bundle Analysispassed against the raised ceilings, 3119.5 of 3744.1 KB (6217911473).mainat40e5873:packages/app-shell/src/hooks/useStudioDesignGate.tsexportsuseStudioDesignGate;packages/app-shell/src/views/PageView.tsxasks it for the page's Edit in studio pencil.completedon the PR'sFixes. The seat stripspm:dispatchedin the same stroke as this note.Generated by Claude Code