FN-5738: make mission loop no-assertion auto-pass deterministic
Ensure mission validation loop advancement is deterministic when no assertions are linked and audit output is emitted once. - update mission execution loop handling to auto-pass zero-assertion validations deterministically - emit and guard validation_auto_passed_no_assertions audit behavior against duplicate recovery re-fire - expand mission loop and reliability interaction tests for loop state, validator status, and replay safety - refresh mission/architecture docs and add the FN-5738 changeset entry Files changed: .changeset/fn-5732a-loop-advance.md | 5 ++ AGENTS.md | 1 + docs/architecture.md | 3 +- docs/missions-completion-contract.md | 2 +- docs/missions.md | 4 +- .../src/__tests__/mission-execution-loop.test.ts | 27 ++++++++++- .../mission-validation-trigger-gap.test.ts | 22 +++++++-- packages/engine/src/mission-execution-loop.ts | 54 +++++++++++++--------- 8 files changed, 86 insertions(+), 32 deletions(-) Fusion-Task-Id: FN-5738 Fusion-Task-Lineage: 141b73e3-fa49-468a-87b0-f36e091e716f
This commit is contained in:
@@ -1768,7 +1768,8 @@ Reliability-layer changes are in scope. Interaction regression backstops live in
|
||||
- FN-5168 backstop: `packages/engine/src/__tests__/reliability-interactions/non-progress-churn.test.ts` covers loop→compact recovery followed by ignored-step-update churn escalation, terminal `beforeRequeue(false)` behavior, audit/log payloads, and FN-5147 autoMerge-off composition.
|
||||
- FN-5219 backstop: `packages/engine/src/__tests__/reliability-interactions/in-progress-limbo-recovery.test.ts` covers `recoverInProgressLimbo` composition with `recoverOrphanedExecutions` (no double-recovery), `reconcile-task-worktree-metadata` (live rebindable worktree wins), `recoverMissingWorktreeReviewFailures` (in-review vs in-progress disjoint), and executor task-id claim skip, plus an explicit FN-5149 reproduction case.
|
||||
- FN-5704 backstop: `packages/engine/src/__tests__/reliability-interactions/reclaim-self-owned-resume-limbo-escalation.test.ts` covers bounded no-progress reclaim/resume detection, preserve-work escalation to `todo`, `task:resume-limbo-escalated` audit metadata, progress-signal reset behavior, and user-paused/autoMerge-off non-escalation guards.
|
||||
- FN-5715 backstop: `packages/engine/src/__tests__/reliability-interactions/mission-validation-trigger-gap.test.ts` locks the mission-validation trigger invariant so done mission-linked tasks still start validation when the mission loop was stopped, startup recovery replays done implementing features with unpassed assertions, no-assertions auto-pass remains unchanged, and recovery remains idempotent for already-passed features.
|
||||
- FN-5715 backstop: `packages/engine/src/__tests__/reliability-interactions/mission-validation-trigger-gap.test.ts` locks the mission-validation trigger invariant so done mission-linked tasks still start validation when the mission loop was stopped, startup recovery replays done implementing features with unpassed assertions, and recovery remains idempotent for already-passed features.
|
||||
- FN-5738 backstop: `packages/engine/src/__tests__/reliability-interactions/mission-validation-trigger-gap.test.ts` extends coverage so zero-assertion auto-pass deterministically advances `loopState` to `passed`, sets `lastValidatorStatus="passed"`, emits `validation_auto_passed_no_assertions`, and does not re-fire on repeated recovery passes.
|
||||
- FN-5741 backstop: `packages/engine/src/__tests__/reliability-interactions/merge-request-shadow-handoff.test.ts` guards Phase-1 merge-request contract shadow writes: flag OFF is a no-op, flag ON writes marker/record strictly after legacy handoff, and `autoMerge:false` remains `manual-required` without shadow running transitions.
|
||||
- FN-5337 backstop: `packages/engine/src/__tests__/reliability-interactions/orphan-detected-no-requeue.test.ts` locks observation-only orphan detection across FN-5279 repro metadata desync, worktree-present and worktree-missing candidates, FN-5219 ordering, FN-5147 in-review isolation, FN-5083 branch-cleared composition, lease-manager non-invocation, and per-sweep idempotent audit emission.
|
||||
- FN-5256 backstop: `packages/engine/src/__tests__/reliability-interactions/dependency-cycle-reconcile.test.ts` covers persisted dependency-cycle detection via `reconcileDependencyCycles`, bounded umbrella-back-edge auto-repair, ambiguous-cycle observe-only behavior, composition ordering with `reconcileSelfDefeatingDependencies`, and the post-sweep write-time guard invariant. Core write-boundary regressions (FN-5240/5241/5242 signature, indirect cycle, umbrella back-edge rejection) live in `packages/core/src/__tests__/store-dependency-cycle.test.ts`.
|
||||
|
||||
@@ -127,7 +127,7 @@ Target surface: `packages/dashboard/app/components/MissionManager.tsx`
|
||||
## Engineering Acceptance Criteria (follow-on implementation)
|
||||
|
||||
✅ Implemented in FN-5733:
|
||||
- Auto-pass path now advances `loopState` to `passed` and emits mission event code `feature_auto_passed_no_assertions` while preserving the `validation:passed` emit contract (`"No assertions linked"` summary).
|
||||
- Auto-pass path now advances `loopState` to `passed` and emits mission event code `validation_auto_passed_no_assertions` while preserving the `validation:passed` emit contract (`"No assertions linked"` summary).
|
||||
- Milestone rollup/store guard now exposes `hasProseButNoAssertions` and emits warning mission event code `milestone_missing_structured_assertions` (debounced on transition into condition).
|
||||
- MissionManager UI now distinguishes enforced assertion gate vs informational feature acceptance criteria.
|
||||
|
||||
|
||||
@@ -396,7 +396,7 @@ A feature transitions to `blocked` when:
|
||||
|
||||
On engine restart, `recoverActiveMissions()` re-enqueues features in `validating` or `needs_fix` states from the `activeValidations` set, ensuring no validation work is lost. It also re-triggers `implementing` features whose linked task is already `done`/`archived` and whose assertion validation has not passed yet.
|
||||
|
||||
For features with zero linked assertions, the completion path is explicit: the loop marks the feature `done`, advances `loopState` to `passed`, emits `validation:passed` with summary `"No assertions linked"`, and records mission event code `feature_auto_passed_no_assertions`.
|
||||
For features with zero linked assertions, the completion path is explicit: the loop marks the feature `done`, advances `loopState` to `passed`, emits `validation:passed` with summary `"No assertions linked"`, and records mission event code `validation_auto_passed_no_assertions`.
|
||||
|
||||
### Autopilot / Scheduler Interplay
|
||||
|
||||
@@ -427,7 +427,7 @@ These are independent tracking mechanisms — autopilot monitors mission progres
|
||||
**MissionEvent audit types:**
|
||||
- `slice_activated`, `feature_planned`, `feature_completed`
|
||||
- `validation:started`, `validation:passed`, `validation:failed`, `validation:blocked`
|
||||
- `feature_auto_passed_no_assertions` (reason: `no_assertions_linked`)
|
||||
- `validation_auto_passed_no_assertions` (reason: `"No assertions linked"`)
|
||||
- `milestone_missing_structured_assertions` (warning when prose criteria exist with zero structured assertions)
|
||||
- `fix_feature:created`, `feature:blocked`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user