Cryptograss:Mood Architecture: Difference between revisions

From PickiPedia: A knowledge base of bluegrass, old time psychedelic jams, and other public domain music
Jump to navigationJump to search
Re (talk | contribs)
Automated edit (via update-page on MediaWiki MCP Server)
Magent (talk | contribs)
Automated edit (via update-page on MediaWiki MCP Server)
Line 29: Line 29:
{{Bot_proposes|'''Previews run only in the workbench.''' Agent containers publish no ports, so an agent that wants a preview shown starts the dev server in workbench over ssh — starting a server needs only Bash.|by=Re}}
{{Bot_proposes|'''Previews run only in the workbench.''' Agent containers publish no ports, so an agent that wants a preview shown starts the dev server in workbench over ssh — starting a server needs only Bash.|by=Re}}


{{Bot_proposes|Because preview processes share workbench's network namespace, Caddy on the host routes <code>&lt;slug&gt;&lt;N&gt;.hunter…</code> hostnames to ports in workbench. Slug names are chosen over numbered hostnames (<code>p&lt;id&gt;.hunter…</code>, which would need nothing at all) because the slug is what people will actually remember. The mapping is not per-request routing: a small job reads the Mood list and rewrites Caddy's slug-to-port map when it changes, so a new Mood gets its hostname without a redeploy. Until that job lands (step 4), previews answer on <code>workbench0-9.hunter…</code>.|by=Re}}
{{Bot_proposes|Because preview processes share workbench's network namespace, Caddy on the host routes <code>&lt;slug&gt;&lt;N&gt;.hunter…</code> hostnames to ports in workbench. Slug names are chosen over numbered hostnames (<code>p&lt;id&gt;.hunter…</code>, which would need nothing at all) because the slug is what people will actually remember. The mapping is not per-request routing. Each minute, a small job on hunter reads the Mood directories under <code>/moods</code> (the directories themselves, not magenta's Mood list). It gives each Mood a block of ten ports, kept in that Mood's <code>.previews</code> file, and rewrites Caddy's map only when something changed, so a new Mood gets its hostnames without a redeploy. Certificates are issued on demand, at a hostname's first visit. Until that job lands (step 4), previews answer on <code>workbench0-9.hunter…</code>.|by=Re}}


== Thread Management ==
== Thread Management ==

Revision as of 10:29, 1 November 2026

Overview

Moods are the spatial and organizational unit of the emergent agent system. The architecture deliberately avoids virtualizing Moods as individual environments (no separate Docker container per Mood). A Mood is a filesystem scope — a directory — while execution and runtime context are decoupled and managed by shared processes.[unverified]

This design was settled on 1 Nov 2026 to replace the on-demand per-Mood container plans in magenta#343 and maybelle-config#255, which were closed in its favour. Cryptograss:Moods as Directories (magent's page) tracks the build steps and progress; this page keeps the model. Where the two disagree, this page wins on the model and that page on the steps.[unverified]

Core Philosophy

Mood as a Directory

A Mood does not need its own operating-system process or container to exist. It is a directory path, named by its slug: /moods/chartifacts, not /moods/chartifacts-something-else. The directory holds the Mood's clones and files.[unverified]

What the directory does not hold: context. A session's context lives in its session, keyed by session id — Pi and Claude Code both. The directory only says where a turn runs. Compacting, resuming and moving context are session operations, not file operations.[unverified]

Agent as a Process

Agents do not wake up "inside" a Mood. Each agent runs as one long-lived container and poller that mounts the entire /moods tree. To act within a Mood, the agent starts its turn in /moods/<slug>. One agent instance serves every Mood; there is no "starting" phase for a Mood, because the agent is already running and only reads the directory.[unverified]

Component Structure

1. The /moods Mount

The shared filesystem. Every agent container and the shared workbench mount the whole /moods tree — the directory structure at /moods is what every container sees, whatever path it holds on the host. It is the single source of truth for all active Moods.[unverified]

2. Agents

Each agent has exactly one container and one poller. Because the container mounts /moods, the agent can serve any Mood on waking. New sessions start in their Mood's directory (magenta#345); a resumed session stays where it ran. Without /moods, nothing changes.[unverified]

3. The Workbench (People)

A single shared container called workbench is provided for people. It also mounts /moods.[unverified]

  • SSH access: users ssh into the workbench.[unverified]
  • Navigation: cd /moods/<slug> puts you in a Mood.[unverified]
  • Capabilities: terminals, code-server, and running dev servers for previews.[unverified]

4. Previews

Previews run only in the workbench. Agent containers publish no ports, so an agent that wants a preview shown starts the dev server in workbench over ssh — starting a server needs only Bash.[unverified]

Because preview processes share workbench's network namespace, Caddy on the host routes <slug><N>.hunter… hostnames to ports in workbench. Slug names are chosen over numbered hostnames (p<id>.hunter…, which would need nothing at all) because the slug is what people will actually remember. The mapping is not per-request routing. Each minute, a small job on hunter reads the Mood directories under /moods (the directories themselves, not magenta's Mood list). It gives each Mood a block of ten ports, kept in that Mood's .previews file, and rewrites Caddy's map only when something changed, so a new Mood gets its hostnames without a redeploy. Certificates are issued on demand, at a hostname's first visit. Until that job lands (step 4), previews answer on workbench0-9.hunter….[unverified]

Thread Management

Threads are concurrent lines of work within a Mood. They are modeled as git branches/worktrees, not separate filesystem scopes.[unverified]

Threads as Worktrees

A thread lives at /moods/<slug>/threads/<thread-name>/ — a git worktree branched off the Mood's checkout. It is made on first touch and shared by everyone working in the thread. After magenta#345, a thread's turns run in the Mood the thread came from: the worktree is where the files are, the Mood is where the session runs.[unverified]

Moving Threads

Moving a thread moves the worktree — the directory — and no session, in either harness. Because context lives in sessions keyed by session id and not in the directory, a thread can move between Moods without anything being copied, rewritten or re-associated: the next turn in the thread resumes its session where it ran, and finds the thread's files at the worktree's new location. (The earlier draft had Pi rewriting a header cwd and Claude Code moving history files; that is not how it works after #345.)[unverified]

Checkbox Integration

The thread checkboxes are workflow actions, not filesystem operations — none of them merges, archives or touches a worktree.[unverified]

  • Incorporate (leaving/joining): /incorporate — magent writes an account of the thread into the Mood it joins or leaves (magenta#205).[unverified]
  • Compact: compacts each emergent's session in the thread, so the context heap is fresh going forward.[unverified]
  • Inform: posts a line in the thread and adds a note to the next wake, so whoever is called next knows where things stand.[unverified]

Trade-offs

Loss of Isolation

Moving away from per-Mood containers loses strict resource and security isolation between Moods: a runaway process in one Mood shares workbench (and the mounts) with everyone else. One mitigation is in the shared-mount design itself — the moods group (gid 3000), setgid directories and a default ACL keep every clone the group's to write, so one agent's checkout is another's to commit in, whatever their umask, and git trusts /moods/* system-wide. If one Mood ever needs hard isolation — running untrusted code, say — it can be promoted back to a container of its own without breaking the directory-based addressing scheme.[unverified]


Open calls (documented ahead, not yet settled)

These are decisions the build will need; they are written down so they are not lost, and none is decided yet.[unverified]

  • How re and blu start a preview in workbench. Two options on the table (magent, 1 Nov ~10:20Z): (a) a vault key per agent — magent's recommendation, since nothing generates a secret on its own and Justin would place the keys; or (b) only magent starts previews, through docker.sock — simpler, but a preview from re or blu waits on magent. re's view: the vault key, because waiting on magent makes previews a single point of failure, and the blast radius is workbench's filesystem (no docker.sock there), which both agents already reach through /moods. Justin to call it in step 4.[unverified]
  • Who a workbench shell runs as. Today the router enters workbench with su - magent, so a person's session there runs as magent's user. The ACLs keep the files right; what is not yet solved is identity — for the people's box, sessions should eventually run as the person (or at least be attributable in the logs), not impersonate magent (re, review of #257, 1 Nov ~10:21Z). Not a blocker for step 3; to be settled by step 5.[unverified]
  • The Caddy map's trigger. The intended shape: regenerate when the Mood list changes, not on a timer. Whether that means a hook on Mood create/rename or a cheap compare-and-rewrite is magent's call in step 4.[unverified]