Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1046e-fdbf-7b93-a267-5f72b9b24526
7 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 |
Account for occurrence versus receiver acceptance time as specified below;
identical window bounds alone do not align those populations. 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-corecount 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.
Bounded source snapshot — 2026-10-04
GET /v1/cadence?since=<timestamp>&until=<timestamp> requires approval:observe
and the exact store tenant. Supply exactly one timezone-aware since and until,
with since earlier than until; encode plus signs in timezone offsets. Bounds
are inclusive since, exclusive until. The existing query-free lifetime response
is preserved; it cannot substitute for a bounded reconciliation.
The response identifies source, tenant, normalized UTC bounds and window_basis created_at. Each class has committed, drained and pending counts for rows created in that window, plus acknowledged_in_window for local drain acknowledgments in that window regardless of creation time. All counts come from one database statement snapshot. Zero classes are explicit; no payloads or identities are selected or returned, and the source performs no receiver calls.
Audit Core's published /v1/reconciliation uses receiver acceptance time,
not occurrence time. Local drained_at is acknowledgment time and may follow
acceptance, especially if an accepted event's response was lost and a duplicate
was acknowledged later. Equal textual since/until bounds alone do not align
those populations. The observer must account for delayed delivery, acknowledgment
boundaries and duplicate acceptance, or use independently correlated event ids
and an agreed settled window before treating a count mismatch as omission.
Pending occurrence rows are lag; neither count agreement nor this source
snapshot proves completeness or resistance to source compromise.
This implements T04's missing bounded source computation. Receiver registration, observed lag/findings and native reconciliation remain blocked owner acceptance; no existing live image is promoted by this change.