Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1046e-fcad-7ea3-bf36-361fc8d679e8
4 KiB
Decision emission preparation
FLEX-WP-0031 implements a durable local outbox, daily per-class heartbeats,
asynchronous delivery and optional PVC. Every pin still defaults to no outbox
and no delivery worker. cadence.yaml remains declared-not-yet-emitting; G2
does not close on local tests or chart rendering.
After sender admission and the exact approved rollout, enable the chart's
outbox.enabled, choose a unique outbox.source for the pin, and set
outbox.size against measured capacity and expected cumulative log growth.
outbox.existingClaim can reuse its own retained claim. New claims carry Helm's keep policy so uninstall does not remove the
evidence log; any eventual claim cleanup needs its own reviewed action.
The chart enforces one
replica and Recreate; each source requires its own outbox. Never run two
processes against one outbox directory. The fsGroup permits the non-root
process to write the mount while keeping its root filesystem read-only.
Delivery requires explicit serve flags:
--audit-url <admitted audit-core http(s) /v1/events endpoint>
--audit-token-file <governed mounted sender token path>
Neither flag is enabled by the chart or any checked-in production pin. These
flags require --outbox-dir; the source is supplied by --emission-source.
The worker reads the token file per event to support rotation, refuses HTTP
redirects, and does not log tokens or receiver response bodies. Receiver
authentication/network admission and token mounts remain owner dependencies.
The worker commits due heartbeats into the same log as decisions, then drains
bounded batches in order. The daily timestamp is recovered from the committed
log after restart. Each heartbeat has its own event/correlation ID and carries
data.class, committed count and the process's released-uncommitted count.
Known uncommitted releases produce released-uncommitted-finding instead of a
nothing-to-report assertion. This count is volatile across restart, as the
existing atomicity ruling states; the heartbeat does not strengthen that bound.
Only documented 200 (duplicate) and 202 (accepted) responses advance
drain.json. The cursor is fsynced, atomically replaced and its directory
synced. A rejection, timeout or cursor-write failure retains the event and
replays its original idempotency key. A failing head event blocks subsequent
delivery rather than being dropped. HTTP occurs outside the decision lock.
GET /v1/emission reports committed and released-uncommitted decision counts,
pending event depth, oldest pending commit time and lag_exceeded when depth
exceeds 100 or age exceeds 1h. Counts include no record payload. The drain
cursor advances over heartbeats as well as decisions; pending depth includes
both. Acknowledged entries are retained in the append-only log. There is no
compaction/retention worker, so operators must plan storage and monitoring for
cumulative log growth before rollout.
docs/contracts/decision-emission-cadence.json is the schema-valid wire
declaration for receiver registration. It names all five classes explicitly;
allow's additional reconciliation obligation is in a source extension because
the generic expected-rate form prohibits a reconciliation block and the
security profile prohibits duplicate classes. audit-core's parser accepts the
declaration; that does not prove native sender admission or evaluation of the
source extension.
Run make verify-emission-cadence against the sibling InfoTechCanon schema and
NetKingdom profile checker. The declaration pins the schema SHA-256 and the
check rejects drift. Go tests check inventory/heartbeat parity; chart checks
exercise auth on/off, existing/new PVCs and refusal of multiple replicas.
A valid remote comparator remains blocked: audit-core windows use receiver
accepted_at, and local windows would use commit time. The current ingest
receipt contains no acceptance timestamp. Comparing these directly would
manufacture divergence after delayed delivery. Requirements and native
acceptance gates are in blocked-task-dependencies-2026-10-04.md.