From d059af214699a138d72ec9e22ccf15609ad2df25 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Tue, 23 Dec 2025 02:39:25 -0800 Subject: [PATCH] docs: Christmas Ornament pattern and activity feed vision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added to molecular-chemistry.md: - Dynamic Bonding section with Christmas Ornament pattern - WaitsFor directive documentation - Activity feed examples - Variable substitution syntax - Mol Mall integration notes Added to architecture.md: - Christmas Ornament pattern summary - Activity feed section - bd activity command documentation This design enables mol-witness-patrol to dynamically bond inspection arms per-polecat, with real-time work state visibility. πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- docs/architecture.md | 64 +++++++++++++++ docs/molecular-chemistry.md | 159 ++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+) diff --git a/docs/architecture.md b/docs/architecture.md index 66f2b912..cdf7d4bd 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -603,6 +603,70 @@ Patrol agents (long-running monitors) execute in infinite wisp loops: This gives patrols full audit trails without ledger bloat. +### Dynamic Bonding: The Christmas Ornament Pattern + +Some workflows need **dynamic structure** - steps that emerge at runtime based +on discovered work. Consider mol-witness-patrol: it monitors N polecats where +N varies. A static molecule can't express "for each polecat, do these steps." + +The solution is **dynamic bonding** - spawning child molecules at runtime: + +```bash +# In survey-workers step: +for polecat in $(gt polecat list gastown); do + bd mol bond mol-polecat-arm $PATROL_WISP_ID --var polecat_name=$polecat +done +``` + +This creates the **Christmas Ornament** shape: + +``` + β˜… mol-witness-patrol (trunk) + /|\ + β”Œβ”€β”€β”€β”€β”€β”˜ β”‚ └─────┐ + ● ● ● mol-polecat-arm (dynamic arms) + ace nux toast + β”‚ β”‚ β”‚ + β”Œβ”€β”€β”΄β”€β”€β” β”Œβ”€β”€β”΄β”€β”€β” β”Œβ”€β”€β”΄β”€β”€β” + β”‚stepsβ”‚ β”‚stepsβ”‚ β”‚stepsβ”‚ (each arm has 4-5 steps) + β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ + β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + ⬣ base (cleanup) +``` + +Arms execute in **parallel**. The `aggregate` step uses `WaitsFor: all-children` +to gate until all dynamically-bonded children complete. + +See [molecular-chemistry.md](molecular-chemistry.md#dynamic-bonding-the-christmas-ornament-pattern) +for full documentation. + +### The Activity Feed + +Dynamic bonding enables a **real-time activity feed** - structured work state +instead of parsing agent logs: + +``` +[14:32:01] βœ“ patrol-x7k.inbox-check completed +[14:32:03] βœ“ patrol-x7k.check-refinery completed +[14:32:08] + patrol-x7k.arm-ace bonded (5 steps) +[14:32:08] + patrol-x7k.arm-nux bonded (5 steps) +[14:32:09] β†’ patrol-x7k.arm-ace.capture in_progress +[14:32:10] βœ“ patrol-x7k.arm-ace.capture completed +[14:32:14] βœ“ patrol-x7k.arm-ace.decide completed (action: nudge-1) +[14:32:17] βœ“ patrol-x7k.arm-ace COMPLETE +[14:32:23] βœ“ patrol-x7k SQUASHED β†’ digest-x7k +``` + +**This is what you want to see.** Not Claude's internal monologue. WORK STATE. + +The beads ledger becomes a real-time activity feed: +- `bd activity --follow` - Stream state transitions +- `bd activity --mol ` - Activity for specific molecule +- Control plane IS data plane - state transitions are queryable data + +This transforms debugging from "read the logs" to "watch the feed." + ### Step States ``` diff --git a/docs/molecular-chemistry.md b/docs/molecular-chemistry.md index 517953a5..0c287afe 100644 --- a/docs/molecular-chemistry.md +++ b/docs/molecular-chemistry.md @@ -591,6 +591,165 @@ This ensures cross-phase references remain valid: - On squash: Replace placeholder with actual digest - Cross-phase references never break +## Dynamic Bonding: The Christmas Ornament Pattern + +Static molecules have fixed steps defined at design time. But some workflows +need **dynamic structure** - steps that emerge at runtime based on discovered work. + +### The Problem + +Consider mol-witness-patrol. The Witness monitors N polecats where N varies: +- Sometimes 0 polecats (quiet rig) +- Sometimes 8 polecats (busy swarm) +- Polecats come and go during the patrol + +A static molecule can't express "for each polecat, do these steps." + +### The Solution: Dynamic Bond + +The **bond** operator becomes a runtime spawner: + +```bash +# In survey-workers step: +for polecat in $(gt polecat list gastown); do + bd mol bond mol-polecat-arm $PATROL_WISP_ID \ + --var polecat_name=$polecat \ + --var rig=gastown +done +``` + +Each bond creates a **wisp child** under the patrol molecule: +- `patrol-x7k.arm-ace` (5 steps) +- `patrol-x7k.arm-nux` (5 steps) +- `patrol-x7k.arm-toast` (5 steps) + +### The Christmas Ornament Shape + +``` + β˜… mol-witness-patrol (trunk) + /|\ + / | \ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ └─────────┐ + β”‚ β”‚ β”‚ + PREFLIGHT DISCOVERY CLEANUP + β”‚ β”‚ β”‚ + β”Œβ”€β”€β”€β”΄β”€β”€β”€β” β”Œβ”€β”€β”€β”΄β”€β”€β”€β” β”Œβ”€β”€β”€β”΄β”€β”€β”€β” + β”‚inbox β”‚ β”‚survey β”‚ β”‚aggreg β”‚ + β”‚refnry β”‚ β”‚ β”‚ β”‚save β”‚ + β”‚load β”‚ β”‚ β”‚ β”‚summaryβ”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”˜ β”‚contxt β”‚ + β”‚ β”‚loop β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β””β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + ● ● ● mol-polecat-arm + ace nux toast + β”‚ β”‚ β”‚ + β”Œβ”€β”€β”΄β”€β”€β” β”Œβ”€β”€β”΄β”€β”€β” β”Œβ”€β”€β”΄β”€β”€β” + β”‚cap β”‚ β”‚cap β”‚ β”‚cap β”‚ + β”‚ass β”‚ β”‚ass β”‚ β”‚ass β”‚ + β”‚dec β”‚ β”‚dec β”‚ β”‚dec β”‚ + β”‚exec β”‚ β”‚exec β”‚ β”‚exec β”‚ + β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ β””β”€β”€β”¬β”€β”€β”˜ + β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + ⬣ base (cleanup) +``` + +The ornament **hangs from the Witness's pinned bead**. The star is the patrol +head (preflight steps). Arms grow dynamically as polecats are discovered. +The base (cleanup) runs after all arms complete. + +### The WaitsFor Directive + +A step that follows dynamic bonding needs to **wait for all children**: + +```markdown +## Step: aggregate +Collect outcomes from all polecat inspection arms. +WaitsFor: all-children +Needs: survey-workers +``` + +The `WaitsFor: all-children` directive makes this a **fanout gate** - it can't +proceed until ALL dynamically-bonded children complete. + +### Parallelism + +Arms execute in **parallel**. Within an arm, steps are sequential: + +``` +survey-workers ─┬─ arm-ace ─┬─ aggregate + β”‚ (seq) β”‚ + β”œβ”€ arm-nux ── (all arms parallel) + β”‚ (seq) β”‚ + └─ arm-toastβ”˜ +``` + +Agents can use subagents (Task tool) to work multiple arms simultaneously. + +### The Activity Feed + +Dynamic bonding enables a **real-time activity feed** - structured work state +instead of agent logs: + +``` +[14:32:01] βœ“ patrol-x7k.inbox-check completed +[14:32:03] βœ“ patrol-x7k.check-refinery completed +[14:32:07] β†’ patrol-x7k.survey-workers in_progress +[14:32:08] + patrol-x7k.arm-ace bonded (5 steps) +[14:32:08] + patrol-x7k.arm-nux bonded (5 steps) +[14:32:08] + patrol-x7k.arm-toast bonded (5 steps) +[14:32:08] βœ“ patrol-x7k.survey-workers completed +[14:32:09] β†’ patrol-x7k.arm-ace.capture in_progress +[14:32:10] βœ“ patrol-x7k.arm-ace.capture completed +[14:32:14] βœ“ patrol-x7k.arm-ace.decide completed (action: nudge-1) +[14:32:17] βœ“ patrol-x7k.arm-ace COMPLETE +[14:32:23] βœ“ patrol-x7k SQUASHED β†’ digest-x7k +``` + +This is what you want to see. Not logs. **WORK STATE.** + +The beads ledger becomes a real-time activity feed. Control plane IS data plane. + +### Variable Substitution + +Bonded molecules support variable substitution: + +```markdown +## Molecule: polecat-arm +Inspection cycle for {{polecat_name}} in {{rig}}. + +## Step: capture +Capture tmux output for {{polecat_name}}. +```bash +tmux capture-pane -t gt-{{rig}}-{{polecat_name}} -p | tail -50 +``` + +Variables are resolved at bond time, creating concrete wisp steps. + +### Squash Behavior + +At patrol end: +- **Notable events**: Squash to digest with summary +- **Routine cycle**: Burn without digest + +All arm wisps are children of the patrol wisp - they squash/burn together. + +### The Mol Mall + +mol-polecat-arm is **swappable** via variable: + +```markdown +## Step: survey-workers +For each polecat, bond: {{arm_molecule | default: mol-polecat-arm}} +``` + +Install alternatives from the Mol Mall: +- `mol-polecat-arm-enterprise` (compliance checks) +- `mol-polecat-arm-secure` (credential scanning) +- `mol-polecat-arm-ml` (ML-based stuck detection) + ## Summary of Operators | Operator | From | To | Effect |