flex-auth/cadence.yaml
tegwick 80ffe729d4
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 5s
Build and Publish Container Image / build-and-push (push) Successful in 1m11s
Apply gate-house's section 11 rulings: four-token validator, emission guarantee, resource.system.
GH-DEC-2026-017: the validator admitted {Staff, Engine, Tooling}, built from
section 4's catalog rows, and rejected Taxonomy, which section 3.1 defines.
railiance-master was conforming; the validator was the divergent artifact.
Now four tokens, ASCII case folded, section 4's spelling canonical, INTENT.md
governing while form disagreements are still reported, and every run states
its scope (section 11 binds section 4; volunteers are not non-conformances).
Also fixes the survey silently dropping audit-core's layer.yaml by decoding
peers into flex-auth's own struct.

GH-DEC-2026-018: flex-auth is a section 4 source of evidence. G2 closes as a
question and reopens as a dated gap (review 2026-10-19). cadence.yaml
publishes the per-event-class inventory: deny, redact, not_applicable and
audit_only rare load-bearing (heartbeat and reconciliation, rate forbidden);
allow volume load-bearing (expected-rate and reconciliation). INTENT.md
declares source_of_evidence and names it; tests assert both. Delivery is
FLEX-WP-0031.

FLEX-DEC-2026-015: resource.system follows the runtime, not the repository,
answering ops-warden's WARDEN-IN-0003.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-21 06:35:30 +02:00

146 lines
6.4 KiB
YAML

# flex-auth (access-engine) — §11 emission guarantee, per event class.
#
# Authority: security-layer-model §9.6 and §11; GH-DEC-2026-018 §2 and §3;
# net-kingdom/canon/standards/emission-cadence-security-profile_v0.1.md.
# Reference instance: approval-engine/cadence.yaml. Detection form:
# gate-house/docs/contracts/approval-emission-detection.md.
#
# WHY THIS FILE EXISTS AND WHY IT IS PER CLASS.
#
# flex-auth asked whether it is a §4 source of evidence for the decision record
# or only the producer of an artifact audit-core sources, declined to take the
# reading that favoured it, and held the question open as declared gap G2.
# GH-DEC-2026-018 §1 ruled that a custodian is never the source of what it
# holds: §9.6 rests on an archive being unable to prove a record was never
# sent, and that sentence has content only because archive and emitter are
# different parties. audit-core reached the same conclusion on its own
# authority (AUDIT-IN-0005) and declined the role. So flex-auth is the source.
#
# GH-DEC-2026-018 §4 ruled the declaration is PER EVENT CLASS and deliberately
# did NOT classify these classes, because §11 forbids a conformance run to
# infer class from event name, payload or observed rate and that prohibition
# binds a ruling as hard as it binds a runner. The classification below is
# therefore flex-auth's, published as §11 requires the source to publish it,
# and it is supplied to a checker rather than derived by one.
#
# The reason it is per class and not per repository: one guarantee averaged
# over a stream carrying both a high-volume allow and a rare deny is an
# average, not a declaration, and rate monitoring over that average cannot see
# the deny go missing. A denial is one of the three paradigm load-bearing
# events §9.6 names, and it is the event an adversary most wants absent.
schema_version: "0.1"
source: flex-auth # §4 row `access-engine`; FLEX-DEC-2026-013
kind: load-bearing
form: heartbeat-or-reconciliation
rate_monitoring: forbidden # class-level exception stated on `allow` only
# STATE. The classification below is published and in force as a declaration.
# The emission pipeline is not built: no sender named flex-auth or
# access-engine is registered with audit-core, no token lane, no scope row, and
# the decision record reaches consumers in the /v1/check response rather than
# into any custody. This file is therefore the declaration §11 requires and not
# a claim that the guarantee is delivered today. The delivery gap is G2 in
# docs/conformance/security-layer-conformance.md, with owner, blocker and
# review date, and it fails CLOSED on its distinguishing case: a stream with no
# declared cadence produces no silence finding, so the failure mode is a missed
# detection and never a manufactured permission.
state: declared-not-yet-emitting
gap: G2 # docs/conformance/security-layer-conformance.md
heartbeat:
class: flex-auth.decision.heartbeat
interval: 24h
assertion: nothing-to-report
missing: finding
reconciliation:
# Declared for EVERY class, including the volume one. Rate monitoring can see
# a stream stop; it cannot see a targeted subset removed, and a suppression
# aimed at one subject or one tenant is exactly the shape that leaves the
# aggregate rate inside its window.
compare:
local: committed outbox counts per class
remote: "audit-core event counts where source=flex-auth"
divergence: finding
undrained_local: lag-not-divergence
lag_bound:
outbox_depth: 100
outbox_age: 1h
exceed: finding
# EVENT CLASS INVENTORY.
#
# The classes are the decision-record effect vocabulary of
# `flex-auth.decision-record.v1` (docs/decision-record-contract.md,
# pkg/api.DecisionEffect). Every one of them is load-bearing: a decision record
# is the artifact a consumer's authority rests on, and §17 moved its schema
# here on the ground that it is the one thing in the estate only this
# repository produces.
classes:
deny:
action: flex-auth.decision.deny
evidence_class: load-bearing
rarity: rare
rate_monitoring: forbidden
detection: [heartbeat, reconciliation]
note: >-
§9.6's paradigm case, named there by the standard. Rare by nature, which
is where rate monitoring is the wrong instrument and the stakes are
highest.
redact:
action: flex-auth.decision.redact
evidence_class: load-bearing
rarity: rare
rate_monitoring: forbidden
detection: [heartbeat, reconciliation]
note: >-
A partial denial. It restricts authority, so it carries the same
suppression incentive as a deny and is classified with it.
not_applicable:
action: flex-auth.decision.not_applicable
evidence_class: load-bearing
rarity: rare
rate_monitoring: forbidden
detection: [heartbeat, reconciliation]
note: >-
No policy matched. A consumer fails closed on it, so its absence has the
same effect as a suppressed deny.
audit_only:
action: flex-auth.decision.audit_only
evidence_class: load-bearing
rarity: rare
rate_monitoring: forbidden
detection: [heartbeat, reconciliation]
note: >-
The effect whose entire purpose is the record. A record of it that does
not arrive is the decision not having happened.
allow:
action: flex-auth.decision.allow
evidence_class: load-bearing
rarity: volume
rate_monitoring: permitted # §3 of the profile: explicitly classified rate-suitable
expected_rate:
window: 1h
minimum: 1
below_minimum: finding
detection: [expected-rate, reconciliation]
note: >-
Classified volume, and stated as a classification rather than left to be
inferred from observed traffic. Reconciliation is declared anyway,
because rate monitoring over an allow stream cannot see a targeted subset
removed. An allow carries a TTL lifetime, so a suppressed allow expires
into a denial of service rather than into a standing grant.
heartbeat:
action: flex-auth.decision.heartbeat
evidence_class: operational
rarity: scheduled
note: The positive assertion above; not a decision.
bound: >-
Heartbeat and reconciliation detect loss, outage, drain failure and accident.
Neither detects a compromised source suppressing an event and its own count
together — §9.6's stated residual, and §16 puts the independent observer
outside audit-core's scope. Conformance to this declaration is not a claim of
stream completeness.