railiance-telemetry/docs/signal-contract.md
tegwick ae37a78e31 Bind Q2 production architecture to rapp-telemetry
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
2026-09-06 20:27:30 +02:00

6.7 KiB

Private signal contract v1

Q2 owns carriage and visibility; producers own signal meaning. This initial contract and CLI receiver are a local reference implementation, not a deployed monitoring package or authenticated network service.

The stream contract pins producer, stream, exact signal names, intended local recipient, freshness budget, heartbeat budget and retention. See contracts/platform-assurance.json. Its 15-minute budgets and 30-day retention are proposed defaults pending runtime/operator acceptance. The recipient railiance-platform-operator names an intended role, not a confirmed person or external messaging address. No notification is sent by these tools.

An event has exactly schema (railiance-telemetry.signal.v1), canonical UUID id, stream, producer, timezone-aware observed_at, and states. Every registered signal is present, with one of healthy/stale/missing/unavailable/ failed. There are no values, logs, URLs or free-text details. Duplicate JSON keys, unknown fields, payloads over 32 KiB, wrong producer/stream/signal names, future/expired events and out-of-order events are rejected. Local process/file access is the trust boundary; producer names are not authentication. Do not expose this CLI through an unauthenticated HTTP wrapper.

Acceptance commits an event and an operator notice in one SQLite transaction. The returned receipt says local-inbox-only. Reusing an ID with identical data is idempotent and does not advance liveness; changed data under that ID fails. Equal timestamps under new IDs also fail. Retry the same event file, not a newly translated event. Contract changes require an explicit database migration.

check detects both never-seen and expired emissions, based on original event time. It suppresses repeated missing-emission notices until a new event arrives. An independent accepted scheduler must run it. If that scheduler or this receiver stops, these tools cannot report their own absence: runtime acceptance must add an external receiver heartbeat check. Inbox reads never acknowledge implicitly. ack records explicit local operator acknowledgment; it proves no external notification. Run in a private directory (umask 077), one database per stream.

Retention is an explicit prune operation: retain at least the contract's days, all unacknowledged notices/events and the latest replay/absence anchors. Pending acknowledgments can extend retention indefinitely. At 10,000 events ingestion fails rather than silently dropping evidence. Monitor capacity and prune through the approved owner; no background expiry is installed. This is operational storage, not immutable audit custody or independently backed-up evidence.

Local workflow

Python 3.11+ standard library only. From the repository root:

python3 -m unittest discover -s tests -v
umask 077
mkdir -p /tmp/rtel-private
python3 scripts/platform_event.py --contract contracts/platform-assurance.json /path/to/fresh-platform-report.json > /tmp/rtel-private/event.json
python3 scripts/receiver.py --contract contracts/platform-assurance.json --database /tmp/rtel-private/receiver.db ingest /tmp/rtel-private/event.json
python3 scripts/receiver.py --contract contracts/platform-assurance.json --database /tmp/rtel-private/receiver.db check
python3 scripts/receiver.py --contract contracts/platform-assurance.json --database /tmp/rtel-private/receiver.db inbox

The platform adapter consumes the existing assurance evaluator report, preserves evaluated_at as producer observation time, and carries each existing state. Backup/restore age remains S3's classification; Q2 does not re-age those receipts. The adapter does not change the source report's unmonitored/unsupported status. Its signal inventory is pinned to platform source at initial review; changes require coordinated contract review and tests.

Required live acceptance

RTEL-WP-0002-T04 tracks runtime/package owner selection, private authenticated execution, durable storage/backup, confirmed operator recipient, accepted cadence and retention, independent receiver-watchdog delivery, and controlled failure / producer-absence delivery acknowledged by that operator. Request scope already covers reference implementation; no live scheduler or messaging authorization is inferred. RPF-WP-0036-T04 stays open until those receipts exist.

Runtime job candidates

scripts/runtime.py supplies bounded ingest-report, check, health and snapshot jobs. It requires an owned 0700 state directory, uses a private umask, and refuses a symlink database. Identical reports derive identical event IDs, so process retries neither duplicate notices nor renew producer time. A stale report fails instead of being stamped with the current time.

check atomically records invocation time and pending notice count, including missing-emission results. health reads that receipt without touching SQLite or renewing it; older than 180 seconds is stale (exit 1), absent/invalid is an error (exit 2). This 180-second budget is a proposed runtime default. Run this probe from an independent executor/failure domain; local implementation alone does not establish that independence or route an alert.

snapshot <new-path> uses SQLite's backup API and validates the resulting DB. It preserves contract binding and pending notices, refuses overwrite, and emits SHA-256 plus counts. The receipt explicitly says off_host=false: off-host backup, expiry, storage capacity and restored-runtime acceptance remain T04 gates.

Candidate activity definitions are disabled: ingest every five minutes and producer watchdog every two minutes, UTC/skip misfires. Activity-core's native parser accepts both. The tasks describe deterministic execution, not permission to launch coding agents periodically. Before projecting/enabling, bind the actual executor/profile, immutable bundle, upstream platform report command, state location and notification channel. No resolver, live schedule or second host cron has been introduced. Strict profile-enforcing environments need the accepted profile binding before registration; none is invented in these candidates.

Production architecture decision — 2026-09-06

The user directed Master-compliant package establishment on railiance01. rapp-telemetry now owns the maintained kube-prometheus-stack release: Prometheus, Alertmanager and Grafana. Grafana's intended hostname is telemetry.coulomb.social. The local SQLite receiver/runtime remains a reference implementation. Do not activate its candidate activity definitions as a parallel production monitoring plane. Q2 now needs a reviewed Prometheus exporter/rule mapping preserving the existing state semantics, and actual Alertmanager delivery acceptance. Package runtime/admission is tracked by RAPP-TELEMETRY-WP-0001.