Widens the stranded-done recovery branch so a reaped task-less validating/done feature is re-driven to a terminal verdict instead of stalling its slice forever (closes the reaper->slice-deadlock P0). Adds a Surface Enumeration + adversarial re-drive reliability suite (git-clean, no duplicate Fix Features, terminal verdict, no deadlock) gating release. Updates missions docs + CONCEPTS for the default-to-fail posture, non-mutating verification, and inconclusive verdict. Adds changeset.
5.4 KiB
Mission Completion Gate Contract
Status
- Decision date: 2026-06-02
- Current contract task: FN-5902
- Supersedes: FN-5718 baseline contract
- Depends on runtime trigger/recovery behavior from: FN-5715
- Implementation status: Realized by FN-5902
Decision
Mission completion now uses an all-criteria AI-run contract:
MissionFeature.acceptanceCriteriais the canonical authored feature criteria text.- MissionStore must maintain or lazily restore one store-managed per-feature
MissionContractAssertionderived from feature content with text priority:feature.acceptanceCriteriafeature.descriptionVerify implementation of: {feature.title}
- The mission validator must run for every feature completion trigger. Runtime validation may lazily call
ensureFeatureAssertionLinked(feature.id)before starting the validator so legacy missing-link rows still become validator-backed. milestone.acceptanceCriteriais also part of the enforced gate by being threaded into the validator prompt for every feature in that milestone.- Feature, slice, milestone, and mission advancement are gated by the validator result — not by an informational-only path.
Enforcement Model
Feature-level enforcement
A feature is autopilot-complete only when the validator passes after evaluating:
- the feature's linked contract assertions, including its store-managed assertion, and
- the parent milestone's
acceptanceCriteriatext when present.
Milestone-level enforcement
milestone.acceptanceCriteria is no longer informational-only. FN-5902 enforces it by threading the milestone pass-bar text into the validator prompt for each feature under that milestone.
This is intentionally prompt-threading, not per-feature milestone assertion row synthesis:
- store-managed per-feature assertions remain the canonical feature assertion rows,
- milestone acceptance text remains milestone-authored prose,
- the validator sees both and must satisfy both.
Legacy data and lazy repair
Legacy missions can still contain features with missing assertion links. Runtime enforcement no longer depends on pre-running backfill:
- mission execution lazily restores the store-managed feature assertion just before validation, and
fn_mission_backfill_assertions/backfillFeatureAssertions()remain available as operator repair tooling for data hygiene and visibility.
Removed behavior (FN-5902 inversion)
FN-5718's zero-assertion auto-pass behavior is superseded.
Removed contract:
- no
validation_auto_passed_no_assertionscompletion path, - no silent or explicit rubber-stamp pass because assertions were missing,
- no informational-only feature criteria bucket in MissionManager.
Instead, features are routed through validator execution after lazy assertion ensure.
Worked examples
-
Feature has acceptance criteria; no linked assertion row is present yet
- Runtime calls
ensureFeatureAssertionLinked(feature.id). - Validator runs against the restored managed assertion.
- Result gates completion normally.
- Runtime calls
-
Feature has acceptance criteria and milestone acceptance criteria
- Validator evaluates the linked feature assertion(s).
- Validator also evaluates the milestone acceptance text in the prompt.
- Feature passes only when both are satisfied.
-
Operator runs backfill on legacy data
- Backfill pre-restores missing managed assertions for visibility/reporting.
- Runtime behavior is unchanged because lazy ensure already guarantees validator-backed enforcement.
-
Feature has a behavioral / bug-fix assertion
- The read-only AI judge produces an advisory verdict only.
- The assertion defaults to fail unless a bounded, non-mutating verification run confirms the observable behavior by exercising the code (test suite / agent-supplied regression test against a disposable checkout under an isolating sandbox).
- A genuine behavioral failure →
fail→ Fix Feature with a recorded observed-vs-expected reason. - Verification that cannot run or conclude (no isolating backend, timeout, isolation-setup failure, rejected proof, detected flakiness) →
inconclusive→ needs-attention, no Fix Feature, never a default pass. - The verification run creates no board task, mutates no mission/board row, and leaves the source tree git-clean.
-
Static assertion (e.g. "documented in README")
- Keeps the existing read-only static judging path; no verification run is invoked and no added strictness applies.
UI contract
MissionManager must present mission criteria as AI-validated rather than informational:
- assertion heading text reflects AI validation,
- informational / not-enforced labels are removed,
- zero-assertion warning guard is removed,
- fallback feature-criteria rollups, when shown for missing loaded assertions, describe runtime AI validation rather than non-enforced prose.
Success invariant
For any mission feature that reaches validation trigger points:
- a validator run must occur,
- the feature must not auto-pass due to missing assertion links,
- milestone acceptance text must be visible to the validator when present,
- a behavioral/bug assertion must not pass on the read-only judge's advisory verdict alone — it requires a confirming non-mutating verification run,
- a non-passing verification must resolve to
failorinconclusive, never a default pass, - advancement decisions must derive from validator outcomes only.