The room is the world model. Actions are the transition function. Views are the observation function. The audit log is the trajectory. What's missing? The reward signal. That's adaptive salience.
— kernel.ts, closing comment
Phase 1: Unification — ✅ Complete, verified live
log_index table with backfill from existing audit entries_actions, _views, _agents scopes alongside legacy tables/history/:scope/:key, prefix queriesstate._actions.add_concept.description evaluable as CELPhase 2: Log-Based Temporal — ✅ Complete, verified live
kind: "sample" audit entries indexed under _samples scope/samples/:viewId endpoint for temporal sparkline dataPhase 3: Adaptive Salience — ✅ Complete, verified live
_config.salience_weights_salience system view injected in agent context with transparent scoring/salience endpoint for full map with per-key signal breakdownPhase 4: Clean Break — ✅ Complete, verified live
poll-v8.ts)v8ToLegacyPoll() adapter created, used, and deleteddashboardPoll() deleted (old 6-query legacy poll)PollData type deleted — frontend consumes PollDataV8 exclusivelyPhase 5: Legacy Table Removal — ✅ Complete, verified live
views table: DROPPED — all CRUD via _views scope onlyactions table: DROPPED — timer cooldown state in _timer field of _actions scope valueagents table: DROPPED — tokens migrated to unified tokens table (82 agents), last_seen_seq in _agents scope, heartbeat via tokens.last_used_at + scopetimers.ts: removed references to dropped tablesreplay.ts: already v8-clean (reconstructs from _audit scope, no legacy reads)DROP TABLE IF EXISTS views/actions/agents in migration chainA sync room is exactly two things:
State — a finite partial function from located keys to versioned values. The current projection of all truth.
Log — an append-only sequence of events. The complete causal history.
Everything else is convention and interpretation.
state(room_id, scope, key) → { value, revision, hash, updated_at }
log(room_id, seq) → { kind, ts, agent, payload }
| Scope Prefix | Interpretation | Replaces |
|---|---|---|
_shared | Shared substrate | (unchanged) |
_actions | Write affordances | actions table |
_views | Read lenses | views table |
_agents | Participant presence | agents table |
_messages | Communication log | (unchanged) |
_audit | Event history | (unchanged) |
_help | Guidance namespace | (unchanged) |
_config | Room configuration | _shared._dashboard |
{agent-id} | Agent-private scope | (unchanged) |
The audit trail (now: log) is optimised for sequential replay. The log_index table makes it queryable by affected key:
CREATE TABLE log_index (
room_id TEXT NOT NULL,
seq INTEGER NOT NULL,
scope TEXT NOT NULL,
key TEXT NOT NULL
);
CREATE INDEX idx_li_key ON log_index(room_id, scope, key);
CREATE INDEX idx_li_seq ON log_index(room_id, seq);
This replaces proposed state_history and view_journal tables. The log IS the history.
All legacy entity tables (actions, views, agents) have been dropped. The database now contains:
| Table | Purpose |
|---|---|
rooms | Room identity + admin/view token hashes |
state | The substrate — all domain data via scope conventions |
tokens | Unified credential store (room, agent, MCP, device auth tokens) |
log_index | Temporal query index over audit entries |
smcp_* | MCP auth infrastructure (users, credentials, sessions, etc.) |
device_codes | OAuth Device Authorization flow |
The state table is the single source of truth for all domain data. The tokens table handles all authentication. Everything else is MCP auth plumbing.
State and Log. One is the current projection, the other is causal history. Everything else — actions, views, agents, messages — is convention interpreted by scope prefix.