The final piece of the heartbeat-system task. With this wired in,
Aster (or any agent) can schedule a prompt and the runtime fires it
back at the configured time as a fresh user turn.
Plumbing:
- `TurnInjector` trait in core/nervous/handler.rs decouples the
nervous module from any specific backend; LocalBackend implements it
- HeartbeatHandler now takes Arc<dyn TurnInjector>; on schedule_due
events it pulls agent_id + prompt from the payload and injects
- CronSensor includes agent_id in event payload so the handler knows
who owns the schedule
- LocalBackend gains an `active_sessions: Arc<AtomicU32>` counter that
send() increments and the spawned turn decrements; CronSensors read
this to skip firing while conversations are active (the existing
pause-during-presence semantics)
- On startup, LocalBackend::new discovers agents from the inventory
and spawns one CronSensor per agent + one HeartbeatHandler on the bus
- inject_background_turn reuses the agent's most recent conversation
(falls back to ensure_conversation), then drains the stream silently
Drive-by fix:
- write.rs append mode now calls file.flush() before drop. tokio's
File::Drop doesn't sync, which surfaced as a flaky test_append under
parallel test runs once compilation timing shifted.
102 tests, 0 failures.
Constitution Article V.3 is explicit — each model has different physics,
don't guess at 128K. Pressure calculation now reads from the agent's
`llm_config.context_window` (which inherits per-model defaults via
ModelConfig.context_limit).
- ConsciousnessEngine::calculate_pressure now takes `context_limit: usize`
- New `pressure_for_session` async helper looks up the agent's
context_window once and computes pressure
- backend/local.rs: bifrost_pressure takes `context_limit`; loop pulls
agent.llm_config.context_window once at the top
- api/handlers.rs uses pressure_for_session
128_000 only remains as a last-resort fallback if the agent isn't
findable; existing per-agent and per-model config flows now drive
the value.
Lays the substrate for Aster's clockmaker role and federation.
Nervous system (src/core/nervous/):
- EventBus broadcast channel with SensorEvent (universal event type
carrying seed_id for future federation)
- CronSensor loop with tokio::select!, mtime caching, active-session
pause, at-most-once firing semantics
- HeartbeatHandler scaffold (turn injection still stubbed)
- Persistent JSONL EventLog firehose
Schedule tool (src/core/tools/schedule.rs):
- CRUD over schedule files with body-knowledge prose descriptions
- Added to ASTER_SAFE_TOOLS so Aster can schedule her own rhythm
- CLI subcommand for direct schedule management
Seed identity (src/core/identity/):
- Ed25519 keypair, load-or-generate at init
- sign/verify primitives, CLI subcommand (show/sign/verify)
- Wired into LocalBackend, threaded through SensorEvent for federation
Credentials (src/core/credentials.rs):
- OS keyring (Linux/macOS/Windows) + env var fallback
- `souveraine auth` subcommand
- Removes hardcoded Bifrost api_key from souveraine.toml
Subconscious ledger (src/core/memory/mod.rs init_subconscious_ledger):
- 6 ledger files (commitments/assumptions/patterns/drift_log/
relationships/infrastructure) with proper YAML frontmatter
- Paths fixed: ledger/ not subconscious/ledger/
- Body usage instructions, idempotent init
Prompt orientation (src/core/prompt.rs build_ledger_orientation):
- Scans ledger/ directory, injects last 3 entries from each file
into Aster's system prompt (live context, not just awareness)
- Routing table + workflow (read before write, timestamped append)
Consciousness engine (src/server/consciousness_engine.rs):
- Adaptive rate delay shared with primary loop
- Four-fold mandate (Complete/Verify/Persist/Surface) in hardcoded
default prompt; observation format extracted for sharing
- Schedule added to ASTER_SAFE_TOOLS
Backend + CLI wiring expanded to mount the nervous system, identity,
and credentials at startup. New TOML sections: [schedules], [events],
[federation].
102 tests passing.
The repo had accumulated 20 root-level .md files (multiple architecture
versions, master spec, opus implementation guide, status docs from May 5)
and 35+ docs/ files mixing canonical references with stale planning notes.
Recent commits had moved the project well past the state those docs
described.
Changes:
- Move 19 pre-rebuild root docs to docs/archive/ (architecture v1/v2.1/
v2.2, master spec, opus guide, phases, status, README pitch). Pre-
served because they show the architectural conversation; not
authoritative anymore.
- Move 17 stale docs/ files to docs/archive/ (alignment report, May 6
handoff, interface planning trio, tool-system design rounds,
subagent investigation, sea-consciousness analysis, sexy-ui, tui
enhancement guides, sensorium questions).
- Move 34 superseded task scopes to docs/tasks/archive/ (scope-1/2/3
landed, tool-system phases 1-4 superseded, all 10 tui-component
tasks completed, n1-four-fold / aster-rebuild / n25-four-elements
folded into scope-3/4 and N+1 LLM pass, port-compaction superseded
by in-session-compaction-implementation).
- Delete 5 .bak files (ASTER_ARCHITECTURE, CONSCIOUSNESS_CYCLE,
energy-topology, scope-3-n1-consciousness x2).
- Delete docs/FIMEG_REFERENCE.md (byte-identical duplicate of
reference/Fimeg.md; the NOTE TO OPUS header belongs in reference/).
- Delete 3 .txt session captures (harnesstime, massive,
"souveraine updates") and souveraine.log; add log to .gitignore.
- Delete orphan src/core/persona/mod.rs (~220 LOC referencing the
~/.pi/unified/ paths from the TypeScript precursor; never exported
in core/mod.rs; the persona-router-completion task survives so the
goal isn't lost).
- Rewrite README.md to reflect the actual current state instead of
the May 5 pitch.
- Rewrite docs/INDEX.md as a navigable map of the canonical set plus
a pointer at the archive.
Active state after this commit:
- root: README.md, Cargo.toml/lock, souveraine.toml(.example), src/,
docs/, saf/, reference/, examples/, tauri/, web/, target/, .gitignore.
- docs/: 14 canonical docs (THE_QUESTION, CONTEXT_CONSTITUTION,
SENSORIUM_ARCHITECTURE, ASTER_ARCHITECTURE, CONSCIOUSNESS_CYCLE,
DECISIONS, MEMORY_BLOCKS_DECISION, CRON_API_AUTH, FEDERATION_SKETCH,
ARCHITECTURE_v3, HANDOFF_NEXT, SCOPED_WORK_PLAN, PROJECT_STATE_ANALYSIS,
INDEX) + archive/ (36 files).
- docs/tasks/: 15 active scopes + archive/ (34 files).
- cargo build: 0 errors, 145 pre-existing warnings (unchanged).
- Added src/ui/buddy.rs with CompanionSprite, BuddyState, and draw functions
- Integrated buddy into app.rs for welcome screen and dashboard
- Added agent selection via 'a' key on welcome screen
- Buddy shows agent name, mood, energy, health, and subconscious status
- WIP: Needs full agent alias creation/removal flow