Skip to content

Discrete mode: stage advancement gated on PR/MR merge (followup hardening) #248

Description

@jwaldrip

Summary

PR #245 added discrete-mode coercion in `gate.ts` so every stage gate forces external PR/MR review (`review: auto` → `external`, `review: ask` → `ask,external` compound, etc.). This issue tracks the hardening followups that didn't land in #245.

What's already in place (verified during #245)

  • `ensureOnStageBranch()` runs at the top of `haiku_run_next` (`tools/orchestrator/haiku_run_next.ts:176`) — pickup-from-main reroutes to the active stage branch, forward-merges main → stage if drifted.
  • Merge-detection gates completion — when `status: completed + gate_outcome: blocked`, the gate handler at `gate.ts:449` calls `isBranchMerged(stageBranch, mainline)` and only flips to `gate_outcome: advanced` after the actual merge happens. Local approve alone never advances the stage.

What's still missing

1. `writeOnIntentMain()` for intent-scope frontmatter writes

`intent.md` is intent-scope metadata. Today it's written via `setFrontmatterField(intentFile, ...)` from ~25 call sites, including some that run while checked out on a stage branch. Result: `intent.md` can diverge between the stage branch and intent main (observed bug: `twelve-week-plan-accountability-app` had `active_stage: product` on intent main while the stage branch had `active_stage: development`).

Fix shape:

  • Introduce a `setIntentField()` helper that wraps `setFrontmatterField` AND mirrors the write to intent main via `writeOnIntentMain()`.
  • Migrate every intent-scope FM call site (`active_stage`, `status`, `archived`, `phase`, `started_at`, `completed_at`, `completion_review_*`, `autopilot`, `mode`).
  • Add a startup/pre-tick consistency check that compares `intent.md`'s key fields between the active stage branch and intent main; surface as a guard error if they diverge.

2. Pre-tick `active_stage` repair (✅ shipped in #245 — kept here for cross-reference)

`preTickConsistency` in `workflow/pre-tick.ts` now derives `active_stage` from state.json walk and rewrites `intent.md` when stale. This masks the divergence bug above as a self-healing safety net, but the underlying writes-on-stage-branch is what should actually be fixed.

3. Mode-change tool (out-of-scope for this issue, mentioned for completeness)

There's currently no `haiku_intent_change_mode` tool. Mode is fixed at intent creation. If we want to support mode migration (continuous ↔ discrete), it needs its own dedicated tool with branch-migration logic — not a frontmatter edit.

Acceptance criteria

  • All intent-scope `setFrontmatterField(intentFile, ...)` calls route through `setIntentField` (or equivalent)
  • Pre-tick consistency check detects intent.md divergence between stage branch and intent main; surfaces a guard error with recovery instructions
  • Test: simulate a stage-branch write that mutates intent.md; assert that the next `haiku_run_next` tick from intent main propagates the change correctly
  • Test: simulate intent.md divergence; assert that pre-tick surfaces the guard error rather than silently picking one version

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions