Repository navigation
feat(lifecycle): legal recorded backward transitions — frame→discover (RFC item #3) - #180
Merged
Merged
Conversation
… (RFC item #3) Hole 3: the lifecycle was forward-only at the early stages, so `frame→discover` threw "Illegal Nexus transition", forcing the operator-attested fabrication workaround. This makes evidence-driven retreat a first-class, RECORDED primitive. - lib/nexus/governance/backtrack.ts: pure BACKTRACK_EDGES (reverse of the early forward spine: discover←frame, frame←plan, plan←handoff) + evaluateBacktrack (allowed only when the edge is recognized AND a matching, non-empty justification is recorded) + fail-soft readBacktrackJustification + the canonical path helper. - lib/nexus/commands/discover.ts: the bespoke `→discover` guard now permits a retreat when a justification is recorded at .planning/current/discover/backtrack-justification.json; an allowed retreat REUSES the existing run (run-id continuity), reset to the discover stage by nextLedger — recorded via previous_stage + command_history. Design (per the confirmed v1): - File-based justification {from,to,reason}, symmetric with the decomposition record (operator-authored, command-gated, auditable). - Additive/conservative: forward-only is unchanged; backward requires the explicit justification. Existing flows (no justification) throw exactly as before. - v1 wires the flagship frame→discover; plan→frame and handoff→plan are recognized in BACKTRACK_EDGES but their command-guard wiring (via assertLegalTransition, touching frame.ts/plan.ts) is a documented follow-on. Verification (Iron Law 1): - backtrack unit tests: 8/8 (edges, eval allow/deny/mismatch/empty-reason, reader valid/absent/malformed fail-soft). - discover integration test: frame→discover throws without a justification, and with one succeeds continuing the SAME run (previous_stage=frame, run_id stable). - typecheck:check baseline 0, 0 new; full unit gate exit 0, 0 fail markers on re-run — behavior-preservation holds (closeout-rollover + same-stage re-discover unaffected). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
E2E Evals: ✅ PASS0/0 tests passed | $0 total cost | parallel matrix jobs
pull_request: ubuntu-latest fallback; workflow_dispatch: configured suite runners | Docker: pre-baked toolchain + deps | wall clock ≈ slowest suite |
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.
Summary
RFC item #3 — legal, recorded backward transitions (Hole 3 + addition D). The lifecycle was forward-only at the early stages, so
frame→discoverthrewIllegal Nexus transition, which forced the operator-attested fabrication workaround the RFC documents. This makes evidence-driven retreat a first-class, recorded primitive: a backward edge is legal only when accompanied by a non-empty, matching justification — honest and auditable rather than illegal-or-faked.What shipped
lib/nexus/governance/backtrack.ts(pure):BACKTRACK_EDGES(reverse of the early forward spine —discover←frame,frame←plan,plan←handoff) +evaluateBacktrack(allowed only when the edge is recognized AND a matching, non-empty justification is recorded) + fail-softreadBacktrackJustification+ the canonical path helper.lib/nexus/commands/discover.ts: the bespoke→discoverguard now permits a retreat when a justification is recorded at.planning/current/discover/backtrack-justification.json. An allowed retreat reuses the existing run (run-id continuity), reset to the discover stage bynextLedger— recorded viaprevious_stage+command_history.Design (confirmed v1)
{from,to,reason}— symmetric with the decomposition record (operator-authored, command-gated, auditable). Does not duplicate the existing forward-legal fix-cycle edges (review/qa→build), which are plainlegal_predecessors.frame→discoverend-to-end.plan→frameandhandoff→planare recognized inBACKTRACK_EDGESbut their command-guard wiring (viaassertLegalTransition, touchingframe.ts/plan.ts) is a documented follow-on — those guards differ (plan has none today), so wiring them is its own bounded change.Verification
frame→discoverthrows without a justification; with one, it succeeds continuing the same run (previous_stage=frame,run_idstable).typecheck:checkbaseline 0, 0 new; full unit gate exit 0, 0 fail markers on re-run (run 1 = known fresh-worktreePhase 5.5manifest race). Behavior-preservation holds: closeout-rollover + same-stage re-discover are unaffected.RFC backlog after this
#1 decomposition ✅ shipped · #2 lanes (unblocked) · #3 backward transitions → this PR (flagship) · #4 spike (deferred) · #5 → Problem A. This also gives Problem C (lifecycle re-entry) its mechanism — it now folds into completing #3 (wireplan→frame/handoff→plan).🤖 Generated with Claude Code