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_indextable with backfill from existing audit entries- CEL dependency extraction (hybrid AST walking + regex for pipe expressions)
- Dual-write to
_actions,_views,_agentsscopes alongside legacy tables - Temporal query endpoints:
/history/:scope/:key, prefix queries - Structural event indexing (register/delete actions, views, agents)
- Observable vocabulary:
state._actions.add_concept.descriptionevaluable as CEL
Phase 2: Log-Based Temporal — ✅ Complete, verified live
- View value sampling piggybacked on dashboardPoll (60s interval)
kind: "sample"audit entries indexed under_samplesscope/samples/:viewIdendpoint for temporal sparkline data- marked.js (v15) + mermaid.js (v11.4) loaded in dashboard shell
- MarkdownSurface renders markdown + detects mermaid code blocks
Phase 3: Adaptive Salience — ✅ Complete, verified live
- Six structural signals: recency, dependency, authorship, directed, contest, delta
- Per-room configurable weights via
_config.salience_weights _saliencesystem view injected in agent context with transparent scoring/salienceendpoint for full map with per-key signal breakdown- Salience is observable — agents can inspect their own relevance map
Phase 4: Convergence — ✅ Complete, verified live
buildContext(cel.ts) reads agents, actions, views from v8 scopes with legacy fallbackbuildExpandedContext(context.ts) reads actions from_actionsscope with legacy fallback- Old
dashboardPolldeleted from context.ts (replaced by poll-v8.ts) v8ToLegacyPolladapter deleted — Surfaces.tsx uses decoupled interfacePollDatatype deleted — frontend consumesPollDataV8exclusively- Legacy table reads reduced to:
last_seen_seq(agents table, single row per request),invoke.ts(action lookup for invocation),replay.ts(audit reconstruction)
Phase 5: Legacy Removal — not started
- Remove dual-write from actions.ts, views.ts, agents.ts
- Switch invoke.ts to read action definitions from
_actionsscope - Switch replay.ts to read from v8 scopes
- Drop legacy
actions,viewstables (agents table kept for auth tokens + last_seen_seq)
A 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.
Phase 1 is additive. Existing tables remain. New scope conventions are populated in parallel. Reads fall back to legacy tables when scope data is absent. Once validated, legacy tables become read-only, then removable.
The buildContext and dashboardPoll functions detect whether a room is v8 (has _actions scope entries) or legacy (has rows in actions table) and assemble context accordingly. This lets existing rooms continue working while new rooms use the unified model.
- Schema: Add
log_indextable. No changes to existing tables. - Log index population: On every audit append, also populate
log_index. - Registration path:
_register_actionand_register_viewwrite to both legacy tables AND_actions/_viewsscopes (dual-write). - Context assembly: Read from scope-based entries when present, fall back to legacy tables.
- Agent join: Write to
_agentsscope in addition toagentstable. - Temporal queries: New endpoints using
log_indexfor key history. - Deprecation: Stop reading from legacy tables for rooms that have scope entries.