Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
cfb42e8
fix(memory): extend background-maintenance lock discipline to the per…
LeXwDeX Aug 18, 2026
1d087ff
Merge pull request #333 from LeXwDeX/fix/memory-lock-discipline
LeXwDeX Aug 18, 2026
bcad76e
docs(audit): add three-module functional audit evidence (DAG/MEMORY/G…
LeXwDeX Aug 18, 2026
ed7185a
fix(goal): boundary gate suppresses re-judgment, not the drive (GOAL-01)
LeXwDeX Aug 18, 2026
551b8f7
fix(goal): keep turn-driven mark when ESC pause exhausts retries (GOA…
LeXwDeX Aug 18, 2026
9fc67e8
fix(goal): failed judge is budget-neutral, does not stamp judged boun…
LeXwDeX Aug 18, 2026
f0e7278
fix(goal): startup scan busy skip is logged and retried once, never s…
LeXwDeX Aug 18, 2026
429e588
chore(goal): align comments with GOAL-02/04 semantics (review round 1)
LeXwDeX Aug 18, 2026
5dd5a30
fix(goal): distinguish ESC-pause no-op from retry exhaustion; silence…
LeXwDeX Aug 18, 2026
ce87f84
docs(goal): record review round-3 findings and closures
LeXwDeX Aug 18, 2026
db44487
refactor(goal): address review round-4 findings (no-op classification…
LeXwDeX Aug 18, 2026
58b56b4
docs(goal): sync D-4/status-branch/freshMsgs comments with the GOAL-0…
LeXwDeX Aug 18, 2026
5e6ab11
docs(goal): declare module convergence after two consecutive clean re…
LeXwDeX Aug 18, 2026
a56ed05
docs(goal): record PR #334 delivery and closure of the goal run
LeXwDeX Aug 18, 2026
799ea05
docs(goal): correct turbo typecheck status (pre-push hook green)
LeXwDeX Aug 18, 2026
43fd72b
docs(audit): add three-module functional audit evidence (DAG/MEMORY/G…
LeXwDeX Aug 18, 2026
71ab1bd
fix(dag): gate equality conditions on string outputs and enforce chec…
LeXwDeX Aug 18, 2026
1c4f1ad
fix(dag): replan-verdict pause gate fails closed and folds pause defe…
LeXwDeX Aug 18, 2026
db626d4
fix(dag): rethrow publisher interrupts and bound global disposeAll (D…
LeXwDeX Aug 18, 2026
3378146
fix(dag): veto hold survives flag re-syncs, released by parent contro…
LeXwDeX Aug 18, 2026
ff1f8da
docs(dag): sharpen vetoHold release-scope and bounded-dispose comment…
LeXwDeX Aug 18, 2026
85df043
docs(dag): correct the vetoHold resume-reachability enumeration (revi…
LeXwDeX Aug 18, 2026
5128f09
docs(dag): attach the output_schema clause to the gating fix in the u…
LeXwDeX Aug 18, 2026
230fd2c
docs(dag): declare module convergence after two consecutive clean rev…
LeXwDeX Aug 18, 2026
39affbd
Merge pull request #335 from LeXwDeX/fix/dag-batch
LeXwDeX Aug 18, 2026
11cfafe
Merge pull request #334 from LeXwDeX/fix/goal-batch
LeXwDeX Aug 18, 2026
70291fb
fix(memory): matcher calls run outside the fence, coalescing via in-f…
LeXwDeX Aug 18, 2026
f08548d
fix(memory): in-flight matcher registration is exit-safe and publishe…
LeXwDeX Aug 18, 2026
ef8d6b8
fix(memory): bracket the whole runner tail from registration, turn-sc…
LeXwDeX Aug 18, 2026
9094abc
docs(memory): record review round-2 closures
LeXwDeX Aug 18, 2026
04385af
docs(memory): sync in-flight key wording and awaiter interrupt commen…
LeXwDeX Aug 18, 2026
0c19194
docs(memory): precise awaiter failure mapping and topics-read suspens…
LeXwDeX Aug 18, 2026
57a1a81
docs(memory): declare acceptance-leftover batch convergence
LeXwDeX Aug 18, 2026
3f23ff3
Merge pull request #336 from LeXwDeX/fix/memory-fence-scope
LeXwDeX Aug 18, 2026
833f0b8
fix(dag): reporting checkpoints carry an adversarial verification cla…
LeXwDeX Aug 18, 2026
4019ddf
fix(dag): add a quantified spot-check floor to the adversarial clause…
LeXwDeX Aug 18, 2026
32d15cd
Merge pull request #337 from LeXwDeX/fix/dag-adversarial-checkpoint
LeXwDeX Aug 18, 2026
37ee09c
fix(dag): host-level supervision sweep settles nodes orphaned by inst…
LeXwDeX Aug 18, 2026
9b76a87
fix(dag): sweep survives layer context (no ambient InstanceRef), cade…
LeXwDeX Aug 18, 2026
0d11e05
fix(dag): per-node cadence-aware freeze window from workflow config (…
LeXwDeX Aug 18, 2026
5033463
fix(dag): defensive config parsing and pure cadence lookup in sweep (…
LeXwDeX Aug 18, 2026
f185065
fix(dag): cause-recover the sweep cancel seam, gate settle success (r…
LeXwDeX Aug 18, 2026
235d031
fix(dag): propagate interrupts in sweep recovery sites, correct cross…
LeXwDeX Aug 18, 2026
a957cb7
chore(dag): merge duplicate dag import
LeXwDeX Aug 18, 2026
44c5843
Merge pull request #338 from LeXwDeX/fix/dag-node-supervision
LeXwDeX Aug 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
537 changes: 537 additions & 0 deletions docs/audit-dag-memory-goal-2026-08-18.md

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions docs/findings/dag-batch-findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# DAG 批次 Findings Register

- 验收 primary source:`docs/audit-dag-memory-goal-2026-08-18.md`(DAG 章节)
- 分支:`fix/dag-batch` → PR `dev`
- 收敛判据:连续两轮独立审阅(Spec 镜 + Standards 镜)零 findings + 模块门禁全绿
- 规格:`workflows/audit-fix-loop.md`
- 触发:用户指示在 GOAL run(PR #334)之后立即开工,不等合入

## 审计缺陷切片(输入项,非审阅 finding)

| ID | 严重性 | 切片顺序 | 状态 | 提交 |
|---|---|---|---|---|
| DAG-01 + DAG-02 | High | A(P0,审计明确要求一并修) | 完成(红-绿-变异×3 通过) | 71ab1bdf6 |
| DAG-03 | Medium | B (P1) | 完成(红-绿-变异×2 通过) | 1c4f1ad7a |
| DAG-04 | Medium | C (P1,#316 机制部分;触发源不追查,按审计记录缺口) | 完成(红-绿-变异×2 通过) | db626d4ba |

## 切片设计要点(实现后回填)

- **A(DAG-01+02)**:
- 运行时:spawnReady 条件求值前对字符串依赖输出做 `parseJsonOption` 归一化(与 replan-verdict 门同源);非 JSON 回退原串(整串等值可用、字段路径仍 false、数值比较仍 loudly-fail)。
- authoring:`checkpointGateDiagnostics` 追加「被门控 checkpoint 必须声明 output_schema」(authoring 期错误;运行时路径不要求——runtime-created 图按 CONTEXT.md 有意豁免 authoring 校验,`requireOutputSchema:false`)。
- 门禁接线:`validatePostCompile` 的 checkpoint 门不再随 `structural:false` 对 replan/extend 关闭(fragment 内对生效);`replanStructuralDiagnostics` 对 merged 图补跑 checkpoint 门(覆盖 fragment 挂到既有 checkpoint 的场景),**豁免持久图中已终态的 checkpoint**(裁决已交付,加波/重开是受 sanction 的模式——reopenDenial 加性重开的既有语义)。
- 波及适配 2 个既有 harness(blanket `report_to_parent:true` 的 rev-view / stale-nodefailed 形状按门禁语义补 condition);dag-wake-integration 的加波/重开场景经终态豁免自然兼容,无需改动。
- **B(DAG-03)**:pause 终态失败 fail-closed(恒 hold),`Effect.catch` → `Effect.catchCause`(hasInterrupts 再抛)折叠 defect;logWarning → logError(含 durableStatus)。
- **C(DAG-04)**:publisher 外层 catchCause 依 F1 模式 `hasInterrupts` 再抛;`disposeAllInstancesAndEmitGlobalDisposed` 加 10s 有界超时(`timeoutOption`——超时即放弃且不产生错误,保住 HttpApi dispose endpoint 的 `never` 错误通道),去掉 uninterruptible 包裹;Disposed 事件在超时/吞错后仍必落地;真实处置失败在非 swallow 路径仍传播。
- 中断测试注入方式:scope-disposal 杀 fiber 的 cause 实测为 Die 而非 Interrupt(已实证),改用 `Effect.failCause(Cause.interrupt(0))` 在 store 边界直接注入 interrupt cause(goal e2e 既有模式),精确命中被修复的 catchCause 判别线。

## 模块门禁
- 切片级:每切片 dag 目标测试簇绿 + 包内 typecheck 绿 + 变异翻红验证(见上表)
- 全量套件:进行中

## 审阅轮次

(每轮审阅结果记账于此;全部关闭后才具备发 PR 资格)

### Round 1
- Spec 镜:**PASS**,3 条 Low INFO;Standards 镜:**PASS**,6 条 findings(F1-F6)。处置:
- F1 + INFO-2(Medium):ADR-0003 与新 enforcement 矛盾。→ **已同步**:Decision/Consequences/Deferred 改写为「validatePostCompile 全动作 + replanStructuralDiagnostics merged 图(终态豁免)+ create 刻意不动 + output_schema authoring 义务」,Deferred 首项标记 resolved。
- F2 + INFO-1(Medium,需主裁决):fail-closed 保持会被后续 NodeCompleted/NodeSkipped/stepped 的 durable-row re-sync 解除;且 Replanned 处理器从不重同步 paused(hold 也会闷死 corrective 派发)。用户裁决「解决所有已知问题」。→ **已实装**:`WorkflowEntry.vetoHold`——门设置、两处 re-sync 点(node 终态序言 + refreshControlFlags)尊重保持、三个父控制事件(Replanned/Resumed/Stepped)释放并重同步(Replanned 补上从未有过的 flag 重同步);新增 2 条红绿测试(re-sync 存活 + replan 释放)+ 双向变异验证。
- F3(Low):global-lifecycle.test.ts 未用 `Option` 导入。→ 已删。
- F4(Low):loop.ts「normalization above」方向失准。→ 已改为指向 NodeCompleted 处理器。
- F5(Low):终态豁免措辞「delivered its verdict」对 failed/aborted/skipped 不真。→ 三处改为「settled and immutable」(CONTEXT.md/validation.ts×2)。
- F6(Low, informational):无 uninterruptible 的取舍记录。→ 无需动作(reviewer 确认 trade 正确)。
- INFO-3(Low):register 误记「3 个 harness 适配」。→ 已更正为 2(wake-integration 经终态豁免免改)。
- 结论:非干净轮。修复后进入 Round 2。

### Round 2
- Spec 镜:**PASS**,3 条 INFO;Standards 镜:**PASS**,1 条 INFO。处置:
- R2-1(INFO):vetoHold 注释宣称「replan/resume/step 均可释放」不精确——hold 态持久行是 running,resume 对 running 是非法迁移(InvalidTransitionError),resume 释放仅在 stepping/pending 态可达。→ 已改写字段注释:replan/step 任何 hold 态可达;resume 仅 stepping/pending;control(replan) 正是 verdict 所求的处置路径。
- R2-2(INFO):hold 为进程内状态,重启后从持久行重建(审计 DAG-03 的范围就是进程内 fail-open)。→ 已在字段注释记录该边界。
- R2-3(INFO):timeoutOption 的切断发生在第一个可中断点——uninterruptible finalizer 区域内的 wedge 可越过上限(硬切断需 Effect.disconnect,刻意不取,与 exerciser 的 Promise.race 同残差)。→ 已在 global-lifecycle 注释精确化。
- Standards INFO-1:dag-loop-guards.test.ts 未用的 `probe` 变量。→ 已删。
- 结论:非干净轮(4 INFO)。修复后进入 Round 3。

### Round 3
- Spec 镜:**PASS,no findings**(干净轮候选)。
- Standards 镜:**PASS**,1 条 INFO:R3-1——vetoHold 注释的 resume 枚举「stepping/pending」不完整:hold 之后父层仍可先持久 pause 再 resume(该路径释放有效),且 pending 对已启动工作流不可达。→ 已改为「resume only when the durable row is not running (paused/stepping)」并说明直至持久 pause 落地。
- 结论:非干净轮。修复后进入 Round 4。

### Round 4
- Spec 镜:**PASS,no findings**。
- Standards 镜:**PASS**,1 条 INFO:R4-1——ungated 诊断的 hint 把「declare output_schema」列为独立替代项,但单独声明 schema 不能解除 ungated 错误(须与 gating 条件组合)。→ 已改写为「Gate … with condition … and declare output_schema …」组合句式。
- 结论:非干净轮。修复后进入 Round 5。

### Round 5
- Spec 镜:**PASS,no findings**;Standards 镜:**PASS,no findings**(R4 hint 修复逐条复核为真)。
- 结论:**干净轮 1/2**。

### Round 6
- Spec 镜:**PASS,no findings**(四缺陷 + F2 + 文档同步独立复核;附 process note:PR 前回填 R5 结果——本条即回填)。
- Standards 镜:**PASS,no findings**(Effect v4 API 对照 effect-smol 源码逐一验证;注释真实性对照 transition table/replan.ts/spawn.ts 复核)。
- 结论:**干净轮 2/2**。连续两轮零 findings → **DAG 模块收敛**。

## 收敛结论

R1(Spec 3 Low + Standards 6)→ R2(Spec 3 + Standards 1)→ R3(Spec 0 + Standards 1)→ R4(Spec 0 + Standards 1)→ **R5+R6 连续两轮双镜零 findings**。全部 findings 关闭,findings 衰减轨迹清晰(Medium 实装 → Low 措辞 → 零)。

## 模块门禁(终态)

- 切片级:dag 测试簇绿(579/579 含新增 19 条回归)+ 包内 `bun typecheck` 绿 + 每切片变异翻红验证。
- 全量套件:4157 tests / 342 files,仅 2 失败均为 GOAL run 期间已在干净基线 detached 复跑证实的 darwin 环境既有失败(help-snapshots、project-copy;pty 本轮通过),与本批无因果;DAG/GOAL 相关零失败。

## 交付

- 分支:`fix/dag-batch`(基于 origin/dev 1d087ffe9)
- 提交链:43fd72bbd(audit 文档)→ 71ab1bdf6(DAG-01/02)→ 1c4f1ad7a(DAG-03)→ db626d4ba(DAG-04)→ 337814648 / ff1f8dab5 / 85df04311 / 5128f0958(审阅轮修复)
- PR → dev(Typecheck 门禁),合入由用户授权执行
89 changes: 89 additions & 0 deletions docs/findings/goal-batch-findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# GOAL 批次 Findings Register

- 验收 primary source:`docs/audit-dag-memory-goal-2026-08-18.md`(GOAL 章节)
- 分支:`fix/goal-batch` → PR `dev`
- 收敛判据:连续两轮独立审阅(Spec 镜 + Standards 镜)零 findings + 模块门禁全绿
- 规格:`workflows/audit-fix-loop.md`

## 审计缺陷切片(输入项,非审阅 finding)

| ID | 严重性 | 切片顺序 | 状态 | 提交 |
|---|---|---|---|---|
| GOAL-01 | High | 1 (P0) | 完成(红-绿-变异通过) | ed7185a0f |
| GOAL-02 | Medium | 2 (P2) | 完成(红-绿-变异通过) | 551b8f78a |
| GOAL-03 | Low | 3 | 完成(红-绿-变异通过) | 9fc67e8e7 |
| GOAL-04 | Low | 4 | 完成(红-绿-变异通过) | f0e727865 |

## 模块门禁
- `bun typecheck`(tsgo --noEmit):✅ 绿
- goal 目标测试簇(test/goal/,107 tests):✅ 绿
- 每切片变异验证(revert 翻红 → 恢复):✅ GOAL-01/02/03/04 均通过
- 全量测试套件(`bun test`,4141 tests / 341 files):goal 相关全绿;另 3 处失败经基线复跑判定为**非本批引入**(见下)。
- 基线 CI(`1d087ffe9`,GitHub linux)全量 **success** → 基线干净。
- 本机(darwin)基线 detached 复跑:`project-copy`、`help-snapshots` 同样失败,`httpapi-v2-pty` 计时性 flake(隔离复跑即过)。三者均不 import `src/goal`,diff 亦不触及其依赖闭包 → 环境/时序性既有缺陷,与本批改动无因果。

## 审阅轮次

(每轮审阅结果记账于此;全部关闭后才具备发 PR 资格)

### Round 1
- 派遣:Spec 镜(对照审计 GOAL 章节逐条验收)+ Standards 镜(仓库规约/Effect/CONTEXT/测试纪律),只读、并行、互不复用上下文。
- Standards 镜:**PASS,no findings**。
- Spec 镜:**PASS**,2 项 Low findings(均已关闭):
- F-1(Low)`src/goal/goal.ts`:GOAL-02 后 turnDriven 汇总注释仍写"ESC-cancel 即清除",与"仅 pause 持久化成功才清除"不符。→ 已改写注释(commit 429e58815)。
- F-2(Low)`test/goal/e2e-loop.test.ts`:GOAL-04 断言所在用例名/注释未提"有界 scan 重试也可驱动 deferred 会话"。→ 已改名 + 补注释(commit 429e58815)。
- 结论:非干净轮。修复 F-1/F-2 后进入 Round 2。

### Round 2
- Spec 镜:**PASS,no findings**(F-1/F-2 修复逐行复核通过;四缺陷验收保持满足;429e58815 仅注释/命名变更,无行为影响)。
- Standards 镜:**PASS,no findings**。
- 结论:第 1 个干净轮。按收敛判据需连续两轮零 findings → 进入 Round 3。

### Round 3
- Spec 镜:**PASS,no findings**。
- Standards 镜:**PASS**(verdict),3 条 INFO(非阻塞),处置如下:
- R3-INFO-1(goal.ts pauseForUserCancel):成功 no-op(ESC 落在已暂停/已清除目标上,如 auto-pause 提交与 mark 之间的窗口)被误报为 retry-exhaustion ERROR。→ **已修复**(commit 5dd5a3037):以 `lastCause` 区分三态——成功 pause(清 mark+unregister)、真实耗尽(保留 mark+ERROR)、成功 no-op(静默清除陈旧 mark);新增回归测试 `cancel on an already-paused goal is a silent no-op that retires a stale mark`。
- R3-INFO-2(loop.ts scan 级 catchCause):GOAL-04 新增 2s 重试放大了 dispose 中断窗口,正常关停会被记成 "goal startup scan failed"。→ **已修复**(commit 5dd5a3037):与同文件 triggerEvaluation 相同的 F1 纪律——`Cause.hasInterrupts` 静默,真实失败才告警。无独立红测试:dispose-期间中断无法在当前 harness 内确定性触发而不耦合 instance 内部;以同文件既有 F1 模式一致性为准。
- R3-INFO-3(分支含 3 个非 goal 文件):审计文档/findings register/workflow 规格随 GOAL PR 落地是 workflow 规格的设计决定(audit-fix-loop.md §0:审计文档必须先于两个 run 进 dev),**非缺陷,按设计关闭**。
- 结论:非干净轮(Round 2 的连续干净计数重置)。修复后进入 Round 4。

### Round 4
- Spec 镜:**PASS**,2 条 INFO;Standards 镜:**PASS**,4 条 INFO(其中 lastCause 混合结果一条与 Spec 镜重合)。处置:
- lastCause 分类按最终尝试结果(R4 共同项):成功退出重试循环时 `lastCause = undefined`,杜绝「早期瞬态失败 + 后续成功 no-op」被误判为耗尽。→ 已修复。
- pause 文案「judge 期间会话状态变化」在 GOAL-01 gate-hit 路径失准:改为中性「会话状态变化(X),目标已暂停」(既有测试只断言 contains「状态变化」,不受影响)。→ 已修复。
- noop 回归测试未真正钉住(Goal.pause 本身清 mark,前置 mark 到不了 pauseForUserCancel):重写为 pause 之后重新 markTurnDriven 造真实陈旧 mark,并断言 logLines 不含 "failed after retries"(旧代码必触发该日志 → 测试真正翻红可验证)。→ 已修复。
- 两处注释(Interface doc + GOAL-TURN-SCOPE 块)与第三分支(no-op 静默清 mark)矛盾:已改写一致。
- GOAL-04 重试环的 per-session catchCause 缺 interrupt 抑制(与外层 scan handler 不一致):两处 per-session catchCause(首轮 + 重试环)均加 `Cause.hasInterrupts` F1 抑制。→ 已修复。
- 结论:非干净轮。修复后进入 Round 5。

### Round 5
- Spec 镜:**PASS,no findings**(干净轮 1/2 候补——但 Standards 非干净,计数重置)。
- Standards 镜:**PASS**,2 条 INFO(GOAL-01 judge-less 路径后遗留的陈旧注释):
- R5-INFO-1:D-4 evaluatedRevisions 头注释仍称「仅由成功 updateAfterJudge commit 写入」,未含 gate-hit drive-restored 写入点。→ 已改写(并自查发现同根第 3 处:freshMsgs 的 "Reload messages after judge LLM call" 一并改为两可措辞)。
- R5-INFO-2:branch-3 首行 "Session is no longer idle after the judge call" 对 gate-hit 路径失准。→ 已改写。
- 结论:非干净轮。进入 Round 6。

### Round 6
- Spec 镜:**PASS,no findings**。
- Standards 镜:**PASS,no findings**(含注释真实性、Effect 习语、测试纪律、CONTEXT.md 不变量的全量复核)。
- 结论:**干净轮 1/2**。进入 Round 7;若再干净 → 连续两轮零 findings,模块收敛。

### Round 7
- Spec 镜:**PASS,no findings**(独立复核 GOAL-01..04 修复 + 测试义务 + 验证为正确部分)。
- Standards 镜:**PASS,no findings**(Effect 习语/风格/CONTEXT.md 不变量/测试纪律/注释真实性全量复核)。
- 结论:**干净轮 2/2**。连续两轮零 findings → **GOAL 模块收敛**。

## 收敛结论

R1 有 2 Low → 修复;R2 干净(因 R3 有 findings 计数重置);R3 有 3 INFO → 修复;R4 有 5 INFO → 修复;R5 有 2 INFO → 修复;**R6+R7 连续两轮双镜零 findings**。全部 findings 已关闭,模块具备发 PR 资格。

## 交付

- **PR**:https://github.com/LeXwDeX/OpenCode-GraphAgent/pull/334 → `dev`(门禁 Typecheck;CI run 32113882464 进行中)
- 提交链:bcad76ebf(audit 文档)→ ed7185a0f(GOAL-01)→ 551b8f78a(GOAL-02)→ 9fc67e8e7(GOAL-03)→ f0e727865(GOAL-04)→ 429e58815 / 5dd5a3037 / ce87f84bd / db44487c7 / 58b56b490 / 5e6ab11fe(审阅轮修复与记账)
- 终态门禁:goal 测试簇 108/108 绿;`bun typecheck`(packages/opencode)绿;全量 4142 tests 除 3 项基线既有 darwin 环境性失败外全绿(已在干净基线 detached 复跑证实非本批引入)。
- 已知本地环境既有失败(与本批无关,已在干净基线 detached 复跑证实):全量测试中 project-copy / help-snapshots / pty 三项(darwin 环境/计时性)。根 turbo typecheck 曾一次命中 `@opencode-ai/app` 的瞬时缓存失败,随后(pre-push 钩子)29/29 全绿自愈。

## 下一 run

DAG 批次(DAG-01..04):事件触发 = 本 PR 合入 dev 后从新基线切 `fix/dag-batch`。
Loading
Loading