Skip to content

Commit 02bc042

Browse files
committed
fix(plan): review fixes — single notify per check_replace with Revised flag, rune-safe evidence_note truncation, wire rollback note
1 parent 761076e commit 02bc042

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

‎docs/PLANNING.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ standard built-in interface (`Name`/`Description`/`Schema`/`Call`).
300300
| `check_replace` | `step_id`, `check_id`, `justification`, plus `replacement` or `evidence_note` | Replaces one dead/stale/environment-denied check with a fresh pending one, or marks it satisfied by equivalent verification that ran via other tools. Justification is mandatory and audit-trailed in the revision block. |
301301
| `get` | — | Returns the current plan (or `"No active plan."`). |
302302

303+
Note on wire compatibility: a check whose tool call was denied by the
304+
approval gate renders with status `blocked`. Sessions persisted by builds
305+
that know `blocked` fail to parse on older odek binaries (which reject the
306+
unknown status); resume such sessions only on equal-or-newer builds.
307+
303308
### Incremental revisions
304309

305310
Use `revise` when the plan changes after work or evidence already exists.

‎internal/loop/plan.go‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,8 @@ func (s *PlanStore) checkReplace(args planArgs) (string, error) {
637637
wStep.Checks[ci] = fresh[0]
638638
case args.EvidenceNote != "":
639639
note := normalizePlanText(args.EvidenceNote)
640-
if len(note) > maxPlanCheckDescChars {
641-
note = note[:maxPlanCheckDescChars]
640+
if runes := []rune(note); len(runes) > maxPlanCheckDescChars {
641+
note = string(runes[:maxPlanCheckDescChars])
642642
}
643643
wStep.Checks[ci] = PlanCheck{
644644
ID: old.ID,
@@ -660,7 +660,10 @@ func (s *PlanStore) checkReplace(args planArgs) (string, error) {
660660
}
661661
s.noteStatusTransitionsLocked(s.plan.Steps, working)
662662
s.plan = &candidate
663-
s.notifyLocked(false, false)
663+
// executeArgs fires the single notify for every effective mutation;
664+
// notifying here would double-fire plan_updated. Mark the revision so
665+
// downstream change events carry Revised (same contract as revise).
666+
s.revisionNotify = true
664667
return s.renderLocked(), nil
665668
}
666669

0 commit comments

Comments
 (0)