Skip to content

fix(ensemble-workflow): null-skip fail-open in shared harness + harness regression tests#16

Merged
kiki830621 merged 1 commit into
mainfrom
fix/dogfood-other-skills
Jun 3, 2026
Merged

fix(ensemble-workflow): null-skip fail-open in shared harness + harness regression tests#16
kiki830621 merged 1 commit into
mainfrom
fix/dogfood-other-skills

Conversation

@kiki830621

Copy link
Copy Markdown
Contributor

摘要

對另外三個 skill(lecture / academic / compose)+ 共用 harness 做與 code-review 三輪同等強度的 dogfood(task 2)。結論:三個 skill 的 harness contract 全部正確,唯一真 bug 在共用 harness —— 一個 fail-OPEN 假綠燈。順手把 harness 補上 regression 測試、修了 plugin CLAUDE.md 的 drift。

Dogfood 結果

目標 結論
ensemble-lecture-review ✅ clean。args(profile/file/srtFile/contextBlock/replicas/codexEnabled)全對得上 harness;SRT 走 path、內容不進 args/git(合隱私規則)。
ensemble-academic-review ✅ contract clean。disableLenses:["number-verifier"]priors:{"reference-verifier","da"}、codexMaxTime 走 profile 預設 900 —— 欄位名/值全對。disableLenses 永不空集(methodology/writing 恆在 + harness 空集 backstop)。
ensemble-compose ✅ clean。CSV 用 python3 csv 模組(非 naive split)、空 key/focus skip、與 harness customLenses filter 對稱;includeLenses/customLenses 欄位對得上;大 CSV 由 harness slice 封頂。
共用 harness ensemble-workflow.js ⚠️ 1 個真 bug(已修) + 多項確認穩健。

修的 bug(共用 harness,fail-OPEN)

null-skip fail-open:Workflow runtime 在「使用者中途 skip 某 agent」時讓 agent()null(官方語意)。但 review / codex / devil's-advocate 三個 .then 只用 (r && r.findings) || [] 處理 null 的 findings沒處理 ok flag

// 修前:null(skip)→ ok:true(被當乾淨通過)→ 繞過 fail-closed → 假 PASS
.then((r) => ({ lens, findings: ((r && r.findings) || []).map(...), ok: true }))
// 修後:
.then((r) => r == null ? { lens, findings: [], ok: false } : { lens, findings: (r.findings||[]).map(...), ok: true })

.catch 只攔 throw、攔不到 null 回傳。後果:被 skip 的 core lens / DA 不會觸發 fail-closed 的 HIGH integrity finding,verdict 可能假 PASS —— 與 code-review 三輪一直在防的「git fatal → 假綠燈」同一類,只是換成 JS 的 null 路徑。

repro + 整合測試已證實:修前 skip security → PASS(無 integrity);修後 → FINDINGS + security:HIGH

新增:harness regression 測試(task 2 = task 1 的同等待遇)

harness 原本零測試。test/ensemble-workflow.test.mjs(8 個,純 node)把 workflow script body 包成可 import 的 async 函式、注入 mock 的 agent/parallel/phase/log/args 實跑整個 orchestration:

  • unknown profile → HIGH harness finding
  • 空 lens 組合(custom 無 lens)→ HIGH "no active lenses"
  • all-ok → PASS、無 integrity
  • REGRESSION:skip core lens(null) → fail-closed HIGH(鎖死本次修正)
  • error(throw) core lens → fail-closed HIGH
  • skip devil's-advocate → fail-closed HIGH
  • skip codex → INFO 非阻塞、verdict 維持 PASS
  • mergeDedup 對 malformed severity 穩健(不 crash、finding 不掉)

已接進 test/run.sh.github/workflows/test.yml

Docs

plugin CLAUDE.md 修 drift:原本只列已不存在的單一 /parallel-ai-agents:ensemble-review + 「4 teammates + 1 Codex」舊架構 → 改成實際的 4 個 skill + 雙 backend(Workflow harness 預設、legacy fallback)+ fail-closed 說明。

驗證

$ ./test/run.sh
shellcheck ✓ | bats 25/25 ✓ | harness node 8/8 ✓

版本

2.14.02.14.1(plugin.json + marketplace.json 同步)。CHANGELOG 已補 [2.14.1]

…egression tests

Dogfood 另外三個 skill(lecture/academic/compose)+ 共用 harness:3 個 skill 的
harness contract(欄位名)全部正確、無 mismatch;唯一真 bug 在共用 harness。

修正:
- null-skip fail-OPEN:Workflow 在使用者中途 skip agent 時 agent() 回 null,
  但 review/codex/da 三個 .then 只處理 null 的 findings、沒處理 ok flag
  → 被 skip 的 reviewer 當成 ok:true(乾淨通過)→ 繞過 fail-closed → 假 PASS。
  三處 .then 把 r==null 視為 ok:false。repro + 整合測試已證實。

新增:
- test/ensemble-workflow.test.mjs — harness 的 8 個 node regression
  (unknown profile/空 lens/skip/throw/DA 缺席→HIGH integrity、codex→INFO、
  mergeDedup malformed severity 穩健)。把 fail-open 修正鎖死。接進 run.sh + CI。

Docs:
- plugin CLAUDE.md 修 drift:4 個實際 skill + 雙 backend + fail-closed。

bump 2.14.0 → 2.14.1(plugin.json + marketplace.json)。
@kiki830621 kiki830621 merged commit eefee1f into main Jun 3, 2026
1 check passed
@kiki830621 kiki830621 deleted the fix/dogfood-other-skills branch June 3, 2026 08:09
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.

1 participant