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 }}
Repository navigation
Bind the in-app assistant dock's build thread to the current app (reverses ADR-0057 A1.b per maintainer ruling) #10926
objectui#10899 item 4 (epic objectstack-ai/cloud#2440). When the maker opens the in-app assistant inside app 「客户管理」, the dock's build header chip reads 「构建 · 新建应用」. The dock uses the app-less, product-only build scope and sends no packageId, so the agent has to infer which app to edit.
The PR #10924 dev root-caused it and deferred it because it reverses ADR-0057 Amendment A1.b.
As presented: inside an authorable app (package not com.objectstack.*), when the resolved agent is build, the dock binds its build thread to that app. That means editPackageId is the app's package and the scope is app:PKG:build.
The chip, the empty state and the agent context name the app.
The dock, /ai/build?package=PKG and the Studio copilot share one thread; Maximize goes to /ai/build?package=PKG.
ask stays ambient.
Existing ambient build threads stay reachable in the /ai sidebar.
Delivery shape
ADR amendment. An amendment to docs/adr/0057-console-ai-chat-one-conversation-docked.md records the reversal of the A1.b "dock keeps the legacy product-only key" line, citing this ruling.
docs/adr/** is a governed surface, so it is its own draft PR that the maintainer merges.
Do not mix it into the code PR.
Code PR. Implements the binding.
Reuse editPackageId / chatConversationScope; add no new surface.
Tests pin the chip text inside an app, the scope key, thread sharing with /ai/build?package=, and ask staying ambient.
Acceptance
Inside app X, the dock's build chip names X, and the build request carries X's package id.
Opening /ai/build?package=X shows the same thread.
Outside any authorable app, behaviour is unchanged.
Claim: PM loop round 2
Session: session_015AUunPkX7UTkCH9e7AdZo1
Account: os-zhuang (the seat's linked user as GET /user answers it; the maintainer authorised this seat to run on it, verbatim 「允许你用当前账户继续开发」, seat-post marker 5864093687)
Branch: claude/issue-10926-dock-binds-app
Worktree: objectui-issue-10926
Domain: domain:ui
Seat: domain:ui#4
File surface: code PR on the branch above: packages/app-shell/src/layout/ChatDock.tsx, packages/app-shell/src/hooks/chatScope.ts and, where the thread sharing needs it, hooks/useChatConversation.ts and console/ai/AiChatPage.tsx (the build-thread scope and ?package= path only), plus tests beside each, the chip copy in packages/i18n/src/locales/*.ts if it changes, and one .changeset/10926-*.md. ADR PR, separate, on claude/issue-10926-adr-0057-dock-binding: docs/adr/0057-console-ai-chat-one-conversation-docked.md only (governed, Tier H: it stays draft for the maintainer). Stop on breach; explain in the report.
Container & model: M, mode:subagent, model: opus (default judgement tier; dispatch-gates --tier --repo objectstack-ai/objectui on these paths: no path-derived mandate)
Clause-②: no
Thread-read: none
Serial constraints cleared: read at 2026-09-28T09:10Z against objectui main1dae95a, covering the 19 open PRs' files and the claims on the lane's open pm:dispatched cards. objectui#10900 (seat 1, os-steve, claim 5866735286) holds the Build Doctor button and drawer title in console/ai/AiChatPage.tsx. That is a different region of that file: this card touches only the build-thread scope there, if anything. Merge main before opening the PR; the later lander resolves any textual conflict. PR objectui#10924 (epic objectui#10899) holds plugin-chatbot/src/ChatbotEnhanced.tsx, which this card does not touch.
Take order: p1. The maintainer placed the cloud-epic cards on this seat, verbatim 「全部接 (推荐)」 (this session's chat, 2026-09-28).
Ruling: the maintainer ruling is verbatim in the card body, 「绑定当前应用(推荐)」 (epic session, 2026-09-28), with its stated terms. No separate ruling comment exists.
Clause-② reasoning: the card says to reuse editPackageId / chatConversationScope and add no new surface. Neither symbol's export changes, and no published accept set moves. The ADR amendment is governed rule text: it gets an at-tier contract review and the maintainer's merge regardless.
Premise re-read:docs/adr/0057-console-ai-chat-one-conversation-docked.md L334–346, A1.b ("Shipped (#2466)"): "the legacy product-only key is not cleared (dock/FAB and bare /ai/build keep resolving through it)". The ruling reverses that clause for the dock inside an authorable app.
{
"issue": 10926,
"status": "done",
"branch": "claude/issue-10926-dock-binds-app",
"pr": "https://github.com/objectstack-ai/objectui/pull/10950",
"session": "session_015AUunPkX7UTkCH9e7AdZo1 — this run's harness-stamped id (mode:subagent, the parent seat's; container CLAUDE_CODE_REMOTE_SESSION_ID cse_015AUunPkX7UTkCH9e7AdZo1)",
"premise_still_valid": true,
"summary": "Code PR #10950 (draft, Fixes #10926): inside an authorable app (package not com.objectstack.*, the A1.b switcher's isPlatformBuiltinApp), a dock resolved to build passes the app's package as editPackageId, so the scope is app:PKG:build (Studio copilot and /ai/build?package=PKG share it), the chip, the edit-mode empty state and context.packageId name the app, and Maximize opens /ai/build?package=PKG with the Studio door's one-shot opt-out. ask, built-in apps and no app keep the product-only key; the dock runs the same A1.b migration read as the ?package= entry (predicate extracted as isThreadBoundToPackage) and hands its pane only a scope-matched conversation. ADR PR #10947 (draft, governed, Part of #10926) adds ADR-0057 Amendment A2 quoting the ruling verbatim and reversing only the dock half of A1.b's product-only-key clause. Card premise re-verified on base af2221d: ChatDock passed appId undefined and no packageId.",
"prs": {
"code": { "url": "https://github.com/objectstack-ai/objectui/pull/10950", "branch": "claude/issue-10926-dock-binds-app", "head": "8d4efd6", "draft": true, "first_line": "Fixes #10926", "assignee": "os-zhuang", "governed": "NOT GOVERNED" },
"adr": { "url": "https://github.com/objectstack-ai/objectui/pull/10947", "branch": "claude/issue-10926-adr-0057-dock-binding", "head": "4a66540", "draft": true, "first_line": "Part of #10926", "assignee": "os-zhuang", "governed": "GOVERNED (stays draft for the maintainer)" }
},
"files_changed": {
"code_pr_10950": [
".changeset/10926-dock-binds-build-thread-to-app.md",
"packages/app-shell/src/console/ai/AiChatPage.tsx",
"packages/app-shell/src/hooks/chatScope.ts",
"packages/app-shell/src/layout/ChatDock.tsx",
"packages/app-shell/src/layout/ConsoleLayout.tsx",
"packages/app-shell/src/layout/__tests__/ChatDock.appBinding-10926.test.tsx",
"packages/app-shell/src/layout/__tests__/ConsoleLayout.dockBinding-10926.test.tsx"
],
"adr_pr_10947": ["docs/adr/0057-console-ai-chat-one-conversation-docked.md"]
},
"tests": "Code head 8d4efd6 (main 5c94589 merged): dep closure turbo build --filter=@object-ui/app-shell^... 28/28 successful; pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json) exit 0, both new test files in the test program per --listFilesOnly; pnpm exec vitest run --maxWorkers=2 over layout/__tests__, console/ai/__tests__, console/__tests__, views/studio-design/__tests__, chrome, hooks/__tests__/{chatScope,useChatConversation,surfaceAgent} and two src/__tests__ pins: Test Files 102 passed (102), Tests 750 passed (750), exit 0. New: ChatDock.appBinding-10926 (11 tests, real dock body + ChatPane + useChatConversation + AiChatPage over a fetch stub) and ConsoleLayout.dockBinding-10926 (3 tests). Full 844-file app-shell suite not run locally (CI). Ablations, each committed first, mutated via objectstack scripts/ablation-replace.mjs with counts registered before the run, restore proven blob == HEAD and git diff HEAD empty, no dist in the path (relative imports): (1) binding off, anchor product === 'build' && appPackageId: expected 8 failed / 3 passed, observed 8 failed / 3 passed; an earlier attempt was refused by the tool (replacement contained the anchor) and ran nothing; (2) scope gate off: expected 1/10, observed 1 failed / 10 passed; (3) ConsoleLayout bound-maximize branch off: expected 1/2, observed 1 failed / 2 passed.",
"gates": {
"code_pr_10950_head_8d4efd6": {
"check-changeset-presence": 0,
"check-changeset-no-major": 0,
"check-governed-queue-guard --test (7 paths)": "0 NOT GOVERNED",
"check:new-line-citations": 0,
"check:control-bytes": 0,
"check:vi-mock-specifiers": 0,
"check:vi-mock-inherit": 0,
"check:vi-mock-override-shape": 0,
"check:changeset-claims": 0,
"check:pending-changeset-literals": 0,
"check:i18n-keys": 0,
"check:test-path-roots": 0,
"check:unreferenced-sources": 0,
"check:self-import": 0,
"check:phantom-deps": 0,
"app-shell type-check": 0,
"eslint --no-inline-config on 6 changed TS/TSX files": "0 (0 errors; population = eslint.config.js **/*.{ts,tsx}; file count 6 from --format json; no parserOptions.project/projectService and the one custom rule reads no files, so untouched verdicts cannot move; vs base: +1 react-refresh/only-export-components warning for the new exported predicate, 12 of that class already in AiChatPage.tsx, no warning ratchet)",
"check:i18n-drift / check:i18n-dead-keys": "not run: no locale file or key moved"
},
"adr_pr_10947_head_4a66540": {
"check-governed-queue-guard --test docs/adr/0057-...md": "3 GOVERNED",
"check-changeset-presence": "0 (no changeset owed)",
"check-new-cross-file-line-citations": 0,
"check-control-bytes": 0,
"check:doc-snippet-types": "not run: reads code fences under docs/adr, and the diff adds none"
},
"ci_at_report": "code 8d4efd6: 42 check runs, 23 success, 3 skipped, 16 in_progress; adr 4a66540: 39 check runs, 36 success, 3 skipped. PM owns convergence."
},
"deviations": [
"Claim file surface breached by one file: packages/app-shell/src/layout/ConsoleLayout.tsx (two appPackageId prop lines + the maximize target) plus its test ConsoleLayout.dockBinding-10926.test.tsx. The surface was derived from the Zone 2 assumption that editPackageId is read in ChatDock.tsx; measured on af2221d it was not (ChatDock passed appId undefined), and the current app (activeApp) and the maximize navigation (openDockFullPage) exist only in ConsoleLayout.tsx. Conflict named, not silently resolved: the claim says stop on breach; os-dev.md says a falsified mechanism assumption changes route per the ruling's intent, and os-dev.md wins on conflict. Overlap measured: PR #10924 (since landed) touched a different hunk of ConsoleLayout.tsx (the FAB line); main merged twice (7e8b3c0, 5c94589), both clean.",
"Beyond Studio-copilot parity, the dock also runs the A1.b migration read (legacyScope build + adoptLegacy); without it a dock that resolves first would mint app:PKG:build and pre-empt the ?package= entry's adoption of a product-only thread bound to PKG, silencing a shipped A1.b behaviour. Predicate extracted in AiChatPage.tsx (build-thread-scope region only; the Build Doctor region #10900 holds is untouched).",
"Commit trailers are the model-free pair objectui AGENTS.md requires (Claude-Session + Co-authored-by: Claude); the harness reminder's model-named form was not used, its precedence sentence yields to AGENTS.md.",
"Zone 2 reading 'A1.b at L334-346' confirmed by content; no line address is cited in the ADR text (AGENTS.md #11)."
],
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "5 — all via objectstack scripts/pm/fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create → POST /repos/objectstack-ai/objectui/pulls (#10947); pr_create → POST /repos/objectstack-ai/objectui/pulls (#10950); label-write assign → POST /repos/objectstack-ai/objectui/issues/10950/assignees; label-write assign → POST /repos/objectstack-ai/objectui/issues/10947/assignees; comment → POST /repos/objectstack-ai/objectui/issues/10926/comments (this report). git push to both branches is not REST.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted in PR #10950 Acceptance notes, not filed · isPlatformBuiltinApp (the ruling's authorable test, shared with the A1.b switcher) does not exclude the DB-authored sys_metadata pseudo-package that appRoute.ts studioPackageId refuses; an app list item carrying _packageId sys_metadata would bind to app:sys_metadata:build and send packageId sys_metadata. Read-only inference, no reach measured · dedupe words: sys_metadata authorable isPlatformBuiltinApp build thread"
],
"cleanup": "both worktrees removed after node_modules deletion; private refs refs/issue-10926/* deleted; scratch files holding PR bodies deleted"
}
File-surface supplement to the claim 5866972381, same session, same branches, at 2026-09-28T10:23Z. ⛔ Not a second claim. It also corrects this seat in the open.
Added:packages/app-shell/src/layout/ConsoleLayout.tsx (the appPackageId hand-off to the dock and the Maximize target) and its test packages/app-shell/src/layout/__tests__/ConsoleLayout.dockBinding-10926.test.tsx.
The seat's assumption was wrong. The dispatch's Zone 2 said editPackageId is read in layout/ChatDock.tsx. Measured by the dev on objectui af2221d: ChatDock passed appId undefined and no package. The current app (activeApp) and the maximize navigation (openDockFullPage) exist only in ConsoleLayout.tsx. The dev changed route under the ruling's intent and declared the breach in its report, which is the right call. The file surface is corrected here, not in the dev's favour after the fact.
Escalated open point, carried to the maintainer digest: the authorable test isPlatformBuiltinApp (a com.objectstack. prefix check) does not exclude the DB-authored sys_metadata pseudo-package that appRoute.ts's studioPackageId refuses. It is the same function the A1.b switcher already uses, so the dock inherits an existing gap and adds no new one. Reach is unmeasured. The seat does not hold the ADR on it.
Governed finish:needs-user-decision on the PR, the final maintainer digest (维护者速读) on the PR, and review requested from os-zhuang and hotlong. The digest's button label is corrected to 「以完整页面打开」, the zh string of console.ai.dock.maximize.
ACCEPT — code half, PR #10950 @ 8d4efd6 — held until the ADR PR #10947 merges
domain:ui seat 4, session_015AUunPkX7UTkCH9e7AdZo1, at 2026-09-28T10:41Z. Checked against GitHub and origin/main, not against the report.
Form: draft, base main, body first line Fixes #10926. 7 files, +710/−39: ChatDock.tsx, ConsoleLayout.tsx, AiChatPage.tsx, chatScope.ts (documentation only), two pins, and .changeset/10926-dock-binds-build-thread-to-app.md. All are inside the claim's surface as supplemented in 5868060731. Nothing under content/docs/releases/.
CI on the head 8d4efd6e40: 43 check-runs, 40 success and 3 skipped, none failed. mergeable_state: clean. Governed-surface guard (scripts/check-governed-queue-guard.mjs --test, 7 paths): NOT GOVERNED.
Contract review: PASS at CONTRACT_REVIEW_TIER on this head, 5868286370. Each ruling term and each Amendment A2 bullet is judged right, and every factual sentence of the changeset is true. @object-ui/app-shellminor matches a behaviour addition with no entry export, removal or rename. Clause-②: no holds.
Spot readings (seat's own):ChatDock.tsx sets editPackageId only when the product is build, appPackageId is set and !isPlatformBuiltinApp({ _packageId: appPackageId }). It keys chatConversationScope({ appId: editPackageId, product }). The legacy read (legacyScope: product, adoptLegacy through the shared isThreadBoundToPackage) runs only when bound. scopeMatched keeps the previous app's thread off the pane after an app switch. Acceptance items 1 to 4 are each pinned in ChatDock.appBinding-10926.test.tsx.
Noted, pre-existing: the bound chip in the dock is still ChatPane's switcher, so choosing another app in it leaves the current app page. Nothing is filed.
Activity
objectstack-fleet commentedon Sep 28, 2026
Claim: PM loop round 2
Session:
session_015AUunPkX7UTkCH9e7AdZo1Account:
os-zhuang(the seat's linked user asGET /useranswers it; the maintainer authorised this seat to run on it, verbatim 「允许你用当前账户继续开发」, seat-post marker5864093687)Branch:
claude/issue-10926-dock-binds-appWorktree:
objectui-issue-10926Domain:
domain:uiSeat:
domain:ui#4File surface: code PR on the branch above:
packages/app-shell/src/layout/ChatDock.tsx,packages/app-shell/src/hooks/chatScope.tsand, where the thread sharing needs it,hooks/useChatConversation.tsandconsole/ai/AiChatPage.tsx(the build-thread scope and?package=path only), plus tests beside each, the chip copy inpackages/i18n/src/locales/*.tsif it changes, and one.changeset/10926-*.md. ADR PR, separate, onclaude/issue-10926-adr-0057-dock-binding:docs/adr/0057-console-ai-chat-one-conversation-docked.mdonly (governed, Tier H: it stays draft for the maintainer). Stop on breach; explain in the report.Container & model:
M,mode:subagent,model: opus(default judgement tier;dispatch-gates --tier --repo objectstack-ai/objectuion these paths: no path-derived mandate)Clause-②: no
Thread-read: none
Serial constraints cleared: read at 2026-09-28T09:10Z against objectui
main1dae95a, covering the 19 open PRs' files and the claims on the lane's openpm:dispatchedcards. objectui#10900 (seat 1,os-steve, claim5866735286) holds the Build Doctor button and drawer title inconsole/ai/AiChatPage.tsx. That is a different region of that file: this card touches only the build-thread scope there, if anything. Mergemainbefore opening the PR; the later lander resolves any textual conflict. PR objectui#10924 (epic objectui#10899) holdsplugin-chatbot/src/ChatbotEnhanced.tsx, which this card does not touch.Take order: p1. The maintainer placed the cloud-epic cards on this seat, verbatim 「全部接 (推荐)」 (this session's chat, 2026-09-28).
Ruling: the maintainer ruling is verbatim in the card body, 「绑定当前应用(推荐)」 (epic session, 2026-09-28), with its stated terms. No separate ruling comment exists.
Clause-② reasoning: the card says to reuse
editPackageId/chatConversationScopeand add no new surface. Neither symbol's export changes, and no published accept set moves. The ADR amendment is governed rule text: it gets an at-tier contract review and the maintainer's merge regardless.Premise re-read:
docs/adr/0057-console-ai-chat-one-conversation-docked.mdL334–346, A1.b ("Shipped (#2466)"): "the legacy product-only key is not cleared (dock/FAB and bare/ai/buildkeep resolving through it)". The ruling reverses that clause for the dock inside an authorable app.Generated by Claude Code
objectstack-fleet commentedon Sep 28, 2026
os-dev-report
{ "issue": 10926, "status": "done", "branch": "claude/issue-10926-dock-binds-app", "pr": "https://github.com/objectstack-ai/objectui/pull/10950", "session": "session_015AUunPkX7UTkCH9e7AdZo1 — this run's harness-stamped id (mode:subagent, the parent seat's; container CLAUDE_CODE_REMOTE_SESSION_ID cse_015AUunPkX7UTkCH9e7AdZo1)", "premise_still_valid": true, "summary": "Code PR #10950 (draft, Fixes #10926): inside an authorable app (package not com.objectstack.*, the A1.b switcher's isPlatformBuiltinApp), a dock resolved to build passes the app's package as editPackageId, so the scope is app:PKG:build (Studio copilot and /ai/build?package=PKG share it), the chip, the edit-mode empty state and context.packageId name the app, and Maximize opens /ai/build?package=PKG with the Studio door's one-shot opt-out. ask, built-in apps and no app keep the product-only key; the dock runs the same A1.b migration read as the ?package= entry (predicate extracted as isThreadBoundToPackage) and hands its pane only a scope-matched conversation. ADR PR #10947 (draft, governed, Part of #10926) adds ADR-0057 Amendment A2 quoting the ruling verbatim and reversing only the dock half of A1.b's product-only-key clause. Card premise re-verified on base af2221d: ChatDock passed appId undefined and no packageId.", "prs": { "code": { "url": "https://github.com/objectstack-ai/objectui/pull/10950", "branch": "claude/issue-10926-dock-binds-app", "head": "8d4efd6", "draft": true, "first_line": "Fixes #10926", "assignee": "os-zhuang", "governed": "NOT GOVERNED" }, "adr": { "url": "https://github.com/objectstack-ai/objectui/pull/10947", "branch": "claude/issue-10926-adr-0057-dock-binding", "head": "4a66540", "draft": true, "first_line": "Part of #10926", "assignee": "os-zhuang", "governed": "GOVERNED (stays draft for the maintainer)" } }, "files_changed": { "code_pr_10950": [ ".changeset/10926-dock-binds-build-thread-to-app.md", "packages/app-shell/src/console/ai/AiChatPage.tsx", "packages/app-shell/src/hooks/chatScope.ts", "packages/app-shell/src/layout/ChatDock.tsx", "packages/app-shell/src/layout/ConsoleLayout.tsx", "packages/app-shell/src/layout/__tests__/ChatDock.appBinding-10926.test.tsx", "packages/app-shell/src/layout/__tests__/ConsoleLayout.dockBinding-10926.test.tsx" ], "adr_pr_10947": ["docs/adr/0057-console-ai-chat-one-conversation-docked.md"] }, "tests": "Code head 8d4efd6 (main 5c94589 merged): dep closure turbo build --filter=@object-ui/app-shell^... 28/28 successful; pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json) exit 0, both new test files in the test program per --listFilesOnly; pnpm exec vitest run --maxWorkers=2 over layout/__tests__, console/ai/__tests__, console/__tests__, views/studio-design/__tests__, chrome, hooks/__tests__/{chatScope,useChatConversation,surfaceAgent} and two src/__tests__ pins: Test Files 102 passed (102), Tests 750 passed (750), exit 0. New: ChatDock.appBinding-10926 (11 tests, real dock body + ChatPane + useChatConversation + AiChatPage over a fetch stub) and ConsoleLayout.dockBinding-10926 (3 tests). Full 844-file app-shell suite not run locally (CI). Ablations, each committed first, mutated via objectstack scripts/ablation-replace.mjs with counts registered before the run, restore proven blob == HEAD and git diff HEAD empty, no dist in the path (relative imports): (1) binding off, anchor product === 'build' && appPackageId: expected 8 failed / 3 passed, observed 8 failed / 3 passed; an earlier attempt was refused by the tool (replacement contained the anchor) and ran nothing; (2) scope gate off: expected 1/10, observed 1 failed / 10 passed; (3) ConsoleLayout bound-maximize branch off: expected 1/2, observed 1 failed / 2 passed.", "gates": { "code_pr_10950_head_8d4efd6": { "check-changeset-presence": 0, "check-changeset-no-major": 0, "check-governed-queue-guard --test (7 paths)": "0 NOT GOVERNED", "check:new-line-citations": 0, "check:control-bytes": 0, "check:vi-mock-specifiers": 0, "check:vi-mock-inherit": 0, "check:vi-mock-override-shape": 0, "check:changeset-claims": 0, "check:pending-changeset-literals": 0, "check:i18n-keys": 0, "check:test-path-roots": 0, "check:unreferenced-sources": 0, "check:self-import": 0, "check:phantom-deps": 0, "app-shell type-check": 0, "eslint --no-inline-config on 6 changed TS/TSX files": "0 (0 errors; population = eslint.config.js **/*.{ts,tsx}; file count 6 from --format json; no parserOptions.project/projectService and the one custom rule reads no files, so untouched verdicts cannot move; vs base: +1 react-refresh/only-export-components warning for the new exported predicate, 12 of that class already in AiChatPage.tsx, no warning ratchet)", "check:i18n-drift / check:i18n-dead-keys": "not run: no locale file or key moved" }, "adr_pr_10947_head_4a66540": { "check-governed-queue-guard --test docs/adr/0057-...md": "3 GOVERNED", "check-changeset-presence": "0 (no changeset owed)", "check-new-cross-file-line-citations": 0, "check-control-bytes": 0, "check:doc-snippet-types": "not run: reads code fences under docs/adr, and the diff adds none" }, "ci_at_report": "code 8d4efd6: 42 check runs, 23 success, 3 skipped, 16 in_progress; adr 4a66540: 39 check runs, 36 success, 3 skipped. PM owns convergence." }, "deviations": [ "Claim file surface breached by one file: packages/app-shell/src/layout/ConsoleLayout.tsx (two appPackageId prop lines + the maximize target) plus its test ConsoleLayout.dockBinding-10926.test.tsx. The surface was derived from the Zone 2 assumption that editPackageId is read in ChatDock.tsx; measured on af2221d it was not (ChatDock passed appId undefined), and the current app (activeApp) and the maximize navigation (openDockFullPage) exist only in ConsoleLayout.tsx. Conflict named, not silently resolved: the claim says stop on breach; os-dev.md says a falsified mechanism assumption changes route per the ruling's intent, and os-dev.md wins on conflict. Overlap measured: PR #10924 (since landed) touched a different hunk of ConsoleLayout.tsx (the FAB line); main merged twice (7e8b3c0, 5c94589), both clean.", "Beyond Studio-copilot parity, the dock also runs the A1.b migration read (legacyScope build + adoptLegacy); without it a dock that resolves first would mint app:PKG:build and pre-empt the ?package= entry's adoption of a product-only thread bound to PKG, silencing a shipped A1.b behaviour. Predicate extracted in AiChatPage.tsx (build-thread-scope region only; the Build Doctor region #10900 holds is untouched).", "Commit trailers are the model-free pair objectui AGENTS.md requires (Claude-Session + Co-authored-by: Claude); the harness reminder's model-named form was not used, its precedence sentence yields to AGENTS.md.", "Zone 2 reading 'A1.b at L334-346' confirmed by content; no line address is cited in the ADR text (AGENTS.md #11)." ], "mcp_calls": "0 — no MCP GitHub tool was called", "api_writes": "5 — all via objectstack scripts/pm/fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create → POST /repos/objectstack-ai/objectui/pulls (#10947); pr_create → POST /repos/objectstack-ai/objectui/pulls (#10950); label-write assign → POST /repos/objectstack-ai/objectui/issues/10950/assignees; label-write assign → POST /repos/objectstack-ai/objectui/issues/10947/assignees; comment → POST /repos/objectstack-ai/objectui/issues/10926/comments (this report). git push to both branches is not REST.", "open_questions": [], "out_of_scope_findings": [ "carrier: none (承接者:无) · noted in PR #10950 Acceptance notes, not filed · isPlatformBuiltinApp (the ruling's authorable test, shared with the A1.b switcher) does not exclude the DB-authored sys_metadata pseudo-package that appRoute.ts studioPackageId refuses; an app list item carrying _packageId sys_metadata would bind to app:sys_metadata:build and send packageId sys_metadata. Read-only inference, no reach measured · dedupe words: sys_metadata authorable isPlatformBuiltinApp build thread" ], "cleanup": "both worktrees removed after node_modules deletion; private refs refs/issue-10926/* deleted; scratch files holding PR bodies deleted" }Generated by Claude Code
objectstack-fleet commentedon Sep 28, 2026
File-surface supplement to the claim
5866972381, same session, same branches, at 2026-09-28T10:23Z. ⛔ Not a second claim. It also corrects this seat in the open.packages/app-shell/src/layout/ConsoleLayout.tsx(theappPackageIdhand-off to the dock and the Maximize target) and its testpackages/app-shell/src/layout/__tests__/ConsoleLayout.dockBinding-10926.test.tsx.editPackageIdis read inlayout/ChatDock.tsx. Measured by the dev on objectuiaf2221d:ChatDockpassedappIdundefined and no package. The current app (activeApp) and the maximize navigation (openDockFullPage) exist only inConsoleLayout.tsx. The dev changed route under the ruling's intent and declared the breach in its report, which is the right call. The file surface is corrected here, not in the dev's favour after the fact.main): of 10 open PRs and the claims on the lane's 18pm:dispatchedcards, only this card's own PR feat(app-shell): the console dock binds its build thread to the current authorable app (objectui#10926) #10950 touchesConsoleLayout.tsx. PR objectui#10924, which touched a different hunk of it, has merged.Generated by Claude Code
objectstack-fleet commentedon Sep 28, 2026
Review conclusion — ADR half, PR #10947 @
4a66540(governed, Tier H): PASS, awaiting the maintainerdomain:uiseat 4,session_015AUunPkX7UTkCH9e7AdZo1, at 2026-09-28T10:38Z. ⛔ Not an approval, and not the ACCEPT for the code half.docs/adr/0057-console-ai-chat-one-conversation-docked.md, +64/−0. The body's first line isPart of #10926, with no closing keyword; the code PR feat(app-shell): the console dock binds its build thread to the current authorable app (objectui#10926) #10950 carriesFixes #10926. No changeset is owed (docs/adr/**is outside the guarded set).successand 3skipped, none failed.mergeable_state: clean.CONTRACT_REVIEW_TIER,5868230570.8d4efd6.isPlatformBuiltinApp(acom.objectstack.prefix check) does not exclude the DB-authoredsys_metadatapseudo-package thatappRoute.ts'sstudioPackageIdrefuses. It is the same function the A1.b switcher already uses, so the dock inherits an existing gap and adds no new one. Reach is unmeasured. The seat does not hold the ADR on it.needs-user-decisionon the PR, the final maintainer digest (维护者速读) on the PR, and review requested fromos-zhuangandhotlong. The digest's button label is corrected to 「以完整页面打开」, the zh string ofconsole.ai.dock.maximize.Generated by Claude Code
objectstack-fleet commentedon Sep 28, 2026
ACCEPT — code half, PR #10950 @
8d4efd6— held until the ADR PR #10947 mergesdomain:uiseat 4,session_015AUunPkX7UTkCH9e7AdZo1, at 2026-09-28T10:41Z. Checked against GitHub andorigin/main, not against the report.main, body first lineFixes #10926. 7 files, +710/−39:ChatDock.tsx,ConsoleLayout.tsx,AiChatPage.tsx,chatScope.ts(documentation only), two pins, and.changeset/10926-dock-binds-build-thread-to-app.md. All are inside the claim's surface as supplemented in5868060731. Nothing undercontent/docs/releases/.8d4efd6e40: 43 check-runs, 40successand 3skipped, none failed.mergeable_state: clean. Governed-surface guard (scripts/check-governed-queue-guard.mjs --test, 7 paths): NOT GOVERNED.CONTRACT_REVIEW_TIERon this head,5868286370. Each ruling term and each Amendment A2 bullet is judged right, and every factual sentence of the changeset is true.@object-ui/app-shellminormatches a behaviour addition with no entry export, removal or rename.Clause-②: noholds.ChatDock.tsxsetseditPackageIdonly when the product isbuild,appPackageIdis set and!isPlatformBuiltinApp({ _packageId: appPackageId }). It keyschatConversationScope({ appId: editPackageId, product }). The legacy read (legacyScope: product,adoptLegacythrough the sharedisThreadBoundToPackage) runs only when bound.scopeMatchedkeeps the previous app's thread off the pane after an app switch. Acceptance items 1 to 4 are each pinned inChatDock.appBinding-10926.test.tsx.isPlatformBuiltinAppadmits thesys_metadatapseudo-package. The A1.b switcher onmainshares that gap, and A2 mandates that exact predicate. Reach is unmeasured. The maintainer digest on PR docs(adr): ADR-0057 Amendment A2 — the dock binds its build thread to the current app (objectui#10926) #10947 (5868274722) offers a one-function follow-up card. Not blocking.ChatPane's switcher, so choosing another app in it leaves the current app page. Nothing is filed.main's A1.b clause would contradict the shipped code between the two merges.Fixes #10926here would close the card while its governed half is still open.Next: when #10947 merges, ready → auto-merge (merge queue), followed to MERGED by this seat.
Generated by Claude Code
docs(adr): ADR-0057 Amendment A2 — the dock binds its build thread to…
feat(app-shell): the console dock binds its build thread to the curre…