Skip to content

release: issue #285 durable scan boundary + issue #286 hook field drift - #290

Merged
LeXwDeX merged 4 commits into
mainfrom
dev
Aug 15, 2026
Merged

release: issue #285 durable scan boundary + issue #286 hook field drift#290
LeXwDeX merged 4 commits into
mainfrom
dev

Conversation

@LeXwDeX

@LeXwDeX LeXwDeX commented Aug 15, 2026

Copy link
Copy Markdown
Owner

合并 dev 到 main,关闭全部 open issues:

#288 fix(hook): apply prompt-hook timeout, surface dropped HookCommand fieldscloses #286

  • promptHandler 落地 entry.timeout(文档承诺全类型支持,此前唯 prompt 型未执行;超时降级为既有非阻塞 warn)
  • detectUnsupportedFields 追加 allowedEnvVars/statusMessage/per-command once(零消费字段显式告警而非静默 no-op)

#289 fix(goal): durable boundary gate stops crash-recovery turn inflationcloses #285

  • GoalState 新增 last_judged_msg,continue 提交时同事务持久化判定边界
  • 启动扫描门:窗口仍终止于已判定边界时跳过再评估,杜绝崩溃重启的 turns_used 通胀与重复续派;live idle 不受影响

Evidence:两 PR 独立通过 dev 门禁(Typecheck+CodeQL);test/goal 105 pass、test/hook 146 pass;红测先行(/tdd);改动 lint 净零。请 main 全量门禁复核。

issue #286 — HookCommand schema accepted fields that every executor dropped:
- promptHandler now applies entry.timeout (same idiom as command/mcp/http;
  the header doc promised timeout for every hook type but prompt was the only
  executor never enforcing it — expiry degrades to the existing non-blocking warn)
- detectUnsupportedFields now flags allowedEnvVars / statusMessage / per-command
  once (zero consumers; only entry-level _sessionEntry?.once is read) so configs
  warn instead of silently no-op; timeout stays unflagged (now fully honored)

Test: red-first in test/hook/warn-unsupported.test.ts (flagging), 146 hook tests green.
fix(hook): apply prompt-hook timeout, surface dropped HookCommand fields
issue #285 — after a crash, the boot scan could re-judge the exact boundary
the crashed process already judged and committed: evaluatedRevisions is
process-local, so both dedup gates let the stale boundary through, and
updateAfterJudge inflated turns_used and dispatched a duplicate continuation.

- GoalState.Info gains last_judged_msg; updateAfterJudge(judged) persists the
  judged assistant message id on every continue commit (same transition, atomic)
- afterIdle scan path: while the session window still ends on last_judged_msg,
  no new progress has landed — skip re-evaluation. Live idle events are never
  gated: each dispatched continuation produces a fresh assistant message, so
  the live path always judges a new boundary; resume/subgoal edits re-drive
  through live turns, not the scan.
- crash between continue commit and continuation dispatch: the gate skips
  (avoids inflation + duplicate); recovering the lost dispatch remains the
  separate explicit design noted in goal CONTEXT.md.

Tests (red-first): unchanged-boundary scan commits nothing (turns stay 1, judge
0 calls); advanced-boundary scan proceeds (turns 2, continuation dispatched).
fix(goal): durable boundary gate stops crash-recovery turn inflation
@LeXwDeX
LeXwDeX merged commit 7209634 into main Aug 15, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant