Skip to content

fix(harvest): validate identity maps before writing identity.json - #191

Open
titanwings wants to merge 1 commit into
atomic/pr-1-unique-anchorsfrom
atomic/pr-5-identity-write-after-validate
Open

titanwings wants to merge 1 commit into
atomic/pr-1-unique-anchorsfrom
atomic/pr-5-identity-write-after-validate

Conversation

@titanwings

Copy link
Copy Markdown
Owner

Why

harvest --identity 先把映射拷进 Skill 再校验。重复句柄已经 exit 2,但 identity.json 已经落盘。某人没写 handles 时,warnings.push 发生在 const warnings = [] 之前,命令以 Cannot access 'warnings' before initialization 崩溃。

IDENT 纪律是响亮失败且不写任何文件。合法映射本来就是绿的。

数据形状如下。

输入 调用 字面期望
{"people":[{"name":"A","handles":["x"]},{"name":"B","handles":["x"]}]} harvest --identity dup.json --json 退出 2。error.message 是 identity.json: handle "x" is claimed by both "A" and "B"。工作区没有比 dup.json 新的文件
{"people":[{"name":"林工"}]} harvest --identity no-handles.json --json 退出 0。warnings 含 "林工" lists no handles; only its own name is canonicalised
飞书导出加 handles:["ou_lin"] harvest --identity ok.json --json 退出 0。账本 identity.handles 是 ["ou_lin"],identity.turns 是 12

Scope

loadIdentity 在 mkdir 与 copyFileSync 之前跑。重复句柄直接返回,不建人物目录。

const warnings = [] 提前到 identity.warnings 的 push 之前。没写 handles 的人只进回执,命令继续。

harvest 回执改走 createReceipt。前八个键是 command、person、ok、inputs、outputs、anchors、warnings、unavailable。entries 接在契约字段之后。

tests/identity.test.mjs 加两条用例。基线只删下面两行。

  • R21 identity.json: a handle claimed twice exits 2 with the exact message and writes nothing
  • R21 identity.json with a person that lists no handles is a warning, not a crash

本树从 PR-1 起步,删完这两行后基线数据行是 17。不删 R08、R28、R38、R49。

parse-* 回执仍在 src/commands/parse-shared.mjs 手拼。那个文件不在本 PR 的 Files 里。

Blast Radius

已经装进 Skill 的合法 identity.json 不改。非法映射不会再留下半份目录。栈停在 dot-skill-test,dot-skill 保留。

Verification

T35、T37 由红转绿。T36 保持绿。基线从 19 行减到 17 行。

改前,Node v22.14.0:

PASS audit-tests  (5.4s, exit 1)
     ratchet failing 19, baseline 19

T35 失败原文:

written: identity.json

true !== false

T37 失败原文:

error={"code":"unexpected","message":"Cannot access 'warnings' before initialization"}

1 !== 0

T36 同一次跑是 ok 2。

改后,Node v22.14.0:

PASS audit-tests  (5.2s, exit 1)
     ratchet failing 17, baseline 17

改后,Node v20.20.2 与 Node v22.14.0 的 node scripts/run-gates.mjs --without playwright 都是 8/8 gates passed。unit-tests 是 # tests 400、# fail 0。

DISTILLY_PLAYWRIGHT_ROOT=/tmp/pw-root node scripts/run-gates.mjs --requires playwright 在 Node v22.14.0 上是 3/3 gates passed。三份 acceptance 都是 18/18。us-house 含 FAIL · units=2744 speakers=18 attributed=85。

新用例在 base SHA 319e8c36633313450ba0b6c2695c55e39b835085 上失败,在 head 上通过。Node v22.14.0。

重复句柄用例失败:

a duplicate handle must not create the Skill directory

true !== false

无 handles 用例失败:

Error: Cannot access 'warnings' before initialization

1 !== 0

You see。harvest --identity dup.json --json 退出 2,stdout 的 error.message 是 identity.json: handle "x" is claimed by both "A" and "B",find $W -newer dup.json 为空。没写 handles 的映射退出 0,warnings 含林工。

Rollback

回退本 PR head。已经写入的合法映射不用迁移。栈停在 dot-skill-test,dot-skill 保留。

Load and reject duplicate handles before mkdir/copy so a bad map
writes nothing. Declare warnings before pushing empty-handle notices.
Emit harvest receipts through createReceipt with entries after the
contract fields.
Sign up for free to 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.

2 participants