kings-guard/docs/CadenceObserverAdmission.md
tegwick 09ada1d981 Correct acceptance preparation date
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a13eab-1e6a-7b33-9c37-372e90ada3a2
2026-10-15 21:18:37 +02:00

12 KiB

Canonical cadence observer admission

NK-WP-0035; KG-WP-0005. The observer now consumes source-authored extensions.netkingdom.evidence_class, matching NetKingdom's profile namespace. The historical extensions.net-kingdom is refused with an explicit migration diagnostic, including conflicting dual-namespace inputs. Missing/malformed owner classification is an error; no classifier is inferred from traffic or event names. The two local copied fixtures use the canonical namespace. They are local algorithm inputs, not deployment, source approval, or profile-wide adoption.

The profile remains proposed. Imported contract is InfoTechCanon candidate document 0.2.0 / wire schema 0.1, bundle b08b4d95fc4b0bd3, schema SHA256 6d52692eb1e4d1325e0d6062d95acded98beddaae5bcfe24c6f0e91f1b6be6ae. Schema validation belongs to the owner artifact; no competing generic schema is bundled here. The source class inventory stays source-owned.

Reuse the evidence engine's delivered interfaces

AUDIT-WP-0009-T04/T05/T06/T07 are done. Reuse, without duplicating:

  • POST /v1/events authenticated envelope; receiver heartbeat type audit-core.heartbeat with asserted covered class at data.class.
  • Protected AUDIT_CORE_SENDERS registry object carries source-owned canonical emission_cadence, plus exact source/tenant/evidence/credential bindings. heartbeat_classes maps covered event class to maximum gap seconds. The non-secret scope overlay may add/shorten heartbeat bounds but cannot insert/change emission_cadence; platform must provision the protected registry.
  • GET /v1/reconciliation?source=<exact>&tenant=<exact>&since=<bound>&until=<bound> gives accepted counts, not payloads. Own-source sender read is allowed with may_read=false; cross-source requests return403. Explicit equal source/tenant and window boundaries are required for a meaningful local comparison.
  • GET /v1/stream-findings evaluates missing registered heartbeats and declared rates. It requires a may_read identity with full tenant scope. It is not a tenant-filtered observer feed; request an owner-delivered sanitized observation or separately governed read lane rather than widening a source writer token.

Approval Engine already publishes receiver-compatible heartbeats and has exact sender/source approval-engine, tenant tenant:platform. Its local transition classes use bare issuance/use/supersession/revocation while accepted event types are approval.issuance/use/supersession/revocation; owner mapping must preserve both count coordinates. Current prepared source settings derive from the shared coordination frame: heartbeat f=3600s, registration 2f=7200s and effective deadline 3f=10800s after the receiver's 1.5 grace. The copied source fixture retains the same frame digest; neither source configuration nor a fixture is live admission. Canonical declaration admission and heartbeat mapping need actual owner receipts; existing ingestion evidence alone does not prove cadence monitoring was enabled.

Qonto's source is structured stdout, process-instance scoped with event class audit.heartbeat and its own source transition/snapshot counters. Its deployment owner must deliver a bounded capture and snapshot; no audit-core sender/feed is declared in the reviewed receiver source. If routed through Audit Core, owners must explicitly translate the heartbeat envelope, bind exact sender+tenant, retain source instance/sequence/window semantics, and admit its declaration. AUDIT-WP-0013-T04 now supports explicit stream_instance_id on receiver reconciliation. A reviewed receiver release is still required, and acceptance time must be aligned with source/sequence windows. An unbounded database accepted count cannot replace a process-local snapshot.

local-identity has no registered sender or evidence feed, declares no heartbeat, and remains the owner's explicit activity-scoped incompatibility. Do not accept reconciliation-only as satisfying NetKingdom's rare-class conjunction or create an observation from a local TSV file merely to close adoption.

Owned operational wait and acceptance

KG-WP-0005-T03 remains wait/blocked on a runtime-owner supplied authorized Qonto capture from startup through a request allow/deny, periodic heartbeat at the declared interval, and same-instance reconciliation. The namespace migration does not produce that feed. main --live still drives the adjacent source's AuditLogger with a fixture client; it is local emit-path evidence.

Existing executable seams are live._confirm_stream (instance/sequence/count admission), cadence.emission_cadence_from_dict (owner-classified projection), stream.evaluate_stream (heartbeats/reconciliation/observations), and posture.evaluate_with_stream. Feed integration must retain source_id/tenant, declared heartbeat vs covered-class mapping, time bounds, process instance, contiguous sequence and durable/local count scope; missing or malformed inputs remain UNKNOWN or are rejected. A runtime owner returns bounded non-secret positive/missing-heartbeat/count-divergence plus failed-read receipts. Matching counts prove neither completeness nor event occurrence; findings detect omission after the fact. There is no automatic containment authority in this delivery.

Knowledge orientation reloaded 2026-10-03: Emergent Security0.2.5 verified-files, package digest 9e186dbd6f2d5eb455bca24db4b03cd866c63c4e94660430dd15f2ca9856215f, generic start plus evidence source card. Orientation is not a readiness grant.

Heartbeat coverage correction — 2026-10-15

StreamHeartbeat.covered_event_classes explicitly names the classes vouched for by a source or reviewed adapter. Matching requires both the transport event class and that coverage. Shared audit-core.heartbeat transport names alone cannot let a fresh issuance beat hide an expired revocation beat. Missing coverage does not satisfy a covered-class obligation; malformed coverage is refused. Count keys and observed traffic never infer this binding.

The Qonto source adapter explicitly maps its shared heartbeat to the three classes in its source-owned declaration. This is local source-path evidence, not admission of a collector or a receiver feed. The same envelope with an explicit receiver data.class must map only to that named class; do not set all declared classes on every Approval Engine heartbeat.

The existing 2026-09-15 sender bearer-revocation receipt in audit-core already proves scoped overlap/drop: replacement bearer 202 then 401, incumbent 202, for approval-engine and informed-decision. Reuse that exact historical proof; it does not prove lifecycle reconciliation or cadence registry admission. Receiver applies 1.5 grace to registered heartbeat intervals: the requested 172800 seconds would produce a 259200-second effective deadline. Record the source/receiver owner decision before admitting that bound; do not silently claim a 48-hour alert from that registration.

Shared frame decision — 2026-10-15

Founder resolved the earlier daily 48h/72h question by introducing one coordination frame, initially f=1h. Canonical configuration is coordination-engine/config/coordination-frame.json; NetKingdom's compiler regenerates the source-derived Qonto fixture alongside source/receiver artifacts and records the config digest. The historical Taxonomy draft fixture remains a historical worked example. Live admission must supply the actual configured frame/interval and preserve per-class scope; the source fixture cannot prove that a deployed process emits hourly heartbeats.

Deployed-capture verifier — 2026-10-15

kings_guard.acceptance is an offline consumer of runtime/evidence-owner artifacts. It opens no network, cluster, database, or credential client. Run from this repository after the runtime owner has delivered all four inputs:

PYTHONPATH=src python3 -m kings_guard.acceptance \
  --events /path/to/source-instance.jsonl \
  --snapshot /path/to/source-snapshot.json \
  --receiver /path/to/receiver-reconciliation.json \
  --receipts /path/to/collector-accepted.jsonl \
  --source qonto-assistant --tenant '<owner-approved-exact-tenant>' \
  --frame-seconds 3600 --now '<actual-observation-time-with-timezone>'

The output hashes its exact inputs. Exit0 means the supplied bounded capture passes; exit1 means failure or invalid evidence. The verifier does not attest input provenance, signatures, deployed image pins, or the operational matrix below. A fixture passing the command remains fixture evidence.

Input contract:

  • Raw JSONL contains exactly one source instance, startup sequence1 through the source snapshot's last sequence, a real deny, and at least one periodic heartbeat emitted at least f after startup. The source snapshot is the unmodified AuditLogger.reconciliation_snapshot() response from that instance.
  • Receiver JSON is the actual /v1/reconciliation response with exact source, tenant, instance, and explicit acceptance-time since/until. Its counts must equal the capture's allow/deny counts plus heartbeat transport records.
  • Collector JSONL contains one durable original accepted receipt per source sequence with event_id, status_code, accepted_at, source, tenant, stream_instance_id, stream_sequence, type, and covered_event_classes. The reviewed mapping is one source heartbeat to one audit-core.heartbeat covering only audit.deny; it preserves original source fields. This mapping does not claim separate receiver admission of audit.allow or audit.heartbeat obligations.
  • accepted_at records collector response receipt time, an upper bound on acceptance. Original202 receipts can bound delivery lag; a duplicate200 receipt alone cannot establish when the event first entered custody. The verifier requires original202 for timing. Preserve earliest successful receipts across retries, and supply a receiver window enclosing them. Sequence/snapshot bounds are source occurrence coordinates, not receiver acceptance times. Receipt correlation bridges those coordinates.

The runtime owner must keep the authorized candidate active during the real hour-long capture (for example authorized health polling) while retaining its configured scale-to-zero behavior. Do not silently change minScale to obtain heartbeats. Capture restart and scale-to-zero separately: a shutdown heartbeat is a lifecycle claim, not proof the process remains alive; never present its later absence as an unexpected omission when shutdown was intended. Resume with a new instance and sequence1, then reconcile each instance separately.

assess_class_silence independently computes class deadlines from owner-supplied registered waits and explicit per-class receiver last-seen timestamps, then compares the exact missing classes with the receiver's sanitized findings. Use wait2f and grace1.5 (deadline3f). An explicit None is a receiver-observed never-seen class; an omitted last-seen entry is refused. An unrelated fresh class cannot conceal a stale rare class. Supply actual observations and their owner/source/window pins; local projected times are algorithm tests only.

Before T03 can close, collect independent operational receipts for quiet-active, deny, periodic timing, bounded per-instance reconciliation, class-specific missing heartbeat, sequence gap, source/accepted divergence, lag distinguished from persistent divergence, failed cross-source/tenant reads, restart, and scale-to-zero. Negative injection must use an owner-approved isolated lane; do not suppress production evidence or change source registry bounds to make a test finish sooner. The existing full-frame wait remains necessary.

Validation: 144 tests pass, including16 new acceptance/correlation tests and existing class-coverage regressions; changed-file Ruff passes. No live capture or receiver finding was produced by this source delivery. Knowledge package 0.2.6 digest8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02 returned start/evidence withheld, orientation-only; current source cards and Staff-layer owner boundary were read directly. This is not a readiness grant.