diff --git a/INTENT.md b/INTENT.md new file mode 100644 index 0000000..4b95e60 --- /dev/null +++ b/INTENT.md @@ -0,0 +1,152 @@ +# INTENT + +> **Layer: Engine.** NetKingdom Security Layer Model §4 catalog — a deterministic +> API for a modeled concept, where the same authoritative input state yields the +> same result. Standard: `net-kingdom/canon/standards/security-layer-model_v0.3.md`. +> +> This file captures why this repository exists and the kind of system it is +> meant to become. It is aspirational and stable, not a description of current +> implementation. + +## Purpose + +> **approval-engine owns the approval as a durable, authenticated, consumable +> object — issued before an action, verified at the moment of use, and provably +> not replayable.** + +It answers one question, totally and decidably: + +> **Is this approval valid right now — for this exact action, target, actor, and +> purpose — and has it already been used?** + +Nothing else. It does not decide whether the action is permitted; that is +`access-engine`'s and it stays the only decision point. An approval is one +*input* to that decision. + +## Why This Exists + +The gap was raised by `flex-auth` on 2026-08-28 (`FLEX-DEC-2026-001`) while +assenting to the security layer model. Splitting policy authoring from policy +evaluation left one half of the approval contract without an owner: + +- the **design** of the approval contract is `gate-house`'s (Staff — doctrine); +- the **validation** of an approval at decision time is `access-engine`'s; +- the **durable object, authenticated entries, and atomic supersession** were + nobody's. + +It is not `gate-house`'s: Staff holds no state another layer depends on at +runtime (standard §3.4). It is not `access-engine`'s: it does not own the +organizational approval lifecycle, and an evaluator that also owns the object it +evaluates is self-dealing. It is not `audit-core`'s: an approval needs mutable, +in-path, current-state semantics, and an append-only audit fabric is built for +the opposite property. + +So it is a concept, and concepts get engines. + +## The Concept + +An **approval** is an independent authorization artifact required for actions +that exceed normal policy. It binds, at issue time, to: + +- the **action** and the **target** it authorizes; +- the **actor** who may use it, and the **principal** on whose behalf; +- the **purpose** or task it was granted for; +- a **validity window**; +- the **approvers** — identified, authenticated, and countable, so that + distinct-approver requirements are enforceable rather than aspirational. + +And it carries state that is deliberately not a maturity ladder: + +```text +requested → approved → valid → consumed + ↓ + superseded / revoked / expired +``` + +## Rigidity Is the Point + +This engine is deliberately small, boring, and strict. Its state model is a +closed machine rather than a graded progression, because at the moment of use +the answer must be binary, total, and reconstructable. + +**Atomic supersession** and **single consumption** are the security properties +that make Canon test `T-06 — Approval Replay` passable. An approval that is +partly valid, or whose validity must be inferred by replaying a log, is an +approval that can be replayed. Flexibility here is a defect. + +Progression modelling — graded, evidence-based, open-ended — belongs to +`maturity-engine`. The two engines are deliberate opposites and neither should +drift toward the other. + +## What approval-engine Owns + +- the durable approval object and its identifiers; +- authenticated approval entries, and distinct-approver counting; +- the state machine above, with **atomic** supersession and consumption; +- validity windows and expiry; +- binding to action, target, actor, principal, and purpose; +- revocation that does not require the holder's cooperation; +- an introspection API that `access-engine` consumes as an **input claim**; +- emission of every issuance, use, supersession, and revocation to `audit-core` + as tamper-evident evidence. + +## What approval-engine Does Not Own + +- **the decision** — `access-engine`, always and only (standard §6); +- **approval policy** — which actions require approval, how many approvers, and + which separations of duty apply: that is doctrine, and doctrine is + `gate-house`'s (standard §6.2, reaching decisions as input claims or + versioned policy rules); +- **identity and authentication of approvers** — `key-cape`, consumed as claims; +- **the evidence record** — `audit-core` holds the tamper-evident archive; this + engine holds only the operative current state; +- **credentials** materialized after a decision — `secrets-engine`; +- **maturity, readiness, or progression of anything** — `maturity-engine`. + +The repository's seed README described this as "an engine for modelling and +managing decisions". That wording is withdrawn: **decision** is `access-engine`'s +word under standard §8, and this engine must never claim it. + +## Design Principles + +1. **Binary at the point of use.** Valid or not, consumed or not. No grades. +2. **Atomic or it does not count.** Supersession and consumption are + compare-and-swap operations, never read-then-write. +3. **The evaluator is not the owner.** `access-engine` reads; it does not mutate. +4. **Approvals are inputs, never authority.** Holding one is not permission; it + is one claim the decision point weighs. +5. **Revocation beats cooperation.** An approval can be killed without the + holder's participation. +6. **Every transition is evidence.** Issuance, use, supersession, revocation all + reach `audit-core`. +7. **Small on purpose.** Scope growth here is a security regression. + +## Non-Goals + +- Not a policy decision point, and never one. +- Not a workflow or ticketing system; it stores the artifact, not the meeting. +- Not an approvals *inbox* or notification surface. +- Not an audit archive. +- Not a general state-machine service for other concepts. + +## What Would Make This Repository Wrong + +- **It starts deciding.** Any endpoint that answers "may this actor do X" rather + than "is this approval valid" is the failure standard §6 names. +- **Supersession is not atomic.** If two supersessions can interleave, the + replay protection is theatre. +- **It grows a policy layer.** If it starts holding rules about who may approve + what, it has taken doctrine from `gate-house`. +- **Nobody consumes it.** If `access-engine` does not read approvals as input + claims, the object is decorative. + +## Success Criteria + +1. `access-engine` renders approval-bound decisions using this engine's claims, + with the approval identifier reconstructable from the decision record; +2. Canon test `T-06 — Approval Replay` passes against a live implementation; +3. an approval can be revoked without the holder's cooperation, and the + revocation is effective at the next use; +4. distinct-approver requirements are enforced by the engine rather than by + convention; +5. `FLEX-WP-0017` T03 and T05 are unblocked. diff --git a/README.md b/README.md index 811f4d2..9a2d501 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,22 @@ # approval-engine -An engine for modelling and managing decisions. \ No newline at end of file +**The approval as a durable, authenticated, consumable object — issued before an +action, verified at the moment of use, and provably not replayable.** + +An Engine in the NetKingdom security layer model. It answers one question, +totally and decidably: + +> Is this approval valid right now — for this exact action, target, actor, and +> purpose — and has it already been used? + +It does **not** decide whether the action is permitted. That is `access-engine`, +which stays NetKingdom's only policy decision point. An approval is one input to +that decision. + +Deliberately small, boring, and strict: atomic supersession and single +consumption are what make Canon test `T-06 — Approval Replay` passable. +Flexibility here would be a defect. Graded, evidence-based progression belongs to +`maturity-engine`; the two engines are deliberate opposites. + +See [INTENT.md](INTENT.md). Origin: `flex-auth` `FLEX-DEC-2026-001`, raised while +assenting to the security layer model.