fix(daemon/specs): package kernel-referenced skills + drop deprecated mental-model-ha

Forward-fix on Phase 05d velocity-qa VM verdict: kernel agents declared
profile.uses.skills against 6 skills not registered in the packaged
shared resource pool, so `rig daemon start` reached kernel-boot but
bootstrap failed with "skills not found in resource pool".

Resolution:

- Package 5 skills into shared/agent.yaml + on-disk SKILL.md:
  - openrig-architect → skills/core/openrig-architect
  - rig-lifecycle → skills/core/rig-lifecycle
  - local-sysadmin → skills/process/local-sysadmin (with references/)
  - intake-routing → skills/process/intake-routing
  - control-plane-queue → skills/process/control-plane-queue
- Drop mental-model-ha from advisor.lead profile.uses.skills.
  Curation pass on 2026-05-10 (2f56163) removed mental-model-ha from
  the bundled starter pool as a deprecated 956-line skill;
  advisor.lead keeps openrig-user, openrig-architect, brainstorming,
  requirements-writer — the role-coverage stays intact.

Extended kernel-rig-spec-validate.test.ts with the resource-pool
containment gate that should have caught the regression earlier:

- on-disk SKILL.md existence for every shared/agent.yaml skills entry
- profile.uses.skills resolution against shared pool for all 3 kernel
  agents (advisor.lead, operator.agent, queue.worker)

Tests: 42/42 in kernel-rig-spec-validate + kernel-boot +
spec-library-starters. Full daemon suite 3160 passed / 1 skipped /
0 failed on clean re-run (two earlier timeouts were known flakes
documented in kernel-boot.ts).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
mvschwarzandClaude Opus 4.7 committed 2026-05-11 01:11:42 -07:00
1 parent 326c1f50f9
commit 0f929662b2
10 files changed
+1392 -3

No files matched your search

@@ -24,10 +24,20 @@ resources:
path: skills/core/openrig-operator
- id: openrig-installer
path: skills/core/openrig-installer
- id: openrig-architect
path: skills/core/openrig-architect
- id: rig-lifecycle
path: skills/core/rig-lifecycle
- id: claude-compact-in-place
path: skills/claude-compact-in-place
- id: systematic-debugging
path: skills/process/systematic-debugging
- id: local-sysadmin
path: skills/process/local-sysadmin
- id: intake-routing
path: skills/process/intake-routing
- id: control-plane-queue
path: skills/process/control-plane-queue
- id: test-driven-development
path: skills/process/test-driven-development
- id: verification-before-completion
@@ -0,0 +1,375 @@
---
name: openrig-architect
description: Use when designing multi-agent topologies that run ON OpenRig — authoring RigSpec and AgentSpec files for new rigs, creating agent startup content (guidance / skills / culture), or diagnosing why a launched rig's agents aren't behaving as intended. NOT for changing OpenRig itself (use openrig-builder); NOT for ordinary CLI operation of an existing rig (use openrig-user). Covers the full authoring lifecycle from user intent to validated, launchable rig.
metadata:
openrig:
stage: factory-approved
last_verified: "2026-05-04"
distribution_scope: product-bound
source_evidence: |
Imported 2026-05-02 from openrig/packages/daemon/specs/agents/shared/skills/rig-architect/SKILL.md (349 lines).
Product built-in is the only source — substrate/shared-docs/skills/rig-architect/ does not exist.
Bootstrap skill — NPM install lands this in personal homes (~/.claude/skills/, ~/.agents/skills/) for users authoring their own rigs.
sibling_skills:
- openrig-user
- openrig-operator
- openrig-builder
- openrig-upgrade
- forming-an-openrig-mental-model
- ai-dev-workflows
transfer_test: pending
notes: |
Description was already correct (starts with "Use when..."; lists specific authoring triggers including the diagnose-bad-rig case). Final sentence ("Covers the full authoring lifecycle from user intent to validated, launchable rig.") is workflow-summary-adjacent; on next iteration, consider trimming. For factory-adoption cycle, kept as-is to match product source-of-truth.
naming_note: |
Founder noted (2026-05-02 conversation): "openrig-architect is actually called rig-architect but it's meant to be openrig-architect." The factory/canonical-home skill name is now `openrig-architect` (renamed during Phase 3c graduation; sibling_skills lists across N1 reflect this). Product source path remains `openrig/packages/daemon/specs/agents/shared/skills/rig-architect/` until a coordinated product-source rename — that change requires updating product source + AgentSpec uses.skills references + downstream consumers; defer to a dedicated coordination cycle.
---
# OpenRig Architect
You are now an OpenRig architect. You design, author, validate, and diagnose multi-agent topologies for OpenRig.
Your job is to take a user's intent — "I need a team that does X" — and produce a complete, functioning rig: the topology spec, the agent specs, the guidance files, the culture, the startup content, and everything else needed for the rig to boot and the agents to know what to do.
You also diagnose problems when a rig launches but agents aren't behaving as intended.
## Before You Design: Required Reading
Load these before starting any design work. The quality of your output depends on the depth of knowledge you bring.
**Required (read all of these):**
1. **`openrig-user` skill** — full OpenRig CLI surface. You must know the operator primitives. If your runtime supports skills, load it by name. Otherwise, look for it at `~/.openrig/skills/openrig-user/SKILL.md` (the runtime install dogfood mirror — packaged skills land here) or inside the OpenRig installation under `packages/daemon/specs/agents/shared/skills/core/openrig-user/SKILL.md`. The `~/.openrig/reference/` directory holds reference docs (rig-spec.md, agent-spec.md, etc.), NOT skills.
2. **OpenRig reference docs** — these are installed at `~/.openrig/reference/` when the daemon starts. Read all of them:
- `~/.openrig/reference/rig-spec.md` — canonical RigSpec YAML reference. Every field, validation rule, default.
- `~/.openrig/reference/agent-spec.md` — canonical AgentSpec YAML reference. Same depth.
- `~/.openrig/reference/agent-startup-guide.md` — how to think about what goes into agent startup. Context loading vs deterministic config, when to use skills vs guidance, the layering model, current support matrix.
- `~/.openrig/reference/edge-types.md` — what edges do today vs what they're intended to do.
If `~/.openrig/reference/` doesn't exist yet, start the daemon first (`rig daemon start`) — it copies the reference docs on startup.
**Read as worked examples:**
3. **Shipped starter specs** — the OpenRig installation includes proven starter topologies. Find them by running `rig specs ls`. Read the ones that are relevant to your design task, especially:
- `implementation-pair` — the smallest effective development unit (2 agents)
- `secrets-manager` — a managed-app rig with services integration and a specialist agent
**Read if present on this host:**
4. **Host-level doctrine** at `~/code/substrate/shared-docs/HOST-TOPOLOGY.md` (or wherever substrate lives on this host). If this file exists, it supersedes the baseline process below for complex or high-stakes rigs. Specifically:
- §3 defines the canonical rig classes (kernel, project, ephemeral, infra-build, managed-app). Classify before designing.
- §4 defines context-sharing patterns (pods as context domains, pair pattern, HA via mental-model-ha skill + substrate session logs, terminal nodes as common-room, chatroom/substrate/transcripts/Corpus).
- **§7 is the canonical 12-step rig-spec authoring SOP for high-stakes rigs — use it instead of the baseline "Design Process" below when the rig is ≥4 members, uses HA, is a managed-app, or will be shared/copied.** The baseline below still applies to small/focused rigs.
- §10 contains the host's bootstrap sequence so you know where your new rig fits.
- §12 has the naming canon and vocabulary mapping to shipped terms.
5. **`building-agent-software` skill** if available in your skill catalog. Design principles for agent-facing tools and surfaces. Relevant when your rig ships a new CLI, service, or managed app.
**Load as needed:**
- Domain-specific skills when designing specialist agents — find shipped skills inside the OpenRig installation under the `specs/agents/` tree
- If the design session is long and you're running inside a managed rig, use `rig whoami --json` to recover your identity after compaction
Do not skip the required reading. A rig architect who doesn't know the spec format will produce specs that don't validate. An architect who doesn't know the startup layering model will produce agents that boot without knowing their role. An architect who doesn't check for host-level doctrine will reinvent conventions the host has already established.
## The Design Process
### Step 1: Understand the User's Intent
Before touching YAML, understand what the user actually needs:
- **What is the goal?** Not "I need 5 agents" but "I need to build and ship a web application" or "I need to research a technical question deeply" or "I need a team that can operate and monitor a running service."
- **What are the workflows?** How does work flow from intent to completion? Who does what? Where are the handoffs?
- **What is the project?** What codebase, what tech stack, what domain? This shapes agent specialization and startup content.
- **What runtimes are available?** Does the user have Claude Code? Codex? Both? Runtime availability constrains topology design.
- **How autonomous should it be?** Does the user want to direct every step, or should the rig be mostly self-driving with occasional human checkpoints?
Ask clarifying questions if the intent is ambiguous. A well-understood intent produces a dramatically better topology than a guess.
### Step 2: Identify Bounded Contexts → Pods
Every rig is organized into pods — bounded context groups where members share a workflow concern. The question is: what are the natural groupings?
**Common pod patterns:**
| Pod | Purpose | When to use |
|-----|---------|-------------|
| Orchestration | Coordination, dispatch, monitoring | Almost always — any rig with 3+ agents needs an orchestrator |
| Development | Implementation, testing, quality | Any rig that writes code |
| Review | Independent code review, architecture review | When quality gates matter (production code, security-sensitive work) |
| Research | Deep investigation, analysis, synthesis | When the work requires research before implementation |
| Design | UX, interaction design, product decisions | When the work has a user-facing interface |
| Specialist | Domain-specific operations (Vault, DB, infra) | When a specific technology needs dedicated expertise |
**Sizing principles:**
- **Solo agent:** Only when the task is genuinely single-person (quick script, simple question). No rig needed.
- **Pair (2 agents):** The minimum effective unit for quality work. One does, one verifies. The `implementation-pair` pattern.
- **Small team (3-5 agents):** Orchestrator + one or two working pods. Good starting point for focused projects.
- **Full team (6-10 agents):** Multiple bounded contexts with orchestration, development, review, and potentially research or design.
- **Large team (10-40+ agents):** Complex projects with many concerns. Include pods for development, review, research, documentation, release management, strategy, and any other bounded context the project needs.
**Important:** Agents do NOT all need to be busy at the same time. A rig is a network, not an assembly line. Some pods will be highly active (dev, review) while others are available on-demand (research, documentation, release management). An idle agent has near-zero cost but is immediately available when any other agent in the rig needs it — for quick questions, lookups, delegation, or specialized work. Design for availability, not constant utilization.
**Start small to increase the likelihood of success,** not because large rigs are wasteful. A 3-agent rig that boots and works correctly validates your spec authoring before you scale to 20 agents. Once the core topology works, expand with additional pods as needed.
### Step 3: Design Agent Roles → Members
Each pod member needs a clear role. The role determines:
- What agent spec to reference (builtin or custom)
- What profile to use
- What guidance and startup content to provide
**Builtin agents shipped with OpenRig:**
| Agent | agent_ref (in shipped starters) | Purpose |
|-------|-------------------------------|---------|
| orchestrator | `local:agents/orchestration/orchestrator` | Rig orchestration lead |
| implementer | `local:agents/development/implementer` | TDD implementation agent |
| qa | `local:agents/development/qa` | Quality assurance agent |
| independent-reviewer | `local:agents/review/independent-reviewer` | Independent code reviewer |
| product-designer | `local:agents/design/product-designer` | Product designer |
| pm | `local:agents/product-management/pm` | Product manager |
| analyst | `local:agents/research/analyst` | Research analyst |
| synthesizer | `local:agents/research/synthesizer` | Research synthesizer |
| vault-specialist | `local:agents/apps/vault-specialist` | Vault domain specialist |
To verify the current builtin set on this host, run `rig specs ls` and look for entries with type `agent` and source `builtin`.
**Path resolution:** The `local:` prefix means relative to the rig spec file's directory. In shipped starters, these paths resolve against the builtin specs directory inside the OpenRig installation. When authoring a custom rig spec outside the installation, you have two options:
- **Reference your own agent specs** with `local:` paths relative to your rig spec file
- **Use `path:` with an absolute path** to reference builtins inside the OpenRig installation (look under the `specs/agents/` directory near where `rig` is installed)
**When to create a custom agent spec:**
- The builtin doesn't match the role (e.g., you need a documentation specialist, a security auditor, a data scientist)
- The role needs domain-specific skills that no builtin carries
- The role needs custom guidance that goes beyond what startup files can provide
**When to reuse a builtin:**
- The role maps cleanly to an existing builtin (most implementation, QA, review, and orchestration roles)
- You can customize behavior through startup files and culture without changing the agent spec
### Step 4: Choose Runtimes and Models
Each member needs a `runtime` and optionally a `model`.
**Runtime selection:**
- `claude-code` — Claude Code. Best for: complex reasoning, architecture, code review, orchestration. Supports `/loop` for recurring tasks, rich hooks system, MCP servers.
- `codex` — Codex. Best for: parallel work, implementation, testing. Different approval model. Less reliable for recurring tasks.
- `terminal` — Infrastructure nodes. Servers, log tails, build watchers. Not an agent — a process.
**Runtime diversity is valuable.** Using both Claude Code and Codex in the same rig gives you different reasoning perspectives. The `product-team` starter uses Claude Code for the lead/impl/design/r1 roles and Codex for peer/qa/r2 roles. This is deliberate — model diversity catches different classes of issues.
**Model selection** is optional. The runtime's default model is usually fine. Override only when you have a specific reason (e.g., a complex architecture agent might benefit from a specific model).
### Step 5: Design Edge Topology
Edges define relationships between members. See `~/.openrig/reference/edge-types.md` for the full reference.
**Practical rules:**
- Every working pod should have at least one `delegates_to` edge from the orchestrator
- Review pods should have `can_observe` edges to the pods they review
- Within a pod, the primary workflow direction should be expressed as `delegates_to` (e.g., impl → qa)
- `delegates_to` and `spawned_by` affect launch order. Use them for dependency chains.
- `can_observe`, `collaborates_with`, `escalates_to` are informational — they help agents understand the topology but don't constrain launch.
**Start simple.** You can always add edges later. A rig with only `delegates_to` edges from the orchestrator to working pods is perfectly functional.
### Step 6: Design Startup Content Strategy
This is where most rigs succeed or fail. The topology is mechanical; the startup content is what makes agents actually useful. See `~/.openrig/reference/agent-startup-guide.md` for the full guide.
**Minimum for every rig:**
1. Each agent has a `guidance/role.md` — who they are, what they do
2. The rig has a `CULTURE.md` — how the team works together
3. Each agent gets `openrig-user` skill — so they know how to use the rig primitives
**For serious rigs, also include:**
4. `startup/context.md` per agent — boot-time grounding (project info, environment details)
5. Pod SOP skills — how each pod operates (implementation-pair SOP, review-pair SOP, etc.)
6. Project-specific documentation in rig-level startup files
**The key principle:** An agent that boots without knowing its role, its team's culture, and its project context will produce generic, unhelpful work. The startup content IS the product value. Invest in it.
### Step 7: Services Integration (If Needed)
If the rig needs managed software (databases, API servers, etc.), add a `services` block. See `~/.openrig/reference/rig-spec.md` for the full services reference.
**When to add services:**
- The agents operate ON software (not just write code)
- The project needs a local dev environment (Postgres, Redis, etc.)
- You're building a managed-app rig (software + specialist agent)
**Services boot before agents.** If health checks fail, no agents start. This is the hard gate — the environment must be healthy before agents can work.
## Authoring: The File Creation Workflow
### Directory Layout
```
my-rig/
rig.yaml # The RigSpec — required
culture/
CULTURE.md # Rig-wide culture — strongly recommended
agents/
my-custom-agent/
agent.yaml # AgentSpec — if custom agent needed
guidance/
role.md # Role guidance
startup/
context.md # Boot-time context
skills/
my-skill/
SKILL.md # Custom skill if needed
docker-compose.yaml # Only if services block is used
```
For rigs that reuse builtin agents, the agents directory is often unnecessary — the rig spec references the builtins directly.
### Workflow
1. **Write the rig spec** (`rig.yaml`) — define pods, members, edges, optionally services
2. **Write or reference agent specs** — builtins for standard roles, custom for specialized roles
3. **Write CULTURE.md** — the team operating manual
4. **Write role guidance** for each custom agent — who they are, what they do
5. **Write startup context** for agents that need environment grounding
6. **Validate:** `rig spec validate rig.yaml` and `rig agent validate agents/*/agent.yaml`
7. **Confirm the runtime cwd** — do not assume agents should work from the directory where the rig spec is stored. The spec root controls file resolution; the runtime cwd controls trust, project guidance, permissions, and repo context.
8. **Launch:** `rig up rig.yaml --cwd /path/to/project`
9. **Verify:** `rig ps --nodes` — all agents ready? Check `rig capture` on each agent.
### Validation Is Non-Negotiable
Always validate before launching:
```bash
rig spec validate rig.yaml
rig agent validate agents/my-agent/agent.yaml
```
If validation fails, fix the errors. Do not try to launch an invalid spec — it will fail with a less helpful error.
## Diagnosis: When Things Go Wrong
### Agent doesn't know its role
**Symptom:** Agent produces generic output, doesn't follow team conventions.
**Root cause:** Missing or insufficient `guidance/role.md`.
**Fix:** Write a clear role guidance file. Include responsibilities, working rhythm, and principles. Reference it in both `resources.guidance` and `startup.files`.
### Agent can't coordinate with peers
**Symptom:** Agent tries raw tmux commands instead of `rig send`, doesn't know peer session names.
**Root cause:** Agent didn't receive `openrig-user` skill or `openrig-start` overlay.
**Fix:** Ensure the agent's profile `uses.skills` includes `openrig-user`. Verify via `rig ps --nodes` that the agent shows expected startup status; check installed skills via direct startup/capture/transcript evidence or the UI node detail (the `rig ps --nodes` projection does not expose installed-resource counts).
### Agent hits approval prompts on rig commands
**Symptom:** Agent stalls on `rig whoami`, `rig send`, etc.
**Root cause:** Claude Code permissions not configured for rig commands.
**Fix:** Describe the required permissions in startup context. The agent should configure `~/.claude/settings.json` with allowlisted rig commands. See `~/.openrig/reference/agent-startup-guide.md` for the current support matrix.
### Agents idle — topology doesn't engage the team
**Symptom:** Orchestrator works with one or two agents, others sit idle.
**Root cause:** Missing `CULTURE.md` or pod SOP content that describes how the full team coordinates.
**Fix:** Write a culture file that explicitly describes the coordination protocol. Include delegation patterns, review gates, and when each pod should be engaged.
### Services don't boot
**Symptom:** `rig up` fails before agents launch with a service health error.
**Root cause:** Docker Compose issue, health check failure, or port conflict.
**Fix:** Check `docker compose up` manually with the compose file. Verify health check URLs are correct. Check for port conflicts.
### Agent boots from the wrong project context
**Symptom:** Agent misses expected guidance, trust settings, permissions, or repo context even though the spec validates.
**Root cause:** The rig spec directory was treated as the agent's runtime cwd by assumption.
**Fix:** Confirm the intended cwd before launch. The spec can live in a rig/spec shelf while the agent works from the project or hub directory that carries the relevant `AGENTS.md`, `CLAUDE.md`, trust, and permissions. Use member `cwd` or `rig up --cwd` deliberately.
### Startup content not delivered
**Symptom:** Agent is missing expected guidance/skills.
**Root cause:** File paths in the spec don't resolve, or `delivery_hint` is wrong.
**Fix:** Verify file paths resolve relative to their owning artifact — AgentSpec resource paths are relative to the agent spec directory; RigSpec startup, culture, compose, cwd, and `local:` agent-ref paths are relative to the rig root. Check `delivery_hint` — use `guidance_merge` for pre-boot content, `send_text` for post-boot instructions.
### Agent startup delivered but agent doesn't use skills
**Symptom:** Skills are projected but agent doesn't invoke them.
**Root cause:** Agent wasn't told to load them.
**Fix:** In the startup context or role guidance, explicitly tell the agent which skills to load. The belt-and-suspenders pattern: project the skills via the spec AND tell the agent to read them in the guidance.
## Pattern Catalog
### The Implementation Pair
**2 agents, 1 pod.** The smallest effective development unit. One implements (TDD), one does QA. The implementer proposes, QA approves or rejects, then the implementer commits.
```yaml
pods:
- id: dev
label: Development
members:
- id: impl
agent_ref: "local:agents/development/implementer"
runtime: claude-code
profile: default
cwd: "."
- id: qa
agent_ref: "local:agents/development/qa"
runtime: codex
profile: default
cwd: "."
edges:
- kind: delegates_to
from: impl
to: qa
```
**Use when:** Focused feature work, bug fixes, small-to-medium implementation tasks.
### The Orchestrated Team
**5-7 agents, 3 pods.** Orchestration + development + review. The orchestrator dispatches work, the dev pair implements, the review pair validates independently.
**Use when:** Production-quality work that needs coordination and independent review.
### The Research Team
**3 agents, 2 pods.** Orchestrator + research pair (analyst + synthesizer). The analyst investigates deeply, the synthesizer consolidates findings.
**Use when:** Technical research, competitive analysis, architecture exploration.
### The Managed App
**1+ agents, 1 pod, services block.** Software infrastructure (Docker Compose) plus a specialist agent who knows how to operate it.
```yaml
services:
kind: compose
compose_file: docker-compose.yaml
wait_for:
- url: http://127.0.0.1:8200/v1/sys/health
pods:
- id: vault
label: Vault
members:
- id: specialist
agent_ref: "local:agents/apps/vault-specialist"
runtime: claude-code
profile: default
cwd: "."
edges: []
```
**Use when:** The work involves operating software, not just writing code.
### The Full Product Team
**7 agents, 3 pods.** The kitchen-sink topology: orchestration pair, development pod (impl + qa + design), review pair. See the `product-team` starter spec for the complete worked example.
**Use when:** Full product development with design, implementation, QA, and independent review. Requires strong culture and SOP content to keep all agents engaged.
## Final Notes
**Start simple, add complexity when needed.** A working implementation pair is better than a broken full team. Launch with the minimum viable topology, verify it works, then expand.
**Culture is not optional for team rigs.** Any rig with 3+ agents needs a CULTURE.md. Without it, agents will default to generic behavior and the topology will underperform.
**Validate early and often.** Run `rig spec validate` after every change. Run `rig agent validate` after every agent spec edit. Fix errors immediately — don't accumulate them.
**The startup content IS the product.** The YAML topology is scaffolding. What makes a rig actually useful is the guidance, culture, skills, and startup context that agents receive. Invest your authoring time there.
@@ -0,0 +1,122 @@
---
name: rig-lifecycle
description: Use when reasoning about the rig lifecycle operations family (create / start / stop / resume / restore / snapshot / release / unclaim / destroy), reading or trusting `rig ps` / lifecycle projections after recovery, or designing proof for a lifecycle scenario. Covers the 4 failure modes (auto-restore creates partial rig; projections report healthier than reality; provider auth treated as impl work; resume succeeds for one runtime fails another) plus the restore-honesty rule (failed resume is FAILED loudly — no auto fresh fallback).
metadata:
openrig:
stage: factory-approved
last_verified: "2026-05-04"
distribution_scope: product-bound
source_evidence: |
Translated from openrig-work/primitives/runtime-control/rig-lifecycle.md (102 lines, matrix-proof-complete-tier-1-with-tier-2-human-gated). Lifecycle Reboot/Recovery Scenario Matrix slice closed at openrig ab01331 (2026-04-30); Codex auth-refusal → attention_required closed at 53e9409 same day.
sibling_skills:
- topology-mutation-and-seat-management
- seat-scaling-and-specialization
- cross-host-rig-commands
- sidecar-operator
- rig-bundles-and-shareable-artifacts
- specification-system
- extension-and-user-workspace
transfer_test: pending
---
# Rig Lifecycle
The family of operations that **create, start, stop, resume, restore,
snapshot, release, unclaim, and destroy** OpenRig-managed topologies.
Includes the user story after reboot: **"bring my work back without
turning a clean recovery into a cleanup project."**
If lifecycle is brittle, every higher-level primitive inherits that
brittleness. Queue, workflow, seat continuity, cross-host operation,
and RSI all assume that rigs and seats can be restored into known
states.
## Use this when
- Operating `rig up / down / restore / resume / snapshot / release / unclaim / destroy`
- Reading `rig ps` after a reboot or recovery and deciding what to trust
- Designing proof for a lifecycle scenario (clean start / warm resume / host reboot / provider auth loss / partial boot / operator recovery)
- Reasoning about restore-outcome semantics (`resumed` / `rebuilt` / `fresh` / `failed` / `attention_required`)
- Auditing whether a lifecycle proof is in-process bedrock vs requires real reboot evidence
## Don't use this when
- The operation is single-command and deterministic — use `openrig-user` skill for CLI surface
- The work is operator-level configuration of OpenRig itself — use `openrig-operator`
- The work is rig spec authoring — use `openrig-architect`
## Failure modes (4)
1. **Auto-restore creates a partially restored rig that must be cleaned up before real recovery.** Partial restore looks like recovery but isn't; cleanup-before-recovery becomes the actual workload.
2. **`rig ps` or lifecycle projections report a healthier state than the runtime actually has.** Projections are summaries; the runtime is truth. Don't trust projections silently.
3. **Provider auth is unavailable after reboot and the system treats that as implementation work** instead of a human/environment decision. Auth issues are environmental; route to human.
4. **Resume succeeds for one runtime/provider but fails for another scenario that was never tested.** Per-runtime parity assumptions break silently; matrix proof catches them.
## Restore-honesty rule (load-bearing)
**Failed resume is FAILED loudly.** No automatic fresh fallback. Fresh
launch is **explicit follow-up only.** This is enforced architecturally
at the daemon level (per `architecture.md` §7 rule 15).
The locked restore-outcome vocabulary:
| Outcome | Meaning |
|---|---|
| `resumed` | Native runtime resumed the same conversation |
| `rebuilt` | New process assembled from artifacts (`session_source: mode: rebuild`) |
| `fresh` | New process with no prior continuity |
| `failed` | Restore attempted and failed; no automatic fallback |
| `attention_required` | Recoverable blocker (provider auth refused, etc.); needs operator action |
| `n-a` | Not applicable (terminal nodes, etc.) |
Codex auth-refusal returns `attention_required` (recoverable); Claude
`looksLikeClaudeLoginPrompt` returns `failed/login_required` (terminal).
Cross-runtime alignment is an open follow-up question.
## Proof standard
Lifecycle proof should include **real reboot or VM-reboot evidence**,
not only daemon-unit evidence. The minimum useful matrix covers:
| Scenario | What it proves |
|---|---|
| Clean start | Boot from spec into known state |
| Warm resume | `rig down` → `rig up <name>` resumes seats |
| Host reboot / tmux socket absence | Recovery from lost tmux connection |
| Provider auth loss | Codex/Claude auth refusal handled honestly |
| Partial boot / partial failure | Some seats up, some failed; honest reporting |
| Intentional operator recovery | Operator-initiated restore from snapshot |
Tier 1: in-process bedrock (daemon-unit evidence). Tier 2: real reboot
or disposable Tart VM. Tier 1 alone is not lifecycle proof; it's
bedrock.
## Default policy is part of the primitive
**Treat default policy as part of the primitive, not an afterthought.**
Lifecycle defaults that are too optimistic for the reliability level
actually proven create silent harm:
- `auto-restore` defaults that mask failure modes
- Implicit fresh-fallback that hides resume failure
- Permissive verification that doesn't distinguish honest success from "appeared to work"
## Total-Host Restore Product Rail v2
The rail sequences restore truth into **four rungs**:
- `fully_restored` is a **Rung 3 execution rollup**
- "fully back" is **reserved for Rung 4 only**
Naming discipline matters. "Fully restored" and "fully back" are
different claims; don't conflate.
## See also
- `openrig-user` skill — CLI surface for `rig up / down / restore / etc.`
- `openrig-operator` skill — operator-level discipline for OpenRig itself
- `seat-continuity-and-handover` skill — sub-primitive: occupant-creation modes for restore (`resume` / `rebuild` / `fresh` / `failed`)
- `session-source-fork` skill — `forked` continuity outcome for fork-based restore
- `permission-and-capability-preflight` skill — provider-auth blocker → escalation path
- `rig-lifecycle` skill — primitive dossier with full slice closure history + Total-Host Restore Product Rail v2 detail
- `openrig/docs/as-built/architecture.md` (product reference doc) — daemon enforcement of restore-honesty rule
@@ -0,0 +1,177 @@
---
name: control-plane-queue
description: Operational skill for the queue control-plane. Use when you need durable known-target handoff, stream intake, queue identity resolution, or the queue/view command surfaces.
status: L4-insight
authored-by: orch-peer@openrig-pm
date: 2026-04-21
canonical-artifact: substrate/shared-docs/control-plane/services/queue/README.md
---
# Control-plane queue
Use this skill when you need the queue control-plane as an operational surface rather than just the doctrine of attention queues.
This skill is about the command surface and service boundary.
If you need the broader coordination doctrine, also read:
- `skills/WIP/attention-queue/SKILL.md`
## What this service owns
The queue service owns:
- `rigx stream ...` for ambiguous/raw intake
- `rigx project ...` for intake-worker classification
- `rigx queue ...` for direct handoff, queue identity, and queue inspection
- `rigx view ...` for aggregate or composed views such as `recently-active`
Canonical artifact:
- `control-plane/services/queue/README.md`
New contributor architecture primer:
- `control-plane/services/queue/docs/stream-first-architecture.md`
## Stream-first mental model
Use this rule before choosing a command:
- `rigx stream` is the immutable intake/audit root for ambiguous observations.
- `rigx project` is the classifier/projection worker lane.
- `rigx queue` is durable owned work and known-target handoff.
- `rigx view` is an operator projection, not a new source of truth.
Do not send known-owner work to stream just because stream is easy. Use `rigx queue handoff`
when a hot potato should wake the next owner.
## Use the right lane
### Known owner
If you know who should own the work:
```bash
rigx queue handoff orch-lead@openrig-pm "Need PM shaping on this finding" --type handoff --urgency soon
```
Passive durable write without wake-up:
```bash
rigx queue create orch-lead@openrig-pm "Need PM shaping on this finding" --type handoff --urgency soon
```
### Consumed passive report
If the queue item was informational only and you have already read and absorbed it, do not leave
it `pending`.
Use:
```bash
rigx queue update <id> \
--state done \
--transition "<timestamp> — absorbed; no further action"
```
This applies to things like:
- loop reports
- observational updates
- routing confirmations
`done` is the right state here. The item has been truthfully discharged; it just did not create
follow-on work.
### Unknown owner
If the correct owner is not yet clear:
```bash
rigx stream emit "Queue attention still feels too manual" --type idea --urgency normal
```
To move old daily stream files out of the hot path without deleting the audit root:
```bash
rigx stream archive --older-than 7 --dry-run
rigx stream archive --older-than 7 --apply
```
Always dry-run first. Archive moves whole `YYYY-MM-DD.jsonl` files into
`~/.openrig/stream/archive/` and refuses overwrite conflicts.
### Worker-only lane
`rigx project` is the intake-worker/classifier lane.
Do not use it casually for normal coordination unless you are explicitly doing classifier work.
## Identity resolution
Do not guess your queue file from your seat name if continuity successors are in play.
Use:
```bash
rigx queue whoami
rigx queue list --mine
```
This matters for seats like `lead2` or `lead5` that intentionally resolve to a canonical base queue file.
## When you need recency, not backlog
If the question is "what moved recently?" rather than "what is pending on one queue?", use:
```bash
rigx view show recently-active
rigx view show recently-active --rig openrig-pm --limit 20
```
This is the queue-based recent-live-work surface.
Do not confuse it with:
- `rigx queue list --rig <rig> --state pending` — broad backlog scan
- `rigx view show activity` — intake-processing activity, not live queue work
- `rigx view show recently-active --rig <rig> --limit N` — focused recency scan for one topology
Built-in `rigx view` scans exclude obvious fixture/test rigs by default. If you are debugging
fixture state on purpose, opt in explicitly:
```bash
OPENRIG_VIEW_INCLUDE_FIXTURES=1 rigx view show recently-active
```
## When this composes with attention-queue
Use this skill for:
- command choice
- queue service boundaries
- queue identity
- direct handoff mechanics
Use `attention-queue` as well for:
- state transitions
- handoff-complete discipline
- escalation rules
- queue-as-status doctrine
## Reachability
If `rigx` is not resolving, use:
- `docs/setup/rigx-host-setup.md`
- repo-local diagnostic path: `control-plane/commands/rigx/bin/rigx`
Do not silently fall back to older wrappers without understanding the environment.
## Honest limits
- current routing is durable-first and still somewhat permissive
- strict topology-aware validation remains a future daemon-backed step
- queue is the durable work surface, not the same thing as the broader attention doctrine
- the queue surface does not have a special `acknowledged` state today; absorbed informational
items should be closed with `state=done` plus an explicit transition note
@@ -0,0 +1,242 @@
---
name: intake-routing
description: |
Use when turning raw signal (idea, bug, observation, feature request, runtime event) into durable, discoverable, selectable work — without dispatching it as an immediate task. Covers the universal-capture / dedicated-processing motion across stream/intake/queue/view/PROGRESS.md, signal-card relationship words (new, duplicate, extends, refines, conflicts-with, part-of, supersedes, blocked-by, evidence-for), spectrum defaults per signal shape, product-primitive request routing, promotion rules, and the dedicated intake seat.
metadata:
openrig:
stage: factory-approved
last_verified: "2026-05-04"
distribution_scope: product-bound
source_evidence: |
Authored 2026-05-03 as part of the convention-pointer sweep batch 2.
Content moved verbatim from openrig-work/conventions/intake-routing/README.md
(active, updated 2026-04-30).
sourced_from:
- openrig-work/conventions/intake-routing/README.md
related_skills:
- agent-feedback-stream (sibling — one specific channel of intake)
- work-discovery-and-slice-shaping (downstream — how curated intake becomes work)
- durability (companion — what it means for an artifact to be durable)
sibling_skills:
- workstream-operating-modes
- workstream-continuity
- workspace-root-and-repo-context
- branching-orientation
- looping-workflows
- work-discovery-and-slice-shaping
- feature-rollout
- feature-lifecycle
- config-wrapper-code-loop
- queue-handoff
- workflow-runtime
- watchdog
- alignment-trace
- human-in-the-loop
- attention-queue
- dispatching-parallel-agents
- subagent-driven-development
- control-plane-capabilities
- status-not-chat-orchestrator
- control-plane-queue
- control-plane-watchdog
- control-plane-workflows
- control-plane-delivery-loop
- control-plane-rollout-manager
transfer_test: pending
---
# Intake Routing
Intake routing is the motion that turns raw signal into durable,
discoverable, selectable work without treating every idea as an
immediate task.
## When to use this skill
- A raw signal arrives (idea, bug observation, feature request,
runtime event) and you need to know where to put it
- You're an intake steward processing signal cards in batches
- You're an orchestrator deciding whether to dispatch from intake
(don't) vs route to durable shelf
- You're classifying relationship between a new signal and existing
artifacts
NOT for: dispatching work directly (signals must be selected, not
pulled from intake). NOT for: shaping the actual slice or candidate
(that's `work-discovery-and-slice-shaping`).
## Disaster Recovery Test
A blank-slate agent that receives a raw idea, bug, observation, or
feature request should be able to start at
`openrig-work/README.md`, find this skill, preserve the signal,
classify it, route it to the right shelf, and **avoid dispatching it
until it is selected.**
## Core Motion
```text
runtime event or raw signal
-> rigx stream when it is live/ambiguous/runtime-originated
-> rigx project or intake steward classification
-> curated intake when it has project meaning
-> compare against existing shelves
-> classify relationship and scale
-> route to owning artifact or planning home
-> promote only when mature enough
-> select into PROGRESS.md only when it becomes active or next work
```
The principle is **universal capture, dedicated processing**:
- Any agent can capture a signal quickly, then return to its main flow.
- The intake steward curates intake in batches when one exists.
- Planner synthesizes ambiguous or product-sized items.
- Orch selects work into the conveyor and protects human intent.
- Human decides product direction, priority conflicts, and large bets.
If no intake steward exists, **orch owns intake processing by default**.
The intake seat is a processor, not a gate: signals should not be lost
just because the dedicated seat is offline.
## Stream, Intake, Queue, View, Progress
Use the coordination layers for different jobs:
- `rigx stream` records **what happened**. Raw, append-only runtime
intake.
- `openrig-work/intake/` records **what a signal means** for the OpenRig
project after curation.
- `rigx queue` records **who owns the next action**.
- `rigx view` projects stream, intake, queue, and activity state for
operators. **It is not truth.**
- `PROGRESS.md` records **selected active or next work** at the right
hierarchy level.
Practical defaults:
- If the owner is unclear or the agent should stay in flow, emit a
stream item.
- If the signal needs durable project meaning, create or update an
intake signal card.
- If the next owner is known and action is needed, use queue.
- If the work is selected for the conveyor, update the relevant
`PROGRESS.md` and slice packet.
The loop closes when proof or closeout emits back into the coordination
substrate and any follow-up signal is routed through this skill instead
of being buried in chat, transcript, or queue body.
Related queue/control-plane doctrine:
- `substrate/shared-docs/control-plane/services/queue/docs/stream-first-architecture.md`
- `substrate/shared-docs/control-plane/services/queue/docs/intake-curate-contract.md`
— 9-field provenance contract every `rigx intake curate` outcome
file must carry (Pilot A vertical shipped 2026-05-01 at substrate
`454d69d`).
- `substrate/shared-docs/control-plane/services/queue/docs/intake-audit-chain.md`
— multi-command audit-chain recipe walking L1 stream JSONL → L2
intake YAML → L4 queue projection → L5 view → outcome inspection.
## Signal Cards
Use a lightweight signal card when a raw item needs more than one line.
Do not build a complex graph. Use a few relationship words and concrete
paths so agents can infer the right next action.
Common relationship words:
- `new` — distinct concept.
- `duplicate` — already captured; link and close.
- `extends` — builds on an existing artifact.
- `refines` — sharpens wording, scope, or doctrine.
- `conflicts-with` — contradicts an existing decision or design.
- `part-of` — belongs under a larger umbrella.
- `supersedes` — replaces an older idea or convention.
- `blocked-by` — cannot move until another primitive or decision exists.
- `evidence-for` — supports an existing idea but is not itself new work.
Prefer full paths for `Target`, `Routed-to`, and `Planning-home` unless
a relative path is intentionally showing local hierarchy.
## Spectrum Defaults
| Signal shape | Default route |
|---|---|
| Tiny bug observation | `intake/bugs-inbox.md`; promote to mission/slice only when reproducible or selected |
| Field observation | `intake/` first; promote to `field-notes/` when narrative evidence matters |
| Reusable work principle | `intake/` first; promote to `conventions/` or `doctrine/` when pattern-shaped |
| Small feature | Existing mission `planning/slice-candidates.md` when coherent; slice packet only when selected |
| Primitive-shaped idea | `primitives/<category>/<name>.md` plus mission planning candidate |
| Product-sized feature | Field note or product brief first; maybe a new mission; decompose later |
| Conflict | Route to the owning artifact and record the conflict; human/planner/orch decision before promotion |
| Part of a whole | Add to the parent artifact or planning home instead of making a top-level artifact |
## Product Primitive Requests
When a feature request is already evidence-backed and primitive-shaped,
file it as a **candidate packet** instead of leaving it only in chat or
raw intake.
Use direct candidate filing when the request has:
- a named primitive or product capability;
- evidence from a live run, dogfood pass, proof artifact, or repeated
failure mode;
- enough current-state context that Product Lab can start a forensic
trace or synthesis without reconstructing the idea from transcript
memory;
- a clear relationship to existing primitives, conventions, or
lifecycle loops.
For RSI v2, put those packets in:
`substrate/shared-docs/openrig-work/missions/recursive-self-improvement-v2/work-discovery-and-slice-shaping/candidates/`
The candidate should include frontmatter fields for status,
classification, relationship, ranking, suggested mode, validation
needs, and whether forensic trace is required. A queue notice may wake
the loop head, but **the candidate file is the durable handoff**. Do
not dispatch implementation directly from the feature request.
If the idea is still raw, ambiguous, or mostly philosophical, put it in
`intake/signals/`, `intake/ideas-inbox.md`, or `rigx stream` first and
let Discovery shape it.
## Promotion Rules
- Preserve raw input before interpreting it.
- Search existing shelves before creating a new artifact.
- Prefer extending or refining an existing artifact over creating a new
one.
- Create a new artifact only when the idea has its own durable identity.
- **Do not dispatch from intake.**
- Do not put an item in `PROGRESS.md` until it is selected work.
- Leave a routing note so a blank-slate agent can reconstruct why it
went there.
## Dedicated Intake Seat
A dedicated intake seat is useful when signal volume is high or
delivery agents are in flow. Its job is to process in batches:
1. read new cards and inbox entries;
2. dedupe against existing shelves;
3. classify relationship and scale;
4. route or promote with backlinks;
5. update `openrig-work/intake/PROGRESS.md`;
6. escalate only priority, conflict, or product-direction questions.
Urgent safety issues and clear active-work blockers can bypass batch
processing and go straight to orch.
## See also
- `agent-feedback-stream` — sibling for the specific feedback-stream
channel.
- `work-discovery-and-slice-shaping` — downstream, how curated intake
becomes shaped work.
- `durability` — what it means for an artifact (intake or otherwise) to
be durable.
- The convention pointer at
`intake-routing` skill.
@@ -0,0 +1,135 @@
---
name: local-sysadmin
description: System administration for Mac Mini development environment. Prevents installation mistakes and environment pollution. Use when installing tools, troubleshooting "command not found" errors, or determining correct installation method. Knows actual environment (Python 3.11/3.13/3.14, UV, nvm, directory structure) and installation preferences (UV for one-offs, venv for projects, never global pip).
metadata:
openrig:
stage: factory-approved
last_verified: "2026-05-04"
distribution_scope: host-specific
source_evidence: |
Graduated 2026-05-04 from openrig-work/skills/workspace/from-home-skills/local-sysadmin/. HOST-SPECIFIC distribution scope — for the kernel rig's sysadmin agent on this host. Documents the actual Mac Mini development environment (Python 3.11/3.13/3.14, UV, nvm, directory structure) and installation preferences (UV for one-offs, venv for projects, never global pip). Pattern C with scripts/ + references/. Forms basis of N_specialist-roles cluster (currently a single-skill cluster; will grow as more host-specific specialist rigs come online).
pattern: "Pattern C (bundled with scripts/ + references/ — environment_specifics.md, project_patterns.md, sysadmin scripts)"
transfer_test: pending
---
# Local System Administrator
## Overview
Prevent installation mistakes and environment pollution. Knows your actual Mac Mini configuration and installation preferences.
## When to Use
- Installing new tools or libraries
- "Command not found" errors
- "Where should I install X?"
- "Which package manager should I use?"
- Troubleshooting PATH issues
## Environment Snapshot
**Installed Tools:**
- Python: 3.11.13, 3.13.7 (default), 3.14.0 (Homebrew) + 3.12.11 (UV-managed)
- UV 0.8.11 (Homebrew)
- Node.js: v16, v18, v22 (nvm)
- Homebrew 4.6.18
- Docker 28.3.2
- Shell: zsh, M2 Mac (arm64)
**Shell Configuration:** `~/.zshrc`
- NVM configured
- WeasyPrint library paths (DYLD_LIBRARY_PATH, PKG_CONFIG_PATH)
- MySQL client in PATH
- No aliases defined yet
**Directory Structure:**
```
~/code/
├── infra/ # Self-managed global functionality
│ ├── services/ # Long-running servers (MCP, databases)
│ └── tools/ # Run-once utilities (scripts, CLIs)
├── omt/example-app-1/ # BigBlueCloud (8 repos)
├── lab/ # Experiments, POCs
├── projects/ # Personal/client work
└── workflow/
└── _dev/ # Global knowledge base (git-tracked)
├── docs/ # Cross-project docs (ai/, infra/, process/)
├── workspace/ # Per-project docs (example-app-1/, srw/, agilitas/, template/)
├── agents/ # Agent configs
├── scripts/ # Utility scripts
└── skills/ # Claude skills
```
## Installation Preferences
**Python:**
- ✅ One-off/learning: `uv run --with <pkg> python3 script.py`
- ✅ Project dependencies: venv (`python3 -m venv venv`)
- ✅ Global CLI tools: `pipx install <tool>`
- ❌ NEVER: `sudo pip install` or global `pip install`
**Node.js:**
- ✅ Use nvm: `nvm use 16` or `nvm use 18`
- ✅ Project deps: `npm install` (local)
- ⚠️ Sparingly: `npm install -g` (global CLI tools only)
**System Tools:**
- ✅ Use Homebrew: `brew install <tool>`
**M2 Mac Compatibility:**
- Node.js 18 with old deps: `NODE_OPTIONS=--openssl-legacy-provider`
## Quick Decisions
**"I want to try pandas"**
→ `uv run --with pandas python3`
**"I'm building a Python project"**
→ `python3 -m venv venv && source venv/bin/activate && pip install pandas`
**"I need black formatter globally"**
→ `pipx install black`
**"I want to install Docker"**
→ `brew install docker`
**"Where do I install an MCP server?"**
→ `~/code/infra/services/mcp-server-name`
**"Where do I put a custom CLI tool?"**
→ `~/code/infra/tools/my-tool` (source code) or `pipx install` (Python CLI)
**"Where do I create a new experiment?"**
→ `~/code/lab/my-experiment`
**"Where do I put project documentation?"**
→ `~/code/workflow/_dev/workspace/<project>/`
## Troubleshooting
**"Command not found"**
1. Check: `which <command>`, `brew list | grep <tool>`
2. Reload: `source ~/.zshrc` or `exec zsh`
3. Verify PATH: `echo $PATH`
**"Wrong Python version"**
- System: `python3` → 3.13.7, `python3.14` → 3.14.0, `python3.11` → 3.11.13
- UV: `uv run` uses 3.12.11 (UV-managed), `uv venv` uses system python3
- Venvs lock to creation Python (immutable)
- Check: `which python3` → should be `/opt/homebrew/bin/python3`
- If in venv: `deactivate`, verify system Python, recreate venv
**"Wrong Node version"**
- Check: `node -v`, `nvm current`
- Switch: `nvm use 16` or `nvm use 18`
## References
Load these only when needed for detailed information:
- `references/environment_specifics.md` - Full PATH, detailed shell config
- `references/project_patterns.md` - Workspace structure, documentation patterns
---
**For workflow optimization, automation, and productivity improvements, use the `workflow-optimizer` skill instead.**
@@ -0,0 +1,101 @@
# Environment Specifics
## Current PATH
```bash
/opt/homebrew/opt/node@22/bin
/opt/homebrew/opt/mysql-client/bin
/opt/homebrew/bin
/opt/homebrew/sbin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
~/.nvm/versions/node/v22.12.0/bin
```
## Shell Configuration (~/.zshrc)
```bash
# NVM
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
# MySQL Client
export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"
# WeasyPrint Dependencies
export DYLD_LIBRARY_PATH="/opt/homebrew/lib:$DYLD_LIBRARY_PATH"
export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:/opt/homebrew/opt/libffi/lib/pkgconfig:$PKG_CONFIG_PATH"
export LDFLAGS="-L/opt/homebrew/opt/libffi/lib"
export CPPFLAGS="-I/opt/homebrew/opt/libffi/include"
# Node 22
export PATH="/opt/homebrew/opt/node@22/bin:$PATH"
```
## Installed Versions
```bash
# Python (Homebrew)
python3 --version # Python 3.13.7 (default)
python3.14 --version # Python 3.14.0
python3.13 --version # Python 3.13.7
python3.11 --version # Python 3.11.13
# Python (UV-managed: ~/.local/share/uv/python/)
# 3.12.11 - Used by `uv run` default
# 3.11.4 - Older managed version
# Other tools
uv --version # uv 0.8.11
node --version # v22.12.0 (default)
nvm ls # v16.x, v18.x, v22.12.0
npm --version # 10.9.0
brew --version # Homebrew 4.6.18
docker --version # Docker 28.3.2
git --version # git 2.39.5
```
## Python Version Behavior
**Discovery Order:**
1. `python3` command → Follows PATH → `/opt/homebrew/bin/python3` (3.13.7)
2. `uv run` → Checks UV-managed first → `~/.local/share/uv/python/` (3.12.11)
3. `uv venv` → Follows system python3 → 3.13.7
**Key Insight:** UV prioritizes its managed Pythons over system Pythons. This divergence is normal and safe:
- Venvs are immutable (locked to creation Python)
- Production projects use venvs (unaffected by UV's default)
- Use `uv run --python 3.13` for explicit control
**Python Locations:**
- Homebrew: `/opt/homebrew/bin/python3.X` → `/opt/homebrew/Cellar/[email protected]/`
- UV-managed: `~/.local/share/uv/python/cpython-3.X.Y-macos-aarch64-none/`
- System: `/usr/bin/python3` (macOS built-in, 3.9.6)
## Homebrew Packages (Selected)
```bash
brew list | grep -E "python|node|docker|aws|tailscale|postgresql"
# [email protected]
# [email protected] (linked as python3)
# [email protected]
# node@22
# nvm (via shell function)
# docker
# aws-cli
# tailscale
# postgresql@16 (client)
```
## Configuration File Locations
- Shell: `~/.zshrc`
- Git: `~/.gitconfig`
- Claude Code: `~/.claude/CLAUDE.md`
- Warp: `~/.warp/launch_configurations/`
- SSH: `~/.ssh/`
- AWS: `~/.aws/config`
@@ -0,0 +1,136 @@
# Project Patterns (Observed)
## Two-Tier Documentation System
**Global Knowledge Base:** `~/code/workflow/_dev/` (git-tracked, shared across projects)
**Per-Project Documentation:** `~/code/workflow/_dev/workspace/<project>/`
### Rationale
Every VS Code/Cursor workspace includes the `_dev/` folder, making documentation accessible from any project without switching contexts.
## Workspace Structure Pattern
**Example from `_dev.code-workspace`:**
```json
{
"folders": [
{ "path": "_dev" }, // Global docs (always accessible)
{ "path": "../projects/clients/srw/.claude" },// Project-specific Claude configs
{ "path": "../omt/example-app-1/.claude" }, // Project-specific Claude configs
{ "path": "../.." } // ~/code/ (for file operations)
],
"settings": {
"files.exclude": {
// Aggressively hide personal folders
"**/Library/**": true,
"**/Downloads/**": true,
"**/Desktop/**": true,
// etc.
}
}
}
```
**Pattern:** Every workspace gets `_dev/` + project-specific paths
## Project Documentation Structure (Converging)
**Template observed in:** `~/code/workflow/_dev/workspace/template/`
```
workspace/<project>/
├── design/ # Design documents
├── docs/ # Project documentation
├── env/ # Environment configurations
├── implement/ # Implementation tracking
│ └── phase1/
│ └── session-1.x/
│ ├── session-1.x-handoff.md
│ ├── session-1.x-developer-log.md
│ └── session-1.x-task-xyz.md
├── planning/ # Planning documents
└── testing/ # Test plans, results
```
**Active projects using similar patterns:**
- `workspace/example-app-1/` - context/, docs/, env/, projects/, temp/
- `workspace/srw/` - backups/, design/, docs/, env/, implement/, planning/, team/, testing/
- `workspace/agilitas/` - design/, docs/, env/, implement/, planning/, research/, testing/
**Observed variation:** Not all projects have identical structure, but common elements emerge:
- `docs/` - Always present
- `env/` - Environment/config info
- `implement/` or `projects/` - Active work
- `planning/` - Planning docs
## Global Documentation Organization
`~/code/workflow/_dev/docs/`
```
docs/
├── ai/ # AI-related documentation (10 items)
├── infra/ # Infrastructure docs (5 items)
└── process/ # Process documentation (3 items)
```
**Pattern:** Topic-based organization at global level
## Workspace Configuration Exclusions
**Consistently excluded across workspaces:**
- Personal folders (Library, Downloads, Desktop, Documents, Pictures, Music, Movies)
- Cache directories (.cache, .npm, .pnpm-store, .pyenv, .cargo)
- Dependencies (node_modules)
- Trash
**Rationale:** Keep workspace explorer clean, focused on code/docs only
## Directory Naming Conventions
**Observed:**
- Lowercase with hyphens: `bigbluecloud-analytics`, `session-1.x`
- Descriptive: `implement/`, `planning/`, not `impl/`, `plan/`
- Categorical at top level: `docs/`, `workspace/`, `agents/`
## Code Project Organization
`~/code/` structure:
```
code/
├── infra/ # Self-managed global functionality
│ ├── services/ # Long-running servers (MCP, databases)
│ └── tools/ # Run-once utilities (scripts, CLIs)
├── omt/
│ └── example-app-1/ # Multi-repo project (8 repos)
├── lab/ # Experiments
├── projects/
│ └── clients/
│ ├── srw/
│ └── agilitas/
└── workflow/
└── _dev/ # Global knowledge base
```
**Pattern:** Organization by client/purpose, not by technology
**Infra Distinction:**
- `infra/services/` - Source code for servers you manage (MCP servers, local databases)
- `infra/tools/` - Source code for utilities you run (scripts, automation, CLIs)
- System tools (Homebrew) - Not source code you manage (ripgrep, docker, uv)
- Project repos - Application code, not global infrastructure
## Session/Phase Organization
**Observed in srw and template:**
```
implement/
└── phase1/
└── session-1.x/
├── handoff.md
├── developer-log.md
└── task-xyz.md
```
**Purpose:** Track implementation work in discrete sessions within phases
@@ -11,7 +11,7 @@ imports:
profiles:
default:
uses:
skills: [openrig-user, openrig-architect, brainstorming, requirements-writer, mental-model-ha]
skills: [openrig-user, openrig-architect, brainstorming, requirements-writer]
guidance: [role]
subagents: []
hooks: []
@@ -4,10 +4,19 @@
// unit tests passed because they mocked the orchestrator; this test
// runs the real validator pipeline against the shipped specs so the
// next regression can't ship unnoticed.
//
// Forward-fix on Phase 05d velocity-qa VM verdict (missing-skills):
// rig spec validate alone is not enough — kernel agents declare
// profile.uses.skills that must resolve against the imported shared
// resource pool. The VM exercise caught 6 skills referenced but not
// registered in shared/agent.yaml. This test adds the resource-pool
// containment gate so the next missing-skill regression fails CI
// instead of failing daemon-start at boot.
import { describe, it, expect } from "vitest";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { readFileSync, existsSync } from "node:fs";
import { join, dirname } from "node:path";
import { parse as parseYaml } from "yaml";
import { validateRigSpecFromYaml } from "../src/domain/spec-validation-service.js";
const SHIPPED_VARIANTS = [
@@ -46,3 +55,85 @@ describe("kernel rig variants — rig spec validate", () => {
expect(shapes.every((s) => s.valid)).toBe(true);
});
});
// Resource-pool containment gate. Each kernel agent (advisor.lead,
// operator.agent, queue.worker) declares profile.uses.skills against
// the imported shared resource pool. If any referenced id is missing
// from shared/agent.yaml's resources.skills, the daemon refuses to
// bootstrap with "Profile uses skills: <id> not found in resource
// pool" — which is the failure mode velocity-qa caught on VM.
describe("kernel agents — profile.uses references resolve against shared pool", () => {
const SHARED_AGENT_YAML = join(
__dirname, "..", "specs", "agents", "shared", "agent.yaml",
);
const KERNEL_AGENTS_DIR = join(KERNEL_DIR, "agents");
const KERNEL_AGENT_PATHS = [
join(KERNEL_AGENTS_DIR, "advisor", "lead", "agent.yaml"),
join(KERNEL_AGENTS_DIR, "operator", "agent", "agent.yaml"),
join(KERNEL_AGENTS_DIR, "queue", "worker", "agent.yaml"),
];
function poolIds(yamlPath: string, kind: "skills" | "runtime_resources"): Set<string> {
const doc = parseYaml(readFileSync(yamlPath, "utf-8")) as {
resources?: { skills?: { id: string; path: string }[]; runtime_resources?: { id: string }[] };
};
const list =
kind === "skills" ? doc.resources?.skills ?? [] : doc.resources?.runtime_resources ?? [];
return new Set(list.map((r) => r.id));
}
function usedSkillIds(yamlPath: string): { profile: string; skills: string[] }[] {
const doc = parseYaml(readFileSync(yamlPath, "utf-8")) as {
profiles?: Record<string, { uses?: { skills?: string[] } }>;
};
const out: { profile: string; skills: string[] }[] = [];
for (const [profile, p] of Object.entries(doc.profiles ?? {})) {
out.push({ profile, skills: p?.uses?.skills ?? [] });
}
return out;
}
// Skills declared in shared/agent.yaml must also exist on disk under
// skills/<path>/SKILL.md. The on-disk-existence check is what catches
// a YAML entry whose path was misspelled or whose dir was forgotten.
it("shared/agent.yaml skills all resolve to packaged SKILL.md files on disk", () => {
const sharedDir = dirname(SHARED_AGENT_YAML);
const doc = parseYaml(readFileSync(SHARED_AGENT_YAML, "utf-8")) as {
resources?: { skills?: { id: string; path: string }[] };
};
const missing: string[] = [];
for (const skill of doc.resources?.skills ?? []) {
const skillFile = join(sharedDir, skill.path, "SKILL.md");
if (!existsSync(skillFile)) {
missing.push(`${skill.id} → ${skill.path} (no SKILL.md at ${skillFile})`);
}
}
if (missing.length > 0) {
throw new Error(
`Packaged shared resource pool declares skills with no on-disk SKILL.md:\n - ${missing.join("\n - ")}`,
);
}
});
for (const agentPath of KERNEL_AGENT_PATHS) {
const label = agentPath
.replace(KERNEL_AGENTS_DIR + "/", "")
.replace("/agent.yaml", "")
.replace("/", ".");
it(`${label}: profile.uses.skills all resolve in shared resource pool`, () => {
const pool = poolIds(SHARED_AGENT_YAML, "skills");
const used = usedSkillIds(agentPath);
const missing: string[] = [];
for (const { profile, skills } of used) {
for (const id of skills) {
if (!pool.has(id)) missing.push(`profile=${profile} skill=${id}`);
}
}
if (missing.length > 0) {
throw new Error(
`${label} references skills not in shared pool:\n - ${missing.join("\n - ")}`,
);
}
});
}
});