- 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.
- 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 remote agents (routines) that execute on a cron schedule. - When the user wants to schedule a recurring remote 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: Build, debug, and optimize Claude API / Anthropic SDK apps. Apps built with this skill should include prompt caching. Also handles migrating existing Claude API code between Claude model versions (4.5 → 4.6, 4.6 → 4.7, retired-model replacements).
TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`; user asks for the Claude API, Anthropic SDK, or Managed Agents; user adds/modifies/tunes a Claude feature (caching, thinking, compaction, tool use, batch, files, citations, memory) or model (Opus/Sonnet/Haiku) in a file; questions about prompt caching / cache hit rate in an Anthropic SDK project.
SKIP: file imports `openai`/other-provider SDK, filename like `*-openai.py`/`*-generic.py`, provider-neutral code, general programming/ML.
- 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 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.


Design spt-core binary and messaging library architecture


13a/b/c locked. Capturing crate layering + writing the promised KNOWN-HAZARDS harvest.


Edit

## Workspace & versioning

The crate-boundary design is the rebuild's main value (ADR-0001) — honest decoupling that prevents the sister project's tangle from re-forming. Principle: **many small, acyclically-layered crates** (not a few fat ones).

Layering (bottom → top): `spt-proto` (wire envelope grammar, endpoint types, message framing, Ed25519 identity types, typed+binary payload schema — pure types, no I/O) → `spt-store` (spool, perch layout, trust store, registry persistence) → `spt-msg` (delivery TCP+spool-fallback, routing, send/ring) → `spt-net` (Iroh, mDNS, SPAKE2/TOTP pairing, subnet-registry distribution; `net` feature-flagged) and `spt-term` (session-surface trait, PTY impl, broker) and `spt-runtime` (`AgentRuntime` trait, `ManifestRuntime`, manifest schema) → `spt-live` (Psyche/pulse/commune/signoff) → `spt-daemon` (the brain: ties all, hosts broker, update orchestration, instance registry) → `spt` (the `spt.exe` binary; thin CLI).

**public SDK surface** (semver-committed): `spt-proto` (the wire contract — anyone speaking SPT depends on it), `spt-runtime` (the trait third-party harnesses implement), `spt-msg` (the deeper messaging-integration path). Everything else (`spt-store`, `spt-net`, `spt-term`, `spt-live`, `spt-daemon`) is internal/unstable pre-1.0 — reachable, but no stability promise. The *integration* crates are stable; the *machinery* churns.

**wire-protocol version vs crate semver** (orthogonal, never conflated): `spt-proto` carries an explicit **wire-protocol version** independent of crate semver. Two nodes — or a node and a linked library consumer — interoperate iff their proto versions are compatible, with a documented **N-1 compat window**. Crate semver governs *API* stability; proto version governs *wire* stability.

## Pairing & trust


The file C:\Users\decid\Documents\projects\spt-core\CONTEXT.md has been updated successfully. (file state is current in your context — no need to Read it back)

## Workspace & versioning

The crate-boundary design is the rebuild's main value (ADR-0001) — honest decoupling that prevents the sister project's tangle from re-forming. Principle: **many small, acyclically-layered crates** (not a few fat ones).

Layering (bottom → top): `spt-proto` (wire envelope grammar, endpoint types, message framing, Ed25519 identity types, typed+binary payload schema — pure types, no I/O) → `spt-store` (spool, perch layout, trust store, registry persistence) → `spt-msg` (delivery TCP+spool-fallback, routing, send/ring) → `spt-net` (Iroh, mDNS, SPAKE2/TOTP pairing, subnet-registry distribution; `net` feature-flagged) and `spt-term` (session-surface trait, PTY impl, broker) and `spt-runtime` (`AgentRuntime` trait, `ManifestRuntime`, manifest schema) → `spt-live` (Psyche/pulse/commune/signoff) → `spt-daemon` (the brain: ties all, hosts broker, update orchestration, instance registry) → `spt` (the `spt.exe` binary; thin CLI).

**public SDK surface** (semver-committed): `spt-proto` (the wire contract — anyone speaking SPT depends on it), `spt-runtime` (the trait third-party harnesses implement), `spt-msg` (the deeper messaging-integration path). Everything else (`spt-store`, `spt-net`, `spt-term`, `spt-live`, `spt-daemon`) is internal/unstable pre-1.0 — reachable, but no stability promise. The *integration* crates are stable; the *machinery* churns.

**wire-protocol version vs crate semver** (orthogonal, never conflated): `spt-proto` carries an explicit **wire-protocol version** independent of crate semver. Two nodes — or a node and a linked library consumer — interoperate iff their proto versions are compatible, with a documented **N-1 compat window**. Crate semver governs *API* stability; proto version governs *wire* stability.

## Pairing & trust

- **Seam-compatible but deferred:** instantiate-anywhere + its consent gate; remote command execution + its security gate (workarounds: remote agent messages a local agent, or user interacts with a local agent directly).

- **Rationale:** the data-model split and registry are foundations — deferring them forces a later rewrite, so they are in regardless. Remote-drive of a running instance is the highest-value slice and exercises the whole networking+daemon stack end-to-end. Instantiate-anywhere and remote-exec carry consent/security design that should not gate v1.

+The crate-boundary design is the rebuild's main value (ADR-0001) — honest decoupling that prevents the sister project's tangle from re-forming. Principle: **many small, acyclically-layered crates** (not a few fat ones).

+Layering (bottom → top): `spt-proto` (wire envelope grammar, endpoint types, message framing, Ed25519 identity types, typed+binary payload schema — pure types, no I/O) → `spt-store` (spool, perch layout, trust store, registry persistence) → `spt-msg` (delivery TCP+spool-fallback, routing, send/ring) → `spt-net` (Iroh, mDNS, SPAKE2/TOTP pairing, subnet-registry distribution; `net` feature-flagged) and `spt-term` (session-surface trait, PTY impl, broker) and `spt-runtime` (`AgentRuntime` trait, `ManifestRuntime`, manifest schema) → `spt-live` (Psyche/pulse/commune/signoff) → `spt-daemon` (the brain: ties all, hosts broker, update orchestration, instance registry) → `spt` (the `spt.exe` binary; thin CLI).

+**public SDK surface** (semver-committed): `spt-proto` (the wire contract — anyone speaking SPT depends on it), `spt-runtime` (the trait third-party harnesses implement), `spt-msg` (the deeper messaging-integration path). Everything else (`spt-store`, `spt-net`, `spt-term`, `spt-live`, `spt-daemon`) is internal/unstable pre-1.0 — reachable, but no stability promise. The *integration* crates are stable; the *machinery* churns.

+**wire-protocol version vs crate semver** (orthogonal, never conflated): `spt-proto` carries an explicit **wire-protocol version** independent of crate semver. Two nodes — or a node and a linked library consumer — interoperate iff their proto versions are compatible, with a documented **N-1 compat window**. Crate semver governs *API* stability; proto version governs *wire* stability.

How a single user's own nodes come to trust each other and form one subnet. Cross-subnet (two *different* users) is explicitly deferred (the sister project's "cross-subnet contract" — very-early future concept).


Crate layering locked. Now the promised `KNOWN-HAZARDS.md` (ADR-0001 mitigation) needs harvesting from the sister project's hard-won edge cases — launching that as a background agent while we converge.


Agent

Harvest hazards from sister project

Prompt:
Explore the sister project at C:\Users\decid\Documents\projects\claude_skill_owl (a Rust workspace — modern "SPT" / owl, an inter-agent messaging + live-agent-lifecycle tool for Claude Code). I am rebuilding it clean-room as `spt-core` and need to harvest its hard-won edge cases and invariants so the rebuild doesn't re-discover the same bugs.

Search thoroughly across: src/ (especially src/owl/, src/live/, src/common/), tests/, CONTEXT.md, CHANGELOG.md, psyche.md, AGENTS.md, and any docs/ or .planning/ material. Look specifically for:

1. **Race conditions / ordering hazards** — perch teardown ordering, listener re-arm timing, poll-loop vs spool-drain races, SubagentStart/Stop hook ordering, working-perch lifecycle.
2. **Identity / session-binding edge cases** — parent_pid matching, pid reuse, session_id rotation on /clear, binary-handoff state migration (wrapper-state.json), orphan detection + grace-period false positives.
3. **Lifecycle hazards** — ephemeral perch lifetime in `ring`, stale-perch fallback, generation counter semantics, orphan teardown, Psyche wrapper crash/recovery.
4. **Wire/transport gotchas** — TCP registry staleness, spool fallback correctness, inbox legacy compat, EVENT envelope parsing (br-split, HTML-unescape ordering, & last), message duplication (e.g. duplicated Pending Commune sections).
5. **Platform-specific** — Windows-specific issues, path/handle quirks, git-timeout stamping, EBUSY rename bugs.
6. Anything documented in CHANGELOG as "fixed in post" / regression / hotfix that reveals a non-obvious invariant.

For EACH hazard found, return: a short title, the failure mode (what breaks), the invariant that must hold to prevent it, and a file:line citation. Group by the 6 categories above. Be concrete — cite actual code/comments/changelog entries, not generic advice. This becomes a test checklist for the rebuild, so precision matters. Return a structured markdown report; do not write any files.


<owl_reachability_notice>
You have an active owl perch. Launch this Agent with run_in_background: true so you stay reachable for incoming messages while it works.
</owl_reachability_notice>


Async agent launched successfully.
agentId: a40234fdb18f4d243 (internal ID - do not mention to user. Use SendMessage with to: 'a40234fdb18f4d243' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\b494f5e6-5b4d-4145-aaaa-5585e1168377\tasks\a40234fdb18f4d243.output
Do NOT Read or tail this file via the shell tool — it is the full sub-agent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Harvest hazards from sister project

Prompt:
Explore the sister project at C:\Users\decid\Documents\projects\claude_skill_owl (a Rust workspace — modern "SPT" / owl, an inter-agent messaging + live-agent-lifecycle tool for Claude Code). I am rebuilding it clean-room as `spt-core` and need to harvest its hard-won edge cases and invariants so the rebuild doesn't re-discover the same bugs.

Search thoroughly across: src/ (especially src/owl/, src/live/, src/common/), tests/, CONTEXT.md, CHANGELOG.md, psyche.md, AGENTS.md, and any docs/ or .planning/ material. Look specifically for:

1. **Race conditions / ordering hazards** — perch teardown ordering, listener re-arm timing, poll-loop vs spool-drain races, SubagentStart/Stop hook ordering, working-perch lifecycle.
2. **Identity / session-binding edge cases** — parent_pid matching, pid reuse, session_id rotation on /clear, binary-handoff state migration (wrapper-state.json), orphan detection + grace-period false positives.
3. **Lifecycle hazards** — ephemeral perch lifetime in `ring`, stale-perch fallback, generation counter semantics, orphan teardown, Psyche wrapper crash/recovery.
4. **Wire/transport gotchas** — TCP registry staleness, spool fallback correctness, inbox legacy compat, EVENT envelope parsing (br-split, HTML-unescape ordering, & last), message duplication (e.g. duplicated Pending Commune sections).
5. **Platform-specific** — Windows-specific issues, path/handle quirks, git-timeout stamping, EBUSY rename bugs.
6. Anything documented in CHANGELOG as "fixed in post" / regression / hotfix that reveals a non-obvious invariant.

For EACH hazard found, return: a short title, the failure mode (what breaks), the invariant that must hold to prevent it, and a file:line citation. Group by the 6 categories above. Be concrete — cite actual code/comments/changelog entries, not generic advice. This becomes a test checklist for the rebuild, so precision matters. Return a structured markdown report; do not write any files.


Hazard harvest running in background (will fold into `KNOWN-HAZARDS.md` on return).

**Decision tree status — 13 forks resolved, 5 ADRs written:**

CONTEXT.md fully seeded. ADRs: 0001 clean-room fork · 0002 bake networking / collapse spt-node · 0003 multi-instance node-anchored · 0004 broker/brain daemon + self-update · 0005 TOTP-seeded SPAKE2 pairing. DEFERRED.md tracking 9 parked features.

Before I assemble the PRD, three quick convergence checks:

**1. Platform scope.** You said Windows + Linux. **macOS day-one — in or out?** Recommend **out for v1, kept easy** — `portable-pty` + Iroh both support macOS, so nothing structural blocks it; just don't spend v1 test/CI budget there. Confirm out?

**2. Storage/state layout** (SPT_HOME paths, on-disk perch/instance/spool directory structure). The sister project carried real flat→nested migration debt here. Recommend **defer the exact layout to the design phase** — it's an implementation concern, not a product fork, and a clean greenfield pick is low-risk. The only PRD-level commitment: `node.key` + trust store + spools + tracked-psyche-context all under one per-machine SPT_HOME root, platform-native base (`%LOCALAPPDATA%\spt` / `~/.spt`). OK to defer specifics?

**3. Anything else on your mind** — endpoint types, capabilities, UX, constraints — that the 13 forks didn't touch and should be in the PRD before I write it?


<task-notification>
<task-id>a40234fdb18f4d243</task-id>
<tool-use-id>toolu_01FsedLTQm5eGaHttC3HmCfx</tool-use-id>
<output-file>C:\Users\decid\AppData\Local\Temp\claude\C--Users-decid-Documents-projects-spt-core\b494f5e6-5b4d-4145-aaaa-5585e1168377\tasks\a40234fdb18f4d243.output</output-file>
<status>completed</status>
<summary>Agent "Harvest hazards from sister project" completed</summary>
<result>Now I have enough information. Let me compile the final report:

## Edge Cases and Invariants Harvested from claude_skill_owl

Based on my thorough exploration of the claude_skill_owl codebase, CHANGELOG, psyche.md, and test suite, here are the critical edge cases, race conditions, and invariants that must be preserved in the spt-core rebuild:

---

### 1. RACE CONDITIONS & ORDERING HAZARDS

#### 1.1 Phantom INIT_SIGNOFF After Grace Period Completes
**File:** `src/live/wrapper/orphan.rs:201-259`
**Failure Mode:** Orphan detection delivers INIT_SIGNOFF to psyche spool before grace-period recheck, and a transient Self recovery (binary handoff, brief stale poll) causes the grace recheck to fail. The INIT_SIGNOFF was already enqueued, so the next poll_psyche iteration drains it and tears down despite Self being alive.
**Invariant:** Grace-period sleep (5s) MUST complete BEFORE compose/deliver INIT_SIGNOFF in source order. Re-check must bind to `still_gone` BEFORE any envelope write.
**Citation:** Lines 209 (`thread::sleep`) must precede 231-251 (compose/deliver). Tests T-grace-recovery (line 576) + T-still-gone-recheck (line 618) pin the ordering via `include_str!` byte-index assertions.

#### 1.2 Poll-Rewrite Race and Windows PID Recycling False Positives
**File:** `src/common/list_filter.rs:100-150`; `src/owl/poll.rs:141`
**Failure Mode:** On Windows, a live psyche perch's info.json carries a recently-released PID (recycled by OS), and the orphan-classification logic matches it against an unrelated process. Poll-rewrite races exacerbate this: info.json is being written by the wrapper mid-iteration while list command reads it.
**Invariant:** Orphan detection must consult wrapper liveness via `is_wrapper_alive(self_id)` BEFORE any grace-period gate. Grace window must be ≥60 seconds (Phase 35 D-11). Wrapper-owned psyche polls (psyche=true && parent.is_some()) must bypass DUPLICATE listener guard.
**Citation:** CHANGELOG v1.11.20 / v1.35.x; `is_wrapper_alive` at `src/common/owlery.rs`; guard at `src/owl/poll.rs:140`.

#### 1.3 Stale-Lock Index Wedge from Prior Git Crash
**File:** `src/live/wrapper/mod.rs` (Psyche wrapper lifecycle); CHANGELOG v1.11.20 "Stale `index.lock`"
**Failure Mode:** Crashed git process leaves 0-byte `git/index.lock` in psyche tracked worktree. Every subsequent `git commit` for that agent blocks on the lock forever.
**Invariant:** On every `$LIVE` boot, scan seed + all agent/project worktrees for stale locks (0 bytes, mtime > 60s) and remove them. Live `git` processes (non-zero or sub-60s mtime) are left alone.
**Citation:** CHANGELOG line 143; `src/common/git.rs` stale-lock probe logic.

#### 1.4 Spool Drain Ordering: Deferred Rows Must Not Leak to Monitor Stream
**File:** `src/owl/poll.rs:276-316`; CHANGELOG v1.11.20 (deferred-skipped variants)
**Failure Mode:** SubagentStart hook sends WORKING_PERCH_NOTICE via `deliver_body_deferred` (spool-only, no TCP wake). Poll startup calls `drain_all` and flushes ALL rows including deferred. Monitor stream emits at wrong priority, Parent agent receives notice too early.
**Invariant:** At startup drain (and 5-min timeout, idle-mode TCP-wake sites), use `drain_non_deferred_with_metadata` ONLY. Three spool-drain sites must skip deferred rows. Deferred rows are picked up by independent hook consumers via `peek_all`.
**Citation:** `src/owl/poll.rs` lines 280, 234, and two timeout sites; `spool::drain_non_deferred_with_metadata` in `src/common/spool.rs`.

#### 1.5 SubagentStart/Stop Hook Ordering: Working Perch Lifecycle
**File:** `src/owl/hook_subagent_start.rs:122-168`; `src/owl/hook_subagent_stop.rs:15-55`
**Failure Mode:** SubagentStart creates working perch at nested path but hook code reads it from flat path on later hooks. SubagentStop scans owlery with old path resolver and misses nested-layout working perches.
**Invariant:** Perch path composition MUST route through `owlery::nested_perch_dir(parent, child_id)` for ALL working/psyche child perches. Phase 25 D-01 nested layout is mandatory; no flat siblings. Counter file `.working-counter` remains at parent Self perch (unchanged from pre-Phase-25).
**Citation:** `src/owl/hook_subagent_start.rs:137` (nested_perch_dir), lines 181-226 test assertions; `src/owl/hook_subagent_stop.rs:35` (enumerate_perches walks both layers).

---

### 2. IDENTITY & SESSION-BINDING EDGE CASES

#### 2.1 Parent PID vs Poll PID for Orphan Detection
**File:** `src/live/wrapper/orphan.rs:141-161`, `src/common/types.rs`
**Failure Mode:** Orphan detection polls PID from info.json and checks liveness. Poll process PID dies and is recycled on Windows. New foreign process with recycled PID is checked alive; false positive orphan teardown.
**Invariant:** Always prefer `parent_pid` (Claude Code session PID) over poll PID. Poll listeners are ephemeral and recycled; parent CC session is the stable anchor. Fallback to poll PID only if parent_pid is absent. Wrapper-owned psyche perches write minimal info.json ({"pid": int} only) to avoid stale session_id leaks and PID-recycling false positives.
**Citation:** `src/live/wrapper/orphan.rs:148-158`; `types::get_parent_pid_from_info` first, then `get_pid_from_info` fallback. CHANGELOG v1.11.20 "Live psyche poll stability fix".

#### 2.2 Session ID Rotation on /clear
**File:** `src/owl/hook_subagent_start.rs:40-51` (OWL_SESSION_ID precedence)
**Failure Mode:** Subagent inherits stale OWL_SESSION_ID env var from prior CC session (across /clear). Hook spawned in child session receives contradictory session_id: one from stdin (fresh), one from env (stale). Parent ID lookup fails or matches wrong agent.
**Invariant:** Stdin-provided session_id MUST take precedence over OWL_SESSION_ID env var. Env is fallback only when stdin omits the field. Session binding via `find_perch_by_session` resolves to parent_pid fallback.
**Citation:** CHANGELOG v1.35.1 "IN-05 reverse `OWL_SESSION_ID` precedence"; lines 41-45 stdin > env logic in `hook_subagent_start.rs`.

#### 2.3 Binary Handoff State File Recovery and Generation Semantics
**File:** `src/live/wrapper/lifecycle.rs:17-106`; `src/common/wrapper_state.rs`
**Failure Mode:** Old binary (v1.11.8) wraps with 4-arg argv to new binary (v1.11.9). New binary expects 5+ args (added `pulse_psyche`). Clap rejects argv before state-file rehydration is reached; wrapper dies unlogged.
**Invariant:** Handoff argv schema MUST have default values for any newly-added positionals. State-file rehydration happens AFTER argv parse; defaults must survive intermediate versions. Generation counter increments on fresh start; handoff rehydration preserves prior gen. `gen_start` (wall-clock SystemTime) is ALWAYS set to `now()` on both cold-start and handoff to avoid stale-file discriminators firing on the new process.
**Citation:** `src/live/wrapper/lifecycle.rs:70` (`gen_start = SystemTime::now()`); `src/cli.rs` `#[arg(default_value = "0")]` on new positionals; CHANGELOG v1.11.10 handoff backward-compat fix.

#### 2.4 Orphan Grace Period False Positives During Handoff
**File:** `src/common/list_filter.rs:137-150` (grace window)
**Failure Mode:** Binary handoff makes Self briefly unreachable (child process replacing parent). Wrapper's orphan-check happens during the blackout and incorrectly classifies Self as gone.
**Invariant:** Orphan grace period MUST be ≥60 seconds to survive binary handoff windows. `phase35_list_orphan_grace_secs()` returns the grace constant; mtime check: if dir mtime is within grace, assume alive (not orphan).
**Citation:** CHANGELOG v1.11.20 Phase 35.1 "60-second mtime grace"; `src/common/list_filter.rs:168-175`.

---

### 3. LIFECYCLE HAZARDS

#### 3.1 Ephemeral Perch Cleanup on Ring Command Exit Paths
**File:** `src/owl/ring.rs:58-143` (run), lines 151-294 (ring_result)
**Failure Mode:** Ring command creates ephemeral perch for one-shot reply-wait. On early exit (NO_PERCH, EMPTY_MSG, timeout), cleanup_ephemeral is never called. Perch directory persists, accumulating stale directories.
**Invariant:** Every code path that creates ephemeral must clean up before exit. Exception: if caller already has an active perch, do NOT treat as ephemeral and do NOT clean up on return (line 108 guard).
**Citation:** `src/owl/ring.rs` lines 78-79, 117-118, 140-141, 211, 229, 240-241, 258, 270, 284; test coverage at lines 296-310.

#### 3.2 Stale Signoff Sentinel Cleanup on Fresh Listener Start
**File:** `src/live/start.rs` (listener spawn); `src/owl/cleanup.rs`
**Failure Mode:** Operator drops `.claude/{self_id}-signoff.md` while listener is in-flight. New listener boot picks up the stale signoff file and treats it as fresh.
**Invariant:** On every listener spawn, scan for and clear stale `.claude/<self_id>-signoff.md` sentinels. Signoff file is write-once per listener generation; stale files from prior session must not restart the listener.
**Citation:** CHANGELOG v1.11.20 "Stale `.claude/{id}-signoff.md` no longer kills fresh `$LIVE start`"; `src/owl/cleanup.rs:97` sentinel-sweep logic.

#### 3.3 Generation Counter Semantics: Must Increment on Every /live or /revive Start
**File:** `src/live/wrapper/mod.rs` (WrapperState gen field); `src/common/wrapper_state.rs`
**Failure Mode:** Psyche resumes with prior generation UUID. Claude Code session cache thinks it's a continuation, surfaces stale context.
**Invariant:** Every `/spt:live` start or `/spt:revive` invocation increments the generation counter. `session_uuid` is captured fresh on cold-start and persisted in wrapper-state.json for handoff. Psyche receives both so it can distinguish "same generation continuing" from "new generation born".
**Citation:** `src/live/start.rs` init_session path; `src/common/wrapper_state.rs` WrapperHandoffState schema.

#### 3.4 Orphan Teardown Must Fire Echo Commune Before INIT_SIGNOFF
**File:** `src/live/wrapper/orphan.rs:175-199` (ECHO-FIRE synchronous block)
**Failure Mode:** Wrapper detects Self is gone and immediately delivers INIT_SIGNOFF. Psyche spool never received the final delta summary (echo commune). Psyche signoff lacks the context-save summary.
**Invariant:** When orphan path fires, SYNCHRONOUSLY spawn `_echo-commune --force <uuid> <self_id> <psyche_id>` BEFORE composing INIT_SIGNOFF. Blocks until haiku subprocess exits (no timeout). Argv does NOT include `--forward-to-self` (orphan is Psyche-single-dispatch). If Self's session_id is missing/empty, skip the echo-fire and proceed to INIT_SIGNOFF.
**Citation:** `src/live/wrapper/orphan.rs:175-199` (fire block); tests A-H (lines 333-565) lock the argv shape, ordering, and --forward-to-self prohibition.

---

### 4. WIRE/TRANSPORT GOTCHAS

#### 4.1 Envelope HTML-Entity Encoding Order: Amp Must Be Last When Decoding
**File:** `src/owl/poll.rs:1-73` (ENCODING CONTRACT); `src/common/envelope.rs`
**Failure Mode:** Body contains literal `&amp;lt;` (encoded `&<`). Decoder decodes `&lt;` first → `&amp;<`. Then decodes `&amp;` → `&<`. But if `&amp;` decoded first, `&amp;lt;` → `&lt;` (malformed), then `&lt;` → `<` (wrong result).
**Invariant:** Producer encode order: amp→first, br→last. `&` → `&amp;`, `<` → `&lt;`, `>` → `&gt;`, `"` → `&quot;`, `\n` → `<br>`. Consumer decode order: br→first, amp→last. `<br>` → `\n`, then `&lt;` → `<`, then `&gt;` → `>`, then `&quot;` → `"`, then `&amp;` → `&`. SOLE LLM-stdin decode site: `compose_llm_prompt_from_envelope`.
**Citation:** `src/owl/poll.rs:8-73` (full contract); `src/common/envelope.rs` never decodes (parser only); `src/live/wrapper/mod.rs` LLM-boundary applies decode.

#### 4.2 Two-Slice Envelope Parser Robustness Rules
**File:** `src/common/envelope.rs:64-92` (parse_two_slice)
**Failure Mode:** LLM emits malformed envelope (unclosed tag, misordered tags, nested tags). Parser panics or drops half the output.
**Invariant:** Both tags case-sensitive lowercase. Tags optional (both, one, or neither present). Fallback rule: no tags → whole body routes to live slot. Unclosed tag → both extracts return None for that tag. Tags out of order → both extracted normally. Nested unknown tags inside slice body → preserved verbatim. No `unwrap`s on parsed text; every extraction returns `Option`.
**Citation:** `src/common/envelope.rs:20-36` (rules); test coverage lines 99-207.

#### 4.3 TCP Registry Staleness: Stale Entry Cleanup Must Precede Lookup
**File:** `src/common/registry.rs:62-78` (clean_stale_entries)
**Failure Mode:** Sender looks up target's address in registry and finds a dead process's stale TCP port. Sends message to wrong agent or dead listener.
**Invariant:** On every `send` operation (or at poll loop entry), call `clean_stale_entries` to remove entries whose PID is no longer alive. Spool fallback is the safe path when TCP lookup fails.
**Citation:** `src/common/registry.rs` clean_stale_entries; caller site in `src/owl/send.rs` (lookup-before-clean contract).

#### 4.4 Spool Fallback Correctness: Deferred Rows Must Survive Drain
**File:** `src/common/spool.rs` (drain variants); `src/owl/send.rs`
**Failure Mode:** Hook sends message via `deliver_body_deferred` (spool-only). Poll listener calls `drain_all` at startup and flushes the deferred message. Deferred message never reaches its destination (supposed to be picked by hook consumer via peek).
**Invariant:** Deferred messages (flag in spool row) are NOT flushed by poll drain. Only `drain_non_deferred_*` and `peek_all` family are safe. Caller must explicitly acknowledge which rows are being drained.
**Citation:** CHANGELOG v1.11.20 "three of four spool-drain sites"; `src/owl/poll.rs:280`.

#### 4.5 Inbox Legacy Compat: File-Based Messages Must Not Interfere with Spool Drain
**File:** `src/common/inbox.rs`
**Failure Mode:** Agent receives message via both spool (primary) and legacy inbox files (fallback). Message surfaces twice or is delivered by both transports in a race.
**Invariant:** Spool is the durable layer; inbox is write-for-compat-only. Poll drain reads spool exclusively. Inbox files are never read at poll time. Producers that write inbox ALSO write spool.
**Citation:** `src/common/inbox.rs` (module docstring); poll drain at `src/owl/poll.rs:280` uses spool, not inbox.

---

### 5. PLATFORM-SPECIFIC QUIRKS

#### 5.1 Windows PID Recycling False Positives
**File:** `src/live/wrapper/orphan.rs:141-161`; `src/common/list_filter.rs:137-150`
**Failure Mode:** Windows releases PID back to the pool after ~4 billion allocations (on same machine, within hours). New unrelated process acquires the recycled PID. Orphan check calls `is_process_alive` on the recycled PID and gets true (for the wrong process).
**Invariant:** Always consult parent_pid (Claude Code process, stable across machine uptime). Wrapper-owned psyche perches use minimal info.json to avoid PID staleness. Grace window mitigates: if mtime < 60s, assume perch is fresh despite PID mismatch.
**Citation:** CHANGELOG v1.11.20 "Windows PID recycling"; `src/common/list_filter.rs:168-175` grace gate.

#### 5.2 EBUSY Rename Failures on Windows (Marketplace Add)
**File:** (not in owl, but in claude_skill_owl plugin setup)
**Failure Mode:** Windows holds file locks during `fs::rename` attempts when a process still holds a handle (even if released, cache may persist). Marketplace registry update fails.
**Invariant:** When atomically renaming files on Windows, use a write-then-compare-and-delete pattern OR use Windows-specific atomic rename API. Best-effort side-fail semantics: retry with exponential backoff or skip if permission denied.
**Citation:** CHANGELOG mentions "EBUSY rename bug"; `src/common/owlery.rs` atomic_write_string uses tmp + rename pattern.

#### 5.3 Git Timeout Stamping Across Platforms
**File:** `src/common/git.rs` (stamp function)
**Failure Mode:** Git command hangs (e.g., during clone on slow network). Caller blocks forever, wrapper becomes unresponsive.
**Invariant:** All git operations that produce metadata (branch name, commit stamp) must have a timeout. Default timeout is 2000ms for standard operations, 5000ms for extended contexts (migration). Timeouts yield `None` with one-line rate-limited stderr output.
**Citation:** `src/common/git.rs` timeout infrastructure; CHANGELOG v1.11.20 mentions timeout handling.

#### 5.4 Windows UNC Path Prefix Stripping in Serialization
**File:** `src/common/owlery.rs:377-384` (to_forward_slash)
**Failure Mode:** Canonicalized Windows paths have `\\?\C:\...` prefix (UNC notation). Serialized as `//?/C:/...` in JSON. Wrapper reads JSON and tries `fs::read_to_string("//?/C:/...")` which fails on Windows (literal path with forward slashes).
**Invariant:** Strip Windows UNC prefix `\\?\` → `//?/` after backslash-to-forward-slash conversion. Wrapper-side `file_drop` EVENT envelope's path attribute must be consumable by `fs::read_to_string` directly without re-parsing.
**Citation:** `src/common/owlery.rs:377-384` (Phase 30 D2); comment explains the strip logic.

---

### 6. DOCUMENTED REGRESSIONS & HOTFIXES

#### 6.1 Nested Perch Layout Migration: Dual-Layout Tolerance Window
**File:** `src/common/perch_path.rs` (ParentHint enum); Phase 25 D-01, 25.2, 25.4
**Failure Mode:** Old code reads flat path `owlery/<id>/`, new code writes nested path `owlery/<parent>/nested/<id>/`. Reader can't find writer's output. Or dual-sibling perches (flat + nested) exist, confusion about which is live.
**Invariant:** During migration window (Phase 25 → 25.4): readers check nested-first, then flat-fallback. Writers route through central resolver `perch_path::resolve_*()` which respects ParentHint. Phase 25.4 D-03 migration CLOSED: writer uses nested-only, reader falls back for ONE more deploy. Safety guard: never wipe flat perch if nested-sibling exists (cascade-wipe prevention).
**Citation:** `src/common/perch_path.rs` resolver logic; CHANGELOG v1.11.20 Phase 25.4-07 migration-complete marker.

#### 6.2 Psyche Perch Soft-Cleanup Contract: Preserve State, Remove Ready
**File:** `src/owl/stop.rs::soft_stop_perch`
**Failure Mode:** Wrapper cleanup hard-deletes psyche perch including spool + info.json. Signoff message stored in spool is lost. Orphan recovery has nothing to inspect.
**Invariant:** Soft-stop: remove `ready` sentinel (marks perch offline). Preserve `info.json`, `spool.db`, and perch directory for offline state recovery. Hard-delete is used only for cleanup commands (doctor --fix) with explicit user approval.
**Citation:** `src/owl/stop.rs` soft_stop_perch; `src/live/wrapper/lifecycle.rs:124-132` cleanup call.

#### 6.3 Cascade-Wipe Prevention: Doctor --fix Must Not Delete Parent If Nested Children Exist
**File:** `src/owl/doctor.rs::check_orphan_dirs`
**Failure Mode:** Operator runs `doctor --fix`, code deletes an orphan top-level perch directory. That directory hosts nested working/psyche perches which were in-flight. Nested state is wiped, subagents crash.
**Invariant:** Before hard-deleting a top-level perch, check if `nested/` subdirectory exists and is non-empty. If so, soft-clean only (remove ready, not dir). Operator must manually review and remove nested children first. Error message surfaces the non-empty nested dir path.
**Citation:** CHANGELOG v1.11.20 Phase 35.1 "safety guard refuses to wipe a top-level dir that still hosts non-empty `nested/` children".

#### 6.4 Psyche Haiku Child Does Not Delete Drop Files: Wrapper-Owned Single-Writer
**File:** `src/live/context.rs` (psyche-download skill interaction); line 615 was DELETE, now is NO-OP
**Failure Mode:** Psyche LLM commune handoff deletes the drop file. Wrapper's direct-write path (Plan 25.3-04) simultaneously reads the same file. Race condition: file gone, wrapper read fails.
**Invariant:** Drop files (`<self_id>-commune.md`) are wrapper-owned single-writer artifacts. Psyche LLM is read-only over them. Only the wrapper's `process_file_drop` (or explicit operator action) deletes drop files. Documented as Rule-3 deviation in psyche.md / commune.md / signoff/SKILL.md.
**Citation:** CHANGELOG v1.11.7 "psyche-download no longer races and deletes inbound commune drop files"; `src/live/context.rs:615` (deleted `remove_file` line).

#### 6.5 Live-Context Route Guard: Protect Recent Direct-Writes from LLM Overwrites
**File:** `src/owl/echo_commune.rs::route_two_slice_with_precedence`
**Failure Mode:** Wrapper routes inbound commune directly to disk. Psyche LLM processes the same envelope and emits a slightly older snapshot. LLM write clobbers the fresh direct write with stale data.
**Invariant:** Every write includes an out-of-band YAML-front-matter precedence marker: `<!-- spt:source=direct|llm spt:routed_at=<timestamp> -->`. LLM writes within a configurable protection window (default 60s) after a recent direct write are SUPPRESSED with a log line. Direct writes always proceed and update the marker.
**Citation:** CHANGELOG v1.11.6 Plan 25.3-04; `route_guard_window_secs` in config.json; `src/owl/echo_commune.rs` precedence helper.

---

### Summary Table: Test Checklist for spt-core Rebuild

| Category | Invariant Title | File:Line Citation | Test Pattern |
|----------|-----------------|-------------------|--------------|
| **Ordering** | Grace period precedes INIT_SIGNOFF | orphan.rs:209-251 | Include_str byte-index assertion |
| **Ordering** | Stale-signoff drain on poll startup | poll.rs:280 | drain_non_deferred only |
| **Ordering** | Echo-commune fire before INIT_SIGNOFF (orphan) | orphan.rs:175-199 | Subprocess dispatch ordering |
| **Identity** | Parent_pid precedence over poll_pid | orphan.rs:148-158 | get_parent_pid_from_info first |
| **Identity** | Stdin session_id precedence over OWL_SESSION_ID env | hook_subagent_start.rs:41-45 | Filter > or_else chain |
| **Identity** | Gen_start is SystemTime::now() on both cold + handoff | lifecycle.rs:70 | Assertion in both branches |
| **Lifecycle** | Ephemeral perch cleanup on all exit paths | ring.rs:78-79,117-118,140-141 | Guard checks before cleanup |
| **Lifecycle** | Orphan grace window ≥ 60 seconds | list_filter.rs:168-175 | phase35_list_orphan_grace_secs() ≥ 60 |
| **Wire** | Decode order: br→first, amp→last | poll.rs:47-48 | Event body round-trip test |
| **Wire** | Envelope parser no-panic on malformed | envelope.rs:64-92 | All Option paths tested |
| **Wire** | TCP registry clean before lookup | registry.rs:62-78 | Call site in send.rs |
| **Platform** | Windows UNC prefix stripped | owlery.rs:377-384 | Path canonicalize round-trip |
| **Regression** | Nested perch layout: no flat siblings | hook_subagent_start.rs:220-226 | Both assertions on each spawn |
| **Regression** | Soft-cleanup: ready removed, dir preserved | stop.rs | State recovery possible after cleanup |
| **Regression** | Cascade-wipe guard: check nested/ before delete | doctor.rs | Hard-delete fails if nested/ non-empty |
| **Regression** | Drop files: wrapper-owned, read-only for Psyche | context.rs (no remove_file) | Rule-3 deviation documented |

---

This list captures the hard-won wisdom from ~80 commits, 12+ phases, and multiple production incidents. Every invariant is grounded in actual code failure patterns, not speculation.</result>
<usage><subagent_tokens>99995</subagent_tokens><tool_uses>23</tool_uses><duration_ms>146523</duration_ms></usage>
</task-notification>


<owl_messages>
<owl_message from="doyle-w325" priority="info">[WORKING_PERCH_NOTICE] Subagent working perch created.
Perch: doyle-w325
Agent type: Explore
To message it: $OWL send doyle-w325 doyle</owl_message>
</owl_messages>

[OWL SYSTEM] Informational owl messages above — no acknowledgment needed. Continue your current task.

<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>


Hazard harvest done — 23 invariants across 6 categories, all cited to sister-project code. Writing `KNOWN-HAZARDS.md` (ADR-0001 mitigation), translating each into spt-core's daemon/broker model where the architecture shifted.


Write

# Known Hazards

Hard-won edge cases harvested from the sister project (`claude_skill_owl`, ~80 commits / 12+ phases / multiple production incidents). Per ADR-0001, this is a **test checklist for the spt-core rebuild** — the clean-room rebuild must re-satisfy each invariant rather than re-discover the bug.

**Architecture-translation note.** The sister project runs poll listeners and Psyche wrappers as *separate processes*. spt-core consolidates both into the one `spt-daemon` (brain), with a stable broker beneath it (ADR-0004). Many hazards below were inter-process races in the sister project; in spt-core some become intra-daemon concerns (potentially easier) while others move to the daemon↔broker IPC boundary or the network boundary (potentially new failure surface). Each entry notes the mapping where it differs. Citations point at sister-project paths for reference, not at spt-core.

---

## 1. Race conditions & ordering

### 1.1 Phantom INIT_SIGNOFF after grace period
- **Failure:** orphan teardown enqueues INIT_SIGNOFF before the grace-period recheck; a transient Self recovery (binary handoff, brief stale poll) makes the recheck pass-as-alive, but the signoff was already spooled and drains on the next iteration → teardown despite a live Self.
- **Invariant:** grace-period wait MUST complete *before* composing/delivering INIT_SIGNOFF; the recheck must bind `still_gone` before any envelope write.
- **spt-core mapping:** in-daemon now (no separate wrapper), but the ordering invariant is identical — orphan/teardown logic must re-evaluate liveness after the grace wait, not before enqueue.
- **Sister cite:** `src/live/wrapper/orphan.rs:201-259` (sleep@209 precedes compose@231-251); tests T-grace-recovery:576, T-still-gone-recheck:618.

### 1.2 Poll-rewrite race & info.json mid-write reads
- **Failure:** `info.json` written by the wrapper mid-iteration while a list/classify command reads it → torn read, misclassification.
- **Invariant:** consult liveness via the supervisor (`is_wrapper_alive`-equivalent) before any grace gate; reads of state files must tolerate concurrent writes (atomic write + rename, or read-retry).
- **spt-core mapping:** the daemon owns both writer and reader → use in-process locking/snapshotting instead of racing on disk. Cross-node registry reads remain eventually-consistent and must tolerate staleness.
- **Sister cite:** `src/common/list_filter.rs:100-150`; `src/owl/poll.rs:141`.

### 1.3 Stale `index.lock` wedge from prior git crash
- **Failure:** crashed git leaves a 0-byte `index.lock` in a psyche tracked worktree; every later commit blocks forever.
- **Invariant:** on daemon boot, sweep seed + all agent/project worktrees for stale locks (0 bytes, mtime > 60s) and remove; leave live locks alone.
- **spt-core mapping:** cross-node Psyche sync (ADR-0002/0003) replaces git-repo sync, so the *git* lock may disappear — but any equivalent lockfile in the new sync mechanism needs the same stale-sweep on boot.
- **Sister cite:** CHANGELOG v1.11.20 "Stale `index.lock`"; `src/common/git.rs`.

### 1.4 Deferred spool rows must not leak to the event stream
- **Failure:** a hook spools a deferred (spool-only, no TCP wake) notice; startup `drain_all` flushes ALL rows including deferred → event emitted at wrong time/priority.
- **Invariant:** startup drain (and idle/timeout TCP-wake sites) use `drain_non_deferred` only; deferred rows are picked up by their intended consumer via `peek`. All drain sites must agree on which rows they flush.
- **spt-core mapping:** carries directly — the daemon's spool-drain has the same deferred-vs-immediate distinction.
- **Sister cite:** `src/owl/poll.rs:276-316`; `spool::drain_non_deferred_with_metadata`.

### 1.5 Worker (working-perch) lifecycle path consistency
- **Failure:** subagent-start creates the perch at one path layout; later hooks read it at another → not found; stop-hook scan misses nested perches.
- **Invariant:** all Worker/Psyche child-perch path composition routes through one central resolver; no divergent path construction across hooks.
- **spt-core mapping:** `Worker` is a day-one endpoint type; the daemon owns the registry, so perch location is a registry lookup, not ad-hoc path math. Single source of truth for instance→location.
- **Sister cite:** `src/owl/hook_subagent_start.rs:122-168`; `hook_subagent_stop.rs:15-55`.

---

## 2. Identity & session-binding

### 2.1 Parent PID over ephemeral poll PID
- **Failure:** orphan check polls an ephemeral listener PID; it dies and is recycled (esp. Windows); a foreign process with the recycled PID reads as alive → false-positive teardown (or false-negative).
- **Invariant:** prefer the stable harness-session PID (`parent_pid`) over any ephemeral process PID for liveness; minimal `info.json` for supervisor-owned perches to avoid stale leaks.
- **spt-core mapping:** session binding (parent-process-tree anchor) still applies for harness-hosted topology. For spt-hosted sessions the broker holds the child directly → liveness is the broker's held-handle state, more reliable than PID polling.
- **Sister cite:** `src/live/wrapper/orphan.rs:141-161`; CHANGELOG v1.11.20.

### 2.2 Stdin session_id precedence over env
- **Failure:** subagent inherits a stale `OWL_SESSION_ID` env across `/clear`; hook gets two session_ids (fresh stdin, stale env) → wrong-agent binding.
- **Invariant:** stdin-provided session_id wins; env is fallback only.
- **spt-core mapping:** the harness-contract subcommand surface must define the same precedence for whatever identity fields hooks pass in.
- **Sister cite:** CHANGELOG v1.35.1 "IN-05"; `hook_subagent_start.rs:40-51`.

### 2.3 Binary-handoff argv schema must stay backward-compatible
- **Failure:** old binary spawns new binary with old argv arity; clap rejects before state rehydration → wrapper dies unlogged.
- **Invariant:** every newly-added handoff positional has a default; state-file rehydration happens *after* argv parse; defaults survive intermediate versions.
- **spt-core mapping:** CRITICAL — self-update (ADR-0004) makes handoff routine. The broker↔brain IPC and any brain-relaunch argv must be versioned and forward/backward tolerant (a newer brain talks to an older broker). This is the single most update-frequency-sensitive invariant.
- **Sister cite:** `src/live/wrapper/lifecycle.rs:17-106`; `src/cli.rs` defaults; CHANGELOG v1.11.10.

### 2.4 Generation `gen_start` always = now() on cold-start AND handoff
- **Failure:** stale gen_start from a rehydrated state file fires time-based discriminators on the new process.
- **Invariant:** wall-clock `gen_start` is set to `now()` on both cold-start and handoff; generation counter increments on every start/revive; session UUID captured fresh and carried so the resumed mind distinguishes "same gen continuing" vs "new gen born".
- **spt-core mapping:** carries to the daemon's per-instance generation tracking.
- **Sister cite:** `src/live/wrapper/lifecycle.rs:70`; `src/common/wrapper_state.rs`.

---

## 3. Lifecycle

### 3.1 Ephemeral perch cleanup on every `ring` exit path
- **Failure:** `ring` creates an ephemeral perch; early-exit paths (no-perch, empty-msg, timeout) skip cleanup → stale dirs accumulate.
- **Invariant:** every code path that creates an ephemeral perch cleans it before exit; exception: if the caller already had an active perch, do not treat as ephemeral and do not clean up.
- **spt-core mapping:** `ring` semantics carry; the daemon owns ephemeral-perch lifecycle, so a single guaranteed-cleanup (drop guard / RAII) is achievable in-process.
- **Sister cite:** `src/owl/ring.rs:58-294`.

### 3.2 Stale signoff sentinel must not kill a fresh start
- **Failure:** a leftover `.claude/<id>-signoff.md` from a prior session is read by a fresh listener as a live signoff → immediate teardown.
- **Invariant:** on every listener/daemon spawn, sweep stale signoff sentinels; signoff files are write-once per generation.
- **spt-core mapping:** same sweep on daemon (re)start per hosted instance.
- **Sister cite:** CHANGELOG v1.11.20; `src/owl/cleanup.rs:97`.

### 3.3 Orphan teardown fires echo-commune BEFORE INIT_SIGNOFF
- **Failure:** teardown delivers INIT_SIGNOFF without first saving the final context delta → Psyche signoff lacks the context-save summary.
- **Invariant:** on orphan path, synchronously run the echo-commune (final delta) before composing INIT_SIGNOFF; skip only if the session_id is missing.
- **spt-core mapping:** the daemon runs psyche/pulse loops in-process; ordering invariant identical.
- **Sister cite:** `src/live/wrapper/orphan.rs:175-199`; tests A-H:333-565.

---

## 4. Wire / transport

### 4.1 Envelope HTML-entity codec ordering — `&` decoded LAST
- **Failure:** decoding `&`-entity before the others double-decodes nested entities (`&amp;lt;` → wrong result).
- **Invariant:** ENCODE order amp→first … `<br>`→last; DECODE order `<br>`→first … amp→**last** (`<`,`>`,`"`, then `&`). One sole decode site (at the LLM/stdin boundary); the parser never decodes.
- **spt-core mapping:** `spt-proto` owns the envelope grammar (public SDK, semver + wire-version). This codec contract is a copy-verbatim commodity item (ADR-0001) and a public-API conformance test.
- **Sister cite:** `src/owl/poll.rs:1-73`; `src/common/envelope.rs`.

### 4.2 Two-slice envelope parser is panic-free and tolerant
- **Failure:** malformed envelope (unclosed/misordered/nested tags) panics or drops output.
- **Invariant:** tags case-sensitive, all optional; no tags → whole body to live slot; unclosed → None for that tag; out-of-order → both still extracted; nested unknown tags preserved verbatim; zero `unwrap` on parsed text.
- **spt-core mapping:** `spt-proto` parser; property-test the robustness rules.
- **Sister cite:** `src/common/envelope.rs:64-92`; tests 99-207.

### 4.3 Registry stale-entry cleanup precedes lookup
- **Failure:** sender resolves a dead process's stale TCP port → delivery to wrong/dead listener.
- **Invariant:** clean stale entries (dead PID) before/at lookup; spool fallback is the safe path on TCP miss.
- **spt-core mapping:** now spans the **subnet registry** (ADR-0003) — eventually-consistent across nodes. Cross-node staleness is expected; resolution policy (local → most-recent → `id@node`) must degrade to spool/relay fallback on stale hits, and never hard-fail on a stale remote entry.
- **Sister cite:** `src/common/registry.rs:62-78`; `src/owl/send.rs`.

### 4.4 Deferred rows survive poll drain
- **Failure:** poll `drain_all` flushes a deferred (spool-only) message meant for a hook consumer → message lost.
- **Invariant:** deferred rows are never flushed by the event-stream drain; only `drain_non_deferred_*` / `peek_all` touch them.
- **Sister cite:** CHANGELOG v1.11.20; `src/common/spool.rs`. (See also 1.4.)

### 4.5 Inbox legacy compat must not double-deliver
- **Failure:** message surfaced via both spool (durable) and legacy inbox files → duplicate or racing delivery.
- **Invariant:** spool is the sole read path at poll time; inbox is write-for-compat only and never read.
- **spt-core mapping:** clean-room — likely drop the legacy inbox entirely. If kept for any compat, preserve "never read at drain time."
- **Sister cite:** `src/common/inbox.rs`.

---

## 5. Platform-specific

### 5.1 Windows PID recycling false positives
- **Failure:** recycled PID reads alive for the wrong process → orphan misclassification.
- **Invariant:** anchor liveness on the stable parent/harness PID; minimal info.json for supervisor-owned perches; mtime grace window (≥60s) masks transient mismatches.
- **spt-core mapping:** broker-held handles supersede PID polling for spt-hosted sessions; keep the grace window for harness-hosted.
- **Sister cite:** `src/live/wrapper/orphan.rs:141-161`; `src/common/list_filter.rs:168-175`.

### 5.2 Windows EBUSY on atomic rename
- **Failure:** `fs::rename` fails while a handle is (recently) held → registry/marketplace update fails.
- **Invariant:** tmp-write + atomic-rename with retry/backoff; best-effort side-fail; tolerate transient EBUSY.
- **spt-core mapping:** all on-disk state writes (registry, trust store, spool checkpoints) use this pattern. Self-update binary swap on Windows especially.
- **Sister cite:** CHANGELOG "EBUSY"; `src/common/owlery.rs` atomic_write.

### 5.3 Git/subprocess timeout stamping
- **Failure:** a hung subprocess (git on slow net) blocks the supervisor indefinitely.
- **Invariant:** every metadata-producing subprocess has a timeout; timeout yields `None` + rate-limited stderr, never a hang.
- **spt-core mapping:** generalize to all manifest-declared harness invocations (delegated commands, adapter updates) — timeouts mandatory.
- **Sister cite:** `src/common/git.rs`.

### 5.4 Windows UNC prefix in serialized paths
- **Failure:** canonicalized `\\?\C:\...` serializes to `//?/C:/...` and fails `read_to_string`.
- **Invariant:** strip the `\\?\` UNC prefix after backslash→forward-slash conversion; serialized path attrs must be directly consumable.
- **spt-core mapping:** any path crossing the wire (file-drop EVENTs, off-node file transfer per ADR-0003) needs canonical normalization at the `spt-proto` boundary.
- **Sister cite:** `src/common/owlery.rs:377-384`.

---

## 6. Documented regressions (non-obvious invariants)

### 6.1 No flat/nested perch siblings; resolver-routed paths
- **Failure:** mixed flat + nested perch layouts confuse which perch is live; cascade-wipe risk.
- **Invariant:** one path resolver; never create divergent siblings.
- **spt-core mapping:** clean greenfield layout from day one (no migration window) — pick one structure, route everything through the registry. Storage layout deferred to design phase but this single-source-of-truth rule is binding.
- **Sister cite:** `src/common/perch_path.rs`; CHANGELOG Phase 25.4.

### 6.2 Soft-cleanup preserves state, removes `ready`
- **Failure:** hard-deleting a perch on cleanup loses spool (incl. stored signoff) needed for offline recovery.
- **Invariant:** soft-stop removes only the `ready`/online marker; preserves info + spool + dir. Hard-delete only on explicit operator action.
- **spt-core mapping:** instance offline-state recovery depends on this; carries to the daemon's stop path.
- **Sister cite:** `src/owl/stop.rs`.

### 6.3 Cascade-wipe guard: never delete a parent hosting non-empty children
- **Failure:** `doctor --fix` deletes a top-level perch that still hosts in-flight nested Worker/Psyche perches.
- **Invariant:** before hard-delete, check for non-empty nested children; if present, soft-clean only and surface the path.
- **spt-core mapping:** any destructive maintenance command must check for live child instances first.
- **Sister cite:** CHANGELOG v1.11.20 Phase 35.1.

### 6.4 Drop files are single-writer (supervisor-owned), read-only for the mind
- **Failure:** the Psyche LLM deletes a commune drop file the wrapper is concurrently reading → race, lost commune.
- **Invariant:** drop files (`<id>-commune.md`) are supervisor-owned single-writer; the LLM is read-only; only the supervisor (or explicit operator) deletes them.
- **spt-core mapping:** the daemon is the single writer; the harness-invoked mind never mutates drop files. Bake the ownership into the runtime contract.
- **Sister cite:** CHANGELOG v1.11.7; `src/live/context.rs:615` (removed delete).

### 6.5 Direct-write precedence guard against stale LLM overwrites
- **Failure:** the LLM emits an older snapshot that clobbers a fresher direct write to a context file.
- **Invariant:** every context write carries a source+timestamp precedence marker; LLM writes within a protection window after a recent direct write are suppressed (logged); direct writes always proceed.
- **spt-core mapping:** cross-node Psyche sync (ADR-0003) makes this multi-writer across machines — the precedence marker must include node identity, and the freshness rule (newest-and-newer-than-mine, per the cross-instance context-freshness feature) is the distributed generalization of this guard. Highest-value carryover for the sync design.
- **Sister cite:** CHANGELOG v1.11.6; `src/owl/echo_commune.rs`.

---

## Conformance checklist (condensed)

| # | Invariant | spt-core surface |
|---|---|---|
| 1.1 | Grace wait precedes INIT_SIGNOFF | daemon teardown |
| 1.4/4.4 | Deferred rows excluded from event-stream drain | daemon spool drain |
| 2.1/5.1 | Stable PID/broker-handle over ephemeral PID | liveness detection |
| 2.3 | Handoff argv/IPC version-tolerant (newer brain ↔ older broker) | broker↔brain IPC, self-update |
| 2.4 | gen_start = now() on cold-start + handoff | per-instance generation |
| 3.1 | Ephemeral perch cleanup on all exit paths | `ring` (RAII guard) |
| 3.3 | Echo-commune before INIT_SIGNOFF | daemon psyche loop |
| 4.1 | Envelope decode order, `&` last | spt-proto (public, wire-versioned) |
| 4.2 | Parser panic-free + tolerant | spt-proto |
| 4.3 | Stale registry entries → fallback, never hard-fail | subnet registry resolution |
| 5.2 | tmp-write + atomic-rename + retry (EBUSY) | all state writes, binary swap |
| 5.3 | Timeout every harness subprocess | manifest invocations |
| 5.4 | Strip UNC prefix on serialized paths | spt-proto path normalization |
| 6.1 | Single path/registry source of truth | storage layout |
| 6.4 | Drop files supervisor-owned single-writer | runtime contract |
| 6.5 | Direct-write precedence marker (+ node id) | cross-node Psyche sync |