flex-auth/workplans/FLEX-WP-0031-decision-record-emission.md

91 lines
3.1 KiB
Markdown
Raw Normal View History

---
id: FLEX-WP-0031
type: workplan
title: "The decision record has a declared emission guarantee and nothing that delivers it"
domain: infotech
repo: flex-auth
status: ready
flavor: implementation
owner: claude
topic_slug: netkingdom
planning_priority: P1
planning_order: 310
related_workplans:
- FLEX-WP-0030
- FLEX-WP-0019
created: "2026-09-21"
updated: "2026-09-21"
---
# FLEX-WP-0031 — Deliver the decision-record emission guarantee
`GH-DEC-2026-018` ruled that flex-auth is the §4 source of evidence for the
decision record, and that it is not conforming on §11 until it declares and
delivers a per-event-class emission guarantee. The declaration is published
(`cadence.yaml`, `FLEX-WP-0030-T07`). Nothing emits: the decision record reaches
consumers only in the `/v1/check` response, no sender named flex-auth or
`access-engine` is registered with `audit-core`, and there is no outbox,
heartbeat or reconciliation count. This plan closes declared gap **G2**
(`docs/conformance/security-layer-conformance.md`, review 2026-10-19).
Bound, stated up front so no argument rests on more: heartbeat and
reconciliation detect loss, outage, drain failure and accident. Neither detects
a compromised flex-auth suppressing a record and its own count together.
## 1. Decide emission atomicity
```task
id: FLEX-WP-0031-T01
status: todo
priority: high
```
`GH-DEC-2026-018` left open whether decision-record emission must be atomic with
the decision (§9.4), pending the class inventory. It exists now. Decide whether
a rare load-bearing decision (`deny`) may be returned before its record is
committed to the outbox, and record the answer as a `FLEX-DEC`. Gate: decided,
with the latency cost stated.
## 2. Register flex-auth as an audit-core sender
```task
id: FLEX-WP-0031-T02
status: todo
priority: high
```
Open an intake with `audit-core` (worked examples `AUDIT-IN-0002`,
`AUDIT-IN-0003`): sender registration, `evidence_kind`, `heartbeat_classes` per
class exactly as `cadence.yaml` publishes them, and a token lane routed via
`warden route find`. audit-core has said it accepts the classification as
supplied and will not infer it. Gate: sender registered; no secret in any file.
## 3. Transactional outbox, heartbeat and reconciliation counts
```task
id: FLEX-WP-0031-T03
status: todo
priority: high
```
Emit one event per decision into a local outbox, drained to `audit-core`
`POST /v1/events`; a daily `flex-auth.decision.heartbeat`; committed counts per
class exposed for `GET /v1/reconciliation`; lag bound per `cadence.yaml`.
Gate: `cadence.yaml` validates under the net-kingdom emission-cadence profile
checker with the inventory supplied as `--rare-load-bearing`/`--load-bearing`
assertions; tests assert the declared classes equal the `DecisionEffect`
vocabulary so a new effect cannot ship unclassified.
## 4. Close G2
```task
id: FLEX-WP-0031-T04
status: todo
priority: medium
```
Change `cadence.yaml` `state` to emitting, move G2 out of the gap table with the
evidence, and tell `gate-house`, `audit-core` and `kings-guard`. Gate: a silence
finding is observed on a deliberately withheld heartbeat in a non-production
run.