Fountain Coach Gitowner-controlled · read only

LaneResolutionKit.git · PLANS.md

LaneResolutionKit.git / PLANS.md

revision d17d1c98e91b4db8a754a121cc96cac1f3d1814b · complete file

# PLANS.md — LaneResolutionKit

Intent and risk for multi-step work in this repository. `AGENTS.md` defines when a plan is required: any change
that alters public API, gate order, budget derivation, or the failure-evidence set.

---

## Phase 1 — Extraction and first release (v0.1.0) — COMPLETE

**Goal.** Factor lane resolution out of a consuming application into an owned kit, so that "which lane serves
this?" is answered once, by one component, that no consumer can bypass.

**Constraints.**
- Zero dependencies. The package must be incapable of reaching a credential store or a network.
- No consumer domain types, vocabulary, or product decisions (FCIS-KIT-03).
- The suite must never touch a real credential store and never prompt.

**Phased approach (as executed).**
1. Kit built in the consumer's tree as an in-repo module, with its full test suite, and NOT wired to any caller.
2. Callers repointed ONE at a time, each with negative evidence that the replaced path had no remaining users —
   never a single sweep.
3. Extracted here once the seam had stopped moving, renamed off the consumer's vocabulary, released, and consumed
   by semantic version.

**Test plan.** Five obligations, all met before release:
1. **Exhaustive truth table** — `permitted × credentialState × constructible × health × role`, every cell asserted
   against the expected resolution, the expected refusing gate, and that gate's remedy. 864 cells. Example tests
   are not enough for failures this invisible.
2. **Budget belongs to the lane** — property over every reachable decision: `budget.contextWindowTokens ==
   lane.contextWindowTokens`. Accompanied by a test proving the property CAN fail, by reconstructing the defective
   shape (a budget switched on a lane symbol) and showing the same assertion catch it.
3. **No gate widens** — property over the same sweep: survivors after each gate are a subset of the previous set,
   gates run in declared order, no lane vanishes without a refusal, no refused lane survives.
4. **No prompt without a grant** — a fake credential store that counts presence queries and data reads separately.
   Under `localOnly` the credential is `.authorised` and fully readable, and the data read count is still zero.
5. **A named regression per incident** in `docs/INCIDENTS.md`.

**Rollback.** The consumer pins by semantic version; reverting is a manifest change to the previous tag. Nothing in
this package writes state, so there is no data migration to undo.

**Definition of done.** Suite green; public API free of consumer vocabulary; `FCIS_COMPLIANCE.md` records each
org standard's applicability with evidence; tagged release published with notes naming the seam.

---

## Open

- **`preferredOrder` semantics are deliberately weak** and this is worth revisiting with evidence: it can only
  order survivors. A consumer wanting "this lane or fail" must express that by narrowing `configured`, not by
  ordering. No consumer has needed it yet; if one does, the answer is a new gate input, never a widening order.
- **Health is an input, not a memory.** The kit does not remember that a lane failed; the consumer supplies current
  health each time. If several consumers end up re-implementing the same demotion bookkeeping, that is the signal
  to bring it in — with its own tests here, not proved in a consumer.
- **No `Codable` conformance on `LaneResolution`.** Deliberate for now: persisting a decision invites treating a
  stale one as current. A consumer that needs a record should project its own document from the decision.