Decision Lifecycle

Decisions are not permanent. Requirements shift, load increases, teams grow, dependencies update. haft treats every decision as having a shelf life — and provides the machinery to detect when that shelf life has expired.

The lifecycle

  • Pending — decision recorded, not yet implemented (no measurement)
  • Shipped — implemented and measured (verdict: accepted/partial/failed)
  • Active — shipped, R_eff ≥ 0.5, not expired
  • Stale — R_eff < 0.5, or valid_until expired, or code drift detected
  • Superseded — replaced by a newer decision
  • Deprecated — no longer relevant (archived)
Pending → Shipped → Active → Stale
                                ↓
                      Superseded / Deprecated

Evidence and R_eff

Every decision can have evidence attached — test results, benchmarks, user feedback, measurements. Each evidence item has:

  • Verdict — supports, weakens, or refutes the decision
  • Congruence Level (CL) — how relevant is this evidence to this context?
    • CL3: Same project, same context — full weight
    • CL2: Similar project, similar stack — 0.1 penalty
    • CL1: Different context — 0.4 penalty
    • CL0: Opposed context — 0.9 penalty
  • Expiry date (valid_until) — when this evidence is no longer trustworthy. Expired evidence scores 0.1 (weak, not absent).

R_eff (effective reliability) is computed as the minimum across all evidence scores, with CL penalties applied. This is the weakest link principle: the chain is as strong as its weakest link. Never averaged — always min().

  • R_eff ≥ 0.5 — healthy, decision is trustworthy
  • R_eff < 0.5 — degraded, needs review
  • R_eff < 0.3 — AT RISK, needs immediate attention

Claims with verify_after

Decisions can include claims — testable assertions about expected outcomes. Each claim has a verify_after date: the point at which the claim should be measured against reality.

Claim: "P95 latency stays under 100ms"
verify_after: 2026-05-01

When the date passes and the claim remains unverified, /h-verify scan surfaces it. You then either measure it (attach evidence) or waive it (extend with justification). Unverified claims degrade R_eff over time.

Evidence supersession

When you run a new measurement for a claim or acceptance criterion, the new evidence automatically marks the old evidence for the same claim as superseded. R_eff reflects the current state, not historical measurements. This prevents stale evidence from artificially propping up a decision.

Code drift detection

After a decision is implemented, haft snapshots affected file hashes as a baseline. On every /h-verify scan, it recomputes hashes and detects changes:

  • MODIFIED — file changed since baseline (may or may not invalidate the decision)
  • FILE MISSING — file was deleted or moved (likely needs decision update)
  • No drift — file unchanged

Drift is a signal, not an automatic invalidation. The agent reads the diff and judges whether the change is material (broke an invariant) or cosmetic (comments, formatting, unrelated edits).

Module coverage

/h-status shows module coverage — which parts of your codebase are governed by decisions and which are blind spots:

## Module Coverage (9 modules, 77% governed)
  governed  src/internal/artifact — 3 decisions
  governed  src/internal/codebase — 2 decisions
  partial   src/cmd/serve         — 1 decision (stale)
  blind     src/assurance         — no decisions
  blind     src/cmd/indexer       — no decisions

Three states: governed (active decisions), partial (only stale or expired decisions), blind (no decisions at all). Blind modules are parts of your architecture with no formal engineering decisions — not necessarily bad, but worth knowing about.

Verifying decisions

/h-verify

Actions:

Action What it does When to use
scan Find stale artifacts + code drift + pending verify_after claims Routine health check
measure Record evidence for a claim or acceptance criteria Verifying outcomes after implementation
waive Extend validity with justification Decision still valid, just expired
reopen Start new problem cycle from old decision Conditions changed, need to reconsider
supersede Replace with a different artifact New decision replaces old one
deprecate Archive as no longer relevant Decision obsolete, nothing replaces it
reconcile Find notes that overlap with decisions Clean up duplicate knowledge

The two FPF cycles

The systems engineering methodology behind haft describes two interconnected cycles that feed into each other:

The observation cycle

Notice what changed → characterize the situation → measure → identify problems → pick the right problem to work on.

haft supports this with:

  • Drift detection — watches for code changes under existing decisions
  • R_eff degradation — evidence expires, trust scores drop, stale decisions surface
  • Claim verificationverify_after dates trigger measurement prompts
  • Module coverage — shows which parts of the architecture have no decisions (blind spots)
  • Cross-project recall — surfaces related decisions from other projects when framing new problems

The decision cycle

Define comparison criteria → generate variants → fair comparison → select → implement → measure impact → feed results back into the observation cycle.

haft supports this with:

  • Understand → Explore → Choose → Execute → Verify — the five modes with focused prompts at each step
  • Adversarial verification — challenges decisions before recording
  • Baseline + Measure — snapshots implementation, records whether acceptance criteria were met
  • Evidence supersession — newer measurements replace older ones, R_eff reflects current state
  • Failed measurement → reopen — when implementation doesn't meet criteria, the system suggests reopening the problem

Closing the loop

The two cycles connect: results of implementing a decision (measurements, evidence, drift) become inputs to the observation cycle. Stale decisions trigger re-evaluation. Failed implementations create new problems. The goal is that this happens naturally — you don't need to remember to check, the system surfaces what needs attention.

Team workflow

Decision lifecycle isn't solo-only in v6. With haft sync, decisions are shared across the team via git-tracked .haft/*.md files. Every team member sees the same decisions in /h-status and haft board after syncing.

See Team Sync for the full workflow.

Next