fix(harness): bind planning gate approval to the review-cycle epoch - #164
Open
Christiantyemele wants to merge 2 commits into
Open
fix(harness): bind planning gate approval to the review-cycle epoch#164Christiantyemele wants to merge 2 commits into
Christiantyemele wants to merge 2 commits into
Conversation
FORGE could escalate to 'building' by consuming a stale or pre-seeded gate approval from a prior cycle, without SENTINEL having reviewed the current plan. This was observed when a 4-day-old planning approval (legacy, no epoch) authorized a fresh build. Enforce cycle freshness in the shared store: - status set planning advances a per-ticket plan_epoch (INCR) and clears any prior planning-gate approval, opening a fresh review window. - gate approve records the current plan_epoch in the GateApproval and refuses to approve when no cycle is open (epoch missing). - status set out of planning (GETDEL path) now rejects the transition when the consumed approval's plan_epoch does not match the current epoch, so legacy/pre-seeded approvals (epoch 0) cannot authorize a build; SENTINEL must re-review the current plan. - gate status prints the approval's epoch vs. the ticket's current epoch and flags stale approvals (warning) so humans/NEXUS can audit. GateApproval.plan_epoch uses #[serde(default)] for backward compatibility with pre-epoch records (they deserialize as stale).
Christiantyemele
force-pushed
the
fix/plan-epoch-gate-freshness
branch
from
August 18, 2026 16:20
9dd926c to
f9b2d41
Compare
Contributor
|
| Filename | Overview |
|---|---|
| crates/openflows-harness/src/store.rs | Introduces epoch-bound planning approvals, durable approval markers, freshness reporting, and transition validation. |
| crates/agent-forge/src/lib.rs | Detects unapproved completion artifacts and routes planning-gate bypasses to NEXUS. |
| crates/agent-nexus/src/lib.rs | Adds current-cycle approval checks and moves bypassed tickets to human intervention. |
| crates/config/src/state.rs | Adds the shared gate-bypass routing action. |
| binary/src/bin/agentflow.rs | Connects the new gate-bypass action from FORGE back to NEXUS. |
Sequence Diagram
sequenceDiagram
participant F as FORGE
participant H as Harness
participant R as Redis
participant S as SENTINEL
participant N as NEXUS
F->>H: status set planning
H->>R: INCR plan_epoch
H->>R: clear previous gate
N->>S: request plan review
S->>H: gate approve planning
H->>R: write epoch-bound gate
H->>R: write durable approval marker
F->>H: status set building
H->>R: GETDEL gate
H->>R: read current plan_epoch
H-->>F: allow only when epochs match
Reviews (2): Last reviewed commit: "feat(): external auth" | Re-trigger Greptile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
FORGE could escalate to
buildingby consuming a stale or pre-seeded planning-gate approval from a prior cycle, without SENTINEL having reviewed the current plan.Observed live: a 4-day-old
planninggate approval (legacy record, no epoch, timestamp Aug-14) was treated as live authorization, and FORGE escalated tobuilding— SENTINEL was never spawned to review that plan.Root cause: the harness enforced that an approval exists (GETDEL single-use) but had no way to bind an approval to the current plan/review cycle. A leftover or manually-seeded approval could never be distinguished from a fresh one.
Fix
Bind the gate approval to a per-ticket review-cycle epoch in
crates/openflows-harness/src/store.rs:status set planningadvances the ticket'splan_epoch(Redis INCR) and clears any prior planning-gate approval, opening a fresh review window. No stale approval can survive into a new cycle.gate approverecords the currentplan_epochinside theGateApprovaland refuses to approve when no cycle is open (epoch missing) — SENTINEL cannot seed an approval for a cycle FORGE never opened.status setout ofplanning(the GETDEL consume path) now rejects the transition when the consumed approval'splan_epoch≠ the ticket's current epoch. Legacy/pre-seeded approvals (epoch 0) can no longer authorize a build; SENTINEL must re-review the current plan.gate statusprints the approval's epoch vs. the ticket's current epoch and flags stale approvals with a warning, so humans/NEXUS can audit freshness.GateApproval.plan_epochuses#[serde(default)]for backward compatibility with pre-epoch records (they deserialize as stale, epoch 0).Verification
cargo test -p openflows-harness— 14 tests pass (incl. 3 new: staleness predicate, serde round-trip with epoch, legacy-record defaults to stale).cargo clippy -p openflows-harness --all-targets— clean.cargo fmt— clean.status set building→Cannot transition ... gate approval is stale (approval plan_epoch=0, current plan_epoch=2). SENTINEL must re-review the current plan ...andgate statusprints⚠ ... STALE ... It will NOT authorize a transition.Legitimate flows (fresh planning → sentinel approve → build; re-plan → re-review → build) continue to succeed.Scope
Only
crates/openflows-harness/src/store.rsis changed. NEXUS notification logic (which checks for the presence of a planning gate to decide when to wake FORGE) remains correct: signalingplanningclears the gate → NEXUS waits for SENTINEL; SENTINEL approval re-creates it → NEXUS resumes FORGE.