docs(B03): deliver permission and composer fixes with real SDK evidence

This commit is contained in:
Codex committed 2026-10-21 14:46:04 +09:00
1 parent adbbb3bd37
commit 73f0e751f9
4 files changed
+496

No files matched your search

@@ -0,0 +1,295 @@
B03 verification
Code SHA: adbbb3bd37f6043d10cbaa59d6c28ade6387a7f3
Base: 0bc9faa1292c4223a61608e72ba3cd13d572252b
Linux x64; Node24.19.0; npm11.9.0; SDK0.3.304; jsdom30.1.3
UI = React/jsdom only; real SDK = isolated actual ClaudeKernel with local deterministic SSE. No user provider/credentials/workspace.
Independent review: 276 offline policy +43 DOM checks; cancellation error visibility fixed before final run.
Diff check uses core.whitespace=cr-at-eol because ChatPane retained original CRLF.
===== core.txt: exit 0 =====
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test
> npm run test:core
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:core
> npm run typecheck && npm run test:chat && npm run test:sessions && npm run test:persistence && npm run test:conversation
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 typecheck
> tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tsconfig.web.json
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:chat
> esbuild scripts/message-order-regression.ts scripts/chat-store-regression.ts scripts/chat-stream-committer-regression.ts --bundle --platform=node --format=esm --out-extension:.js=.mjs --outdir=.tmp/chat-tests --log-level=warning && node .tmp/chat-tests/message-order-regression.mjs && node .tmp/chat-tests/chat-store-regression.mjs && node .tmp/chat-tests/chat-stream-committer-regression.mjs
message-order-regression: all checks passed
chat-store-regression: all checks passed
chat-stream-committer-regression: all checks passed
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:sessions
> esbuild scripts/session-store-regression.ts --bundle --platform=node --format=esm --external:esbuild --outfile=.tmp/session-store-regression.mjs --log-level=warning && node .tmp/session-store-regression.mjs
session-store-regression: all checks passed
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:persistence
> esbuild scripts/chat-persistence-regression.ts --bundle --platform=node --format=esm --external:esbuild --outfile=.tmp/chat-persistence-regression.mjs --log-level=warning && node .tmp/chat-persistence-regression.mjs
chat-persistence-regression: all checks passed
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:conversation
> esbuild scripts/conversation-renderer-regression.tsx scripts/composer-regression.tsx scripts/completed-fold-regression.tsx scripts/streaming-footer-regression.tsx --bundle --platform=node --format=cjs --jsx=automatic --loader:.css=text --out-extension:.js=.cjs --outdir=.tmp/conversation-tests --log-level=error && node .tmp/conversation-tests/conversation-renderer-regression.cjs && node .tmp/conversation-tests/composer-regression.cjs && node .tmp/conversation-tests/streaming-footer-regression.cjs && node .tmp/conversation-tests/completed-fold-regression.cjs
Conversation specialized renderer SSR regression checks passed
Composer/message action regression cases passed
streaming-footer-regression: persistent stream status, delayed/paused rotation, brand/locale mapping, source CSS, and completed model footer passed
Completed-fold model and SSR regression checks passed
npm notice
npm notice New major version of npm available! 11.9.0 -> 12.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
npm notice To update run: npm install -g npm@12.2.0
npm notice
npm notice
npm notice New major version of npm available! 11.9.0 -> 12.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
npm notice To update run: npm install -g npm@12.2.0
npm notice
npm notice
npm notice New major version of npm available! 11.9.0 -> 12.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
npm notice To update run: npm install -g npm@12.2.0
npm notice
===== alignment-dom.txt: exit 0 =====
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:alignment:dom
> node scripts/run-alignment-regression.mjs --require-dom
PASS model alignment: fresh/legacy migration, new/edit/default/delete/reload, valid selection (offline host fixtures)
PASS model settings: deferred owner switch, rename mapping, addition selection, empty deletion, immutable history
PASS session factory: first-send preference, mode preservation, invalid permission rejection (isolated ports)
{"historyMessages":10000,"bytes":747781,"parseMs":2.9472000000000094,"storeHydrationMs":0.1492190000000022,"note":"Node parsing/store benchmark only, not browser rendering or Windows IPC performance"}
session-composer-alignment: loading/cache/retry/races/model/permissions/modes/SSR passed
alignment-conversation: local groups, original expanded order, question projection and truthful status passed
A01 native MessageBubble identity aliases, immutable inputs and ordinary raw output passed
A01 imported native card, linked dedup and unknown-position compatibility passed
question-answer-shell: structural and recovered CSS contracts passed
question-answer-shell: DOM hierarchy, controls linkage, click, Enter, Space and inert contracts passed
Runtime progress, session-grant scope and approval lifecycle regressions passed
Permission intercept static rendering passed; interactive keyboard/focus remains UI acceptance
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
[claude-permission] {"permissionMode":"full-access","agentMode":"ask","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"mode-or-inactive-deny"}
[claude-permission] {"permissionMode":"full-access","agentMode":"plan","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"mode-or-inactive-deny"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"subcommandResults","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"safetyCheck","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":true,"matchedAskRule":false,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"rule-approval"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"error-deny"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"85aafbf52a5144b5","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"}
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"85aafbf52a5144b5","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"}
Claude host approval policy unit checks passed (no SDK process/application/matching verification)
[claude-permission] {"permissionMode":"full-access","agentMode":"plan","sdkMode":"plan","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"unknown","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"mode-or-inactive-deny"}
Mock SDK replay lifecycle passed: fail closed, retry, session isolation, independent mode guard
B03 offline host policy: 276 checks passed; no real SDK/CLI/model execution.
task popconfirm DOM regression: 34 checks passed (jsdom, not pixel validation)
question-interaction: 24 DOM behavioral checks passed
question-identity: 30 A01 DOM checks passed (not Electron/pixel/SDK acceptance)
completed-fold-nested: real question/tool/thinking/local-summary remount, event, keyboard and identity contracts passed
completed-fold-native-identity: real reducer done correction, native IDs, insertion/reorder, repeated outer toggles, message isolation and legacy fallback passed
Permission intercept DOM: 43 checks passed (not pixel/SDK verification)
{"checks":37,"passed":true,"scope":"Isolated React DOM and CSS contracts; no native keyboard/layout/pixel acceptance"}
{"result":"PASS","phase":"alignment-offline","suites":11}
{"result":"PASS","phase":"alignment-dom","suites":7}
npm notice
npm notice New major version of npm available! 11.9.0 -> 12.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
npm notice To update run: npm install -g npm@12.2.0
npm notice
===== reporting.txt: exit 0 =====
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:reporting
> node --test scripts/regression-reporting.test.mjs
✔ alignment reports absent optional DOM coverage explicitly (2358.188368ms)
✔ alignment requires DOM when requested by flag (68.595048ms)
✔ alignment requires DOM when requested by environment (60.505075ms)
✔ alignment rejects an unloadable configured DOM module instead of skipping (61.004578ms)
✔ backend never reports a skipped real package as PASS (1326.932167ms)
✔ alignment rejects a configured module without a JSDOM export (68.770087ms)
ℹ tests 6
ℹ suites 0
ℹ pass 6
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 4030.393006
===== composer-capabilities.txt: exit 0 =====
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:composer-capabilities
> node scripts/run-composer-capabilities-regression.mjs
prompt-queue-regression: cap, payload, order, isolation, delivery, stop, recovery and unknown checks passed
{
"result": "PASS",
"checks": [
{
"name": "parallel same-instance enqueues preserve exactly 19 items",
"pass": true
},
{
"name": "duplicate take is serialized to one winner",
"pass": true
},
{
"name": "delivering item is immutable and notify does not duplicate delivery",
"pass": true
},
{
"name": "clear removes a non-delivering session queue and is idempotent",
"pass": true
},
{
"name": "first enqueue after an empty queue was paused resumes a new run without unpausing existing work",
"pass": true
},
{
"name": "incoming payload is validated before host side effects and persistence",
"pass": true
},
{
"name": "host-rebuilt capability labels are validated before persistence",
"pass": true
},
{
"name": "two queue instances cannot overwrite one another",
"pass": true
},
{
"name": "corrupt queue cannot redirect or duplicate item identity",
"pass": true
},
{
"name": "invalid revision, status and payload permission are rejected",
"pass": true
},
{
"name": "post-delivery removal failure becomes paused unknown instead of stuck delivering",
"pass": true
},
{
"name": "stale owner nonce is recovered without trusting a reused PID",
"pass": true
},
{
"name": "stale and expired lock files are reclaimed",
"pass": true
},
{
"name": "live foreign lock times out with an explicit error",
"pass": true
},
{
"name": "blocked notify does not create a state revision",
"pass": true
},
{
"name": "host resolver applies dispatch-time permission downgrade without mutating stored payload",
"pass": true
}
]
}
input-composition-regression: precedence, takeover, queue preservation, task placement, toolbar and escape rules passed
{"result":"PASS","checks":30}
{
"result": "PASS",
"tests": [
"serial model writes + frozen active turn",
"send failure retry",
"late result/event session isolation",
"draft settings during first session creation",
"nextRequestSettings whitelist"
]
}
context-usage-regression: latest, previous, active-run, summary identity and failure cases passed
{"result":"PASS","checks":36,"directory":"/workspace/scratch/0aaa9774aecc/single-package-staging/ycode/.tmp/claude-capabilities-i8WXcM"}
npm notice
npm notice New major version of npm available! 11.9.0 -> 12.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
npm notice To update run: npm install -g npm@12.2.0
npm notice
===== tool-approvals.txt: exit 0 =====
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 test:tool-approvals
> esbuild scripts/tool-approval-regression.tsx --bundle --platform=node --format=cjs --jsx=automatic --loader:.css=text --outfile=.tmp/tool-approval-regression.cjs --log-level=error && node .tmp/tool-approval-regression.cjs
Tool approval helper and inline source markup regression checks passed.
===== build.txt: exit 0 =====
Successful full build including typecheck; tail follows:
out/renderer/assets/cytoscape.esm-bVGYt-iW.js 869.69 kB
out/renderer/assets/ArtifactPierreDiff-D5xhRc5y.js 1,119.58 kB
out/renderer/assets/chunk-FOHPRMQF-BCllzKJD.js 1,154.18 kB
out/renderer/assets/index-dE2T-qjC.js 3,765.40 kB
out/renderer/assets/editor.api2-dPwET-7w-BYIQ9bT3.js 4,889.23 kB
✓ built in 1.86s
npm notice
npm notice New major version of npm available! 11.9.0 -> 12.2.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
npm notice To update run: npm install -g npm@12.2.0
npm notice
===== tokens.txt: exit 1 =====
npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm.
> ycode@0.0.7 check:tokens
> node scripts/check-design-tokens.mjs
设计 token 漂移检查(静态)
扫描:src/renderer/src 共 367 个文件(用时 46 ms)
baseline:scripts/design-token-baseline.json(334 个文件)
门禁分类:adapter 8 | core 6 | local 279(合计 293 个文件)
合计:裸 hex=611 裸 px=2680 !important=6 --wb-* 定义=525 var(--yc-*) 使用=1651 var(--wb-*) 使用=1209
非门禁分类:vendor 2 | recovered 22 | source 47 | tokenSource 3(合计 74 个文件,仅记录不阻塞)
合计:裸 hex=10642 裸 px=13642 !important=920 --wb-* 定义=17966 var(--yc-*) 使用=77 var(--wb-*) 使用=19638
非门禁相对 baseline:文件 +0;裸 hex +78 裸 px +64 !important +0 --wb-* 定义 +0 var(--yc-*) 使用 +22 var(--wb-*) 使用 -120
结果:失败,共 6 项:
[新增门禁文件] src/renderer/src/capabilities/recommended-flow.css(local):裸 px=21
[新增门禁文件] src/renderer/src/capabilities/skill-detail-shell.css(local):裸 px=21
[回归] src/renderer/src/capabilities/skills-host.css(local):裸 px 25 → 45(+20)
[新增门禁文件] src/renderer/src/workbuddy/composer/capability-picker.css(local):裸 hex=26,裸 px=48
[回归] src/renderer/src/workbuddy/composer/composer.css(local):裸 hex 23 → 38(+15);裸 px 83 → 139(+56)
[新增门禁文件] src/renderer/src/workbuddy/composer/prompt-queue.css(local):裸 hex=8,裸 px=35
提示:确认变更符合预期后运行 `node scripts/check-design-tokens.mjs --update-baseline` 刷新 baseline;
否则请改用 --yc-* token、复用现有值,或去掉重复的 --wb-* 定义。
提示(不失败,仅记录):3 个门禁文件 token 使用数上升:
src/renderer/src/capabilities/skills-host.css(local):var(--wb-*) 使用 12 → 19(+7)
src/renderer/src/workbuddy/composer/composer.css(local):var(--yc-*) 使用 35 → 48(+13);var(--wb-*) 使用 0 → 1(+1)
src/renderer/src/workbuddy/conversation/conversation.css(local):var(--yc-*) 使用 0 → 4(+4)
提示(不失败):baseline 中 8 个文件已不存在:src/renderer/src/components/ReportedRunUsage.tsx;src/renderer/src/workbuddy/subagents/SourceMemberIcon.tsx;src/renderer/src/workbuddy/subagents/SubagentCollaboration.tsx;src/renderer/src/workbuddy/subagents/SubagentDetailPanel.tsx;src/renderer/src/workbuddy/subagents/adapters.css;src/renderer/src/workbuddy/subagents/member-view.ts;src/renderer/src/workbuddy/subagents/source.css;src/renderer/src/workbuddy/subagents/theme.css
提示:新增门禁文件 36 个且无受控计数(允许):src/renderer/src/capabilities/CapabilityMaintenance.tsx(local);src/renderer/src/capabilities/RecommendedSkills.tsx(local);src/renderer/src/capabilities/SkillAvatar.tsx(local);src/renderer/src/capabilities/SkillDetailShell.tsx(local);src/renderer/src/capabilities/SkillModalPortal.tsx(local);src/renderer/src/capabilities/skill-modal-focus.ts(local);src/renderer/src/components/SessionLoading.tsx(local);src/renderer/src/components/TaskPopconfirm.tsx(local);src/renderer/src/components/session-loading.css(local);src/renderer/src/components/task-popconfirm.css(local);src/renderer/src/components/updates/UpdateSidebarCard.tsx(local);src/renderer/src/components/updates/update-ui-model.ts(local);src/renderer/src/components/updates/update-ui-store.ts(local);src/renderer/src/components/updates/updates-ui.css(local);src/renderer/src/ui/Button.tsx(local);src/renderer/src/ui/IconButton.tsx(local);src/renderer/src/ui/Input.tsx(local);src/renderer/src/ui/Popover.tsx(local);src/renderer/src/ui/Select.tsx(local);src/renderer/src/ui/Switch.tsx(local);…(还有 16 项,详见 --json)