Merge remote-tracking branch 'gitea/master' into HEAD

This commit is contained in:
xiaohan.yuan committed 2026-10-21 12:50:30 +08:00
commit 9f1e583e23
17 files changed
+688 -37

No files matched your search

+71
View File
@@ -0,0 +1,71 @@
# B01 交付 02:F01 与模式、确认按钮修复
日期:2026-10-21(Asia/Shanghai)。开发端接续验收退回与补充反馈,状态:**源码已实现、离线自测通过,真实 Windows 复测待验**。不关闭整个 B01。
- 基线:`ddd677bae3c43a5514eb40f7a1d9749fdf389115`。
- **受测代码 SHA:`1ed71b63b5af9a98b942ff47c66df5799d4d2c8a`**。
- 需求:[验收 01](B01-验收-01.md) 的 F01;[补充反馈 01](B01-补充反馈-01.md) 的 FB01/A06、FB02/A05;沿用 [B01 需求](B01-需求.md) 的 AC1.3、AC3.1~3.3。
- 范围:YC-001 的 F01 修复,以及 YC-003 的 A05/A06 部分交付。A01/A04 已有验收证据不推倒重做;YC-002、YC-004、A07/A08 未在本轮实施。**没有恢复用户撤回的骨架补丁。**
## 1. 实现
### F01:原生 part 稳定身份
`completed-fold.ts` 统一生成展示身份,识别原生 `plan.id`、`task.id`、`artifact.id`,以及 tool、reasoning、image 的稳定 ID;React key 与 disclosure scope 共用同一身份。类型与 ID/位置域分开,消息级 store 不共享。
真实 `applyAssistantEvent → MessageBubble` 回归覆盖原验收的两个 text 被 done 校正合并、原生 plan/task、插入重排、相反展开选择、外层重复开关、同 ID 跨消息隔离。无 ID 旧历史保留位置 fallback;**不承诺没有稳定 ID 时任意重排仍可识别同一项**。未改 reducer 或历史源对象。
### FB02/A05:ModeChip
恢复透明默认背景、pill 圆角、次级文字;模式图标与 X 共用同一 16px grid 槽,hover/focus-within 原位替换,无右上角额外 X。保留 32px 高、13px/500/20px 文字、8px padding、原生退出按钮、craft 隐藏和禁用语义。继续调用原宿主 clear 回调,不重写草稿或权限偏好。
图标仍为本地几何,源码保留待同版本 REA SVG/像素验收的标注。
### FB01/A06:TaskPopconfirm
改用自带 CSS 的 `ui/Button`,明确 primary/secondary/danger,避免依赖 portal 外旧 `.wb-button` 类作用域。恢复 66px 最小宽度、19px 水平 padding、16px 浮层圆角、600 标题,保留 240px 右侧锚定、箭头、焦点、点击吞掉、忙态重复提交锁及失败重试。
按已确认要求保留原版归档说明,移除附加兼容解释。**YCode 当前仍没有“系统设置-数据管理”归档入口,实际查看/恢复仍在侧栏“已归档”;本轮仅恢复指定文案,不声称已实现该设置页。**
## 2. 验证结果
证据:[离线日志](evidence/B01-02/verification.txt)、[浏览器环境失败记录](evidence/B01-02/browser-environment.txt)。Linux x64、Node 24.19.0、npm 11.9.0、jsdom 30.1.3;复用已安装依赖,未改 package/lock。
| 检查 | 结果与边界 |
| --- | --- |
| `npm run build` | 退出 0,含两个 tsconfig 类型检查与 main/preload/renderer 构建;中间发现的 TS narrowing 错误已修正后重跑 |
| `YCODE_TEST_DOM_MODULE=<jsdom模块路径> npm run test:alignment` | 退出 0;包含原生身份新回归、ModeChip 37 项、TaskPopconfirm 34 项(含运行中停止并删除、busy、失败重试)、原有问答/授权 DOM |
| `test:conversation`、`test:workbuddy-import`、`test:artifacts` | 均退出 0 |
| F01 基线负对照 | 以基线两个 CompletedFold 模块替换后准确复现 false→true,预期退出 1;新产品路径通过 |
| `test:fold-summary` | 本 Linux LF 检出退出 0;不等于 Windows CRLF 问题已修复,本轮未改摘要/manifest/行尾策略 |
| `check:tokens` | 退出 1,基线与最终均为相同 6 项既存失败,无新增失败、未刷新 baseline |
| 两个新 UI fixture 的 `--build-only` | 退出 0,仅证明夹具打包成功,不是计算样式/截图通过 |
| 独立复审 | 重跑原生身份、37 项模式、34 项确认 DOM;未发现生产代码阻塞性回归;补齐 fixture CSS、主题同步与安全默认参数 |
本轮无模型请求、无真实 SDK/CLI 执行、无原版访问。当前环境 Chromium 在页面加载前因 socket 权限失败,未取得新截图和真实计算样式;没有绕过限制。实际 Electron 全应用、Windows、窄窗、像素与辅助技术验收仍待执行,不能从 jsdom/构建结果推导通过。
## 3. 验收复跑
按协作流程在固定代码 SHA 的独立检出安装构建。完整应用测试必须使用新临时 `YCODE_USER_DATA_DIR`,不能启动默认正式数据目录。不要复用开发机 node_modules 或旧 out。
```powershell
npm ci --legacy-peer-deps
npm run build
npm install --prefix .tmp/b01-dom --ignore-scripts --no-audit --no-fund jsdom@30.1.3
$env:YCODE_TEST_DOM_MODULE = Join-Path $PWD '.tmp/b01-dom/node_modules/jsdom'
npm run test:alignment
npm run test:conversation
npm run test:workbuddy-import
npm run test:artifacts
node scripts/test-mode-chip-native.mjs
node scripts/verify-task-menu.cjs
```
- `test-mode-chip-native.mjs` 自建隔离 Electron 组件窗口/userData,覆盖浅深、hover/focus、原生 Tab/Enter/Space、禁用、窄窗,输出截图与 report。不是完整宿主草稿/焦点验收;不访问原版或模型。
- `verify-task-menu.cjs` 保留真实隔离 main/preload/IPC/本地落库测试,新增 portal 两主题计算样式;通过 `ycode:theme` storage 通路同步应用主题,不仅改根节点。必须在可用 Electron 环境执行后再判断通过。
- `node scripts/test-task-popconfirm-browser.mjs --build-only` 生成独立可移植 HTML;去掉该参数并设置 `CHROMIUM_PATH` 到本机 Chromium/Chrome 可执行文件可运行真实计算样式断言。浅深、主次危险、busy/error/retry 有断言;这个组件 fixture 不代替真实 IPC/落库。
- 两个新浏览器脚本默认保留 sandbox;无浏览器时不把 build-only 当作验收完成。
重点复测 F01 原验收事件序列,A05 两模式默认/悬停/焦点/退出、权限及草稿保留,A06 取消/确认、运行中停止并删除、两主题样式、焦点和失败重试。保留旧失败记录,另写新验收记录。
交付记录可位于受测代码后的文档提交;只有远端推送与 SHA 核对成功后才算 Git 交接完成。本轮交付完成后推送窗口交回验收端。
@@ -0,0 +1,8 @@
Observed during environment capability check, 2026-10-21 UTC; copied from tool output (not a successful fixture run).
Target: local Chromium headless with explicit repository .tmp user-data-dir.
No page loaded and no computed-style result was obtained.
[6:6:1021/133654.542575:ERROR:third_party/crashpad/crashpad/util/file/filesystem_posix.cc:63] mkdir : No such file or directory (2)
chrome_crashpad_handler: --database is required
Try 'chrome_crashpad_handler --help' for more information.
[6:6:1021/133654.579509:FATAL:chrome/browser/process_singleton_posix.cc:297] Check failed: . socket() failed: Operation not permitted (1)
Stopped after this error. Checked-in browser runner retains the Chromium sandbox; only --build-only completed in this environment.
@@ -0,0 +1,202 @@
B01 delivery 02 offline evidence
Code SHA: 1ed71b63b5af9a98b942ff47c66df5799d4d2c8a
Base: ddd677bae3c43a5514eb40f7a1d9749fdf389115
Linux x64; Node 24.19.0; npm 11.9.0; jsdom 30.1.3
No model/SDK process or original app was started. Native style/layout acceptance is not claimed.
Token failure sets before and after are equal (6 pre-existing failures); baseline unchanged.
First intermediate build found a TS narrowing error; fixed before successful final build.
Independent review repeated DOM tests and found no blocking production regression.
===== alignment.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
> node scripts/run-alignment-regression.mjs
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":3.751840999999999,"storeHydrationMs":0.13198400000000277,"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 host approval policy unit checks passed (no SDK process/application/matching verification)
Mock SDK replay lifecycle passed: fail closed, retry, session isolation, independent mode guard
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: 14 checks passed (not pixel/SDK verification)
{"checks":37,"passed":true,"scope":"Isolated React DOM and CSS contracts; no native keyboard/layout/pixel acceptance"}
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
===== conversation.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: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
===== import.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:workbuddy-import
> esbuild scripts/workbuddy-import-regression.ts --bundle --platform=node --format=esm --outfile=.tmp/workbuddy-import-regression.mjs --log-level=warning && node .tmp/workbuddy-import-regression.mjs
WorkBuddy import regression passed
===== artifacts.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:artifacts
> esbuild scripts/artifact-diff-regression.ts scripts/artifact-renderer-regression.tsx scripts/specialized-block-regression.tsx --bundle --platform=node --format=cjs --jsx=automatic --loader:.css=empty --out-extension:.js=.cjs --outdir=.tmp/artifact-tests --log-level=warning && node .tmp/artifact-tests/artifact-diff-regression.cjs && node .tmp/artifact-tests/artifact-renderer-regression.cjs && node .tmp/artifact-tests/specialized-block-regression.cjs
Artifact diff recovery regression checks passed
Artifact routing, content loading, full write projection and renderer regressions passed
Specialized block icon and label SSR regression checks passed
===== build.txt: exit 0 =====
[Tail of successful full build; includes prior typecheck in command]
out/renderer/assets/vue-vine-DXhYlaTf-DTauGW8s.js 201.27 kB
out/renderer/assets/SourceSelect-DrNU8YnZ.js 203.20 kB
out/renderer/assets/chunk-4HAMMTFA-BEFC_AJa.js 210.32 kB
out/renderer/assets/swimlanes-42K2YHIH-Bp72q37Z.js 265.51 kB
out/renderer/assets/wolfram-BVoTES0L-6ikJLWGF.js 267.14 kB
out/renderer/assets/chunk-DU6HZSFF-DPu5LxXf.js 271.07 kB
out/renderer/assets/architectureDiagram-5GKGNRK7-DAeFXfK3.js 318.23 kB
out/renderer/assets/katex-Y9ra-ykP.js 497.35 kB
out/renderer/assets/texmath-Bkeg3ZLn.js 594.25 kB
out/renderer/assets/wasm-CVjZL0jK-2Bi6p3c3.js 622.62 kB
out/renderer/assets/cpp-9jHBA231-CtHklR8a.js 626.73 kB
out/renderer/assets/app-BYh1ERuc.js 675.57 kB
out/renderer/assets/emacs-lisp-DjtOxg4j-CUUa7aOE.js 780.06 kB
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-lmA4yj_k.js 3,760.12 kB
out/renderer/assets/editor.api2-dPwET-7w-BYIQ9bT3.js 4,889.23 kB
✓ built in 2.08s
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
===== fold-before.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:fold-summary
> node scripts/rea/recovered-fold-summary-regression.mjs
Recovered fold-summary closure regression passed (descriptor aliases, object selection, states, topics and labels).
===== tokens-before.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 个文件(用时 49 ms)
baseline:scripts/design-token-baseline.json(334 个文件)
门禁分类:adapter 8 | core 6 | local 279(合计 293 个文件)
合计:裸 hex=611 裸 px=2682 !important=6 --wb-* 定义=525 var(--yc-*) 使用=1642 var(--wb-*) 使用=1203
非门禁分类: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=22
[新增门禁文件] src/renderer/src/capabilities/skill-detail-shell.css(local):裸 px=21
[回归] src/renderer/src/capabilities/skills-host.css(local):裸 px 25 → 46(+21)
[新增门禁文件] 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 → 47(+12);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)
===== tokens-after.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 个文件(用时 48 ms)
baseline:scripts/design-token-baseline.json(334 个文件)
门禁分类:adapter 8 | core 6 | local 279(合计 293 个文件)
合计:裸 hex=611 裸 px=2682 !important=6 --wb-* 定义=525 var(--yc-*) 使用=1642 var(--wb-*) 使用=1201
非门禁分类: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=22
[新增门禁文件] src/renderer/src/capabilities/skill-detail-shell.css(local):裸 px=21
[回归] src/renderer/src/capabilities/skills-host.css(local):裸 px 25 → 46(+21)
[新增门禁文件] 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 → 47(+12);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)
===== mode-fixture-build.txt: exit 0 =====
{"output":"/workspace/scratch/0aaa9774aecc/single-package-staging/ycode/.tmp/mode-chip-native-ZJMFra","fixtureBuilt":true,"nativeExecuted":false}
===== popconfirm-fixture-build.txt: exit 0 =====
Browser fixture: /workspace/scratch/0aaa9774aecc/single-package-staging/ycode/.tmp/task-popconfirm-browser-RoVW4H/index.html
===== identity-baseline-negative-control.txt: exit 1 =====
AssertionError [ERR_ASSERTION]: terminal correction preserves choices
+ actual - expected
{
plan: [
+ 'true'
- 'false'
],
task: [
+ 'true'
- 'false'
]
}
at main2 (/workspace/scratch/0aaa9774aecc/single-package-staging/ycode/.tmp/f01-baseline-check.cjs:293667:25) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: [Object],
expected: [Object],
operator: 'deepStrictEqual',
diff: 'simple'
}
Baseline negative control reproduced exact terminal correction failure (expected exit 1).