From 164a4cdaf12e7a450ac225f7a645e769a3e76f40 Mon Sep 17 00:00:00 2001 From: tegwick Date: Thu, 15 Oct 2026 20:43:18 +0200 Subject: [PATCH] Keep source-derived cadence fixture bound to the coordination frame Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a13eab-1e6a-7b33-9c37-372e90ada3a2 --- docs/CadenceObserverAdmission.md | 18 ++++++++++++++++-- .../qonto_assistant_source_cadence.json | 12 +++++++++++- tests/test_cadence_declaration.py | 7 ++++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/docs/CadenceObserverAdmission.md b/docs/CadenceObserverAdmission.md index 7a98fd9..a1d76d9 100644 --- a/docs/CadenceObserverAdmission.md +++ b/docs/CadenceObserverAdmission.md @@ -38,8 +38,10 @@ 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. Requested heartbeat_classes bare classes at172800sec -must be reconciled with emitted interval86400sec and the receiver's1.5grace. +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. @@ -106,3 +108,15 @@ 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. diff --git a/src/kings_guard/fixtures/qonto_assistant_source_cadence.json b/src/kings_guard/fixtures/qonto_assistant_source_cadence.json index 95a333d..134326d 100644 --- a/src/kings_guard/fixtures/qonto_assistant_source_cadence.json +++ b/src/kings_guard/fixtures/qonto_assistant_source_cadence.json @@ -9,7 +9,7 @@ "form": "heartbeat-or-reconciliation", "heartbeat": { "event_class": "audit.heartbeat", - "interval_seconds": 86400, + "interval_seconds": 3600, "assertion": "nothing-to-report", "missing": "finding" }, @@ -33,6 +33,16 @@ "drafter": "qonto-assistant", "owner": "qonto-assistant", "reference_instance": "QONTO-WP-0005" + }, + "netkingdom": { + "coordination_frame": { + "ref": "coordination-engine/config/coordination-frame.json", + "sha256": "d15e092387f128ffdfd00b9815707a05ff77c5bb0ba4d9a428fbc37b8c440b67", + "frame_seconds": 3600, + "heartbeat_frames": 1, + "registered_wait_frames": 2, + "effective_deadline_frames": 3 + } } } } diff --git a/tests/test_cadence_declaration.py b/tests/test_cadence_declaration.py index 3b5595a..6b99789 100644 --- a/tests/test_cadence_declaration.py +++ b/tests/test_cadence_declaration.py @@ -1,3 +1,4 @@ +import json from pathlib import Path import pytest @@ -32,7 +33,11 @@ def test_qonto_source_declaration_is_consumed_separately_from_the_taxonomy_draft assert cadence.reference_instance == "QONTO-WP-0005" assert cadence.forms() == {"heartbeat-or-reconciliation"} assert cadence.rates == () - assert cadence.heartbeats[0].interval.total_seconds() == 86400 + fixture = json.loads( + (ROOT / "src/kings_guard/fixtures/qonto_assistant_source_cadence.json").read_text() + ) + frame = fixture["extensions"]["netkingdom"]["coordination_frame"]["frame_seconds"] + assert cadence.heartbeats[0].interval.total_seconds() == frame @pytest.mark.skipif(