approval-engine/docs/emission-cadence.md
tegwick 931e0b3249 Migrate owned cadence declaration to published contract
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1029d-2c93-7500-a0e0-e3e089668b29
2026-10-03 22:59:46 +02:00

5.1 KiB

Emission cadence — source declaration

Statute §9.6: approval evidence is load-bearing and low-volume. Rate monitoring is the wrong form. A handful of revocations a month has no rate to drop below; suppression is indistinguishable from a quiet month.

This file is the source side of GH-WP-0002-T04. That task is the detection surface; this declaration is what it reads. Machine-readable copy: ../cadence.yaml.

Form

Heartbeat, plus reconciliation counts. Not a rate.

Heartbeat

An authenticated positive claim: nothing to report, together with cumulative per-class committed transition counts. The claim can itself go missing, which is the point — silence becomes a missing positive rather than a quiet month.

Field Value
Class heartbeat
Interval 24 hours (SHOULD also be emittable on demand)
Assertion nothing-to-report
Counts {issuance, use, supersession, revocation} of committed outbox rows
Missing heartbeat finding after the requested 172800s receiver bound; registration pending

Reconciliation

Compare this engine's committed outbox counts per class to audit-core's accepted event counts for source=approval-engine and the corresponding action. Divergence is a finding, not a log line.

This engine audit-core action
issuance approval.issuance
use approval.use
supersession approval.supersession
revocation approval.revocation
heartbeat audit-core.heartbeat

Undrained local rows are this engine's lag, not yet a divergence. A row with drained_at set that audit-core does not hold is the omission case §9.6 names.

What is a finding

  • No per-class heartbeat arrives beyond the requested 48h receiver bound (24h emission interval).
  • audit-core count for a class is less than this engine's drained count for that class.
  • Outbox depth or age exceeds the lag bound in cadence.yaml (drain stuck).

None of these are rate drops. None of these are informational logs.

Residual

Atomicity prevents accidental omission (crash between mutation and emit). Cadence and reconciliation detect adversarial omission after the fact. Nothing in the model prevents a compromised source from suppressing. That residual is stated, not closed.

Imported declaration and source inventory — 2026-10-03

cadence.yaml now uses InfoTechCanon's published candidate 0.2.0 contract, schema 0.1, rather than the historical flattened draft. The source-owned inventory is extensions.approval-engine.inventory: issuance, use, supersession and revocation are rare load-bearing transitions; heartbeat is the load-bearing delivery control, reconciled without a recursive heartbeat. No evidence classification or emission interval has been relaxed.

The implementation emits four atomic audit-core.heartbeat events, asserting the four transition classes through data.class; it does not emit approval.heartbeat. Production CLI defaults to 86400s. The receiver request in audit-source-registration.md remains 172800s; it is not a live admission receipt. Lag depth 100 and age 3600s remain declared bounds, with observer enforcement pending. Repository conformance does not prove stream completeness.

Live closure stays in APPROVAL-WP-0002-T04: audit-core/platform must bind exact sender approval-engine, tenant tenant:platform, explicit redact policy, the already delivered protected credential/native custody (2026-09-11), authenticated ingest and all four heartbeat class registrations. Synthetic native accepted/duplicate, read-refusal and independent archive readback already passed in the platform receipts docs/evidence/2026-09-11-factory-native-producers.json and docs/evidence/2026-09-11-factory-native-readback.json; these do not prove deployed service or lifecycle transaction emission. Remaining acceptance requires service admission, actual lifecycle drain and bearer revocation, same-window drained-versus-accepted reconciliation, startup heartbeat and missing-class/lag findings. Existing AUDIT-WP-0009 detection code is reused; neither a second observer nor new receiver APIs are required.

Orientation: Emergent Knowledge 0.2.5, digest 9e186dbd6f2d5eb455bca24db4b03cd866c63c4e94660430dd15f2ca9856215f, start/evidence cards verified-files, orientation-only.

Validation: full owner suite 169 passed. Imported owner schema SHA-256 6d52692eb1e4d1325e0d6062d95acded98beddaae5bcfe24c6f0e91f1b6be6ae and NetKingdom profile returned contract_valid/profile_assessed/conformant true with zero findings for the authoritative inventory above. Reproduce from net-kingdom with:

uv run tools/emission-cadence-profile/emission_cadence_profile.py \
  --contract-schema ../info-tech-canon/infospace/schemas/emission-cadence.schema.yaml \
  --load-bearing heartbeat \
  --rare-load-bearing issuance --rare-load-bearing use \
  --rare-load-bearing supersession --rare-load-bearing revocation \
  ../approval-engine/cadence.yaml

This supplies an owner-authored instance to NK-WP-0035; it does not accept the proposed NetKingdom profile or claim receiver admission/observed cadence.