Files

119 lines
5.6 KiB
Markdown

# Gate Layer
Upstream layer between sensors and the lemniscate. Gates admit signals based on thresholds. Each gate is registered; every decision validates against the register.
## Gate state
Each gate has one registry row and one state row.
- impulses: count since last summary.
- threshold: value shifted by the L1 decision.
- last_opened: cycle index of last opening.
- last_decision_cycle: cycle_uuid of the last decision that shifted this gate.
- counters: per-gate counters (e.g. dropped_pings).
- tier: T0-T3 declared importance.
## Injection loop
1. sensor emits impulse (event_uuid, gate, timestamp, payload).
2. gate summary at L1:
table columns: gate, impulses, threshold, last_opened, drives, last_decision_cycle, tier.
3. L1 decision: open/hold gates; threshold delta; optional evidence request.
4. opened gates compose content at L2 (frames, text, rows).
5. L2 answer + action calls; answer is next summary's salience signal.
## Cycle closure guard
Injection is only allowed while the lemniscate is CLOSED: both crossings complete and gate state snapshotted.
Properties:
1. Validation: the close is the validation point; a bad cycle is diagnosed from the summary table.
2. Staleness: summary and composed input use the same frozen snapshot.
3. Latency: crossing callbacks that block inference hold the cycle open; no desync.
Exceptions (re-run, not mid-cycle):
- threshold breach during an open cycle: summary rebuilt, cycle re-runs before inference lands.
- safety gate (T0): pierces the closed state; immediate cycle.
- starvation: a gate unseen for K cycles is force-opened at the next cycle boundary.
## Identity and causality
| ID | Assigned | Carries |
|---|---|---|
| event_uuid | sensor, at impulse | (the origin) |
| cycle_uuid | lemniscate, at open | admitted event_uuids |
| decision_uuid | L1 decision | event_uuids opened |
- L2 answer carries cycle_uuid + decision_uuid; output traces to its admitted impulses.
- UUID v7: 48-bit timestamp prefix; sort order = causal order.
- No record enters Phoebe without its causal UUIDs.
- Gate history keyed by cycle_uuid is replayable.
## Intake tiers
- Summary (poll): aggregate table each cycle.
- Evidence (pull): raw impulse rows for one gate, since last cycle, on request. The request is part of the L1 decision; rows are validated against the registry; they arrive as L2 composed input in the same cycle.
Impulse row: `(event_uuid, gate, timestamp, payload)`.
Created at the sensor; UUID v7; immutable. Failed ping is an emitted impulse, never inferred from absence.
## Policy layers
Higher layers cannot be overridden by lower ones; lower layers cannot close what a higher one opened.
| Layer | Owner | Decides |
|---|---|---|
| Hard floor | operator (dafit) | T0 gates; never closable |
| Presence policy | harness/switchboard, rule-bound | all closed / task-relevant open |
| Attention policy | runtime L1 | remainder |
Presence is a gate input above the L1 policy. It is rule-bound and has no LLM in the loop. Presence is the physical form of operator override.
## Gate tags (declared importance)
Importance is declared, never inferred.
| Tier | Meaning | Guarantee | Example |
|---|---|---|---|
| T0 critical | safety | pierces the closed cycle; hard floor; never closable | fire alarm, operator channel |
| T1 relational | operator presence | presence-owned; guaranteed attention share; cannot be attention-closed while active | chat/text gate, sofa camera |
| T2 standard | normal attention | tunable thresholds; starvation sampling | keepalive, host monitors |
| T3 ambient | background | poll-only; summary trend, on-demand evidence | telemetry |
Tag row: `(gate, tier, why, mode_overrides)`.
- Registry-declared and signed. T0/T1 immutable at runtime.
- T2/T3 may shift per mode (e.g. webcam T3 -> T1 in sofa mode); each shift is a UUID-logged decision.
- `why` is the audit reason string.
- Attention budget never starves a tier: T0 pierces, T1 holds a guaranteed share; L1 allocates the remainder.
## Adaptive timing
- L1 round-trip: decision capacity.
- L2 round-trip: synthesis capacity.
- Both derived from v7 timestamps; no new instrumentation.
- Cycle interval = mean(L1_RTT) + mean(L2_RTT) + margin.
- Animation duration >= L2_RTT; holds the gesture through synthesis.
- Estimator: sliding mean with hysteresis.
- RTT values feed schedule parameters, not gate thresholds.
## Long-running probes and heartbeat integrity
- Probes are async: issued at the crossing, not awaited. Result returns as an impulse into the next cycle's summary.
- RTT measures decision capacity only; probe wall-clock never enters the cycle interval.
- Probe latency is gate metadata; results accumulate losslessly into the next window.
- Silence must be manufactured: a probe's absence cannot be inferred. The deadline emits a timeout impulse (event_uuid, tiered); escalation rides a real signal.
- Pierce is for inspection, never effect-side arbitration: T0 forces the cycle to see; actions still resolve under mutex/priority.
## Persistence and restart
- Gate table in Phoebe, checkpointed after each cycle. The table is the resumable self; restart restores attention profile and thresholds.
- Raw impulses: bounded in-RAM ring buffer per gate; flushed to Phoebe at checkpoint. Evidence reads the buffer; audit reads the store.
- Truncation is explicit: an evidence request older than the buffer returns the buffer's lower bound; the gate table records the truncation.
## Attention semantics
Gates that close under sustained noise are the noise suppression: the gate stops mattering, rather than filtering smarter. Attention is a first-class resource with a budget and decay. The trait algebra at L2 tunes attention itself.
Version: 0.9 | Updated: 2026-11-04