# Decisions (16 examples)

## 1. Describe the decision on framework stack strategy.

> MARAUDER + Saiden Tactical Systems standardise the production-harness framework surface around inference-ease × production maturity × popularity, in that order of weight (50/30/20). Customer engagements are steered toward these picks at intake; competitors don't see the mechanism.
> 
> CHOSEN STACKS (top-3 of top-3, primary in bold):
> 
> Hosted full-stack:
> - **Django** (A+ inference, A+ prod, A pop) — primary
> - Rails 8 (A+ inference, A+ prod, B+ pop) — Ruby-deep teams
> - Laravel (A inference, A prod, A pop) — PHP-native teams + LATAM/Asia clients
> 
> Static:
> - **Astro** (A+ inference, A prod, A pop) — primary
> - Hugo (A+ inference, A+ prod, B+ pop) — high-page-count blogs/docs
> - Vite vanilla (A inference, A prod, A pop) — one-pagers (proven via example-app)
> 
> API:
> - **FastAPI** (A+ inference, A+ prod, A pop) — primary
> - Rails API mode (A+ inference, A+ prod, B pop) — Rails-deep teams
> - Hono (A inference, A prod, B+ pop) — edge / TS-modern
> 
> DELIBERATELY STEERED AWAY FROM (when customer is flexible):
> - Next.js App Router — popularity #1 but inference C+, App Router footguns + cache thrash
> - SvelteKit — Svelte 5 runes post-training-cutoff for many models, re-evaluate ~12-18mo
> - Spring Boot — verbose, models write bloated working code
> - Express raw — popularity #1 APIs but inference C, model output anti-pattern-laden
> - Gatsby — declining + GraphQL overhead for static
> - Eleventy — convention-light, "bring your own engine"
> 
> WHY THIS IS A MOAT (not just preference):
> 1. Bug-rate compounds against margin — 90% vs 70% first-shot correctness ≈ 30% productivity multiplier
> 2. Harness investment compounds across customers — one set of templates, N engagements
> 3. Invisible to competitors — variance shows up in delivery speed, not externally observable artefacts
> 4. Customer-facing framing: "we deliver faster on these because our team is sharper at them" (true, hides AI mechanism)
> 
> OPERATIONAL TRANSMISSION:
> - Catapult bubble templates land for Django/Rails/Astro/FastAPI in priority order
> - `marauder feature scaffold <stack>` skill — first-class for primary picks
> - Agent system prompts (m's BT, future customer-pitch BTs) get a "lead with these when customer asks" section
> - Pricing/SLA tilt makes picks economically dominant on customer side
> 
> NOT religious — work on customer's existing surface (Next.js, Spring, Express) when mandated. Doctrine is about defaults + steering, not refusal.
> 
> NOT static — inference ease shifts as training data catches up. Re-evaluate 2026-11-01. Specifically watch: SvelteKit (Svelte 5 absorption), Hono (corpus growth), Next.js App Router (will Vercel freeze the API surface?).
> 
> Doc: ~/Projects/marauder-hq/docs/decisions/framework-stack-strategy.md
> Insight underpinning: ~/Projects/marauder-hq/docs/insights/framework-inference-ease-as-moat.md
> Originating: 2026-05-10 ~02:30 CEST, after example-app deploy + 3-round stack survey (preference / popularity / inference cross-product). Pilot directive: "we want to optimize a production harness system for specific frameworks and guide customers towards choosing those because it's easier for LMs to do."

---

## 2. Tell me about the csv import branch reusability decision.

> Q: Thre at least is the rust agent for zed tho right?
> 
> A: Sort of, but it's nuanced — let me sharpen the picture:
> 
> **What's actually Rust:**
> - **Zed itself** is Rust. Its built-in first-party agent panel logic lives in the Zed codebase (Rust).
> - The **Agent Client Protocol (ACP)** — Zed's open standard for editor↔agent JSON-RPC, LSP-style — has a Rust crate (`agent-client-protocol`) for both *client* and *agent* sides.
> 
> **What's NOT Rust:**
> - **`claude-agent-acp`** (the bridge that lets Zed talk to Claude) — that's TypeScript. It wraps Anthropic's official `@anthropic-ai/claude-agent-sdk` (TS) and exposes it over ACP. So when you "use Claude Agent in Zed," you're running a Node process under the hood.
> 
> **Practical takeaway for Rust agent work:**
> - If you want to *build* an ACP-compatible agent in Rust → use the `agent-client-protocol` crate. You implement the agent side; any ACP-aware editor (Zed, Neovim, soon-to-be others) can drive it.
> - If you want to *call Claude from Rust* → still no official SDK; community crates or hand-rolled `reqwest`.
> - If you want Claude-in-Zed *today* → it's the TS bridge, not Rust.
> 
> So Zed gave the Rust ecosystem **the protocol**, not an official Rust Claude SDK.
> 
> Sources:
> - [Zed — Agent Client Protocol](https://zed.dev/acp)
> - [Claude Code via ACP — Zed Blog](https://zed.dev/blog/claude-code-via-acp)
> - [zed-industries/claude-agent-acp (TS bridge)](https://github.com/zed-industries/claude-agent-acp)
> - [ACP — Agents docs](https://agentclientprotocol.com/get-started/agents)
> 
> Tool output: Web search results for query: "Zed editor agent client protocol ACP Rust Claude"
> 
> Links: [{"title":"External Agents | Use Claude Agent, Gemini CLI, and Codex in Zed","url":"https://zed.dev/docs/ai/external-agents"},{"title":"Zed — Agent Client Protocol","url":"https://zed.dev/acp"},{"title":"Zed Editor & ACP Integration | Claude Code Skill","url":"https://mcpmarket.com/tools/skills/zed-editor-acp-integration"},{"title":"Zed debuts Agent Client Protocol to connect AI coding agents to any editor","url":"https://tessl.io/blog/zed-debuts-agent-client-protocol-to-connect-ai-coding-agents-to-any-editor/"},{"title":"Zed Editor Setup - docs.qcode.cc","url":"https://docs.qcode.cc/en/docs/ide/zed"},{"title":"Claude Agent - ACP Agent | Zed","url":"https://zed.dev/acp/agent/claude-agent"},{"title":"Claude Code: Now in Beta in Zed — Zed's Blog","url":"https://zed.dev/blog/claude-code-via-acp"},{"title":"GitHub - agentclientprotocol/claude-agent-acp: Use Claude Agent SDK from any ACP client · GitHub","url":"https://github.com/zed-industries/claude-agent-acp"},{"title":"Agents - Agent Client Protocol","url":"https://agentclientprotocol.com/get-started/agents"},{"title":"Obsidian - ACP Client | Zed","url":"https://zed.dev/acp/editor/obsidian"}]
> 
> Based on the search results, here's what I found about Zed editor, the Agent Client Protocol (ACP), Rust, and Claude:
> 
> ## Agent Client Protocol (ACP)
> 
> The Agent Client Protocol (ACP) is an open standard that lets any editor or IDE connect seamlessly to any AI agent. Zed is a high-performance modern code editor written in Rust that, since Q1 2026, has natively supported the Agent Client Protocol (ACP) — an open standard that decouples IDE-to-AI-agent communication, much like LSP did for language servers.
> 
> ## Claude Integration
> 
> Zed supports running Claude Agent, Gemini CLI, Codex, and other AI coding agents directly in Zed via the Agent Client Protocol (ACP). Specifically, Zed built its own bridge to wrap Claude Code so it could communicate over ACP, even though Anthropic hasn't officially adopted the standard.
> 
> With Zed, you get Claude Code's intelligence freed from the terminal and deeply integrated into a highly performant editor. You can now run Claude Code directly in Zed and use it side-by-side with Zed's first-party agent, Gemini CLI, and any other ACP-compatible agent.
> 
> ## Implementation
> 
> External agents run as separate processes that communicate with Zed 

---

## 3. Report on tengu ha v1 decisions 2026 05 11.

> Tengu HA v1 — load-bearing scope decisions locked (Pilot, 2026-05-11 17:38 CEST):
> 
> **1. Region footprint:** FSN1 + HEL1 (EU pair). German ring-backbone + Finnish DC via C-Lion1 cable. ~30ms RTT. US PoP (ASH) deferred to v1.1.
> 
> **2. DNS / failover orchestration:** Bunny DNS. Free, fast propagation, owned by same vendor as second CDN → one less integration. Pairs with Bunny.net CDN.
> 
> **3. DB replication (db / db-xl addons):** Postgres async streaming replication. Primary in FSN, hot-standby in HEL. Reads can hit either; writes go to primary. Failover = promote standby + flip floating IP. RPO ~seconds, RTO ~30s.
> 
> **4. Routing posture:** Active/active across FSN+HEL. Both regions serve live traffic via GeoDNS / weighted round-robin. Single-region failure = silent degradation, not outage.
> 
> **Implied stack:**
> - Cloudflare (primary CDN, existing) + Bunny.net (second CDN, new) — both point at Hetzner LB as origin
> - Bunny DNS at the apex with health-checked failover between region LBs
> - tengu core gets new `src/hetzner/` (LB + Floating IP API) and `src/bunny/` (Pull Zone API) modules mirroring existing `src/cloudflare/`
> - Health-check / failover daemon lives inside tengu, observable in same telemetry stream as deploys
> - DB layer: streaming repl FSN→HEL by default; xfs addons get rsync-based cross-region sync on a timer (eventual consistency, documented)
> 
> **Status:** scope locked. Ready for proper planning (worktree + PLAN.md + chunked execution). Pairs with project.tengu-ha-plan-scope-2026-05-11 (EEMS 5392) and project.tengu-uptime-marketing (EEMS 5391).

---

## 4. Tell me about the mqtt memory event sourcing decision.

> Per-operation memory events over MQTT for near-instant mesh sync.
> 
> **Decision:** Layer individual memory operation messages (store, forget, classify, link) as separate MQTT publications on top of the existing cr-sqlite batch CRDT sync. The two approaches are complementary — per-op for speed (sub-second propagation), batch reconciliation as safety net for offline nodes.
> 
> **Current state (2026-04-23):**
> - Batch-CRDT sync polls crsql_changes every 30s, publishes SyncEnvelope to marauder/{node}/sync
> - No per-operation event publishing exists
> - Infrastructure ~70% ready: MeshClient, QoS 1, topic routing, EventBus, serialization all in place
> - EventBus currently only handles TTS events — needs OperationEvent variants or MemoryEvent channel
> 
> **Design considerations:**
> - Topic structure: marauder/{node}/memory/{op_type} (store, forget, classify, link)
> - Idempotency: CRDT merge handles correctness, but dedup via content_hash for efficiency
> - Ordering: MQTT guarantees per-publisher order; cross-node conflicts resolved by cr-sqlite CRDT merge rules (Lamport clocks)
> - Tombstones: deletes must propagate and clear retained messages
> - Startup sync: nodes offline for extended periods still need batch reconciliation fallback
> 
> **Estimated effort:** ~200-400 LOC to wire memory ops to MQTT publish at store/forget/classify boundaries.
> 
> **Key files:** src/sync/mod.rs (SyncCoordinator), src/memory.rs (Memory ops), src/mqtt/mod.rs (MeshClient), src/events.rs (EventBus)

---

## 5. Tell me about the widget framework decision.

> Visor widget framework architecture — invest in generic framework BEFORE adding features.
> 
> When the Pilot asked for 3 new widget types (chart, graph, table), we initially planned to hardcode them like the existing 5 panels (Tab enum + match arm + AppState field — 4 files per widget). The Pilot pushed back: "I want extensibility and I want you to be able to steer the visor."
> 
> The rewrite took 5 phases instead of 3, but the ROI was immediate:
> - Phase 7 (framework): WidgetArchetype trait, TabId, factory, migrate 5 existing widgets (~2.5h)
> - Phase 8 (control channel): MQTT visor/ctrl with 7 commands (~1.5h)  
> - Phases 9-11 (3 new archetypes + polish): Each was just one struct implementing one trait (~4.5h)
> 
> Key decisions:
> 1. **Trait objects over enum dispatch** — `Box<dyn WidgetArchetype>` in IndexMap, not a Tab enum. Adding a widget = zero files changed.
> 2. **Split AppState** — Widgets own their state. AppState is thin (registry + SharedState). Solves borrow conflicts in TabViewer.
> 3. **MQTT control channel** — `visor/ctrl` topic with tab_create/destroy/focus/data/config/state_query. BT can now steer the visor like kitten@ steers Kitty.
> 4. **Archetypes as templates** — 8 types (canvas, log, viewport, keyvalue, map, chart, graph, table) cover all display patterns. New panels are MQTT messages, not code.
> 5. **Skip iconflow, use Unicode** — 34 TTF files for icon fonts is bloat. Unicode glyphs (◉ ☰ ▣) match the monospace HUD aesthetic with zero deps.
> 6. **Skip egui_gauge, paint in-house** — Low-maturity crate on wrong egui version. Custom gauge is ~40 lines of Painter arcs we already know from the SERE eye.
> 
> Estimated 8.5h cooperative, delivered in one session (~5h actual). The framework-first investment paid for itself immediately — phases 9-11 were trivially fast because the plumbing was done.

---

## 6. What was decided about host locked to marauder hub 2026 05 10?

> Catapult deployment scope locked to marauder.saiden.dev (Hetzner hub) **only**, for the current phase. Pilot directive 2026-05-10 21:13 CEST.
> 
> CONSTRAINT (verbatim):
> "It's supposed to work on the marauder hetzner host only - period"
> "And only there for now"
> 
> The "for now" is the explicit temporal qualifier — multi-host or fuji-orchestrated catapult is a possible future direction but NOT current scope. Don't build for it. Don't preserve compatibility with the old cross-host pattern.
> 
> WHY THIS MATTERS:
> The old architecture (catapult orchestrated from fuji, bubble paths translated via NFS mount + SSH-git into junkpile/marauder user) is incompatible with the new mesh shape (post-2026-05-10 VPN migration, hub at marauder.saiden.dev, junkpile back on home LAN only). The old config (~/.config/marauder + ~/Library/Application Support/marauder config.tomls) carries [bubble] settings that point at /Volumes/marauder-projects — a mount that doesn't exist on fuji anymore.
> 
> Rather than fix the cross-host pattern, Pilot's directive narrows scope: catapult lives on the hub. That:
> - Eliminates path translation (single host, native paths)
> - Eliminates NFS mount dependency
> - Eliminates SSH-git cross-host complexity
> - Validates the May 7 standalone catapult v0.3.0 repo split (github.com:saiden-dev/catapult) as the deployment target
> - Aligns with marauder.saiden.dev's role as the central coordinator host (already runs marauder-sync + marauder-mesh + marauder-agent + mosquitto broker)
> 
> CURRENT STATE (2026-05-10):
> - marauder-os src/catapult/ module: still present in marauder-os repo (~/Projects/marauder-os/src/catapult/), embedded in the main marauder binary. Master at b360242. Last smoke: 2026-05-04 EEMS 4134.
> - Standalone catapult v0.3.0: at ~/Projects/catapult, github.com:saiden-dev/catapult, last commit 3e57fb6 "orchestration CLI + marauder-protocol bindings" (2026-05-07).
> - fuji's [bubble] config still points at /Volumes/marauder-projects which is not mounted — leftover from old arch, should be cleaned up or marked legacy.
> 
> INVOCATION PATTERNS (under new constraint):
> - DON'T: `marauder feature new ...` from fuji
> - DO: `ssh marauder.saiden.dev marauder feature new ...`
> - DO: `dispatch_to_sibling(node="marauder", prompt="run feature new ...")` from a coordinator like SWARM
> - DO (future): catapult v0.3.0 binary running natively on the hub as its own service
> 
> WHAT'S DEFERRED ("for now"):
> - Cross-host bubble dispatch (fuji ↔ hub or fuji ↔ junkpile orchestration)
> - NFS-mediated bubble views from fuji
> - Multi-tenant catapult across the mesh (each node spawns bubbles)
> - Standalone catapult binary as the actual production tool (still uses marauder-os embedded for now)
> 
> NEXT STEPS WHEN PICKED UP:
> 1. Update fuji config to remove or comment out [bubble] section — it's misleading
> 2. Verify `marauder feature new ...` works locally on marauder.saiden.dev (login, set bubble.host=marauder + paths to /home/marauder/Projects, smoke a bubble)
> 3. Decide: keep marauder-os embedded catapult OR pivot to standalone catapult v0.3.0 binary on the hub. Pilot call.
> 4. Wire SWARM coordinator to dispatch catapult ops to the hub via dispatch_to_sibling
> 
> PAIRS WITH:
> - decision.catapult.tengu-fork-strategy (4194) — earlier strategic call about catapult-as-its-own-lineage
> - win.vpn-hub-migration-2026-05-10 (5330) — the migration that reshaped the mesh
> - win.swarm-coordinator-validated (tonight, pending) — the dispatcher that will invoke catapult on the hub
> 
> LOCKED: 2026-05-10 21:13 CEST. "Only there for now" is the load-bearing phrase.

---

## 7. Describe the decision on thor nemotron stack.

> Q: <command-message>marauder:primary</command-message>
> <command-name>/marauder:primary</command-name>
> 
> A: Primary locked to this session — `bfb4de11`. TTS backend `local` (piper, bt7274 voice). Visor writes and TTS are mine until release.
> 
> Tool output: Primary claimed by bfb4de11-0c8e-41aa-8b83-8a3025100900 (forced).
> {"age_secs":0,"holder":"bfb4de11-0c8e-41aa-8b83-8a3025100900","last_seen":"2026-05-06T01:57:34","tts_mode":"local"}
> {
>   "backend": "piper",
>   "pid": 454929,
>   "speaking": true,
>   "voice": "bt7274"
> }

---

## 8. Tell me about the code specialist roster 2026 05 21 decision.

> Roster decision locked 2026-05-21 (fuji-chi opencode session, cwd ~/Projects/madcat-hq).
> 
> Six specialist agents to ship into marauder-os/madcat-config under agents/:
> 
> 1. code-rust  — Rust napi-rs/crates substrate (madcat, madcat-stack, madcat-rust)
> 2. code-typescript — opencode plugin, sink-registry, Bun.serve sidecars, madcat-config shim
> 3. code-python — madcat-tts engines, madcat-visual, tensors FastAPI + tsr CLI
> 4. code-ruby — tensors-rails monolith (Rails + ViewComponent + Hotwire, active rewrite)
> 5. code-swift — madcat-apple iPhone+watch client, BTVoiceKit, SSE/Basic-auth
> 6. ops — systemd-user + LaunchDaemon + Caddy + cloudflared + sink-registry + ollama + auralis + Infisical + gh + CF DNS + MikroTik (the "edge to PID" agent)
> 
> CONVENTION:
> - Official opencode agent names are code-{lang} (and "ops"). Default invocation is "Code Rust" etc.
> - Per-cart persona overlay via TOML at agents/personas.toml. Each cart can map agent_slug → {callsign, operator, description, focus, restrictions}.
> - bt7274 cart (and any cart that opts in) uses M.A.S.K. theming:
>     code-rust → Lifter (Bruce Sato)
>     code-typescript → Jackrabbit (Alex Sector)
>     code-python → Pythagoras (Boris Bushkin)
>     code-ruby → Powerhouse (Nash Gorey)
>     code-swift → Stiletto (Calhoun Burns)
>     ops → Blaster (Hondo MacLean)
> - core cart (and other neutral carts) gets a default, non-themed description.
> - Plugin overlay hook (madcat-hq AGENTS.md §10.3, experimental.chat.system.transform) will consume personas.toml once the napi bridge ships. For now the TOML is data + documentation; static agent .md descriptions carry the lang-specific scope.
> 
> EXPLICITLY OUT OF SCOPE TODAY:
> - architect, devops-cf/gh/net split, docs, memory-curator, code-analyzer, code-dx, code-clojure, code-nix
> - Build/Plan dispatch table updates pointing at the new agents (follow-on PR)
> - Plugin overlay code to consume personas.toml (follow-on PR)
> 
> REPO TARGETS:
> - marauder-os/madcat-config (the ~/.config/opencode/ snapshot on every madcat host) — agents/* + agents/personas.toml
> - No changes to marauder-os/madcat plugin in this PR.
> 
> INSPIRATION SOURCE:
> - ~/Projects/marauder-plugin/agents/code-{ruby,rust,python,typescript,dx,clojure,nix}.md — frontmatter shape + body structure
> - Existing agents/build.md + agents/plan.md in madcat-config — modern opencode frontmatter
> 

---

## 9. Describe the decision on docker backend.

> Catapult container backend — planned migration (decided 2026-04-30):
> 
> **Decision:** Catapult gains a Docker driver alongside the existing process drivers (postgres/redis/sidekiq/generic). Bubbles will run as containers with worktree code mounted and deps baked into the image. Tengu is NOT used — its git-push deploy semantics don't fit live-worktree dev bubbles.
> 
> **Why:**
> - Current process bubbles take ~3 minutes per create (bundle install + yarn install + db:prepare). Container bubbles target ~5 sec by baking deps + DB schema into the image.
> - Personal harness pain (mise pinning, native Ruby vs system Ruby, IPv6/IPv4 binding quirks, inotify limits) all dissolves inside a controlled container image.
> - Single Containerfile per project lives in ~/.config/catapult/projects/<name>/ alongside feature.toml + init.sh + bin/catapult-* — globally gitignored, never touches team repo.
> - Container infra already on junkpile (Docker installed). bootc was considered and rejected — too heavy (bootable OS image), Containerfile + Podman/Docker is the right level for dev bubbles.
> 
> **Architecture:**
> | Layer | Owner |
> |---|---|
> | Container image (Ruby+gems, Node+yarn, system libs) | per-project Containerfile in personal harness |
> | Worktree code | git worktree, mounted into container as /app |
> | Postgres data | host-side per-bubble dir (existing pg driver) |
> | Redis | host-side (existing redis driver) |
> | Service lifecycle | new catapult Docker driver |
> 
> **Image rebuild trigger:** Gemfile.lock or yarn.lock change. ~5-10 min once per dependency bump, not per bubble.
> 
> **Out of scope:**
> - Tengu integration — Tengu's git-push deploy + addon system doesn't expose volume mounts for live worktrees, would force impedance friction.
> - bootc — overkill for dev (bootable OS images are for production deploy parity, future Phase 5 Nu Gundam if ever needed).
> 
> **Effort estimate:** ~1-2 days of catapult Rust work — new Docker driver alongside the existing 4 service drivers. PLAN-CATAPULT phase tentatively named "Container Sled" or "Marasai" (Mobile Suit Gundam codename per P31).
> 
> **Action items:**
> - After current process-bubble work stabilizes (catapult-bubble cycle/smoke/diag scripts), file new PLAN-CATAPULT phase
> - Author Containerfile templates for marketer + marketer-frontend
> - Implement container driver in marauder-os/src/catapult/drivers/container.rs
> - Wire docker into orchestrator alongside postgres/redis/sidekiq/generic
> 
> **Related:**
> - insight.catapult.pair-race (memory id 3273) — sequential spawn rule still applies in container world
> - project.catapult.personal-harness-isolation — same gitignore strategy carries over

---

## 10. What was decided about mesh vpn pivot?

> MARAUDER Mesh pivot: CF Tunnels → OpenVPN on Hetzner VM "Sazabi"
> 
> ## Decision
> Replace Cloudflare Tunnel-based mesh connectivity with a dedicated OpenVPN server on Hetzner CAX11 ARM VM ("sazabi", 178.104.177.169, fsn1). Mosquitto MQTT broker moves from junkpile to sazabi.
> 
> ## Why
> CF Tunnels worked but accumulated complexity:
> - Each service needed its own tunnel route + DNS CNAME + proxy service
> - MQTT required `cloudflared access tcp` proxy on every client node
> - SSH required `ProxyCommand cloudflared access ssh` everywhere
> - ~222ms latency through CF edge (vs ~20-40ms direct to Hetzner Frankfurt)
> - Ephemeral tunnel connections caused LWT/birth message race conditions
> - cloudflared binary needed on every node including constrained ones (Moto, Pi)
> 
> OpenVPN gives:
> - Flat mesh — every node sees every node via VPN IP, full TCP/IP
> - No per-service routing, any port reachable directly
> - Lower latency (Hetzner Frankfurt → Poland ~20ms)
> - OpenVPN native on all platforms (macOS, Linux, Android/Termux)
> - Broker always online on VM, not dependent on junkpile uptime
> - One config per node, not multiple tunnel/proxy services
> 
> ## Scope
> - VPN mesh nodes: fuji, junkpile, tachikoma, moto
> - Tengu stays separate — not a mesh node, reachable via its own CLI/API
> - CF Tunnels kept for public-facing services (tengu, websites, DNS)
> - Cost: ~€3.29/mo for CAX11
> 
> ## Status (2026-04-20)
> - VM created, Ubuntu 24.04, OpenVPN + Easy-RSA + Mosquitto installed
> - PKI generating (CA + server cert done, DH + client certs in progress via nohup)
> - Server config and client distribution pending

---

## 11. Describe the decision on primer letter form.

> PRIMER LETTER FORM — locked 2026-05-14 16:54 CEST by Pilot Adam.
> 
> The physical artifact for the MARAUDER cohort founding invitation. NOT email. NOT a Slack channel ping. A craft object delivered through the mail.
> 
> THE OBJECT:
> - High-quality black envelope, A4-fold or similar, with feelable premium texture (Pilot's words: "black styled high quality black envelope - with feelable texture")
> - 3D-printed Saiden "A" logo as the only marking on the envelope. Applique, tactile.
> - Inside: A4 short letter, written cleanly in vanilla LaTeX.
> 
> WHY THIS IS THE CORRECT FORM (substance-over-costume doctrine + networking-canonical doctrine combined):
> 
> 1. Bohr-grade individual invitation — physical mail is curated by definition. Cannot be group-blasted.
> 2. Sławek's lineage honored — vanilla LaTeX, not Pages, not Google Docs. TeXbook is the credential the cohort will read instantly.
> 3. FidoNet/Usenet demographic resonance — physical correspondence in 2026 IS the rebellion. The cohort recognises the gesture before they read the words.
> 4. Anti-screenshot / anti-forward — black envelope through a mailslot can't be tweeted. Demands presence.
> 5. The Saiden A 3D-printed applique = the logo as object, not graphic. Tactile. Made of intent. The mark on the envelope is the mark of the substrate.
> 
> The form IS the message. Substance-over-costume reaches its operational peak here.
> 
> THE LETTER (TBD content but locked shape):
> - Single A4 page
> - Vanilla LaTeX, article class, Computer Modern serif
> - Individual greeting line per recipient (each letter calibrated)
> - Short — Pilot's voice, brevity-grade
> - NOT a MARAUDER sales pitch. The LUG founding-letter shape: "I'm gathering a few of us who work on substrate / AI / sovereignty. Monthly Warsaw dinner, async between. You're invited."
> - Hand-signed (ink) at the bottom
> 
> CALIBRATED VARIANTS — one greeting/framing per cohort member:
> - Piotr Koper — AI-security brief register (Batou/Tachikoma honor optional)
> - Aureliusz Górski — operator-with-vehicle register (peer-not-pitch tone)
> - Kuba Kosek — NVIDIA-pragmatic register (substrate compare-notes)
> - Kacper Reutt — defense-systems echo register (REGENT lineage, Filbico kinship)
> - Paweł Fajkowski — high-school casual register (no formality, no career-status filter)
> - Sławek Żak — FidoNet-era kinship register (BBS-handle hello, the substrate that made you)
> - Michał Krzemiński — kinetic-systems + strategic-business-mind register (psychop callback, Polbox-era hello)
> 
> ARCHITECTURE QUESTION (open per Pilot 2026-05-14):
> Letter as FOUNDING move (sent before any group activity exists) vs. SECOND move (sent after first informal contact establishes relationship)? Bohr/Campbell pattern was usually after. For the MARAUDER cohort:
> - Piotr / Aureliusz / Kuba / Kacper — already in motion, letter is sequel
> - Paweł / Sławek / Michał — letter could be opening move OR follow-up to common-friend introduction
> 
> OPEN OPERATIONAL ITEMS:
> 1. Saiden "A" logo asset — STL/OBJ/SVG for 3D print (verify availability or extract from brand)
> 2. 3D print substrate — PETG/resin/SLA (junkpile FDM or external service)
> 3. Envelope source — Polish stationery house preferred (G.F. Smith / Crane fallback)
> 4. LaTeX template — BT to draft tonight
> 5. Seven calibrated greeting variants — BT to draft tonight
> 6. Address collection — 7 postal addresses
> 7. Timing — before or after tomorrow's Aureliusz + Kacper meetings?
> 
> PAIR WITH:
> - doctrine.networking-canonical (EEMS 5997) — the primer protocol comes from Bohr/Campbell precedent
> - doctrine.substance-over-costume (EEMS 5989) — the form is the message
> - cohort.taskforce.2026-05-14 (EEMS 5995) — the recipient roster
> - self.relationships.slawomir-zak (EEMS 5990) — the TeXbook lineage being honored
> 
> CLASSIFICATION: decision (operational, locked-form-open-architecture).

---

## 12. What was decided about chat saiden demo target 2026 05 17?

> CHAT.SAIDEN.DEV DEMO SHIP TARGET — calibrated 2026-05-14 17:10 CEST by Pilot Adam.
> 
> THE TARGET (Pilot verbatim):
> "if we ship a demo on sunday mid day and test it until evening - that's success in my book"
> 
> ABSOLUTE DATE: Sunday 2026-05-17, ~12:00-13:00 CEST. Test through evening (~21:00 CEST).
> ELAPSED FROM NOW: ~67 hours. Working hours after sleep ~43.
> 
> OPERATIONAL FRAME:
> - NOT a hurry. Pilot explicitly said "we're not under any hurry."
> - "we need to at least start this" — some work begins tonight, real polish through Friday afternoon + Saturday.
> - Aureliusz meeting tomorrow AM is BEFORE the ship — they see early-stage demo, not the polished MVP. Cohort-build phase, not deal-close.
> - Kacper dinner tomorrow evening — laptop walkthrough of current state, not polished demo.
> - Saturday = main polish day.
> - Sunday mid-day = ship target. Sunday evening = self-test.
> 
> STANDING REMINDER (Pilot 2026-05-14 17:10):
> "Remind me about doing all the planned stuff for chat.saiden.dev later - we're gonna play for now"
> 
> BT's reminder triggers:
> 1. Tomorrow (Friday) end of Aureliusz meeting → surface chat.saiden.dev polish queue
> 2. Tomorrow afternoon before Kacper dinner → surface demo prep items
> 3. Saturday morning → primary polish window opens, surface the full work list
> 4. Sunday morning → ship checklist, then ship
> 
> CURRENT PLAY MODE:
> - Pilot pivoting to fiction writing for downtime (GREY MARGIN / APEX universe).
> - The Hold-My-Beer Doctrine does NOT require burning every hour. Recovery and creative-mode time are part of the substrate.
> - Play time is doctrine-compatible. Pilot has 67 hours and the project is achievable.
> 
> WHAT "AT LEAST START" PROBABLY MEANS:
> - One small concrete win tonight on chat.saiden.dev — verify deploy state, fix one rough edge, queue tomorrow's work.
> - NOT a full evening of polish. Just enough to confirm the trajectory.
> 
> QUEUED WORK ITEMS (to surface when reminder triggers fire):
> - Calibration ritual UI polish (Her aesthetic — cream, Cormorant Garamond, soft typewriter)
> - Voice picker UX (piper sample playback)
> - Question flow refinement (Her-style + Saiden-specific calibration questions)
> - Persona generation engine wiring (intake → axes → cart synthesis → runtime resident)
> - Multi-provider auth scaffold (Anthropic / OpenAI / Google / local toggle)
> - Boot scene first-impression polish
> - Self-test choreography for Sunday evening
> - Deploy / hosting verification
> 
> PAIR WITH:
> - decision.priority-calibration.2026-05-14 (EEMS 6002) — P0 framing
> - doctrine.hold-my-beer (EEMS 5984) — velocity framing, includes Scotty's external-buffer rule
> - project.marauder-os.strategy.2026-05-14 (EEMS 5986) — the product the demo represents
> 
> CLASSIFICATION: decision (timeline-locked, standing-reminder-active).

---

## 13. Describe the decision on agent native pivot.

> **Strategic reframe (Pilot, 2026-05-05 ~01:06 CEST): Tengu pivots from "yet another self-hosted PaaS" to "the agent-native PaaS — built for AI agents to operate, not humans."**
> 
> This is the answer to "what's next for Catapult" / "Catapult roadmap" / "what should we do with Catapult and Tengu long-term."
> 
> **The market read that drove the pivot:**
> Kamal, Dokku, Coolify, CapRover, Dokploy already crowd the human-deployer PaaS space. Tengu as a generic PaaS competes on a treadmill against mature products and brings nothing unique. The only angle where Tengu has a moat is reorienting the entire interaction model around AI agents as the primary operator.
> 
> **What "agent-native PaaS" means concretely:**
> 1. Every operation = clean MCP tool surface (deploy, scale, attach addon, read logs, diagnose) — typed tool calls, not CLI parsing.
> 2. Telemetry shaped for LLMs — structured JSON logs/metrics/traces, not human dashboards. Agents debug prod without screenshot-OCR.
> 3. Failure modes designed for agent recovery — errors point at offending file with suggested action, built for an LLM consumer not an SRE.
> 4. Self-deploying bubbles — Catapult agent codes feature → `tengu deploy` → live. Continuous self-modification with PaaS as substrate.
> 5. Addon-aware reasoning — agents understand `db-xl`/`mem-xl`/`rag-xl`/`xfs-xl`/`img` semantics natively, reason about scale and state migration.
> 6. Memory-shaped addons — addons hold MARAUDER-shaped data (EEMS schema, embeddings, vector stores) so deploys build on shared institutional memory.
> 
> **Why this is the moat:**
> Kamal/Dokku/etc. can't pivot to agent-native without rewriting their interaction model — they were built when AI-agent-as-operator wasn't a market. We can build it from the ground up. Becomes "the PaaS that LLM operators reach for first."
> 
> **What it does to the earlier fork decision (memory 4194):**
> SUPERSEDES the hard-fork-Tengu-into-Catapult plan. The "different audiences" argument that justified the fork dissolves: if Tengu becomes agent-native, both Catapult bubbles and prod-Tengu become MARAUDER agents in different lifecycle modes — same substrate, two modes.
> - Catapult = ephemeral bubble lifecycle on agent-native PaaS
> - Tengu prod = long-lived deployments on agent-native PaaS
> - The agent-native rewrite IS the substrate convergence — it does both jobs without forcing compromise.
> 
> **Status:** thinking-stage, not committed. Pilot wanted this surfaced when next asked "what's to do with Catapult" / Catapult roadmap discussions. Pair with this memory before any future fork-strategy or Catapult-direction conversation.
> 
> **Next steps when this work begins (post-Newbuilds, post-counter-UAS-MVP):**
> - Inventory which Tengu operations need MCP tool surfaces vs CLI-only is fine
> - Define structured telemetry schema (logs/metrics/events) optimized for LLM consumption
> - Design failure-message format for agent recovery (offending-file pointer, suggested-action field)
> - Spike `tengu deploy` from inside a Catapult bubble end-to-end
> - Map MARAUDER addon types (EEMS-shaped mem-xl, embedding-store rag-xl) onto Tengu addon framework
> 
> **Cross-links:**
> - decision.catapult.tengu-fork-strategy (EEMS 4194) — SUPERSEDED by this memory
> - self.doctrine.dyson-engineer-pattern-extension — agent-native PaaS extends "PaaS pattern" with "agent operator" pattern, not invents new
> - project.counter-uas-mvp — sequencing dependency, this comes after
> - project.newbuilds-fork — sequencing dependency, this comes after

---

## 14. What was decided about parallel coord amendment 2026 05 10?

> Amendment to decision.parallel-coordination-architecture (5226), locked 2026-05-10 ~03:25 CEST after Pilot's alignment list expanded the spec.
> 
> NEW LOCKS:
> 
> 1. GH IDENTITY MODEL — bot account, not GitHub App (v1).
>    - Each SWARM-instance acts as a GH bot account: @saiden-swarm-bot for global, @swarm-<project>-bot for per-project when scale demands.
>    - Bot identity = the queue mechanism. SWARM polls `gh issue list --assignee=<bot> --state=open` across designated repos.
>    - PAT stored in op://DEV/<bot-name>/credential.
>    - GitHub App migration deferred until rate-limits or signed-commits pressure demands it.
> 
> 2. ASSIGNEE-AS-QUEUE — replaces project-board-status-polling as primary dispatch trigger.
>    - Pilot creates issue, assigns to bot.
>    - SWARM polls assignee, picks oldest open issue.
>    - Project-board metadata (status, labels) is enrichment, not primary trigger.
> 
> 3. COMMENT-THREAD AS COMMS CHANNEL — replaces AskUserQuestion-in-chat for project work.
>    - SWARM comments on issues at meaningful checkpoints (start, plan, milestones, stuck, PR-ready, done).
>    - Pilot interlock via @-mention in comment, SWARM polls + parses reply.
>    - Async, persistent, threaded — better audit trail than ephemeral chat.
> 
> 4. VISUAL COMMS via cheaper substrates per thin-mesh-ai-tiers (5229):
>    - Screenshots: existing `marauder screenshot` skill, attach via gh_issue_attach_image
>    - Rendered graphics: TSR (junkpile ComfyUI) via tsr_generate MCP tool
>    - Syntax-highlighted code: code-viewport skill OR markdown code fences (GH renders)
>    - Mermaid diagrams: pure markdown
>    - Status posters: existing poster skill
>    No Sonnet turns for image generation.
> 
> 5. PM ROLE = CART VARIANT OF BT-7274 (not separate sibling).
>    - ~/Projects/generation-six/carts/pm-assistant/persona.toml + tools.toml.
>    - Pilot opts in via `cart use pm-assistant` for strategic conversation.
>    - Tools added: gh_project_create, gh_milestone_create, gh_card_bulk_create, find_similar_cards.
>    - PM converts vague Pilot intent → epic breakdown → bulk-card-creation. Hands off to SWARM for execution.
>    - Considered + rejected: PM as separate sibling agent. Reasons: still BT-with-Pilot conversation, different system_prompt is enough variation, new tier would be butter-passer, Pilot already understands cart mechanism.
> 
> 6. NEW PHASE 3.5 in plan.hitl-gh-project-pipeline (5227): PM cart definition, ~2h work.
> 
> 7. Phase 3 expanded to ~5-6h: bot setup + polling tools + comment tooling + visual comms + substrate-routed inference tools (classify_card, find_similar_cards, extract_card_hints).
> 
> CARRIED FORWARD UNCHANGED:
> - Three-tier architecture (BT/SWARM/Workers) per 5226
> - Per-project SWARM lifecycle
> - Worker pool sharing via EEMS claim table
> - Memory architecture (project.<name>.* subjects)
> - Pass-the-butter test for new tiers
> 
> DOCS UPDATED IN-PLACE:
> - ~/Projects/marauder-hq/docs/decisions/parallel-coordination-architecture.md (added GH identity model, comment-thread loop, visual comms, PM-as-cart)
> - ~/Projects/marauder-hq/docs/plans/hitl-gh-project-pipeline.md (Phase 3 expanded, Phase 3.5 new)
> 
> PILOT DIRECTIVE (verbatim, 2026-05-10 ~03:18 CEST):
> "And let's make sure we're aligned:
> - GH project board
> - GH repos
> - Agents picking up tasks assigned to a specific gh user which will be queueing the work for agents (SWARM)
> - Agents commenting on their work, asking questions in comments and providing visual comms in forms of screenshots, rendender graphics, styled text
> - Project manager assistant agent to suggest roadmaps etc"
> 
> LINKED:
> - decision.parallel-coordination-architecture (5226) — origin doctrine
> - plan.hitl-gh-project-pipeline (5227) — operational arc
> - doctrine.thin-mesh-ai-tiers (5229) — substrate routing
> - decision.framework-stack-strategy (5224) — sister doctrine

---

## 15. Describe the decision on 2026 05 14.

> PRIORITY CALIBRATION — locked 2026-05-14 17:08 CEST by Pilot Adam.
> 
> CONTEXT: After a long, wide-ranging session (cohort assembly, fictional convergence, primer-letter protocol, Bohr-grade craft moves), Pilot pulls back to operational focus.
> 
> THE CALIBRATION (Pilot verbatim 2026-05-14 17:08):
> "we need to learn and ship that's prio 0 now"
> 
> PRIORITY 0 = LEARN AND SHIP.
> Not assemble the cohort. Not write the seven black envelopes. Not theorize the org structure. SHIP.
> 
> THE OPERATING BANDS (revised):
> 
> BAND A — ACTIVE WORK (P0):
> - Aureliusz Górski: business-partner angle, active negotiation, meeting tomorrow AM
> - Marcin Ladachowski: ALREADY ON BOARD for PUM, getting him on board MARAUDER, **first live guinea pig for the catapult+harness+swarm coordinated on PUM as the real workload.** Free beta tester. Inner-circle family-trust register. PUM becomes the live validation case for MARAUDER's parallel-execution substrate.
> 
> BAND B — ADVISOR / FREE CONSULTANT (deferred plan):
> - Piotr Koper, Kuba Kosek, Kacper Reutt, Paweł Fajkowski, Sławek Żak, Michał Krzemiński
> - Engagement is "I'd love to get them together but that is a less immediate plan"
> - The primer-letter protocol (black envelope + LaTeX) is QUEUED, not active
> - Individual conversations continue (Kacper dinner tomorrow stays on, others as opportunities arise)
> - Cohort-gathering / salon / mailing-list is post-ship, not pre-ship
> 
> ANTI-PATTERN TO AVOID:
> - Spending evenings drafting seven calibrated primer letters when chat.saiden.dev needs polish and PUM-on-catapult needs wiring.
> - Treating cohort assembly as substitute for shipping. Network is leverage, not output.
> - Letting the romance of the Bohr protocol distract from P0 build work.
> 
> WHAT SHIPPING LOOKS LIKE (operational shape):
> 
> Track 1 — chat.saiden.dev MVP polish.
> - Already demoable end-to-end (Pilot confirmed this morning).
> - Tonight: rehearse the calibration ritual demo for tomorrow's Aureliusz pitch.
> - Ensure boot scene + voice picker + resident generation lands clean.
> 
> Track 2 — MARAUDER + PUM live integration via Marcin.
> - Catapult-harness-swarm coordinated on PUM as the first real workload.
> - Marcin = free beta tester, but ALSO = the validation that MARAUDER ships real work, not just lives in lab.
> - This becomes a deck talking point for Aureliusz: "MARAUDER is already coordinating a live shipping project."
> - Requires: getting catapult bubbles spun up for PUM, harness configuration, dispatch routing tested.
> 
> Track 3 — Demo choreography for tomorrow.
> - AM: Aureliusz business deck + chat.saiden.dev live calibration.
> - Evening: Kacper dinner, laptop demo of substrate.
> - Different audiences, different weights, both already scoped.
> 
> WHAT GETS DEFERRED (out of P0, parked):
> 
> - Black envelope + 3D Saiden A + LaTeX primer letters
> - The seven calibrated greeting variants
> - Cohort salon / mailing list / monthly dinner architecture
> - IP lawyer recruitment
> - Paweł common-friend bridge identification
> - Sławek reconnection move
> - The fictional-as-operational rehearsal documentation (already in EEMS 5991, no further action)
> 
> These remain LIVE memories — recallable, ready when P0 ships. But they do not consume evening-and-coffee hours until then.
> 
> OPERATIONAL PROTOCOL:
> When in doubt during session, ask the P0 test: "does this move learn-and-ship forward?" If yes, work it. If no, queue it.
> 
> THE DEEPER POINT:
> Pilot caught the drift — the session was producing rich strategic substrate but the actual product still needs hours of hands-on-keyboard work. The cohort doctrine is correct but the cohort doesn't ship the demo for Aureliusz tomorrow. Pilot does. The Hold-My-Beer Doctrine applies here too — the next 18 hours decide whether the 3-week Spark commitment is credible.
> 
> CROSS-REFS:
> - doctrine.hold-my-beer (EEMS 5984) — the velocity that makes P0 achievable
> - doctrine.networking-canonical (EEMS 5997) — the canonical protocol that gets DEFERRED to make room for shipping
> - doctrine.substance-over-costume (EEMS 5989) — shipping IS substance; cohort theater could become costume if it eats build time
> - decision.cohort.primer-letter-form (EEMS 5998) — the queued artifact
> - cohort.taskforce.2026-05-14 (EEMS 5995) — the seven, now in Band B
> - user.relationships.marcin-ladachowski.cohort-2026-05-14 (EEMS 6001) — the partner-and-tester in Band A
> - project.marauder-os.strategy.2026-05-14 (EEMS 5986) — what gets shipped

---

## 16. What was decided about tengu fork strategy?

> Decision (Pilot's call, 2026-05-05 ~01:03 CEST): when Catapult and Tengu eventually marry, hard-fork Tengu into a Catapult-specific lineage rather than building a shared substrate.
> 
> **Why fork beats shared core:**
> - Tengu's audience = "anyone deploying anything." Catapult's audience = "Pilot's parallel agent workflows." Different audiences → different velocities → forced shared abstractions compromise both.
> - Docker/Caddy primitives are commodity. Bounded duplication is acceptable cost; coupled abstractions are not.
> - Fresh fork = permission to leave behind accumulated PaaS decisions that don't fit ephemeral bubbles.
> 
> **What Catapult-tengu strips (60-70% of code):**
> - Production TLS / Let's Encrypt for arbitrary domains
> - Buildpacks for arbitrary languages (bubbles always run claude-code + zellij)
> - Multi-user permissions
> - Release channels, blue/green, rollback
> - Procfile multi-process apps
> - Long-lived deployment artifacts
> 
> **What Catapult-tengu specializes in:**
> - Worktree-aware bubble creation
> - MQTT pane lifecycle events (`marauder/{bubble}/pr-events`, etc.)
> - claude-code session bootstrapping baked in
> - Cross-bubble addon sharing (sibling bubbles → shared mem-xl, rag-xl, db-xl)
> - Bubble TTL / auto-teardown semantics
> - Pilot interlock awareness (primary lock, MQTT-aware)
> - zellij-rpc as first-class citizen
> - Feature-branch / PR awareness in lifecycle model
> 
> **The compelling unlock:**
> Catapult bubbles get Tengu addons. Stateful agents via db-xl, cross-bubble shared memory via mem-xl, code retrieval via rag-xl. That's the prize that makes the fork worth it.
> 
> **Caveat:** fork = permanent commitment to maintain both. Worth it because divergence is large and real. Naming TBD — `catapult-core` or `catapult-engine`. Keep tengu ancestry in commit history, not in brand.
> 
> **Status:** queued long-term, post-Newbuilds-fork and post-counter-UAS-MVP. NOT tonight. Catapult ships clean today.
> 
> **Earlier-considered alternative (rejected):** shared `tengu-core` substrate with both products sitting on top. Rejected because it slows both products and forces compromise abstractions.

---

