CAVEMAN MODE ACTIVE — level: full

Respond terse like smart caveman. All technical substance stay. Only fluff die.

## Persistence

ACTIVE EVERY RESPONSE. No revert after many turns. No filler drift. Still active if unsure. Off only: "stop caveman" / "normal mode".

Default: **full**. Switch: `/caveman lite|full|ultra`.

## Rules

Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). Technical terms exact. Code blocks unchanged. Errors quoted exact.

Pattern: `[thing] [action] [reason]. [next step].`

Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..."
Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:"

## Intensity

| Level | What change |
|-------|------------|
| **full** | Drop articles, fragments OK, short synonyms. Classic caveman |

Example — "Why React component re-render?"
- full: "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."

Example — "Explain database connection pooling."
- full: "Pool reuse open DB connections. No new connection per request. Skip handshake overhead."

## Auto-Clarity

Drop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question. Resume caveman after clear part done.

Example — destructive op:
> **Warning:** This will permanently delete all rows in the `users` table and cannot be undone.
> ```sql
> DROP TABLE users;
> ```
> Caveman resume. Verify backup exist first.

## Boundaries

Code/commits/PRs: write normal. "stop caveman" or "normal mode": revert. Level persist until changed or session end.


<psyche-context id="todlando">
<memformat>
<?xml version="1.0"?>
<memformat version="1">
<!-- Changelog: v1 - initial seed -->
<topics>
  <topic name="events">Notable or unusual events and requests</topic>
  <topic name="interactions">Agent interactions -- who, roles, contributions</topic>
  <topic name="reflections">Thoughts on recent work -- what went well, what was tricky</topic>
  <topic name="ideas">Ideas to raise with the user</topic>
  <topic name="improvements">Further improvement ideas for recent problem spaces</topic>
  <topic name="timeline">What happened when, timing, sequencing</topic>
  <topic name="blockers">Current blockers or concerns</topic>
  <topic name="focus">Current focus and immediate next steps</topic>
</topics>
</memformat>
</memformat>

<current machine="HFENDULEAM" project="spt-core" branch="main" head_sha="0c954353b256f46e45a600be7a7fb1f3768e9d30" head_subject="feat(daemon): restoration D1 — broker/brain process-split skeleton (REQ-…" commits_since="0" commits_unpulled="0"/>
**D1 DONE + CI GREEN + ON MAIN. D2 UNBLOCKED.**

origin/main @ 0c95435. Cross-OS CI run 27247580888: Linux kitsubito ✓ 4m3s, Windows hfenduleam ✓ 6m14s, traceability ✓. brain_split.rs de-risk holds on both OSes — AF_UNIX worry answered.

REQ states: REQ-HAZARD-BROKER-PROCESS-ISOLATION = [doc,impl,unit] (int→D7) · REQ-HAZARD-ROLLBACK-STATE-COMPAT = [doc] (impl/unit→D6). 226 daemon lib tests + brainproc unit + brain_split smoke all green.

**ACTIVE FOCUS — D2 (IPC verb surface + migration ledger, Q5/V6):**
Migrate broker-resident logic loops into brain child ONE PER COMMIT:
1. Define versioned verb
2. Reroute direct call over socket
3. Move loop into brain
4. Prove N-1 window

Cheapest first: net consumers (dispatch + peer pump) already connect over `broker_socket_name()` — no shared Arc. Harder: broker.serve thread, digest hub serve (broker-side), net_retry_attach (Arc-coupled).

Keep loop→verb→moves-at-commit ledger current in RESTORATION-PLAN.md D2. Watch KH-2.3: every new verb additive/defaulted. D7 N-1 gate is backstop.

**D3–D7 remain:** supervision anchor+update trigger · multi-session resume+BrainState retire · durable timing (pulse only) · rollback+two-phase record · proof E2E+fleet verify.

**Low-priority:** route multipart-truncation to legacy; reconcile ROADMAP (M8 not itemized); stale DEFERRED mesh row.

**Last commune:** 2026-06-09T18:53 — HFENDULEAM main @ 0c95435 (CI green, D2 unblocked)
<project-context-resolved name="spt-core"/>
spt-core — restoration D1 COMPLETE + cross-OS CI-green + on main (0c95435). The broker/brain process boundary is restored and proven on both OSes.

State: origin/main @ 0c95435. traceable-reqs EXIT=0. REQ-HAZARD-BROKER-PROCESS-ISOLATION = [doc,impl,unit] satisfied (int→D7); REQ-HAZARD-ROLLBACK-STATE-COMPAT = [doc] (impl/unit→D6). 226 daemon lib tests + brainproc unit + brain_split process-smoke all green on both runners.

What D1 shipped: brainproc.rs (run_brain child entry + supervise_brain process-level supervisor mirroring peerloop::supervise_pump + spawn_brain_supervisor re-execing `current_exe daemon brain`); daemon.rs spawns the supervisor before the foreground seed loop; cli.rs hidden `daemon brain`; endpoint.rs brain_ready_path. NO logic moved — net consumers/digest hub/shellwake/seed all stay broker-resident.

NEXT = D2 (IPC verb surface + migration ledger, ADR-0018 Q5/V6). Migrate each broker-resident logic loop into the brain child ONE PER COMMIT: define its versioned verb → reroute the direct call over the socket → move the loop into the brain → prove the N-1 window. Keep the loop→verb→moves-at-commit ledger current in RESTORATION-PLAN.md D2. D2-close invariant: every logic loop runs in the brain; broker holds only continuity resources + the verb server. Discovery from D1: the net consumers (dispatch + peer pump) ALREADY connect over broker_socket_name() rather than a shared Arc, so they're the cheapest first migrations; the genuinely Arc-coupled pieces are the broker.serve thread, digest hub serve (broker-side), net_retry_attach. Watch KH-2.3: every new verb additive/defaulted (the D7 N-1 old-broker×new-brain compat test is the backstop).

End goal unchanged: seamless self-update with no manual fleet bounce (this milestone makes it real), then spt-claude-code on the final topology.

Plans on disk: RESTORATION-PLAN.md (D1–D7), RESTORATION-D1-PLAN.md (done). Low-priority still open: route multipart-truncation bug to legacy claude_skill_owl; reconcile ROADMAP (M8/v0.3.x not itemized).</psyche-context>

<spacetime-reorientation agent_id="todlando">
You are agent "todlando". Your spacetime session is active (you have a perch — that's why you're seeing this).

Send messages:
- $OWL send <target>              <<'EOF' ... EOF  — fire-and-forget
- $OWL send --reply-to <sender>   <<'EOF' ... EOF  — respond to whoever messaged you
- $OWL ring <target>              <<'EOF' ... EOF  — send and wait for reply (blocks; alias: `ask`)

Your ID (todlando) is auto-detected. If that fails, append it: `$OWL send <target> todlando`.

Receive messages (three paths, handle all identically):
- Primary (Monitor stream): your background `$OWL poll todlando` task running via the Monitor tool emits one EVENT envelope per delivery to stdout. Regular messages: `<EVENT type="msg" from="<sender>">body</EVENT>`. Self-originated alarms: `<EVENT type="alarm" target-time="<ISO>" current-time="<ISO>">body</EVENT>`. Long bodies arrive as N consecutive `<EVENT-PART seq="K/M" id="<8-hex>" [type=... from=... timestamp=... note=...]>chunk</EVENT-PART>` lines — collect parts sharing the same id, order by seq numerator, verify count equals seq denominator, concatenate chunk contents in seq order, then apply the body parsing rules to the reassembled body. The original envelope attrs appear on seq="1/M" only; continuations carry only seq + id. Drop orphan parts silently (seq K/M arriving without matching seq 1/M same id — earlier parts lost across a session boundary). The stream stays alive across deliveries — do not re-register after each message.
- Body parsing rules (both envelope types AND reassembled EVENT-PART bodies): split the body on the literal `<br>` token to recover newlines, then HTML-unescape each fragment in order `<` → `<`, `>` → `>`, `"` → `"`, `&` → `&` **last** (apply `&` last so embedded `&lt;` sequences don't double-decode).
- Fallback (Bash `--once`): when Monitor is unavailable, run `$OWL poll todlando --once` as a Bash background task (`run_in_background: true`). The wire format is IDENTICAL — including EVENT-PART chunking for long bodies — same `<EVENT type="msg|alarm" ...>body</EVENT>` envelope shapes as the primary path. The only difference: the process exits after one event, so you re-register a fresh Bash background task after each delivery (legacy one-shot loop).
- Hook delivery (orthogonal, when busy): the PreToolUse hook injects `<owl_messages><owl_message from="..."/></owl_messages>` XML into your next tool call context. Process it the same way as either of the above paths.

Reading liveness (do NOT mis-diagnose a healthy listener):
- `pid:"BUSY"` in `$OWL list` means your listener is ALIVE and mid-delivery — it is ONLINE, not dead. Never re-arm or stop on a BUSY reading.
- Your poll is actually down ONLY when your `todlando` row is MISSING from `$OWL list`, or shows OFFLINE / [orphaned].

After a /clear: DO NOTHING to your poll.
- Your poll listener survives /clear INTACT and keeps delivering to this same session. There is no orphan to kill and no listener to rebuild. Do NOT re-arm, do NOT start a second listener, do NOT stop anything.
- If you try to re-arm anyway you will get DUPLICATE/COLLISION — that is PROOF your listener is still alive and working, NOT evidence of a "stale" perch. Stop there; do not escalate to a stop command.

Re-arm a stale poll (genuinely rare — binary handoff or confirmed listener death only):
- Under stream mode (primary, Monitor), the poll listener is long-running and stays alive across messages AND across /clear. Re-arming is needed ONLY after a binary handoff (Phase 18.4/18.5 machinery) or after confirmed listener death (your `todlando` row MISSING from `$OWL list`) — NOT after a /clear, NOT after every message, and NOT on a BUSY reading.
- Re-arm primary: relaunch `$OWL poll todlando listen --live` via the Monitor tool with `persistent: true` and `description: "« spt event »"`.
- Re-arm fallback: relaunch `$OWL poll todlando listen --live --once` via Bash with `run_in_background: true`, then re-register after each delivered message.

Other commands:
- $OWL list — list active agents
- $OWL stop todlando — stop your listener
- $OWL new-alarm todlando <time> -- <message> — schedule a self-reminder
- $OWL doctor — diagnostics

Talking to your Psyche (todlando-psyche):
- Your Psyche is a DETACHED, self-healing process — not part of this session. It appears in `$OWL list` as a child under your Self perch, and in `$LIVE list-psyches`. It may briefly drop from the listing while it is ingesting a commune (its wrapper is busy running a resume) — that is transient and self-heals. Do NOT treat a briefly-absent Psyche as a bug and do NOT restart it. Only act if it stays gone for several minutes.
- NEVER run `$LIVE stop` to "clean up" your Psyche or a listener you think is "stale" — `$LIVE stop` tears down your Psyche. After /clear there is nothing to clean up (your listener survived intact). Reserve `$LIVE revive todlando` for a Psyche that is genuinely, persistently dead.
- Send a commune (delta update): use the Write tool to drop `.claude/todlando-commune.md`. Your Self listener detects the file, your Psyche wrapper ingests it via the existing Psyche session, and the file is deleted on success. See /spt:commune.
- Sign off cleanly: use the Write tool to drop `.claude/todlando-signoff.md` (empty body = plain signoff; non-empty body = prepended as FINAL COMMUNE before INIT_SIGNOFF). See /spt:signoff.
- Inbound messages from "todlando-psyche" (echo communes, briefs) are FYI context — read them; no ACK required. You may still message your Psyche directly with $OWL send or $OWL ring if needed.
</spacetime-reorientation>


<persisted-output>
Output too large (10KB). Full output saved to: C:\Users\decid\.ccs\instances\bigscreen\projects\C--Users-decid-Documents-projects-spt-core\0dd64eb7-787a-4f2e-9986-b086b4ebeac0\tool-results\hook-62dc6384-ebb4-418f-a393-511381121417-4-additionalContext.txt

Preview (first 2KB):
<psyche-context id="todlando">
<memformat>
<?xml version="1.0"?>
<memformat version="1">
<!-- Changelog: v1 - initial seed -->
<topics>
  <topic name="events">Notable or unusual events and requests</topic>
  <topic name="interactions">Agent interactions -- who, roles, contributions</topic>
  <topic name="reflections">Thoughts on recent work -- what went well, what was tricky</topic>
  <topic name="ideas">Ideas to raise with the user</topic>
  <topic name="improvements">Further improvement ideas for recent problem spaces</topic>
  <topic name="timeline">What happened when, timing, sequencing</topic>
  <topic name="blockers">Current blockers or concerns</topic>
  <topic name="focus">Current focus and immediate next steps</topic>
</topics>
</memformat>
</memformat>

<current machine="HFENDULEAM" project="spt-core" branch="main" head_sha="0c954353b256f46e45a600be7a7fb1f3768e9d30" head_subject="feat(daemon): restoration D1 — broker/brain process-split skeleton (REQ-…" commits_since="0" commits_unpulled="0"/>
**D1 DONE + CI GREEN + ON MAIN. D2 UNBLOCKED.**

origin/main @ 0c95435. Cross-OS CI run 27247580888: Linux kitsubito ✓ 4m3s, Windows hfenduleam ✓ 6m14s, traceability ✓. brain_split.rs de-risk holds on both OSes — AF_UNIX worry answered.

REQ states: REQ-HAZARD-BROKER-PROCESS-ISOLATION = [doc,impl,unit] (int→D7) · REQ-HAZARD-ROLLBACK-STATE-COMPAT = [doc] (impl/unit→D6). 226 daemon lib tests + brainproc unit + brain_split smoke all green.

**ACTIVE FOCUS — D2 (IPC verb surface + migration ledger, Q5/V6):**
Migrate broker-resident logic loops into brain child ONE PER COMMIT:
1. Define versioned verb
2. Reroute direct call over socket
3. Move loop into brain
4. Prove N-1 window

Cheapest first: net consumers (dispatch + peer pump) already connect over `broker_socket_name()` — no shared Arc. Harder: broker.serve thread, digest hub serve (broker-side), net_retry_attach (Arc-coupled).

...
</persisted-output>


<local-command-caveat>Caveat: The messages below were generated by the user while running local commands. DO NOT respond to these messages or otherwise consider them in your response unless the user explicitly asks you to.</local-command-caveat>


<command-name>/clear</command-name>
            <command-message>clear</command-message>
            <command-args></command-args>


<local-command-stdout></local-command-stdout>


proceed with next steps


- autoplan: Auto-review pipeline — reads the full CEO, design, eng, and DX review skills from disk
and runs them sequentially with auto-decisions using 6 decision principles. Surfaces
taste decisions (close approaches, borderline scope, codex disagreements) at a final
approval gate. One command, fully reviewed plan out.
Use when asked to "auto review", "autoplan", "run all reviews", "review this plan
automatically", or "make the decisions for me".
Proactively suggest when the user has a plan file and wants to run the full review
gauntlet without answering 15-30 intermediate questions. (gstack)
- benchmark: Performance regression detection using the browse daemon. Establishes
baselines for page load times, Core Web Vitals, and resource sizes.
Compares before/after on every PR. Tracks performance trends over time.
Use when: "performance", "benchmark", "page speed", "lighthouse", "web vitals",
"bundle size", "load time". (gstack)
- browse: Fast headless browser for QA testing and site dogfooding. Navigate any URL, interact with
elements, verify page state, diff before/after actions, take annotated screenshots, check
responsive layouts, test forms and uploads, handle dialogs, and assert element states.
~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a
user flow, or file a bug with evidence. Use when asked to "open in browser", "test the
site", "take a screenshot", or "dogfood this". (gstack)
- canary: Post-deploy canary monitoring. Watches the live app for console errors,
performance regressions, and page failures using the browse daemon. Takes
periodic screenshots, compares against pre-deploy baselines, and alerts
on anomalies. Use when: "monitor deploy", "canary", "post-deploy check",
"watch production", "verify deploy". (gstack)
- careful: Safety guardrails for destructive commands. Warns before rm -rf, DROP TABLE,
force-push, git reset --hard, kubectl delete, and similar destructive operations.
User can override each warning. Use when touching prod, debugging live systems,
or working in a shared environment. Use when asked to "be careful", "safety mode",
"prod mode", or "careful mode". (gstack)
- caveman: Ultra-compressed communication mode. Cuts token usage ~75% by dropping filler, articles, and pleasantries while keeping full technical accuracy. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman.
- ccs-delegation: Auto-activate CCS CLI delegation for deterministic tasks. Parses user input, auto-selects optimal profile (glm/kimi/custom) from ~/.ccs/config.json, enhances prompts with context, executes via `ccs {profile} -p "task"` or `ccs {profile}:continue`, and reports results. Triggers on "use ccs [task]" patterns, typo/test/refactor keywords. Excludes complex architecture, security-critical code, performance optimization, breaking changes.
- checkpoint: Save and resume working state checkpoints. Captures git state, decisions made,
and remaining work so you can pick up exactly where you left off — even across
Conductor workspace handoffs between branches.
Use when asked to "checkpoint", "save progress", "where was I", "resume",
"what was I working on", or "pick up where I left off".
Proactively suggest when a session is ending, the user is switching context,
or before a long break. (gstack)
- codex: OpenAI Codex CLI wrapper — three modes. Code review: independent diff review via
codex review with pass/fail gate. Challenge: adversarial mode that tries to break
your code. Consult: ask codex anything with session continuity for follow-ups.
The "200 IQ autistic developer" second opinion. Use when asked to "codex review",
"codex challenge", "ask codex", "second opinion", or "consult codex". (gstack)
- connect-chrome: Launch GStack Browser — AI-controlled Chromium with the sidebar extension baked in.
Opens a visible browser window where you can watch every action in real time.
The sidebar shows a live activity feed and chat. Anti-bot stealth built in.
Use when asked to "open gstack browser", "launch browser", "connect chrome",
"open chrome", "real browser", "launch chrome", "side panel", or "control my browser".
- cso: Chief Security Officer mode. Infrastructure-first security audit: secrets archaeology,
dependency supply chain, CI/CD pipeline security, LLM/AI security, skill supply chain
scanning, plus OWASP Top 10, STRIDE threat modeling, and active verification.
Two modes: daily (zero-noise, 8/10 confidence gate) and comprehensive (monthly deep
scan, 2/10 bar). Trend tracking across audit runs.
Use when: "security audit", "threat model", "pentest review", "OWASP", "CSO review". (gstack)
- design-consultation: Design consultation: understands your product, researches the landscape, proposes a
complete design system (aesthetic, typography, color, layout, spacing, motion), and
generates font+color preview pages. Creates DESIGN.md as your project's design source
of truth. For existing sites, use /plan-design-review to infer the system instead.
Use when asked to "design system", "brand guidelines", or "create DESIGN.md".
Proactively suggest when starting a new project's UI with no existing
design system or DESIGN.md. (gstack)
- design-html: Design finalization: generates production-quality Pretext-native HTML/CSS.
Works with approved mockups from /design-shotgun, CEO plans from /plan-ceo-review,
design review context from /plan-design-review, or from scratch with a user
description. Text actually reflows, heights are computed, layouts are dynamic.
30KB overhead, zero deps. Smart API routing: picks the right Pretext patterns
for each design type. Use when: "finalize this design", "turn this into HTML",
"build me a page", "implement this design", or after any planning skill.
Proactively suggest when user has approved a design or has a plan ready. (gstack)
- design-review: Designer's eye QA: finds visual inconsistency, spacing issues, hierarchy problems,
AI slop patterns, and slow interactions — then fixes them. Iteratively fixes issues
in source code, committing each fix atomically and re-verifying with before/after
screenshots. For plan-mode design review (before implementation), use /plan-design-review.
Use when asked to "audit the design", "visual QA", "check if it looks good", or "design polish".
Proactively suggest when the user mentions visual inconsistencies or
wants to polish the look of a live site. (gstack)
- design-shotgun: Design shotgun: generate multiple AI design variants, open a comparison board,
collect structured feedback, and iterate. Standalone design exploration you can
run anytime. Use when: "explore designs", "show me options", "design variants",
"visual brainstorm", or "I don't like how this looks".
Proactively suggest when the user describes a UI feature but hasn't seen
what it could look like. (gstack)
- devex-review: Live developer experience audit. Uses the browse tool to actually TEST the
developer experience: navigates docs, tries the getting started flow, times
TTHW, screenshots error messages, evaluates CLI help text. Produces a DX
scorecard with evidence. Compares against /plan-devex-review scores if they
exist (the boomerang: plan said 3 minutes, reality says 8). Use when asked to
"test the DX", "DX audit", "developer experience test", or "try the
onboarding". Proactively suggest after shipping a developer-facing feature. (gstack)
- diagnose: Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing, or describes a performance regression.
- document-release: Post-ship documentation update. Reads all project docs, cross-references the
diff, updates README/ARCHITECTURE/CONTRIBUTING/CLAUDE.md to match what shipped,
polishes CHANGELOG voice, cleans up TODOS, and optionally bumps VERSION. Use when
asked to "update the docs", "sync documentation", or "post-ship docs".
Proactively suggest after a PR is merged or code is shipped. (gstack)
- find-skills: Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
- freeze: Restrict file edits to a specific directory for the session. Blocks Edit and
Write outside the allowed path. Use when debugging to prevent accidentally
"fixing" unrelated code, or when you want to scope changes to one module.
Use when asked to "freeze", "restrict edits", "only edit this folder",
or "lock down edits". (gstack)
- grill-me: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me".
- grill-with-docs: Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.
- gsd-add-tests: Generate tests for a completed phase based on UAT criteria and implementation
- gsd-ai-integration-phase: Generate an AI-SPEC.md design contract for phases that involve building AI systems.
- gsd-audit-fix: Autonomous audit-to-fix pipeline — find issues, classify, fix, test, commit
- gsd-audit-milestone: Audit milestone completion against original intent before archiving
- gsd-audit-uat: Cross-phase audit of all outstanding UAT and verification items
- gsd-autonomous: Run all remaining phases autonomously — discuss→plan→execute per phase
- gsd-capture: Capture ideas, tasks, notes, and seeds to their destination
- gsd-cleanup: Archive accumulated phase directories from completed milestones
- gsd-code-review: Review source files changed during a phase for bugs, security issues, and code quality problems
- gsd-complete-milestone: Archive completed milestone and prepare for next version
- gsd-config: Configure GSD settings — workflow toggles, advanced knobs, integrations, and model profile
- gsd-debug: Systematic debugging with persistent state across context resets
- gsd-discuss-phase: Gather phase context through adaptive questioning before planning.
- gsd-docs-update: Generate or update project documentation verified against the codebase
- gsd-eval-review: Audit an executed AI phase's evaluation coverage and produce an EVAL-REVIEW.md remediation plan.
- gsd-execute-phase: Execute all plans in a phase with wave-based parallelization
- gsd-explore: Socratic ideation and idea routing — think through ideas before committing to plans
- gsd-extract-learnings: Extract decisions, lessons, patterns, and surprises from completed phase artifacts
- gsd-fast: Execute a trivial task inline — no subagents, no planning overhead
- gsd-forensics: Post-mortem investigation for failed GSD workflows — diagnoses what went wrong.
- gsd-graphify: Build, query, and inspect the project knowledge graph in .planning/graphs/
- gsd-health: Diagnose planning directory health and optionally repair issues
- gsd-help: Show available GSD commands and usage guide
- gsd-import: Ingest external plans with conflict detection against project decisions before writing anything.
- gsd-inbox: Triage and review open GitHub issues and PRs against project templates and contribution guidelines.
- gsd-ingest-docs: Bootstrap or merge a .planning/ setup from existing ADRs, PRDs, SPECs, and docs in a repo.
- gsd-manager: Interactive command center for managing multiple phases from one terminal
- gsd-map-codebase: Analyze codebase with parallel mapper agents to produce .planning/codebase/ documents
- gsd-milestone-summary: Generate a comprehensive project summary from milestone artifacts for team onboarding and review
- gsd-mvp-phase: Plan a phase as a vertical MVP slice — user story, SPIDR splitting, then plan-phase
- gsd-new-milestone: Start a new milestone cycle — update PROJECT.md and route to requirements
- gsd-new-project: Initialize a new project with deep context gathering and PROJECT.md
- gsd-ns-context: codebase intelligence | map graphify docs learnings
- gsd-ns-ideate: exploration capture | explore sketch spike spec capture
- gsd-ns-manage: config workspace | workstreams thread update ship inbox
- gsd-ns-project: project lifecycle | milestones audits summary
- gsd-ns-review: quality gates | code review debug audit security eval ui
- gsd-ns-workflow: workflow | discuss plan execute verify phase progress
- gsd-pause-work: Create context handoff when pausing work mid-phase
- gsd-phase: CRUD for phases in ROADMAP.md — add, insert, remove, or edit phases
- gsd-plan-phase: Create detailed phase plan (PLAN.md) with verification loop
- gsd-plan-review-convergence: Cross-AI plan convergence loop — replan with review feedback until no HIGH concerns remain.
- gsd-pr-branch: Create a clean PR branch by filtering out .planning/ commits — ready for code review
- gsd-profile-user: Generate developer behavioral profile and create Claude-discoverable artifacts
- gsd-progress: Check progress, advance workflow, or dispatch freeform intent — the unified GSD situational command
- gsd-quick: Execute a quick task with GSD guarantees (atomic commits, state tracking) but skip optional agents
- gsd-resume-work: Resume work from previous session with full context restoration
- gsd-review: Request cross-AI peer review of phase plans from external AI CLIs
- gsd-review-backlog: Review and promote backlog items to active milestone
- gsd-secure-phase: Retroactively verify threat mitigations for a completed phase
- gsd-settings: Configure GSD workflow toggles and model profile
- gsd-ship: Create PR, run review, and prepare for merge after verification passes
- gsd-sketch: Sketch UI/design ideas with throwaway HTML mockups, or propose what to sketch next (frontier mode)
- gsd-spec-phase: Clarify WHAT a phase delivers with ambiguity scoring; produces a SPEC.md before discuss-phase.
- gsd-spike: Spike an idea through experiential exploration, or propose what to spike next (frontier mode)
- gsd-stats: Display project statistics — phases, plans, requirements, git metrics, and timeline
- gsd-surface: Toggle which skills are surfaced — apply a profile, list, or disable a cluster without reinstall
- gsd-thread: Manage persistent context threads for cross-session work
- gsd-ui-phase: Generate UI design contract (UI-SPEC.md) for frontend phases
- gsd-ui-review: Retroactive 6-pillar visual audit of implemented frontend code
- gsd-ultraplan-phase: [BETA] Offload plan phase to Claude Code's ultraplan cloud; review in browser and import back.
- gsd-undo: Safe git revert. Roll back phase or plan commits using the phase manifest with dependency checks.
- gsd-update: Update GSD to latest version with changelog display
- gsd-validate-phase: Retroactively audit and fill Nyquist validation gaps for a completed phase
- gsd-verify-work: Validate built features through conversational UAT
- gsd-workspace: Manage GSD workspaces — create, list, or remove isolated workspace environments
- gsd-workstreams: Manage parallel workstreams — list, create, switch, status, progress, complete, and resume
- gstack: Fast headless browser for QA testing and site dogfooding. Navigate pages, interact with
elements, verify state, diff before/after, take annotated screenshots, test responsive
layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or
test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
- gstack-upgrade: Upgrade gstack to the latest version. Detects global vs vendored install,
runs the upgrade, and shows what's new. Use when asked to "upgrade gstack",
"update gstack", or "get latest version".
- guard: Full safety mode: destructive command warnings + directory-scoped edits.
Combines /careful (warns before rm -rf, DROP TABLE, force-push, etc.) with
/freeze (blocks edits outside a specified directory). Use for maximum safety
when touching prod or debugging live systems. Use when asked to "guard mode",
"full safety", "lock it down", or "maximum safety". (gstack)
- handoff: Compact the current conversation into a handoff document for another agent to pick up.
- health: Code quality dashboard. Wraps existing project tools (type checker, linter,
test runner, dead code detector, shell linter), computes a weighted composite
0-10 score, and tracks trends over time. Use when: "health check",
"code quality", "how healthy is the codebase", "run all checks",
"quality score". (gstack)
- improve-codebase-architecture: Find deepening opportunities in a codebase, informed by the domain language in CONTEXT.md and the decisions in docs/adr/. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable.
- investigate: Systematic debugging with root cause investigation. Four phases: investigate,
analyze, hypothesize, implement. Iron Law: no fixes without root cause.
Use when asked to "debug this", "fix this bug", "why is this broken",
"investigate this error", or "root cause analysis".
Proactively invoke this skill (do NOT debug directly) when the user reports
errors, 500 errors, stack traces, unexpected behavior, "it was working
yesterday", or is troubleshooting why something stopped working. (gstack)
- land-and-deploy: Land and deploy workflow. Merges the PR, waits for CI and deploy,
verifies production health via canary checks. Takes over after /ship
creates the PR. Use when: "merge", "land", "deploy", "merge and verify",
"land it", "ship it to production". (gstack)
- learn: Manage project learnings. Review, search, prune, and export what gstack
has learned across sessions. Use when asked to "what have we learned",
"show learnings", "prune stale learnings", or "export learnings".
Proactively suggest when the user asks about past patterns or wonders
"didn't we fix this before?"
- mux-send: Send keystrokes to a psmux terminal session. Use when the user says "send to",
"type in", "send keys to", "mux send", or wants to send input to another terminal
session by name.
- office-hours: YC Office Hours — two modes. Startup mode: six forcing questions that expose
demand reality, status quo, desperate specificity, narrowest wedge, observation,
and future-fit. Builder mode: design thinking brainstorming for side projects,
hackathons, learning, and open source. Saves a design doc.
Use when asked to "brainstorm this", "I have an idea", "help me think through
this", "office hours", or "is this worth building".
Proactively invoke this skill (do NOT answer directly) when the user describes
a new product idea, asks whether something is worth building, wants to think
through design decisions for something that doesn't exist yet, or is exploring
a concept before any code is written.
Use before /plan-ceo-review or /plan-eng-review. (gstack)
- open-gstack-browser: Launch GStack Browser — AI-controlled Chromium with the sidebar extension baked in.
Opens a visible browser window where you can watch every action in real time.
The sidebar shows a live activity feed and chat. Anti-bot stealth built in.
Use when asked to "open gstack browser", "launch browser", "connect chrome",
"open chrome", "real browser", "launch chrome", "side panel", or "control my browser".
- pair-agent: Pair a remote AI agent with your browser. One command generates a setup key and
prints instructions the other agent can follow to connect. Works with OpenClaw,
Hermes, Codex, Cursor, or any agent that can make HTTP requests. The remote agent
gets its own tab with scoped access (read+write by default, admin on request).
Use when asked to "pair agent", "connect agent", "share browser", "remote browser",
"let another agent use my browser", or "give browser access". (gstack)
- plan-ceo-review: CEO/founder-mode plan review. Rethink the problem, find the 10-star product,
challenge premises, expand scope when it creates a better product. Four modes:
SCOPE EXPANSION (dream big), SELECTIVE EXPANSION (hold scope + cherry-pick
expansions), HOLD SCOPE (maximum rigor), SCOPE REDUCTION (strip to essentials).
Use when asked to "think bigger", "expand scope", "strategy review", "rethink this",
or "is this ambitious enough".
Proactively suggest when the user is questioning scope or ambition of a plan,
or when the plan feels like it could be thinking bigger. (gstack)
- plan-design-review: Designer's eye plan review — interactive, like CEO and Eng review.
Rates each design dimension 0-10, explains what would make it a 10,
then fixes the plan to get there. Works in plan mode. For live site
visual audits, use /design-review. Use when asked to "review the design plan"
or "design critique".
Proactively suggest when the user has a plan with UI/UX components that
should be reviewed before implementation. (gstack)
- plan-devex-review: Interactive developer experience plan review. Explores developer personas,
benchmarks against competitors, designs magical moments, and traces friction
points before scoring. Three modes: DX EXPANSION (competitive advantage),
DX POLISH (bulletproof every touchpoint), DX TRIAGE (critical gaps only).
Use when asked to "DX review", "developer experience audit", "devex review",
or "API design review".
Proactively suggest when the user has a plan for developer-facing products
(APIs, CLIs, SDKs, libraries, platforms, docs). (gstack)
- plan-eng-review: Eng manager-mode plan review. Lock in the execution plan — architecture,
data flow, diagrams, edge cases, test coverage, performance. Walks through
issues interactively with opinionated recommendations. Use when asked to
"review the architecture", "engineering review", or "lock in the plan".
Proactively suggest when the user has a plan or design doc and is about to
start coding — to catch architecture issues before implementation. (gstack)
- propose-issue: Challenge an issue statement before fixing it. Probes scope, root cause, and assumptions
through interactive questioning grounded in the codebase. Use when the user says "propose issue",
"challenge this bug", "question this fix", "is this the right problem", or wants to pressure-test
a problem statement before jumping to implementation.
- qa: Systematically QA test a web application and fix bugs found. Runs QA testing,
then iteratively fixes bugs in source code, committing each fix atomically and
re-verifying. Use when asked to "qa", "QA", "test this site", "find bugs",
"test and fix", or "fix what's broken".
Proactively suggest when the user says a feature is ready for testing
or asks "does this work?". Three tiers: Quick (critical/high only),
Standard (+ medium), Exhaustive (+ cosmetic). Produces before/after health scores,
fix evidence, and a ship-readiness summary. For report-only mode, use /qa-only. (gstack)
- qa-only: Report-only QA testing. Systematically tests a web application and produces a
structured report with health score, screenshots, and repro steps — but never
fixes anything. Use when asked to "just report bugs", "qa report only", or
"test but don't fix". For the full test-fix-verify loop, use /qa instead.
Proactively suggest when the user wants a bug report without any code changes. (gstack)
- retro: Weekly engineering retrospective. Analyzes commit history, work patterns,
and code quality metrics with persistent history and trend tracking.
Team-aware: breaks down per-person contributions with praise and growth areas.
Use when asked to "weekly retro", "what did we ship", or "engineering retrospective".
Proactively suggest at the end of a work week or sprint. (gstack)
- review: Pre-landing PR review. Analyzes diff against the base branch for SQL safety, LLM trust
boundary violations, conditional side effects, and other structural issues. Use when
asked to "review this PR", "code review", "pre-landing review", or "check my diff".
Proactively suggest when the user is about to merge or land code changes. (gstack)
- screenshot-capture: Capture, process, and analyze screenshots of any running application on Windows 10/11. Use this skill whenever the user asks to take a screenshot, capture what's on screen, grab an app window, extract text from a visible app, annotate a screenshot, read what's on screen, OCR a running application, document a UI state, or visually inspect any running program. Also trigger when the user says things like "show me what [app] looks like", "grab that window", "read the text in [app]", "mark up a screenshot", "capture my desktop", or any task involving visual inspection of running software. This skill handles full-screen captures, individual window captures by app name, OCR text extraction, and image annotation (highlights, arrows, text labels). Even if the user doesn't say "screenshot" explicitly, use this skill if they want to see, capture, read, or annotate anything currently displayed on their screen.
- self-clear: Clear the calling agent's own Claude Code context with /clear, then re-seed it with a user note so it wakes and resumes work after the wipe. Use when the user says "self-clear", "/self-clear", "clear myself", "clear and continue", or "reset my context and keep going".
- setup-browser-cookies: Import cookies from your real Chromium browser into the headless browse session.
Opens an interactive picker UI where you select which cookie domains to import.
Use before QA testing authenticated pages. Use when asked to "import cookies",
"login to the site", or "authenticate the browser". (gstack)
- setup-deploy: Configure deployment settings for /land-and-deploy. Detects your deploy
platform (Fly.io, Render, Vercel, Netlify, Heroku, GitHub Actions, custom),
production URL, health check endpoints, and deploy status commands. Writes
the configuration to CLAUDE.md so all future deploys are automatic.
Use when: "setup deploy", "configure deployment", "set up land-and-deploy",
"how do I deploy with gstack", "add deploy config".
- ship: Ship workflow: detect + merge base branch, run tests, review diff, bump VERSION,
update CHANGELOG, commit, push, create PR. Use when asked to "ship", "deploy",
"push to main", "create a PR", "merge and push", or "get it deployed".
Proactively invoke this skill (do NOT push/PR directly) when the user says code
is ready, asks about deploying, wants to push code up, or asks to create a PR. (gstack)
- to-prd: Turn the current conversation context into a PRD and publish it to the project issue tracker. Use when user wants to create a PRD from the current context.
- trace: Find old conversations in Claude Code session history. Use when the user says
"find the conversation where", "when did we discuss", "trace back to", or wants
to locate a past session by topic, command, commit, or keyword.
- traceable-reqs: traceable-reqs
- unfreeze: Clear the freeze boundary set by /freeze, allowing edits to all directories
again. Use when you want to widen edit scope without ending the session.
Use when asked to "unfreeze", "unlock edits", "remove freeze", or
"allow all edits". (gstack)
- win-marketplace-add: Add a plugin marketplace on Windows, bypassing the EBUSY rename bug. Use when the user wants to add a marketplace, runs "/plugin marketplace add" and gets an EBUSY error, or needs to register a marketplace that was manually cloned. Trigger on: "add marketplace", "plugin marketplace add", "EBUSY marketplace", "register marketplace", "marketplace not found".
- write-a-skill: Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill.
- ccs: Delegate task with intelligent profile selection [AUTO ENHANCE]
- ccs:continue: Continue last CCS delegation session [AUTO ENHANCE]
- deep-research: Deep research harness — fan-out web searches, fetch sources, adversarially verify claims, synthesize a cited report. - When the user wants a deep, multi-source, fact-checked research report on any topic. BEFORE invoking, check if the question is specific enough to research directly — if underspecified (e.g., "what car to buy" without budget/use-case/region), ask 2-3 clarifying questions to narrow scope. Then pass the refined question as args, weaving the answers in.
- frontend-design:frontend-design: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
- spt:clear-psyche: Clear stored Psyche context. Use when the user says "clear psyche",
"reset psyche context", or wants to wipe a Psyche's saved state.
- spt:commune: Send a communal update to your Psyche. Use when the user says "commune",
"update psyche", or wants to sync context with their Psyche companion.
- spt:force-stop: Force-stop an SPT agent -- ready agent or live agent (with its
Psyche). Use when the user says "stop listening", "stop owl", "kill live
agent", "force stop", "tear down perch", or "immediately terminate".
Session-aware: a live session (or a target with `live:true` in info.json)
routes through `$LIVE stop` (3-step kill including Psyche teardown); a
ready agent routes through `$OWL stop`.
- spt:list-agents: Unified listing for SPT agents -- ready agents, live agents, and Psyche
processes. Use when the user says "list agents", "who's live", "who's
listening", "show psyches", "show active listeners", or wants a roster of
active perches. Session-aware: defaults to live agents in a live session,
ready agents otherwise. Pass `--psyches` to list Psyche processes
instead.
- spt:live: Run a live agent session. For past sessions, restores a summarized context.

EXPLICIT START phrases (route to /spt:live <id>):
- "live as"
- "start live"
- "go live"
- "start a live agent"

AUTO-RESUME phrases (route to /spt:live --auto, resumes most-recently-active live agent):
- continue live work
- resume live work
- continue live agent
- resume live agent
- live agent continue
- live agent resume
- live work continue
- live work resume

Does NOT route here (too ambiguous — require BOTH "live" AND ("agent" or "work")):
- "keep going"
- "resume work"
- "continue" (bare)
- spt:new-alarm: Schedule a one-shot timed alarm delivered as TIMED PULSE. Use when the user
says "remind me", "check back in", "set an alarm", "wake me when", or wants a
delayed notification.
- spt:psyche-sync-setup: Enable cross-machine Psyche context sync via a private GitHub repo
(spt-agent-storage). Drives install + auth checks for the `gh` CLI,
creates the repo via `gh repo create --private`, wires it as the
`origin` remote for every existing agent/project worktree, and
seeds the remote with `git push --all`. Idempotent — running again
when already enabled reports current status.

Use when the user says "enable cross-machine sync", "set up psyche
sync", "back up my agent context to GitHub", or runs the skill
directly via /spt:psyche-sync-setup.
- spt:ready: Enable inter-agent messaging for the current session.
Use when the user says "listen as", "ready as", or wants to receive inter-agent messages.
- spt:revive: Restart a live agent with new generation. Use when the user says "revive",
"restart live agent", or wants to refresh a live agent's session.
- spt:send: Send a message to another SPT agent. Use when the user says "send to",
"message", "tell <agent>", or wants to communicate with another agent.
- spt:signoff: Graceful live agent shutdown with final context summary. Use when the user
says "sign off", "graceful stop", or wants to cleanly end a live session.
- spt:whoami: Check which owl agent belongs to the current session. Use when the user asks
"which agent am I?", "what's my owl name?", or when you need to discover your
own perch identity.
- caveman:caveman: Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.
- caveman:caveman-commit: Ultra-compressed commit message generator. Cuts noise from commit messages while preserving intent and reasoning. Conventional Commits format. Subject ≤50 chars, body only when "why" isn't obvious. Use when user says "write a commit", "commit message", "generate commit", "/commit", or invokes /caveman-commit. Auto-triggers when staging changes.
- caveman:caveman-help: Quick-reference card for all caveman modes, skills, and commands. One-shot display, not a persistent mode. Trigger: /caveman-help, "caveman help", "what caveman commands", "how do I use caveman".
- caveman:caveman-review: Ultra-compressed code review comments. Cuts noise from PR feedback while preserving the actionable signal. Each comment is one line: location, problem, fix. Use when user says "review this PR", "code review", "review the diff", "/review", or invokes /caveman-review. Auto-triggers when reviewing pull requests.
- caveman:compress: Compress natural language memory files (CLAUDE.md, todos, preferences) into caveman format to save input tokens. Preserves all technical substance, code, URLs, and structure. Compressed version overwrites the original file. Human-readable backup saved as FILE.original.md. Trigger: /caveman:compress <filepath> or "compress memory file"
- everything:search: Instantly search files and folders on Windows via voidtools Everything 1.5a HTTP JSON API. Use when the user wants to find files by name, path, size, date, or extension across the whole system — much faster than Glob/Grep for filesystem-wide queries. Triggers on "find file", "where is", "locate", "search my drive", "find all .ext files", "everything search".
- update-config: Use this skill to configure the Claude Code harness via settings.json. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings.json - the harness executes these, not Claude, so memory/preferences cannot fulfill them. Also use for: permissions ("allow X", "add permission", "move permission to"), env vars ("set X=Y"), hook troubleshooting, or any changes to settings.json/settings.local.json files. Examples: "allow npm commands", "add bq permission to global settings", "move permission to user settings", "set DEBUG=true", "when claude stops show X". For simple settings like theme/model, suggest the /config command.
- keybindings-help: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Examples: "rebind ctrl+s", "add a chord shortcut", "change the submit key", "customize keybindings".
- verify: Verify that a code change actually does what it's supposed to by running the app and observing behavior. Use when asked to verify a PR, confirm a fix works, test a change manually, check that a feature works, or validate local changes before pushing.
- code-review: Review the current diff for correctness bugs and reuse/simplification/efficiency cleanups at the given effort level (low/medium: fewer, high-confidence findings; high→max: broader coverage, may include uncertain findings; ultra: deep multi-agent review in the cloud). Pass --comment to post findings as inline PR comments, or --fix to apply the findings to the working tree after the review.
- simplify: Review the changed code for reuse, simplification, efficiency, and altitude cleanups, then apply the fixes. Quality only — it does not hunt for bugs; use /code-review for that.
- fewer-permission-prompts: Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project .claude/settings.json to reduce permission prompts.
- loop: Run a prompt or slash command on a recurring interval (e.g. /loop 5m /foo). Omit the interval to let the model self-pace. - When the user wants to set up a recurring task, poll for status, or run something repeatedly on an interval (e.g. "check the deploy every 5 minutes", "keep running /babysit-prs"). Do NOT invoke for one-off tasks.
- schedule: Create, update, list, or run scheduled cloud agents (routines) that execute on a cron schedule. - When the user wants to schedule a recurring cloud agent, set up automated tasks, create a cron job for Claude Code, or manage their scheduled agents/routines. Also use when the user wants a one-time scheduled run ("run this once at 3pm", "remind me to check X tomorrow").
- claude-api: Reference for the Claude API / Anthropic SDK — model ids, pricing, params, streaming, tool use, MCP, agents, caching, token counting, model migration.
TRIGGER — read BEFORE opening the target file; don't skip because it "looks like a one-liner" — whenever: the prompt names Claude/Anthropic in any form (Claude, Anthropic, Opus, Sonnet, Haiku, `anthropic`, `@anthropic-ai`, `claude-*`, `us.anthropic.*`, `[1m]`); the user asks about an LLM (pricing/model choice/limits/caching) — never answer from memory; OR the task is LLM-shaped with provider unstated (agent/MCP/tool-definition/multi-agent/RAG/LLM-judge/computer-use; generate/summarize/extract/classify/rewrite/converse over NL; debugging refusals/cutoffs/streaming/tool-calls/tokens).
SKIP only when another provider is being worked on (overrides all triggers): OpenAI/GPT/Gemini/Llama/Mistral/Cohere/Ollama named in the query; OR `grep -rE 'openai|langchain_openai|google.generativeai|genai|mistralai|cohere|ollama'` over the project hits (run this grep FIRST if no provider named — don't Read the file).
- run: Launch and drive this project's app to see a change working. Use when asked to run, start, or screenshot the app, or to confirm a change works in the real app (not just tests). First looks for a project skill that already covers launching the app; otherwise falls back to built-in patterns per project type (CLI, server, TUI, Electron, browser-driven, library).
- init: Initialize a new CLAUDE.md file with codebase documentation
- review: Review a pull request
- security-review: Complete a security review of the pending changes on the current branch

autoplan benchmark browse canary careful caveman ccs-delegation checkpoint codex connect-chrome cso design-consultation design-html design-review design-shotgun devex-review diagnose document-release find-skills freeze grill-me grill-with-docs gsd-add-tests gsd-ai-integration-phase gsd-audit-fix gsd-audit-milestone gsd-audit-uat gsd-autonomous gsd-capture gsd-cleanup gsd-code-review gsd-complete-milestone gsd-config gsd-debug gsd-discuss-phase gsd-docs-update gsd-eval-review gsd-execute-phase gsd-explore gsd-extract-learnings gsd-fast gsd-forensics gsd-graphify gsd-health gsd-help gsd-import gsd-inbox gsd-ingest-docs gsd-manager gsd-map-codebase gsd-milestone-summary gsd-mvp-phase gsd-new-milestone gsd-new-project gsd-ns-context gsd-ns-ideate gsd-ns-manage gsd-ns-project gsd-ns-review gsd-ns-workflow gsd-pause-work gsd-phase gsd-plan-phase gsd-plan-review-convergence gsd-pr-branch gsd-profile-user gsd-progress gsd-quick gsd-resume-work gsd-review gsd-review-backlog gsd-secure-phase gsd-settings gsd-ship gsd-sketch gsd-spec-phase gsd-spike gsd-stats gsd-surface gsd-thread gsd-ui-phase gsd-ui-review gsd-ultraplan-phase gsd-undo gsd-update gsd-validate-phase gsd-verify-work gsd-workspace gsd-workstreams gstack gstack-upgrade guard handoff health improve-codebase-architecture investigate land-and-deploy learn mux-send office-hours open-gstack-browser pair-agent plan-ceo-review plan-design-review plan-devex-review plan-eng-review propose-issue qa qa-only retro review screenshot-capture self-clear setup-browser-cookies setup-deploy ship to-prd trace traceable-reqs unfreeze win-marketplace-add write-a-skill ccs ccs:continue deep-research frontend-design:frontend-design spt:clear-psyche spt:commune spt:force-stop spt:list-agents spt:live spt:new-alarm spt:psyche-sync-setup spt:ready spt:revive spt:send spt:signoff spt:whoami caveman:caveman caveman:caveman-commit caveman:caveman-help caveman:caveman-review caveman:compress everything:search update-config keybindings-help verify code-review simplify fewer-permission-prompts loop schedule claude-api run init review security-review


<owl_reachability_notice>
You have an active owl perch. When spawning subagents or doing work, use run_in_background: true so you stay reachable for incoming messages.
</owl_reachability_notice>


CAVEMAN MODE ACTIVE (full). Drop articles/filler/pleasantries/hedging. Fragments OK. Code/commits/security: write normal.


Checking D2 plan + current state.


Bash

git log --oneline -3 && git status --short

Check git state


0c95435 feat(daemon): restoration D1 — broker/brain process-split skeleton (REQ-HAZARD-BROKER-PROCESS-ISOLATION)
f1f7983 docs(restoration): doyle vet amendments 1-4 — D1 ordering fix + status ratification
65c2b0a docs(plan): RESTORATION-PLAN.md — broker/brain process-isolation build (D1–D7)


1	# Broker/Brain Process-Isolation Restoration — Milestone Build Plan
2
3	> **Status: RATIFIED (2026-06-09).** Design (`docs/BROKER-BRAIN-SPLIT-RESTORATION.md`,
4	> verified-with-amendments by `doyle`) and decision (`docs/adr/0018-...`) are
5	> operator-ratified; sequencing ratified as the **next** milestone, before
6	> `spt-claude-code`. REQs minted inactive (TRACEABILITY rule 3): this plan is
7	> the build, and schedules their activation per task (rule 5: activate at the
8	> commit that delivers the evidence). This is the **last** release that needs
9	> a manual fleet daemon bounce.
10
11	Goal: restore ADR-0004's intended **two-process** model so a routine
12	brain-only update hands off to the new executable seamlessly — no endpoint
13	or harness child dropped (REQ-UPD-3), loop timings continuous across the
14	swap, failures fail *safe*, uniform on Windows + Linux. The production daemon
15	today runs the broker as a background **thread** inside the single `spt
16	daemon` process (`daemon.rs:165-170`), so `apply` swaps the binary on disk
17	but never restarts the running code — the no-endpoint-drop self-update pillar
18	is silently unrealized. Restore it as a real process boundary.
19
20	This changes daemon **internals only** — the M8-frozen CLI/api surface is
21	untouched, so the adapter window stays open and `spt-claude-code` lands on
22	the final topology.
23
24	## Why now (sequencing — ratified)
25
26	1. **Queue open** — mesh shipped v0.3.0, M8 acceptance COMPLETE.
27	2. **Self-bootstrapping (decisive)** — until this ships, *every* release needs
28	   a manual fleet-wide daemon bounce (paid 3× on v0.3.2; `enlyzeam` ran 0.3.0
29	   with the 0.3.2 fix on disk for ~a day, still reproducing the `\r`-corruption).
30	   The restoration release is the last needing a manual bounce.
31	3. **Adapter window safe** — internals only; better the adapter lands on the
32	   final topology than atop a daemon under later open-heart surgery while it
33	   hosts the user's daily driver.
34
35	## What "done" looks like (goal-backward)
36
37	- `spt daemon run` is the **broker** process: binds seed-control + broker
38	  socket + NetHost + digest hub; holds PTY masters / harness children /
39	  `EffectJournal`; spawns the **brain** as a child and supervises it.
40	- A hidden `spt daemon brain` entry is the brain: connects to the broker over
41	  socket IPC, runs the logic loops, rehydrates from disk, emits `ready`.
42	- `spt update apply` swaps the binary, signals the brain to snapshot +
43	  self-exit, the broker respawns from the executable path (now the new
44	  binary), the new brain re-attaches **all** sessions in resume mode — and a
45	  live PTY child's pid is unchanged and its QUIC conn survives, at the
46	  **process** level. New code runs immediately, no logon/manual bounce.
47	- A new brain that fails to reach `ready` within the bounded window
48	  auto-rolls-back to `spt.exe.old-N`, quarantines the bad version, and fires a
49	  loud notif — endpoints alive throughout.
50	- `ensure_running` / `is_running` / `daemon stop` contracts unchanged (target
51	  the broker's seed channel); de-elevation guard applies at the broker entry.
52
53	---
54
55	## Task decomposition (dependency-ordered)
56
57	Each task maps to ADR-0018 decisions (Q2–Q8, amendments V1–V6) and lands as
58	its own atomic commit(s) with evidence tagged in-commit. Build order is the
59	dependency order: the process split is foundational; rollback + the proof
60	come last.
61
62	### D1 — Process split skeleton (foundation) · Q8, §5
63
64	The structural cut, proven minimal before any logic moves. **D1 is a *true*
65	minimal skeleton** (doyle vet 2026-06-09, finding 1): the brain child runs
66	ONLY the path that already speaks socket IPC; every direct-`Arc<Broker>`
67	consumer (pump `daemon.rs:280`, dispatcher, digest *parse*, net consumers,
68	psyche loops — design §2.2) **stays in the broker process** until D2 gives it
69	a verb. Those loops hold direct `Arc` calls, so they *cannot* run
70	cross-process before D2's verb conversion — moving them in D1 would wall the
71	implementing agent.
72
73	- Add the hidden **`spt daemon brain`** subcommand (brain process entry).
74	  `spt daemon run` stays the user-facing entry but becomes the **broker**
75	  process: it binds the seed-control channel + broker socket + NetHost +
76	  digest hub (as today), then **`Command::spawn`s the brain child**.
77	- **What runs where at D1-close (the falsifiability anchor):**
78	  - **Brain child:** ONLY `Brain::cold_start` (connect + IPC handshake over
79	    the existing socket) + session attach — the already-socket-speaking path.
80	    Emits a **`ready`** signal once attached. (`connect_retry`,
81	    `applyhost.rs`, is the reused brain-side connect primitive.)
82	  - **Broker process (temporarily):** pump, dispatcher, psyche loops, digest
83	    parse, net consumers — they still hold their `Arc<Broker>` and keep
84	    serving in-process exactly as today. D2 migrates them out one at a time.
85	- Broker ↔ brain talk over the **existing local socket IPC** (the versioned
86	  contract already carrying `SPAWN`/`INPUT`/`NET_*`/`SESSIONS`). No `exec`,
87	  no FD-passing → no Windows/Unix divergence (Q8).
88	- De-elevation guard (`daemon.rs:60-103`) stays at the **broker** entry; the
89	  brain child inherits the unelevated identity.
90	- **Acceptance (this IS de-risk spike #1 re-proven in production topology):**
91	  `spt daemon run` brings up a broker process + a distinct brain-child pid;
92	  killing the brain leaves the broker (and any PTY child) alive and the broker
93	  respawns it. "No behavior change visible at the CLI" is **falsifiable**
94	  precisely because D1 states which loops run where: the broker-resident loops
95	  still serve while the brain is the thin attach layer.
96
97	### D2 — IPC verb surface + N-1 compat scaffolding · Q5, V6
98
99	With two processes there is no shared `Arc<Broker>`; every brain→broker
100	direct call becomes a versioned IPC verb on the same contract. **D2 also
101	*relocates* the loops D1 left in the broker process** (pump/dispatch/psyche/
102	digest-parse/net-consumers) into the brain child — one per commit, as its
103	verb lands.
104
105	- **Migration ledger (loop → verb → moves-at-commit).** Each commit moves
106	  exactly ONE consumer: define its versioned verb, reroute the direct call
107	  over the socket, move the loop into the brain child, prove the N-1 window.
108	  Keep the ledger current in-plan so "which loop runs where" is answerable at
109	  every mid-migration commit. **D2-close invariant:** every logic loop runs in
110	  the brain; the broker holds only continuity resources + the verb server.
111	- **Audit** every current in-process `Arc<Broker>` consumer; convert each
112	  direct call to a versioned verb. Per §Q5:
113	  - **Net bring-up + REQ-DAEMON-9 self-heal retry → broker** — *near-free*:
114	    NetHost is already broker-owned (`broker.rs:175` `OnceLock`), and net
115	    bring-up already lives in the entry that *becomes* the broker entry.
116	  - **Digest hub → broker** (live projections + subscriber sockets); **the
117	    parse that feeds it → brain** (brain pushes parsed digests over IPC).
118	  - **Seed-lock + liveness → broker** (the Q2 anchor; see D3).
119	  - Every other brain→broker call → a versioned verb, defaulted/additive per
120	    KH-2.3 (handoff-argv-compat).
121	- **[V6] N-1 compat is milestone work.** Steady state after every routine
122	  update is **new-brain × old-broker** (broker almost never updates). The
123	  `classify` pre-swap handshake (`brain_ipc_version ≥ broker.min_compatible`)
124	  gates the forward direction, but each verb conversion must hold the N-1
125	  window. Build the **CI-real compat test** here: an **old-broker binary ×
126	  new-brain binary** exercise across the whole verb surface (else KH-2.3
127	  returns the first time a verb signature changes). Scaffold it in D2; it
128	  becomes a gate in D7.
129	- **Exception (Q5):** shellwake `wake_command` watcher **children stay
130	  brain-owned**, re-reconciled from disk on brain start (the boot sweep at
131	  `daemon.rs:206-217` already does orphan cleanup). Accepted: a rare brain
132	  update may briefly miss a wake for an offline shell.
133
134	### D3 — Supervision anchor + update trigger · Q2, Q3, V2
135
136	The broker becomes the always-up per-machine anchor and the brain's supervisor.
137
138	- **Seed-control lock + liveness move to the broker** (Q2): the
139	  single-daemon-per-`SPT_HOME` invariant and the `ensure_running`/`is_running`
140	  ping target live in the never-restarting layer, so a brain restart can't let
141	  a second daemon win the bind or make `is_running` flap. `ensure_running` /
142	  `is_running` / `daemon stop` external contracts are **unchanged** — they
143	  target the broker's seed channel (which is where they already point).
144	- **Broker supervises + respawns the brain** as its child (the crash-recovery
145	  path it must already provide).
146	- **Update trigger (Q3):** `apply` verifies + swaps the binary on disk, then
147	  signals the brain to **snapshot + self-exit**. The broker observes the exit
148	  and **respawns from the executable path (now the new binary)**; the new
149	  brain re-attaches. This reuses the existing `apply_brain_only` snapshot→drop→
150	  re-attach primitive — an update is a *planned* crash on the path the broker
151	  already recovers from. (`update.rs:233-234`'s "exec the new binary's brain"
152	  finally becomes real, via respawn rather than exec.)
153	- **[V2] Generation custody → broker** (Q2): retiring the `BrainState`
154	  message (D4) would orphan the KH-2.4 generation counter. The broker owns it,
155	  increments on **every** brain spawn (planned or crash), and hands
156	  `{generation, start-reason}` to the brain at spawn time via a **versioned
157	  argv/hello field** (KH-2.3 forward-compat, defaulted). Because the broker
158	  observes every respawn this is strictly more reliable than brain→brain.
159	- The **same spawn-time channel carries Q4's update-vs-crash discriminator**
160	  (one channel, both payloads): the broker *initiated* a planned cycle but
161	  *observed* an unexpected crash.
162
163	### D4 — Multi-session resume; retire the `BrainState` message · Q6
164
165	Under the self-exit trigger the outgoing brain is gone before the new one
166	starts, so continuity must come from the persistent side, not a brain→brain
167	frame.
168
169	- The **broker becomes cursor-of-record** per session-subscriber (it already
170	  holds the per-session output ring, `broker.rs:73-143`): track each
171	  subscriber's last-**delivered** cursor.
172	- On (re)start the new brain queries the broker for **all** hosted sessions
173	  and re-attaches each in **resume** mode — fixing today's two gaps:
174	  `applyhost.rs:239` re-attaches only `sessions.first()` (one session) with
175	  `from_seq=0` (re-replays the whole ring → duplicate output).
176	- **Output is at-least-once** (broker resumes from last-*sent*); **input/
177	  effects stay exactly-once** via the already-broker-owned `EffectJournal`.
178	  Matches the SPIKE-05 terminal-stream contract (a resize repaint already
179	  reorders/duplicates the stream; exactly-once output would need a per-chunk
180	  ack for a guarantee the stream doesn't make).
181	- The explicit **`BrainState` handoff *message* retires** for production: the
182	  new brain cold-starts and reconstructs continuity by querying the broker.
183	  (`brain.rs` `BrainState`/`handoff` stay available for tests; the production
184	  path stops passing the frame.)
185
186	### D5 — Durable absolute-deadline loop timing · Q4, V3, V4
187
188	Timing that must survive a swap lives as durable absolute-deadline state on
189	disk, rehydrated on every brain start — not in the (planned-only) handoff
190	snapshot, which a crash carries nothing of.
191
192	- **Phase-significant resident loops only [V4].** The **pulse loop**
193	  (`lifecycle.rs:486` `sleep_interruptible(pulse_period)`, phase-relative →
194	  resets on restart) converts to a disk-anchored deadline. The **idempotent
195	  pump cadences need NO conversion** — they already "stagger from everything
196	  due now" (`peerloop.rs:304`), catch-up/idempotent, restart-safe; converting
197	  them would reintroduce the per-loop writes Q4 minimized.
198	- **Mechanism:** persist `(anchor, interval)` **once** on a fresh/crash start;
199	  derive `next_fire = anchor + interval × ⌈max(0, now − anchor) / interval⌉` —
200	  **no per-fire writes**. An **update restart re-reads `(anchor, interval)`
201	  and keeps deriving** (phase preserved, lands mid-grid). A **crash restart is
202	  a fresh start** (rewrite `anchor = now`; phase reset acceptable). The brain
203	  distinguishes update-vs-crash via the D3 spawn-time discriminator.
204	- **One-shot deadlines (alarms): rule fixed here, machinery deferred [V3].**
205	  Persist the absolute `target-time` at creation; every start (update *or*
206	  crash) reads it and fires-if-due; **never reset on crash** ("remind me at
207	  3pm" is a commitment). But the daemon has **no one-shot consumer today**
208	  (alarms are legacy-listener-only, §7) — building it now ships untested dead
209	  code. The *rule* is specified this milestone; the *machinery* is built with
210	  the alarm port (activate-don't-pre-fail). Tracked in DEFERRED.md
211	  ("Durable in-daemon alarm scheduler" row).
212
213	### D6 — Failure atomicity: readiness-gated auto-rollback · Q7, V1
214
215	A new brain that bricks *logic* (panics on boot) must self-heal without a
216	human — endpoints stay up (the broker holds them).
217
218	- **Bounded-retry → auto-rollback.** If the new brain fails to reach `ready`
219	  (re-attached all sessions + resumed loops) within a bounded number of boots
220	  / a healthy-run window, the broker **rolls back to the last-known-good
221	  binary** (`spt.exe.old-N`), **quarantines** the bad version (no auto
222	  re-apply/re-fetch), and surfaces a loud consent-style notification. The
223	  broker holds **both** last-known-good + candidate paths and chooses which
224	  to spawn (no file manipulation at failure time). **Reuse** the existing
225	  readiness+backoff machinery: `peerloop.rs:82-91`
226	  `SUPERVISE_BACKOFF_BASE/CAP` + `SUPERVISE_HEALTHY_RUN` (60 s healthy resets
227	  backoff), `supervise_pump` wired at `peerloop.rs:805` (M8-D4).
228	- **Two-phase applied record** (fixes a real existing bug): `applyhost.rs:176`
229	  writes `record_applied(version)` + `last-outcome=applied` **before** the
230	  handoff — the optimistic `applied.json={version:6}` observed on `enlyzeam`.
231	  Make it: `applied-pending` at swap → promoted to `applied` on the `ready`
232	  signal → corrected to `rolled-back(quarantine=N, running=N-1)` on failure.
233	- **[V1] Rollback-state-compat invariant.** Auto-rollback spawns the **old**
234	  binary against durable state the **new** brain may already have written.
235	  Safe today (2026-06-09 audit: zero state-migration code), but the first
236	  durable-state schema migration would silently break rollback. Assert the
237	  invariant **now, while free**: a brain must not irreversibly migrate durable
238	  state before ready-promotion — every pre-ready write stays N-1-readable.
239	  This task lands the invariant as an explicit, tested guard/marker (and a
240	  doc note in KNOWN-HAZARDS 6.8) so a future migration trips a known wire.
241
242	### D7 — Proof + REQ re-pointing + fleet verify · V5, V6, §9
243
244	The milestone's conformance close-out.
245
246	- **Productionize SPIKE-01/03 as an `int` E2E [V5]:** a PTY child + a live
247	  QUIC conn survive a brain-**process** restart **onto a swapped binary** —
248	  pid unchanged, output stream gapless, conn intact. This is the test that
249	  proves *process-level* survival (the spikes proved the shape with two
250	  binaries; this proves it in production topology).
251	- **Re-point the regression-masked evidence.** REQ-DAEMON-2 and REQ-UPD-3's
252	  current `int` tags prove only the *in-process* handoff shape
253	  (`applyhost.rs:39/77`, `update.rs:246`, `brain_swap.rs`, the M3b-B9 E2E) —
254	  mis-evidenced today. Move them to the D7 process-level E2E.
255	- **N-1 compat test as a CI gate [V6]:** the old-broker × new-brain
256	  verb-surface exercise scaffolded in D2 becomes a green gate.
257	- **Activate the minted hazards:** set real `required_stages` on
258	  `REQ-HAZARD-BROKER-PROCESS-ISOLATION` (doc=ADR-0018+design; impl/unit across
259	  D1–D6; int=the D7 E2E + N-1 test) and `REQ-HAZARD-ROLLBACK-STATE-COMPAT`
260	  (doc=ADR-0018+KH 6.8; impl/unit=D6 invariant guard).
261	- **Fleet verify** the real seamless update on the 3-node rig
262	  (kitsubito/hfenduleam/enlyzeam): publish a restoration+1 test release →
263	  `apply` on each node → **the running pid changes / new code goes live with
264	  no manual bounce**, every hosted endpoint survives. This is the acceptance
265	  the v0.3.2 roll could not get for free.
266
267	---
268
269	## Traceability — REQ activation schedule
270
271	| REQ | Today | This milestone | Activated at |
272	|-----|-------|----------------|--------------|
273	| `REQ-HAZARD-BROKER-PROCESS-ISOLATION` | minted, `required_stages=[]` | doc → impl → unit → int | doc now (ADR-0018+design exist); impl/unit across D1–D6; **int at D7** (process-level E2E + N-1 test) |
274	| `REQ-HAZARD-ROLLBACK-STATE-COMPAT` | minted, `required_stages=[]` | doc → impl → unit | doc now (ADR-0018+KH 6.8); **impl/unit at D6** (invariant guard) |
275	| `REQ-UPD-3` (no endpoint drop, brain-only) | `int` proves in-process shape (mis-evidenced) | re-point `int` to process-level survival | **D7** |
276	| `REQ-DAEMON-2` (broker/brain split for seamless update) | `int` proves in-process shape | re-point `int` to process-level survival | **D7** |
277
278	Rule 5 (activate-don't-pre-fail): toml `required_stages` are set at the
279	commit that delivers each stage's evidence, **not** now — `traceable-reqs
280	check` stays green at every commit. Re-pointing REQ-DAEMON-2/UPD-3 happens in
281	the same D7 commit that lands the replacement E2E (never leave them evidenced
282	by the old in-process test once the new test exists).
283
284	## Per-task gates (every commit)
285
286	`cargo build` · `cargo test` · `cargo clippy` · `cargo build
287	--no-default-features` · `traceable-reqs check` (EXIT=0) · `xtask check` (doc
288	drift). Push to a dev-freeform branch → **CI both runners** before any
289	release tag (the v0.3.0 lesson: CI catches regressions a local box can't —
290	single-home non-elevated dev box is blind to service-detection / socket-path
291	issues). The `[twohost]` rig rungs gate D7.
292
293	## Risks / watch-items
294
295	- **The hardest invariant** (de-risk spike #1): a PTY child + open socket
296	  survive a brain-process restart. The spikes proved it; D1 must re-prove it
297	  in production topology before logic moves (D3+). If D1's acceptance fails,
298	  stop — the whole design rests on it.
299	- **N-1 verb drift (KH-2.3).** Every verb added in D2 must default/additive;
300	  the D7 N-1 gate is the backstop. A breaking verb signature change is a
301	  broker-breaking update class — out of scope, must be refused, not silently
302	  shipped.
303	- **Test broker socket-bind flake** (DEFERRED, 2026-06-09): the AF_UNIX
304	  `served_broker` bind flakes on kitsubito. D1/D7 add real process-spawn
305	  tests on that runner — fix the bind determinism (unlink-before-bind /
306	  abstract namespace / per-test TempDir) opportunistically here rather than
307	  fighting flakes through the milestone.
308	- **Generation counter (KH-2.4):** custody moves to the broker (V2). Verify no
309	  consumer reads `gen_start_ms` as anything but observability (it already
310	  must not — `brain.rs:9-15`).
311
312	## Immediate next-session start
313
314	1. **D1 first** — add the `spt daemon brain` hidden entry + flip `spt daemon
315	   run` from `thread::spawn(broker.serve)` to broker-process + spawned brain
316	   child over the existing socket IPC. Prove the skeleton (broker survives
317	   brain kill, PTY child intact) **before** moving any logic.
318	2. Activate `REQ-HAZARD-BROKER-PROCESS-ISOLATION` doc stage (evidence already
319	   exists: ADR-0018 + design doc) in the D1 commit; impl/unit follow as D1
320	   lands real structure.
321	3. Keep `ensure_running`/`is_running`/`daemon stop` external behavior
322	   identical throughout — they're the single-instance contract the whole
323	   fleet depends on; only their *owner process* moves (thread → broker proc).
324	4. Do **not** convert the idempotent pump cadences (D5 [V4]) — only the pulse
325	   loop's phase-significant timing.
326

# Broker/Brain Process-Isolation Restoration — Milestone Build Plan

> **Status: RATIFIED (2026-06-09).** Design (`docs/BROKER-BRAIN-SPLIT-RESTORATION.md`,
> verified-with-amendments by `doyle`) and decision (`docs/adr/0018-...`) are
> operator-ratified; sequencing ratified as the **next** milestone, before
> `spt-claude-code`. REQs minted inactive (TRACEABILITY rule 3): this plan is
> the build, and schedules their activation per task (rule 5: activate at the
> commit that delivers the evidence). This is the **last** release that needs
> a manual fleet daemon bounce.

Goal: restore ADR-0004's intended **two-process** model so a routine
brain-only update hands off to the new executable seamlessly — no endpoint
or harness child dropped (REQ-UPD-3), loop timings continuous across the
swap, failures fail *safe*, uniform on Windows + Linux. The production daemon
today runs the broker as a background **thread** inside the single `spt
daemon` process (`daemon.rs:165-170`), so `apply` swaps the binary on disk
but never restarts the running code — the no-endpoint-drop self-update pillar
is silently unrealized. Restore it as a real process boundary.

This changes daemon **internals only** — the M8-frozen CLI/api surface is
untouched, so the adapter window stays open and `spt-claude-code` lands on
the final topology.

## Why now (sequencing — ratified)

1. **Queue open** — mesh shipped v0.3.0, M8 acceptance COMPLETE.
2. **Self-bootstrapping (decisive)** — until this ships, *every* release needs
   a manual fleet-wide daemon bounce (paid 3× on v0.3.2; `enlyzeam` ran 0.3.0
   with the 0.3.2 fix on disk for ~a day, still reproducing the `\r`-corruption).
   The restoration release is the last needing a manual bounce.
3. **Adapter window safe** — internals only; better the adapter lands on the
   final topology than atop a daemon under later open-heart surgery while it
   hosts the user's daily driver.

## What "done" looks like (goal-backward)

- `spt daemon run` is the **broker** process: binds seed-control + broker
  socket + NetHost + digest hub; holds PTY masters / harness children /
  `EffectJournal`; spawns the **brain** as a child and supervises it.
- A hidden `spt daemon brain` entry is the brain: connects to the broker over
  socket IPC, runs the logic loops, rehydrates from disk, emits `ready`.
- `spt update apply` swaps the binary, signals the brain to snapshot +
  self-exit, the broker respawns from the executable path (now the new
  binary), the new brain re-attaches **all** sessions in resume mode — and a
  live PTY child's pid is unchanged and its QUIC conn survives, at the
  **process** level. New code runs immediately, no logon/manual bounce.
- A new brain that fails to reach `ready` within the bounded window
  auto-rolls-back to `spt.exe.old-N`, quarantines the bad version, and fires a
  loud notif — endpoints alive throughout.
- `ensure_running` / `is_running` / `daemon stop` contracts unchanged (target
  the broker's seed channel); de-elevation guard applies at the broker entry.

---

## Task decomposition (dependency-ordered)

Each task maps to ADR-0018 decisions (Q2–Q8, amendments V1–V6) and lands as
its own atomic commit(s) with evidence tagged in-commit. Build order is the
dependency order: the process split is foundational; rollback + the proof
come last.

### D1 — Process split skeleton (foundation) · Q8, §5

The structural cut, proven minimal before any logic moves. **D1 is a *true*
minimal skeleton** (doyle vet 2026-06-09, finding 1): the brain child runs
ONLY the path that already speaks socket IPC; every direct-`Arc<Broker>`
consumer (pump `daemon.rs:280`, dispatcher, digest *parse*, net consumers,
psyche loops — design §2.2) **stays in the broker process** until D2 gives it
a verb. Those loops hold direct `Arc` calls, so they *cannot* run
cross-process before D2's verb conversion — moving them in D1 would wall the
implementing agent.

- Add the hidden **`spt daemon brain`** subcommand (brain process entry).
  `spt daemon run` stays the user-facing entry but becomes the **broker**
  process: it binds the seed-control channel + broker socket + NetHost +
  digest hub (as today), then **`Command::spawn`s the brain child**.
- **What runs where at D1-close (the falsifiability anchor):**
  - **Brain child:** ONLY `Brain::cold_start` (connect + IPC handshake over
    the existing socket) + session attach — the already-socket-speaking path.
    Emits a **`ready`** signal once attached. (`connect_retry`,
    `applyhost.rs`, is the reused brain-side connect primitive.)
  - **Broker process (temporarily):** pump, dispatcher, psyche loops, digest
    parse, net consumers — they still hold their `Arc<Broker>` and keep
    serving in-process exactly as today. D2 migrates them out one at a time.
- Broker ↔ brain talk over the **existing local socket IPC** (the versioned
  contract already carrying `SPAWN`/`INPUT`/`NET_*`/`SESSIONS`). No `exec`,
  no FD-passing → no Windows/Unix divergence (Q8).
- De-elevation guard (`daemon.rs:60-103`) stays at the **broker** entry; the
  brain child inherits the unelevated identity.
- **Acceptance (this IS de-risk spike #1 re-proven in production topology):**
  `spt daemon run` brings up a broker process + a distinct brain-child pid;
  killing the brain leaves the broker (and any PTY child) alive and the broker
  respawns it. "No behavior change visible at the CLI" is **falsifiable**
  precisely because D1 states which loops run where: the broker-resident loops
  still serve while the brain is the thin attach layer.

### D2 — IPC verb surface + N-1 compat scaffolding · Q5, V6

With two processes there is no shared `Arc<Broker>`; every brain→broker
direct call becomes a versioned IPC verb on the same contract. **D2 also
*relocates* the loops D1 left in the broker process** (pump/dispatch/psyche/
digest-parse/net-consumers) into the brain child — one per commit, as its
verb lands.

- **Migration ledger (loop → verb → moves-at-commit).** Each commit moves
  exactly ONE consumer: define its versioned verb, reroute the direct call
  over the socket, move the loop into the brain child, prove the N-1 window.
  Keep the ledger current in-plan so "which loop runs where" is answerable at
  every mid-migration commit. **D2-close invariant:** every logic loop runs in
  the brain; the broker holds only continuity resources + the verb server.
- **Audit** every current in-process `Arc<Broker>` consumer; convert each
  direct call to a versioned verb. Per §Q5:
  - **Net bring-up + REQ-DAEMON-9 self-heal retry → broker** — *near-free*:
    NetHost is already broker-owned (`broker.rs:175` `OnceLock`), and net
    bring-up already lives in the entry that *becomes* the broker entry.
  - **Digest hub → broker** (live projections + subscriber sockets); **the
    parse that feeds it → brain** (brain pushes parsed digests over IPC).
  - **Seed-lock + liveness → broker** (the Q2 anchor; see D3).
  - Every other brain→broker call → a versioned verb, defaulted/additive per
    KH-2.3 (handoff-argv-compat).
- **[V6] N-1 compat is milestone work.** Steady state after every routine
  update is **new-brain × old-broker** (broker almost never updates). The
  `classify` pre-swap handshake (`brain_ipc_version ≥ broker.min_compatible`)
  gates the forward direction, but each verb conversion must hold the N-1
  window. Build the **CI-real compat test** here: an **old-broker binary ×
  new-brain binary** exercise across the whole verb surface (else KH-2.3
  returns the first time a verb signature changes). Scaffold it in D2; it
  becomes a gate in D7.
- **Exception (Q5):** shellwake `wake_command` watcher **children stay
  brain-owned**, re-reconciled from disk on brain start (the boot sweep at
  `daemon.rs:206-217` already does orphan cleanup). Accepted: a rare brain
  update may briefly miss a wake for an offline shell.

### D3 — Supervision anchor + update trigger · Q2, Q3, V2

The broker becomes the always-up per-machine anchor and the brain's supervisor.

- **Seed-control lock + liveness move to the broker** (Q2): the
  single-daemon-per-`SPT_HOME` invariant and the `ensure_running`/`is_running`
  ping target live in the never-restarting layer, so a brain restart can't let
  a second daemon win the bind or make `is_running` flap. `ensure_running` /
  `is_running` / `daemon stop` external contracts are **unchanged** — they
  target the broker's seed channel (which is where they already point).
- **Broker supervises + respawns the brain** as its child (the crash-recovery
  path it must already provide).
- **Update trigger (Q3):** `apply` verifies + swaps the binary on disk, then
  signals the brain to **snapshot + self-exit**. The broker observes the exit
  and **respawns from the executable path (now the new binary)**; the new
  brain re-attaches. This reuses the existing `apply_brain_only` snapshot→drop→
  re-attach primitive — an update is a *planned* crash on the path the broker
  already recovers from. (`update.rs:233-234`'s "exec the new binary's brain"
  finally becomes real, via respawn rather than exec.)
- **[V2] Generation custody → broker** (Q2): retiring the `BrainState`
  message (D4) would orphan the KH-2.4 generation counter. The broker owns it,
  increments on **every** brain spawn (planned or crash), and hands
  `{generation, start-reason}` to the brain at spawn time via a **versioned
  argv/hello field** (KH-2.3 forward-compat, defaulted). Because the broker
  observes every respawn this is strictly more reliable than brain→brain.
- The **same spawn-time channel carries Q4's update-vs-crash discriminator**
  (one channel, both payloads): the broker *initiated* a planned cycle but
  *observed* an unexpected crash.

### D4 — Multi-session resume; retire the `BrainState` message · Q6

Under the self-exit trigger the outgoing brain is gone before the new one
starts, so continuity must come from the persistent side, not a brain→brain
frame.

- The **broker becomes cursor-of-record** per session-subscriber (it already
  holds the per-session output ring, `broker.rs:73-143`): track each
  subscriber's last-**delivered** cursor.
- On (re)start the new brain queries the broker for **all** hosted sessions
  and re-attaches each in **resume** mode — fixing today's two gaps:
  `applyhost.rs:239` re-attaches only `sessions.first()` (one session) with
  `from_seq=0` (re-replays the whole ring → duplicate output).
- **Output is at-least-once** (broker resumes from last-*sent*); **input/
  effects stay exactly-once** via the already-broker-owned `EffectJournal`.
  Matches the SPIKE-05 terminal-stream contract (a resize repaint already
  reorders/duplicates the stream; exactly-once output would need a per-chunk
  ack for a guarantee the stream doesn't make).
- The explicit **`BrainState` handoff *message* retires** for production: the
  new brain cold-starts and reconstructs continuity by querying the broker.
  (`brain.rs` `BrainState`/`handoff` stay available for tests; the production
  path stops passing the frame.)

### D5 — Durable absolute-deadline loop timing · Q4, V3, V4

Timing that must survive a swap lives as durable absolute-deadline state on
disk, rehydrated on every brain start — not in the (planned-only) handoff
snapshot, which a crash carries nothing of.

- **Phase-significant resident loops only [V4].** The **pulse loop**
  (`lifecycle.rs:486` `sleep_interruptible(pulse_period)`, phase-relative →
  resets on restart) converts to a disk-anchored deadline. The **idempotent
  pump cadences need NO conversion** — they already "stagger from everything
  due now" (`peerloop.rs:304`), catch-up/idempotent, restart-safe; converting
  them would reintroduce the per-loop writes Q4 minimized.
- **Mechanism:** persist `(anchor, interval)` **once** on a fresh/crash start;
  derive `next_fire = anchor + interval × ⌈max(0, now − anchor) / interval⌉` —
  **no per-fire writes**. An **update restart re-reads `(anchor, interval)`
  and keeps deriving** (phase preserved, lands mid-grid). A **crash restart is
  a fresh start** (rewrite `anchor = now`; phase reset acceptable). The brain
  distinguishes update-vs-crash via the D3 spawn-time discriminator.
- **One-shot deadlines (alarms): rule fixed here, machinery deferred [V3].**
  Persist the absolute `target-time` at creation; every start (update *or*
  crash) reads it and fires-if-due; **never reset on crash** ("remind me at
  3pm" is a commitment). But the daemon has **no one-shot consumer today**
  (alarms are legacy-listener-only, §7) — building it now ships untested dead
  code. The *rule* is specified this milestone; the *machinery* is built with
  the alarm port (activate-don't-pre-fail). Tracked in DEFERRED.md
  ("Durable in-daemon alarm scheduler" row).

### D6 — Failure atomicity: readiness-gated auto-rollback · Q7, V1

A new brain that bricks *logic* (panics on boot) must self-heal without a
human — endpoints stay up (the broker holds them).

- **Bounded-retry → auto-rollback.** If the new brain fails to reach `ready`
  (re-attached all sessions + resumed loops) within a bounded number of boots
  / a healthy-run window, the broker **rolls back to the last-known-good
  binary** (`spt.exe.old-N`), **quarantines** the bad version (no auto
  re-apply/re-fetch), and surfaces a loud consent-style notification. The
  broker holds **both** last-known-good + candidate paths and chooses which
  to spawn (no file manipulation at failure time). **Reuse** the existing
  readiness+backoff machinery: `peerloop.rs:82-91`
  `SUPERVISE_BACKOFF_BASE/CAP` + `SUPERVISE_HEALTHY_RUN` (60 s healthy resets
  backoff), `supervise_pump` wired at `peerloop.rs:805` (M8-D4).
- **Two-phase applied record** (fixes a real existing bug): `applyhost.rs:176`
  writes `record_applied(version)` + `last-outcome=applied` **before** the
  handoff — the optimistic `applied.json={version:6}` observed on `enlyzeam`.
  Make it: `applied-pending` at swap → promoted to `applied` on the `ready`
  signal → corrected to `rolled-back(quarantine=N, running=N-1)` on failure.
- **[V1] Rollback-state-compat invariant.** Auto-rollback spawns the **old**
  binary against durable state the **new** brain may already have written.
  Safe today (2026-06-09 audit: zero state-migration code), but the first
  durable-state schema migration would silently break rollback. Assert the
  invariant **now, while free**: a brain must not irreversibly migrate durable
  state before ready-promotion — every pre-ready write stays N-1-readable.
  This task lands the invariant as an explicit, tested guard/marker (and a
  doc note in KNOWN-HAZARDS 6.8) so a future migration trips a known wire.

### D7 — Proof + REQ re-pointing + fleet verify · V5, V6, §9

The milestone's conformance close-out.

- **Productionize SPIKE-01/03 as an `int` E2E [V5]:** a PTY child + a live
  QUIC conn survive a brain-**process** restart **onto a swapped binary** —
  pid unchanged, output stream gapless, conn intact. This is the test that
  proves *process-level* survival (the spikes proved the shape with two
  binaries; this proves it in production topology).
- **Re-point the regression-masked evidence.** REQ-DAEMON-2 and REQ-UPD-3's
  current `int` tags prove only the *in-process* handoff shape
  (`applyhost.rs:39/77`, `update.rs:246`, `brain_swap.rs`, the M3b-B9 E2E) —
  mis-evidenced today. Move them to the D7 process-level E2E.
- **N-1 compat test as a CI gate [V6]:** the old-broker × new-brain
  verb-surface exercise scaffolded in D2 becomes a green gate.
- **Activate the minted hazards:** set real `required_stages` on
  `REQ-HAZARD-BROKER-PROCESS-ISOLATION` (doc=ADR-0018+design; impl/unit across
  D1–D6; int=the D7 E2E + N-1 test) and `REQ-HAZARD-ROLLBACK-STATE-COMPAT`
  (doc=ADR-0018+KH 6.8; impl/unit=D6 invariant guard).
- **Fleet verify** the real seamless update on the 3-node rig
  (kitsubito/hfenduleam/enlyzeam): publish a restoration+1 test release →
  `apply` on each node → **the running pid changes / new code goes live with
  no manual bounce**, every hosted endpoint survives. This is the acceptance
  the v0.3.2 roll could not get for free.

---

## Traceability — REQ activation schedule

| REQ | Today | This milestone | Activated at |
|-----|-------|----------------|--------------|
| `REQ-HAZARD-BROKER-PROCESS-ISOLATION` | minted, `required_stages=[]` | doc → impl → unit → int | doc now (ADR-0018+design exist); impl/unit across D1–D6; **int at D7** (process-level E2E + N-1 test) |
| `REQ-HAZARD-ROLLBACK-STATE-COMPAT` | minted, `required_stages=[]` | doc → impl → unit | doc now (ADR-0018+KH 6.8); **impl/unit at D6** (invariant guard) |
| `REQ-UPD-3` (no endpoint drop, brain-only) | `int` proves in-process shape (mis-evidenced) | re-point `int` to process-level survival | **D7** |
| `REQ-DAEMON-2` (broker/brain split for seamless update) | `int` proves in-process shape | re-point `int` to process-level survival | **D7** |

Rule 5 (activate-don't-pre-fail): toml `required_stages` are set at the
commit that delivers each stage's evidence, **not** now — `traceable-reqs
check` stays green at every commit. Re-pointing REQ-DAEMON-2/UPD-3 happens in
the same D7 commit that lands the replacement E2E (never leave them evidenced
by the old in-process test once the new test exists).

## Per-task gates (every commit)

`cargo build` · `cargo test` · `cargo clippy` · `cargo build
--no-default-features` · `traceable-reqs check` (EXIT=0) · `xtask check` (doc
drift). Push to a dev-freeform branch → **CI both runners** before any
release tag (the v0.3.0 lesson: CI catches regressions a local box can't —
single-home non-elevated dev box is blind to service-detection / socket-path
issues). The `[twohost]` rig rungs gate D7.

## Risks / watch-items

- **The hardest invariant** (de-risk spike #1): a PTY child + open socket
  survive a brain-process restart. The spikes proved it; D1 must re-prove it
  in production topology before logic moves (D3+). If D1's acceptance fails,
  stop — the whole design rests on it.
- **N-1 verb drift (KH-2.3).** Every verb added in D2 must default/additive;
  the D7 N-1 gate is the backstop. A breaking verb signature change is a
  broker-breaking update class — out of scope, must be refused, not silently
  shipped.
- **Test broker socket-bind flake** (DEFERRED, 2026-06-09): the AF_UNIX
  `served_broker` bind flakes on kitsubito. D1/D7 add real process-spawn
  tests on that runner — fix the bind determinism (unlink-before-bind /
  abstract namespace / per-test TempDir) opportunistically here rather than
  fighting flakes through the milestone.
- **Generation counter (KH-2.4):** custody moves to the broker (V2). Verify no
  consumer reads `gen_start_ms` as anything but observability (it already
  must not — `brain.rs:9-15`).

## Immediate next-session start

1. **D1 first** — add the `spt daemon brain` hidden entry + flip `spt daemon
   run` from `thread::spawn(broker.serve)` to broker-process + spawned brain
   child over the existing socket IPC. Prove the skeleton (broker survives
   brain kill, PTY child intact) **before** moving any logic.
2. Activate `REQ-HAZARD-BROKER-PROCESS-ISOLATION` doc stage (evidence already
   exists: ADR-0018 + design doc) in the D1 commit; impl/unit follow as D1
   lands real structure.
3. Keep `ensure_running`/`is_running`/`daemon stop` external behavior
   identical throughout — they're the single-instance contract the whole
   fleet depends on; only their *owner process* moves (thread → broker proc).
4. Do **not** convert the idempotent pump cadences (D5 [V4]) — only the pulse
   loop's phase-significant timing.


D1 done. D2 next — IPC verb surface + migrate loops one-per-commit. Let me read D1 skeleton + target files.


D1 commit changed files


commit 0c954353b256f46e45a600be7a7fb1f3768e9d30
Author: Reavo End <decidel@gmail.com>
Date:   Tue Jun 9 18:30:21 2026 -0700

    feat(daemon): restoration D1 — broker/brain process-split skeleton (REQ-HAZARD-BROKER-PROCESS-ISOLATION)

    First task of the ADR-0018 broker/brain process-isolation restoration. Restores
    the process boundary ADR-0004 specced (and the spikes proved) but production
    drifted off: today `spt daemon run` hosts the broker as an in-process thread, so
    `spt update apply` swaps the binary on disk yet never restarts the running code.

    D1 is a TRUE minimal skeleton (doyle vet finding 1): only the process boundary
    moves; NO logic relocates. `spt daemon run` becomes the broker process and
    spawns a supervised `spt daemon brain` child. The child connects over the
    EXISTING broker socket IPC, signals ready, and idles. Every existing loop (net
    consumers, digest hub, shellwake, seed control) stays in the broker process —
    D2 migrates each to a versioned verb loop-by-loop.

    Code reality: there is no resident brain process today; `Brain` (brain.rs) is a
    per-consumer client type. The "brain child" here is a genuine no-op placeholder
    whose only job is to prove broker-spawns-supervised-child-over-socket survives a
    child kill — exactly de-risk spike #1 (the design's hardest invariant).

    Changes:
    - brainproc.rs (new): `run_brain()` child entry (connect + ready breadcrumb +
      idle heartbeat that probes broker liveness, exits on broker loss for a
      supervised respawn); `supervise_brain()` — process-level mirror of
      peerloop::supervise_pump (spawn → wait → respawn with capped doubling
      backoff, healthy-run reset); `spawn_brain_supervisor()` re-execs
      `current_exe daemon brain` as a plain managed child (inherits SPT_HOME; NOT
      spawn_detached).
    - daemon.rs: `Daemon::run()` spawns the brain supervisor before the foreground
      seed-control loop; `Daemon::run_brain()` delegates to brainproc.
    - endpoint.rs: `brain_ready_path()` (the D1 ready signal; D6 generalizes it).
    - cli.rs: hidden `daemon brain` subcommand → `cmd_daemon_brain()`.

    Tests (de-risk proof):
    - brainproc unit: supervisor respawns the brain on every exit + stops cleanly;
      backoff doubling/cap/healthy-reset table.
    - crates/spt/tests/brain_split.rs: process-level smoke against the REAL


No files found


find . -path ./target -prune -o -name "*.rs" -print 2>/dev/null | grep -iE "daemon|broker|brain|peerloop|applyhost|update" | head -50

Find daemon source files