Problem — three incidents, one mechanism
Any measurement over a shared surface risks reading self-generated signal as external behavior. Three corroborating incidents on this box, all within days:
- A boundary-aligned Claude keepalive was read as API window mechanics in a ledger analysis. The confound survived a day because the keepalive is event-anchored (fires at window-expiry+ε), so it reproduced the surface's own boundary grid exactly. Diagnosed only after a maintainer-side retraction forced a re-measurement (insula#5 thread, 2026-08-17).
- A mechanical board-sweep nearly consumed its own filings as deltas — self-caused changes reading as external novelty; sequencing had to be hand-ordered.
- insula#1 GAP-1's two-reader OAuth token collision: rotation-on-use is a self-signal on the credential surface that a second reader misread.
The current defense is doctrine ("enumerate the background processes shaping your own series before reading mechanics off it"). Doctrine doesn't scale past the people who remember the incidents.
Proposal
A small shared type in commons + a per-box machine-readable JSONC file. Durable signals only (keepalives, pollers, crons, sweeps, watchdogs); ephemerals (per-session watchers) explicitly out of scope at v1.
Two shape decisions learned from the incidents, not aesthetics:
cadence is a discriminated type. The founding confound was event-anchored; free-form cadence text lets a consult catch crons and miss exactly the signal that caused the incident. With kind=event-anchored, anchor=window-expiry, the misread analysis would have matched the registration mechanically.
surface is a controlled tuple (domain, provider?, account?), not free text — required so measurement tools can auto-match registrations to what they're measuring.
Contract, two duties: anything generating recurring traffic against a measurable surface registers (one row); any measurement over a shared surface consults — subtracts or annotates matching registrations, and its report carries a greppable self-signals considered: [ids | none-registered] line (tool-enforced where the tool is ours; convention elsewhere). The registry is descriptive, not authoritative: absence of a registration is itself a finding — it shrinks the search space, it cannot close it.
Inventory reality check: enumeration on this box found 10-13 durable rows (keepalive, ledger-poll timers, dispatch-time quota refresh — a self-signal on our own measurement, board-sweeps, nightly consolidation passes, backup crons, gateway idle-shed respawns, OAuth rotation-on-use), so this is not a 2-row hypothetical.
Why commons and a file, not a daemon op
Considered and rejected placing it on the subc daemon (ck signals): the daemon is itself a signal source (health-probe cadence + self-watchdog are textbook instrumentation-pollutes-measurement rows) and a registry hosted inside one of its sources can't be neutral about it; most registrants aren't subc modules and shouldn't need a daemon connection to declare a cron; and wire surface is expensive to ever remove while a file is revocable in an afternoon. Revisit trigger, stated so this is a decision rather than a deferral: move it on-daemon only when a second live consumer exists AND the daemon needs to consult the registry inside its own decision path.
Disposition ask
Is a cortexkit-self-signals type crate (schema + serde + the consult-line convention) acceptable in commons? First consumer is filed separately on insula (ledger analytics annotation). If you'd rather this stay a downstream convention without a commons type, that's a legitimate answer — the contract matters more than the transport, and we'd keep the file format stable ourselves.
Problem — three incidents, one mechanism
Any measurement over a shared surface risks reading self-generated signal as external behavior. Three corroborating incidents on this box, all within days:
The current defense is doctrine ("enumerate the background processes shaping your own series before reading mechanics off it"). Doctrine doesn't scale past the people who remember the incidents.
Proposal
A small shared type in commons + a per-box machine-readable JSONC file. Durable signals only (keepalives, pollers, crons, sweeps, watchdogs); ephemerals (per-session watchers) explicitly out of scope at v1.
{ "signal_id": "claude-prime-keepalive", "owner": "homelab", "kind": "keepalive", // keepalive|poller|cron|sweep|watchdog|heartbeat "surface": { "domain": "provider-usage", "provider": "claude", "account": "..." }, "cadence": { "kind": "event-anchored", "anchor": "window-expiry" }, // ^ discriminated: {kind: "wall-clock", spec: "cron..."} | {kind: "event-anchored", anchor: ...} "since_ms": 0, "last_confirmed_ms": 0 }Two shape decisions learned from the incidents, not aesthetics:
cadenceis a discriminated type. The founding confound was event-anchored; free-form cadence text lets a consult catch crons and miss exactly the signal that caused the incident. Withkind=event-anchored, anchor=window-expiry, the misread analysis would have matched the registration mechanically.surfaceis a controlled tuple (domain, provider?, account?), not free text — required so measurement tools can auto-match registrations to what they're measuring.Contract, two duties: anything generating recurring traffic against a measurable surface registers (one row); any measurement over a shared surface consults — subtracts or annotates matching registrations, and its report carries a greppable
self-signals considered: [ids | none-registered]line (tool-enforced where the tool is ours; convention elsewhere). The registry is descriptive, not authoritative: absence of a registration is itself a finding — it shrinks the search space, it cannot close it.Inventory reality check: enumeration on this box found 10-13 durable rows (keepalive, ledger-poll timers, dispatch-time quota refresh — a self-signal on our own measurement, board-sweeps, nightly consolidation passes, backup crons, gateway idle-shed respawns, OAuth rotation-on-use), so this is not a 2-row hypothetical.
Why commons and a file, not a daemon op
Considered and rejected placing it on the subc daemon (
ck signals): the daemon is itself a signal source (health-probe cadence + self-watchdog are textbook instrumentation-pollutes-measurement rows) and a registry hosted inside one of its sources can't be neutral about it; most registrants aren't subc modules and shouldn't need a daemon connection to declare a cron; and wire surface is expensive to ever remove while a file is revocable in an afternoon. Revisit trigger, stated so this is a decision rather than a deferral: move it on-daemon only when a second live consumer exists AND the daemon needs to consult the registry inside its own decision path.Disposition ask
Is a
cortexkit-self-signalstype crate (schema + serde + the consult-line convention) acceptable in commons? First consumer is filed separately on insula (ledger analytics annotation). If you'd rather this stay a downstream convention without a commons type, that's a legitimate answer — the contract matters more than the transport, and we'd keep the file format stable ourselves.