Watch
1
0
Fork
You've already forked souveraine
0
souveraine/saf/plan.md
Fimeg 3ff6ffaa7f license: relicense AGPL-3.0; bring SAF docs online; keep CLAUDE.md + docs/ local
SAF (souveraine architecture files) is now the in-repo doc set. working notes
(CLAUDE.md, docs/) stay on disk, gitignored.
2026-06-19 10:17:56 -04:00

6.9 KiB

SAF: Execution Plan

Ordered by impact, sequenced for "real harness today." Last updated: 2026-05-12 (Full audit — several stages now complete, new tasks emerged)


Overview — What Shipped Since May 6

The following was all completed between May 6 and May 12, across ~6,000 new lines of Rust:

  • Stage 3 — TUI Chat: full wired chat with bubbles, tool cards, cockpit (thinking + subconscious panes), schedules editor, portraits, presence mode, markdown rendering
  • Stage 4 — LocalBackend: in-process engine with auto-fallback, SubagentRunner, TurnInjector, CronSensor/HeartbeatHandler wiring
  • Stage 5A — Memory module: git-backed MemFS with 8 subcommands, frontmatter, auto-commit, limit enforcement, ledgers
  • Stage 5B — N+1 Aster pass: full Bifrost tool loop (5 rounds), subconscious agent identity, ledger orientation, 4-fold mandate prompt
  • Stage 5C — N+25 Reflection engine: 5-phase LLM pass with tool access, wired at every 25th turn
  • Stage 5D — Compaction engine: 4 strategies (Microcompact/SlidingWindow/Summary/Cull), audit trail
  • Stage 5E — Skills system: 4-tier discovery, injected into system prompt
  • Stage 5F — Nervous system: EventBus, CronSensor, HeartbeatHandler, EventLog
  • Stage 5G — Seed identity: Ed25519 per-agent keypair + CLI subcommand
  • Stage 5H — Credentials: OS keyring + env var fallback
  • Stage 5I — Auth middleware: bearer-token API protection for memory routes
  • Stage 5J — Conversation persistence: event-sourced disk store with load/save/archive

What's Still TODO (Priority Order)

P1 — N+100 Archivist (Missing)

Files to create/modify:

  • src/core/archivist/mod.rs — NEW: rebuild the Archivist module post-cleanup
  • src/server/consciousness_engine.rs — Wire N+100 pass instead of placeholder pressure check

The original core::archivist/ was removed from compilation (May 6) and never rebuilt. At 0.7+ pressure, the consciousness engine emits a ConsciousnessEvent::Archivist with a generic "Context compression triggered" string. No actual synthesis, no LLM call. The ArchivistConfig (enabled, interval, threshold, compression_model, synthesis_elements) exists in config but nothing reads it.

Target architecture: Smaller/faster model (e.g. qwen2.5-7b) calls Bifrost with a synthesis prompt, writes structured output (Themes/Emotions/Tensions/Anchors/Evolution/Patterns) to system/synthesized/{date}.md. Raw journal entries stay in git forever.

P1 — N+1 After Heartbeat Turns

File: src/core/nervous/handler.rs

TurnInjector::inject_background_turn in LocalBackend drains the stream silently but never calls ConsciousnessEngine::on_response after the turn completes. This means scheduled turns from the cron system never get Aster analysis. The fix is to hook into the post-turn processing path so heartbeat-injected turns also pass through the subconscious.

P2 — Remote Git Sync (push/pull)

Files: src/core/memory/mod.rs

Neither push() nor pull() exist on MemoryRepo. The real agent's .git/config may already have a remote configured. The auto_push config option exists but is never read. Needed for: off-machine backup, letting Ani on the home server sync memory to a remote, federation foundation.

P2 — Per-Agent Context Limit Fix

Status: 🟡 Partially resolved

ConsciousnessEngine now looks up the agent's llm_config.context_window (commit 79a23bb). The context_limit field is correctly read per-agent. What's still hardcoded: the 128_000 fallback in pressure_for_session() when agents.get() fails. No per-agent compaction thresholds (all agents share the global 80/90/95% tiers).

P2 — Subagent Pool (Lifecycle Manager)

Files: src/core/subagent/mod.rs (25 lines, stub)

The SubagentPool exists as a struct with new(). No lifecycle tracking, no concurrency limits, no heartbeat monitoring. The LocalSubagentRunner handles individual spawns correctly but there's no central pool to:

  • Limit concurrent forks
  • Track parent-child relationships
  • Kill orphaned subagents
  • Report pool health

P3 — Sensorium Unification

Files: src/core/sensorium/mod.rs (154 lines, trait + types only)

Sensorium trait exists with BandwidthClass (High/Medium/Low/Minimal) and DiscoveryLevel. Not wired into any backend. Would enable bandwidth-aware SSE events, progressive UI discovery, and context-adaptive interaction. The TuiSensorium, MobileSensorium, and Coordinator from CLAUDE.md are not built.

P3 — Chain Orchestrator (Talking vs Thinking)

Files: src/core/chain/mod.rs (50 lines, stub)

ChainOrchestrator was supposed to manage Talking (reactive, fast) vs Thinking (reflective, slow) chains. Never implemented beyond struct + new().

P4 — Federation Transport

Files: saf/atproto-federation.md (research), src/core/nervous/mod.rs (seed_id pre-wired)

WebSocket bridge between EventBus instances on different machines. ATProto-ready DID identity model. The seed_id field on SensorEvent is pre-wired as the federation identity marker. Not started.

P4 — OSSUI Integration

File: src/api/mod.rs (web routes)

Server has web/dist/ SPA fallback wired. No actual UI built there. Rebrand ex-letta-oss-ui as Souveraine web interface.

P4 — Cloister Diff-Canary

Location: Not yet scoped

N+1 should read git diff of the last commit and validate against domain schema. HALT/WARN/LOG severity. From docs/CONSCIOUSNESS_CYCLE.md § Cloister Security Model.


Remaining Design Decisions

These were deferred in prior sessions and are still unresolved:

  1. Archivist model selection: Should N+100 use a dedicated model (config: archivist.compression_model), or should the agent pick her own compression model? The auto value in config defaults means "let the system decide" — no algorithm written for that yet.

  2. N+1 model for Aster: openai/glm-5.1-precision is the current default hardcoded in reflection.rs line 130. Should this be driven by config only (it is in SubconsciousConfig.model for the engine, but the reflection engine has its own fallback chain)? Current resolution: the consciousness engine passes the config value through; the reflection engine's hardcoded default is a fallback.

  3. Cloister canary severity: HALT vs WARN vs LOG on domain schema violation? Not designed. The current subconscious pass never inspects git diff.

  4. lifetime_active_seconds granularity: Currently ticks in 30s buckets. Useful for uptime percent but not fine-grained enough for "how long has this agent been running this session." No per-session wall-clock tracking.


Resumption Checklist

When a new model picks up:

  • Read saf/plan.md for current priorities
  • Check docs/tasks/ for active task documents
  • Read CLAUDE.md for conventions (substrate, not harness)
  • Start with P1 items: Archivist (N+100) or Heartbeat N+1 wiring
  • Do NOT add --force-compact or auto_compact_at_threshold knobs
  • Update saf/plan.md with progress