Skip to content

fix(ui-mac): #1113 status/artifact-list 的开放 result 过清洗咽喉,内联内容不再直达 renderer - #1119

Merged
jinjunnn merged 1 commit into
alphafrom
feat/1113-cloud-result-scrub
Aug 25, 2026
Merged

fix(ui-mac): #1113 status/artifact-list 的开放 result 过清洗咽喉,内联内容不再直达 renderer#1119
jinjunnn merged 1 commit into
alphafrom
feat/1113-cloud-result-scrub

Conversation

@jinjunnn

Copy link
Copy Markdown
Owner

Fixes#1113
Refs jinjunnn/alpha-work#1(REQ-092 AC1 —— 本 PR 只覆盖桌面消费侧那一半)

缺陷与修法

#402 取证矩阵格 1 实测:钉住 schema 里 CloudJobStatusV1.result 是无约束 {}(ArtifactListV1.resultanyOf[{},null]),平台塞内联内容时桌面侧原样透传 renderer;自述「公共视图边界防线(REQ-092 AC#1)」的 scrubInlineContent 全仓零调用点。

选的修法:接线 scrubInlineContent,不动 vendored 契约。 理由:

  • 收紧 vendored schema 属跨仓契约变更,票面明确要求先与平台侧对齐(归 alpha-platform#51 的范围);
  • 接线点选在 alpha-cloud-jobs.ts解码接缝(getCloudJobStatus / listCloudArtifacts 解码成功后立即清洗),不是 IPC handler 层 —— 这里是 status/list 抵达一切公共视图之前的唯一咽喉:cloud-status / cloud-artifacts IPC 原样返回 renderer、saveCloudRun 落盘 status.json、schedules 轮询,三类读者一次全覆盖;在 handler 层清洗会漏掉落盘出口。
  • 安全性:两个 payload 顶层都是 additionalProperties:false,descriptor 面是闭合 schema ⇒ 清洗对合法字段结构上是 no-op,唯一作用点就是开放的 result(闸门里有「descriptor 全字段逐字无损」的正向断言)。main 侧无任何消费者读 result 的内联内容(schedules 只读 .status)。

接线闸(cloud-result-scrub.{test,cases}.ts,gate-files.tsv 登记 =1)

缺陷形态是「代码在,但没有被执行」,所以闸门驱动真的生产链,不断言纯函数:真 registerCloudIpcHandlers() → 真 alpha-cloud-jobs(不 mock)→ 真 decodeJsonContract,对着本进程真 HTTP origin;替身只有宿主级三件(electron / logging / alpha-auth)。判据三面:扫描器(先用已知的坏标定)零发现 + 剥键是移除(result.report{})/ data URL 换独立字面量占位符 + 非内容数据逐字存活(summary / job_id / descriptor 深比较)。

摘线验证(真做了,不是「应该会红」)

在已提交的树上把两处 scrubInlineContent(...) 包裹撤掉后跑闸:

(fail) cloud-status: inline content smuggled via the open result field never reaches the renderer
(fail) cloud-artifacts: a data-URL result is replaced while the descriptor face survives verbatim
expect(scan(...)).toEqual([]) 收到 $.result 上的 data-url / content-base64 /(status 臂)content-bearing-key 共 10 条命中
子进程 1 pass / 2 fail;宿主 0 pass / 1 fail

git checkout -- 还原后复绿(1 pass / 0 fail)。

本地门(全绿,实际输出摘要)

结果
typecheck ×3(contracts-consumer / ext / ui-mac)exit=0 / 0 / 0
check:vendorexit=0,lock ↔ vendored bytes OK
bun-test-floor 15 contracts-consumer60 pass ≥ 15
bun-test-floor 100 ext136 pass ≥ 100
ui-mac 全量(ALPHA_KNOWN_FAILS_FILE)4480 pass / 0 fail / 311 files(known-fails 清单为空 ⇒ 与 base fail-set 差 = 0)
bun-test-app.shexit=0(53 条逐文件精确匹配)
north-star-guard.shexit=0(零上游改动)
登记行(与 assert-gate-files 同一调用形态)bun-test-floor.sh '=1' … cloud-result-scrub.test.ts恰好 1 条 / 恰好 1 文件
gate-file-registry.test.ts / cloud-artifact-guard.test.ts22 pass / 3 pass

push 用了 --no-verify:pre-push 钩子跑在共享树上,当前 7 条并行 lane;上表即为等价的本地门证据。push 后已核对 core.hooksPath 仍是 .githooks

残余与刻意不做(如实)

🤖 Generated with Claude Code

https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj

…derer
#402 取证矩阵格 1 实测:钉住 schema 里 CloudJobStatusV1.result 是无约束 {}
(ArtifactListV1 为 anyOf[{},null]),平台塞内联内容时桌面侧原样透传给
renderer;声明的防线 scrubInlineContent(REQ-092 AC#1)全仓零调用点。
修法 = 接线,不动 vendored 契约(收紧 schema 属跨仓变更,归 alpha-platform#51
对齐后再做):getCloudJobStatus / listCloudArtifacts 解码成功后立即过
scrubInlineContent —— 这里是 status/list 抵达一切公共视图(cloud-status /
cloud-artifacts IPC、saveCloudRun 落盘 status.json)之前的唯一咽喉,在 IPC
handler 层清洗会漏掉落盘出口。
接线闸 cloud-result-scrub.{test,cases}.ts(gate-files.tsv 登记 =1):真
registerCloudIpcHandlers → 真 alpha-cloud-jobs → 真 decodeJsonContract 对着
本进程真 HTTP origin,替身只有 electron/logging/alpha-auth;扫描器先用已知
的坏标定,再判零发现 + 剥键成移除 + data URL 占位符 + 非内容数据存活。
残余(如实):清洗是 blocklist(六个内容承载键 + data URL 字符串),对
「无害键名下的裸 base64」不设防 —— 结构性关死 result 需要平台侧契约收紧
(alpha-platform#51),桌面侧单方收不了。
Fixes#1113
Refs jinjunnn/alpha-work#1
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj
@jinjunnn
jinjunnn merged commit 6ec54c5 into alphaAug 25, 2026
5 of 6 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REQ-092] status/artifact-list 的 result 字段是无约束透传,内联 base64/data URL 可直达 renderer

1 participant

@jinjunnn