{"owner":"nearai","repo":"ironclaw","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md",".claude/skills/architecture-video/SKILL.md",".claude/skills/mintlify-docs/SKILL.md","skills/github/SKILL.md","skills/developer-setup/SKILL.md"],"skills":{"AGENTS.md":"# Agent Rules\n\n## Purpose and precedence\n\n`AGENTS.md` is the canonical agent contract for this repository — the commands, hard invariants, and routing an agent cannot infer from the tree. It is not the full architecture specification: before changing a complex area, read the owning crate's `AGENTS.md`, then its `CONTRACT.md` or `README.md` when present; cross-crate behavior is specified under `docs/internal/reborn/contracts/`. (`CLAUDE.md` files are Claude Code adapters and pointer stubs; content lives here and in the files this one names.)\n\nAll product work belongs in the Reborn workspace under `crates/`; the shipping binary is `ironclaw` from the `ironclaw` package in `crates/app/ironclaw_cli`. `crates/AGENTS.md` is the routing map into the ten crate families. The repo skills under `.claude/skills/` (`ironclaw-reborn-orientation`, `reborn-feature`, `ironclaw-reborn-architecture-review`, `ironclaw-reborn-testing`, `ironclaw-reborn-skill-maintainer`, `reborn-extension-surfaces`) are plain Markdown — read the `SKILL.md` directly if your harness does not load Claude skills.\n\n## Build, run, debug\n\n```bash\ncargo fmt                                                       # format\ncargo clippy --all --benches --tests --examples --all-features -- -D warnings  # lint (zero warnings; CI denies warnings — an unflagged run exits 0 with them)\ncargo test                                                      # unit + integration suites (Postgres legs self-provision testcontainers; skipped without Docker)\nRUST_LOG=ironclaw=debug cargo run -p ironclaw -- serve          # run the serve binary (add tower_http=debug for HTTP logging)\n```\n\nThe workspace-root `integration` feature is empty with zero consumers — a bare root `cargo test --features integration` adds nothing. Backend-heavy gated suites are crate-level (e.g. `cargo test -p ironclaw_hooks --features integration,test-support`). E2E suite: `tests/e2e/CLAUDE.md`.\n\n**Cargo features are a last resort.** A feature is a second build of the workspace, compiled and tested forever. Add one only for a heavy optional dependency, a build shape that ships with it OFF, a CI lane selector, a dev-only seam (always named `test-support`), or a privilege boundary — and say which in the manifest comment. Deployment shape belongs in `DeploymentConfig` and `[storage]`, not `#[cfg]`. Full bar: `.claude/rules/cargo-features.md`.\n\n## Discover code before changing it\n\nFor where-is, who-calls, data-flow, and impact questions, probe the codebase knowledge graph before text search: run `bash scripts/codebase-graph.sh status` once; if fresh and graph tools are connected, use them; otherwise fall back to `crates/AGENTS.md`, crate-local guidance, and targeted `rg`. Verify graph claims against live code before acting. Use `rg` directly for configuration, prose, and fixtures. `openwiki/` is generated prose — read-only, never hand-edit.\n\n## Where work belongs\n\nExternal surfaces normalize untrusted requests through product adapters or `ProductSurface`; thread/turn services establish durable conversation state; the scheduler and run executor invoke the canonical runner/driver and agent loop; capability execution crosses authorization, approvals, obligations, host-runtime mediation, and the selected runtime lane; durable typed events feed projections and transport streams — transports do not invent state. Verify a flow from live symbols:\n\n```bash\nrg -n \"SessionThreadService|TurnCoordinator|TurnRunScheduler|RebornTurnRunExecutor|CanonicalAgentLoopExecutor|CapabilityHost\" crates\n```\n\nCrates live under a family directory (`crates/<family>/ironclaw_*`); enumerate them with `python3 scripts/ci/lib/crate_tree.py .` rather than assuming a fixed depth. Stable ownership decisions:\n\n- Neutral authority vocabulary belongs in `ironclaw_host_api`; execution does not.\n- Filesystem mounts/CAS belong in `ironclaw_filesystem`; record grammar in the domain crate.\n- Durable events, projections, and transport streams are separate contracts.\n- Authorization, approvals, resources, obligations, dispatch, and runtime lanes remain separate stages.\n- `ironclaw_assistant` owns product-facing orchestration and `ProductSurface`; composition wires dependencies; WebUI owns HTTP/transport and frontend presentation.\n- Provider-neutral model contracts and provider implementations belong in `ironclaw_llm`; wrappers delegate the complete provider trait.\n- Declarative extension metadata belongs in `ironclaw_extension_registry`; execution belongs in runtime lanes and host mediation.\n- Safety scanning is `ironclaw_safety`; skills are `ironclaw_skills`; persistent memory is `ironclaw_memory` (model tools `ironclaw.memory.*`). Always import from the owning crate.\n\nThe composition root assembles dependencies; it does not own domain policy — module-specific initialization stays behind factories or builders in the owning crate. If adding a dependency would point from a lower neutral crate into product or composition, stop and run `cargo test -p ironclaw_architecture_tests` first.\n\nSubagent spawn creates and wires child runs only; planning, execution, capability calls, checkpointing, gates, retries, and completion continue through the existing runner/driver/executor path.\n\nHost-trusted trigger ingress is sealed by trigger-worker-owned request minting and private conversation-owned trusted construction. Product adapters, product workflow, first-party capabilities, and host-runtime handlers use untrusted inbound requests and must not mint `TrustedInboundTurnRequest` or call trusted trigger submitter factories.\n\n## Module Specs\n\nWhen modifying a module with a spec, read the spec first. Code follows spec; spec is the tiebreaker.\n\n| Module | Spec |\n|--------|------|\n| `crates/domains/ironclaw_llm/` | `crates/domains/ironclaw_llm/CONTRACT.md` |\n| `crates/substrates/ironclaw_filesystem/` | `crates/substrates/ironclaw_filesystem/CONTRACT.md` |\n| `crates/product/ironclaw_webui/` | `crates/product/ironclaw_webui/CONTRACT.md` |\n| `crates/app/ironclaw_composition/` | `crates/app/ironclaw_composition/CONTRACT.md` |\n| `crates/domains/ironclaw_identity/` | `crates/domains/ironclaw_identity/CONTRACT.md` |\n| `crates/kernel/ironclaw_trust/` | `crates/kernel/ironclaw_trust/CONTRACT.md` |\n| `tests/` (scenario coverage map) | `tests/CLAUDE.md` |\n| `tests/integration/` | `tests/integration/CLAUDE.md` |\n| `tests/support/reborn_parity_qa/` | `tests/support/reborn_parity_qa/CLAUDE.md` |\n| `tests/e2e/` | `tests/e2e/CLAUDE.md` |\n\n## Coding and contract rules\n\n- No `.unwrap()` or `.expect()` in production code (tests are fine); propagate errors with context — `.map_err(|e| SomeError::Variant { reason: e.to_string() })?` — and use `thiserror` for error types in `error.rs`. Cause-preserving constructors, the `map_err(|_| …)` ban, and the other silent-failure anti-patterns: `.claude/rules/error-handling.md`.\n- Keep clippy clean with zero warnings. Prefer `crate::` imports for cross-module references.\n- Use strong types and enums for known domain shapes; raw strings belong at external boundaries. Shared types live with the contract owner — no mirror DTOs, and `ironclaw_common` is not a dumping ground.\n- No `pub use` re-exports unless exposing to downstream consumers.\n- **Prompt templates live in files, not Rust code**: multi-line prompt strings go in a `prompts/*.md` file inside the crate that owns the behavior, loaded via `include_str!()` (`ls -d crates/*/*/prompts crates/extensions/packages/*/prompts` lists the owners). Single-line format strings are fine inline.\n- Preserve existing defaults unless the task explicitly changes them.\n- All I/O is async with tokio; use `Arc<T>` for shared state.\n\n## Testing discipline\n\n1. **Test-first.** Every feature and fix starts in the tests — pin the behavior, watch it fail for the right reason, then change the implementation. Every fix ships with a regression test.\n2. **Consolidate, don't proliferate.** Extend the test that already exercises the path; add a new test only for a genuinely distinct scenario.\n3. **Integration-first.** Production-wired behavior ships with a test in `tests/integration/`, driven through the harness and asserting at a seam — never `wait_for_status(Completed)` alone. Crate tier is the fallback only when that tier cannot reach the path (say why in the PR).\n4. **Test through the caller, not just the helper.** When a helper gates a side effect, unit-testing the helper alone is not regression coverage — drive the call site at the integration tier or higher, and make mocks capture every argument the production caller passes.\n\nFull rules and tiers: `.claude/rules/testing.md`; authoring guides: `tests/integration/CLAUDE.md`, `tests/e2e/CLAUDE.md`. Select tiers with `docs/internal/testing-playbook.md`, and complete the `Test Strategy` section of `.github/pull_request_template.md` with evidence or `Not applicable: <reason>` per tier.\n\n## Persistence and configuration\n\nNew persistence uses `RootFilesystem`/`ScopedFilesystem` and the mount catalog owned by `ironclaw_filesystem` (spec above); composition chooses concrete backends (PostgreSQL, libSQL, local filesystem) by profile. Domain stores are thin typed wrappers and never branch on backend; keep dual-backend parity via shared conformance suites (`.claude/rules/database.md`). Read-modify-write uses the shared bounded CAS helper, never a process-local mutex held across backend I/O.\n\nKeep bootstrap configuration, persisted settings, and encrypted secrets as separate layers; preserve configuration precedence, secret-mediated provider resolution, and fail-closed startup. Environment variables are documented in `.env.example`; LLM backends in the llm spec (`LlmBackendKind` in `crates/domains/ironclaw_llm/src/config.rs` is the source of truth).\n\n## Security and runtime invariants\n\n- Treat every listener, route, product adapter, runtime lane, container, and external service as untrusted until a typed boundary establishes otherwise.\n- Do not weaken authentication, origin checks, body limits, rate limits, allowlists, approval leases, secret mediation, or redaction guarantees.\n- External HTTP goes through `ironclaw_network`; credentials remain host-side and are injected only through mediated runtime services.\n- New ingress must validate and bound the original payload before persistence, prompt construction, credential injection, or dispatch.\n- Authorization, approval, reservation, dispatch, and execution are distinct stages. Do not bypass or collapse them — product/WebUI handlers, triggers, channels, and agent callers go through `ProductSurface` and the capability contracts, never around them to mutate stores directly.\n- Session, thread, turn, and run identities are typed and must not be re-derived from display strings or transport metadata.\n- **LLM data is never deleted.** Context, reasoning, tool calls, messages, events, steps — mark with timestamps and make filterable, but always retain. In-memory maps are caches; the database is the source of truth. \"Cleanup\" means evicting caches, never deleting rows.\n- Never commit secrets or PII.\n\n## Capabilities, extensions, and lifecycle\n\n- Core host behavior uses typed built-in capabilities behind the same mediated host surface as other execution.\n- Sandboxed extension execution belongs in WASM or a runtime lane; external server integrations belong behind MCP and the network boundary.\n- Discovery is side-effect-free. Installation, credential binding, activation, execution, deactivation, and removal are explicit lifecycle transitions.\n- Capability failures the model or user can correct are model-visible outcomes; host errors are reserved for failures that end the run.\n- Side-effecting success requires durable or provider-issued evidence plus read-back verification; if read-back is impossible, report explicitly unverified rather than completed.\n\n### Extension/Auth Invariants\n\nThe top-level product object is always an **extension**; a channel is one capability surface an extension's manifest declares (`tool` / `channel` / `auth` — `ironclaw_extension_contracts::surface::CapabilitySurfaceKind`), and runtime (`wasm` / `mcp` / `first_party`) is implementation, never taxonomy. `ExtensionId` is the product identity (`slack`, `github`, `gmail`); `VendorId` (manifest field `vendor`) is the credential-authority namespace and may back several extensions (`google` backs gmail + drive + calendar). There is no separate channel registry and no extension `kind` wire string — `crates/app/ironclaw_architecture_tests/tests/reborn_retired_taxonomy.rs` pins the retired vocabulary at zero.\n\nTwo identities must never be conflated (newtypes in `crates/contracts/ironclaw_common/src/identity.rs`; identity model `crates/domains/ironclaw_identity/CONTRACT.md`; OAuth transport `crates/domains/ironclaw_auth`):\n\n- `credential_name` — backend secret identity (storage, injection, gate resume), e.g. `telegram_bot_token`, `google_oauth_token`.\n- `extension_name` — user-facing installed extension/channel identity (setup routing, UI), e.g. `telegram`, `gmail`.\n\nNever route setup/configure UI from `credential_name`; chat and Settings use the same setup path; generic auth-card UI is only for non-extension credential prompts or pure OAuth launches; resolve `extension_name` once in shared backend logic and carry it through the wire contract instead of re-deriving it per layer or adding frontend-only fallbacks.\n\nAdding a channel means adding one capability surface of an extension — a `[channel]` section in the `reborn.extension_manifest.v3` manifest plus a `ChannelAdapter` (`crates/contracts/ironclaw_extension_contracts/src/channel_adapter.rs`), wired through `RebornHostBindings::with_channel_extension_bindings` (`crates/app/ironclaw_composition/src/input.rs`) — never per-channel host code. Start from the `reborn-extension-surfaces` skill; the worked example is `crates/extensions/packages/slack/`; family rules in `crates/extensions/AGENTS.md`.\n\n## Project structure\n\n```\ncrates/                     # all production code, by family (crates/AGENTS.md is the map)\n├── app/                    # ironclaw_cli (binary `ironclaw`), ironclaw_composition, ironclaw_config, ironclaw_architecture_tests\n├── contracts/              # ironclaw_host_api, ironclaw_common, ironclaw_extension_contracts, ironclaw_product_contracts, …\n├── domains/                # ironclaw_llm, ironclaw_skills, ironclaw_threads, ironclaw_auth, ironclaw_memory, …\n├── events/                 # ironclaw_event_log / _projections / _store / _streams\n├── extensions/             # ironclaw_extension_host/_manager/_registry/_support + packages/ (slack, telegram, …)\n├── kernel/                 # ironclaw_turns, ironclaw_capabilities, ironclaw_approvals, ironclaw_host_runtime, …\n├── lanes/                  # ironclaw_wasm, ironclaw_sandbox, ironclaw_mcp\n├── loop/                   # ironclaw_agent_loop, ironclaw_turn_runner, ironclaw_loop_host, ironclaw_hooks\n├── product/                # ironclaw_webui (SPA in frontend/), ironclaw_assistant, …\n└── substrates/             # ironclaw_filesystem, ironclaw_safety, ironclaw_network, ironclaw_secrets, …\n\ntests/                      # root-package integration suite, parity/QA, support, e2e\n```\n\nThe workspace root (`Cargo.toml`, package `ironclaw_integration_tests`) hosts only the integration test suite; the one workspace `exclude` is `tools/ironclaw_silk_decoder`.\n\n`docs/` is the public Mintlify site plus fenced internal material. All new\ninternal engineering docs (design notes, research, plans, QA maps) go under\n`docs/internal/` — nowhere else under `docs/`. A page outside the\n`docs/.mintignore` fence is published even when omitted from `docs.json`\nnavigation (hidden pages stay reachable by URL), and `.mintignore` is frozen:\ndo not add entries. Enforced by `scripts/ci/docs_publication_boundary.py`\n(Code Style workflow); run it to check placement.\n\n## Change discipline, and before finishing\n\n- Keep changes scoped; preserve unrelated work in dirty worktrees; avoid generated-file churn. Security, persistence-schema, runtime, worker, CI, and secrets changes need explicit rollback/compatibility review.\n- Run the narrowest meaningful checks, plus `cargo test -p ironclaw_architecture_tests` when dependency edges, layer keys, crate placement, or test-pinned guidance files change.\n- Search changed production files for `.unwrap()`/`.expect()`, suspicious byte slicing, hardcoded temporary paths, and lost error causes.\n- When a trait changes, enumerate all implementations, decorators, adapters, and test doubles; when a pattern bug is fixed, search `crates/` for sibling instances.\n- After moves/renames, search agent guidance, contracts, docs, tests, scripts, manifests, and frontend imports for old paths.\n- Update the owning contract/docs when behavior changes; the PR title/body must describe every layer in the diff and note compatibility, rollback, and follow-up risks.\n","CLAUDE.md":"# IronClaw — Claude Code adapter\n\n@AGENTS.md\n\nEverything above (from `AGENTS.md`) is the canonical, tool-neutral contract.\nThe rest of this file is Claude-specific.\n\n## Skills and rules\n\n- Project skills live in `.claude/skills/` — start from\n  `ironclaw-reborn-orientation`; use `reborn-feature` for cross-layer product\n  work, `reborn-extension-surfaces` for integrations,\n  `ironclaw-reborn-testing` for test tiers,\n  `ironclaw-reborn-architecture-review` for boundary changes, and\n  `ironclaw-reborn-skill-maintainer` before editing any guidance file.\n- Path-scoped rules in `.claude/rules/*.md` load automatically when you read\n  matching files — they are canonical for their topics (testing, database,\n  types, cargo-features, review discipline, …); do not restate them here.\n\n## Codebase knowledge graph (MCP)\n\nThe `codebase-memory` MCP server indexes `crates/` into a knowledge graph;\nprefer it over `Grep` for *code structure* (cross-crate call chains are\ninvisible to text search). `.codebase-memory/graph.db.zst` is the committed\nbootstrap snapshot; local databases and\n`.codebase-memory/artifact.json` <!-- check-guidance: path-ok --> stay\ngit-ignored (per-environment state, deliberately untracked). Check\nfreshness first: `bash scripts/codebase-graph.sh status`.\n\n- Missing → `index_repository(repo_path=\".\", persistence=true)` once.\n- Stale → `detect_changes(since=\"<indexed-commit>\")`, or re-run\n  `index_repository` to refresh the shared snapshot.\n- Where is a symbol → `search_graph(name_pattern=…)`, then\n  `get_code_snippet(qualified_name=…)`.\n- Who calls X / what X calls → `trace_path(function_name=…, mode=\"calls\")`;\n  value flow → `mode=\"data_flow\"`; cross-crate feature path →\n  `mode=\"cross_service\"`.\n- Structure of an area → `get_architecture(…)`; graph-augmented text search →\n  `search_code(pattern=…)`; arbitrary queries → `query_graph(<Cypher>)`.\n\nThe graph is a point-in-time index — verify anything it asserts against live\ncode before acting. `Grep`/`Glob`/`Read` remain correct for text, config, and\nnon-code files. For narrative *what/why* orientation, read the relevant\n`openwiki/` page (generated — never hand-edit).\n\n## REPL/TUI logging rule\n\n`info!` and `warn!` output appears in the REPL and corrupts the terminal UI.\nUse `debug!` for internal diagnostics (trace analysis, reflection results,\nengine internals); reserve `info!` for user-facing status the REPL\nintentionally renders. Background tasks must NEVER use `info!`.\n",".claude/skills/architecture-video/SKILL.md":"---\nname: architecture-video\ndescription: Generate or update the IronClaw architecture overview video using Remotion. Use when asked to update, regenerate, or modify the architecture video, add/remove scenes, or reflect codebase changes in the video.\n---\n\n# Architecture Video Generator\n\nGenerates and maintains the animated architecture overview video in `docs/internal/architecture-video/` using Remotion (React-based video framework).\n\n## When to use\n\n- User asks to update, regenerate, or modify the architecture video\n- User asks to add or remove scenes from the video\n- Codebase architecture has changed and the video needs to reflect it\n- User wants to preview or render the video\n\n## Before making changes\n\n### 1. Read current architecture\n\nRead these files to understand the current system architecture:\n\n- `AGENTS.md` — top-level commands, invariants, tree map, module specs table\n- `crates/Architecture.md` — **the Reborn stack thesis and component map (the current architecture; lead the video with this)**\n- `crates/AGENTS.md` — the Reborn crate routing map\n- `crates/domains/ironclaw_llm/CONTRACT.md` — canonical LLM provider architecture\n- `crates/substrates/ironclaw_filesystem/CONTRACT.md` — storage fabric / dual-backend architecture\n- `crates/extensions/AGENTS.md` — the installable-package family: extension packages, tool surfaces, lifecycle host (successor of the v1 tool system)\n- `crates/domains/ironclaw_memory/README.md` — the memory contract and conformance seam (successor of the v1 workspace/memory system)\n\n### 2. Read current video scenes\n\nRead `docs/internal/architecture-video/src/IronClawArchitecture.tsx` to understand current scene order, durations, and transitions. Then read individual scenes in `docs/internal/architecture-video/src/scenes/` to see what's already covered.\n\n### 3. Identify gaps\n\nCompare the architecture documentation with what the video covers. Look for:\n- New modules or traits added since the video was last updated\n- Renamed or restructured components\n- New data flows or state machines\n- Removed or deprecated features\n\n## Video project structure\n\n```\ndocs/internal/architecture-video/\n├── package.json              # Remotion deps\n├── remotion.config.ts        # Build config\n├── src/\n│   ├── Root.tsx              # Remotion entry — registers the composition\n│   ├── IronClawArchitecture.tsx  # Main composition — scene order + transitions\n│   ├── theme.ts              # Color palette + font constants\n│   ├── components/\n│   │   └── Code.tsx          # Syntax-highlighted code block component\n│   └── scenes/               # One file per scene\n│       ├── TitleScene.tsx\n│       ├── PrimitivesScene.tsx\n│       ├── ExecutionLoopScene.tsx\n│       ├── CodeActScene.tsx\n│       ├── ThreadStateScene.tsx\n│       ├── SkillsPipelineScene.tsx\n│       ├── ToolDispatchScene.tsx\n│       ├── ChannelsRoutingScene.tsx\n│       ├── ChannelImplsScene.tsx\n│       ├── TraitsScene.tsx\n│       ├── LlmDecoratorScene.tsx\n│       └── OutroScene.tsx\n```\n\nRender script: `scripts/render-architecture-video.sh`\n\n## Current scene inventory (12 scenes, ~82s at 30fps)\n\n| # | Scene | File | Duration | Content |\n|---|-------|------|----------|---------|\n| 1 | Title | TitleScene.tsx | 4s | Animated IronClaw logo + tagline |\n| 2 | Five Primitives | PrimitivesScene.tsx | 8s | Thread / Step / Capability / MemoryDoc / Project |\n| 3 | Execution Loop | ExecutionLoopScene.tsx | 8s | 7-step ExecutionLoop::run() pipeline |\n| 4 | CodeAct | CodeActScene.tsx | 10s | Python code → host fns → suspend/resume flow |\n| 5 | Thread State | ThreadStateScene.tsx | 7s | Created→Running⇄Waiting/Suspended→Completed/Failed→Done |\n| 6 | Skills Pipeline | SkillsPipelineScene.tsx | 8s | Gating → Scoring → Budget → Attenuation |\n| 7 | Tool Dispatch | ToolDispatchScene.tsx | 9s | 9-step ToolDispatcher::dispatch() pipeline |\n| 8 | Channels Routing | ChannelsRoutingScene.tsx | 7s | Channel trait + stream::select_all merging |\n| 9 | Channel Impls | ChannelImplsScene.tsx | 7s | REPL / HTTP / Web / Signal / TUI / WASM |\n| 10 | Traits | TraitsScene.tsx | 8s | 8 traits with concrete implementers |\n| 11 | LLM Decorators | LlmDecoratorScene.tsx | 7s | SmartRouting→CircuitBreaker→...→Base decorator chain |\n| 12 | Outro | OutroScene.tsx | 5s | Start Contributing + getting-started steps |\n\n## Remotion patterns used in this project\n\nAll animations MUST be driven by `useCurrentFrame()` — never CSS transitions or Tailwind animation classes.\n\n### Animation pattern\n\n```tsx\nconst frame = useCurrentFrame();\nconst { fps } = useVideoConfig();\n\nconst opacity = interpolate(frame, [0, 0.5 * fps], [0, 1], {\n  extrapolateRight: \"clamp\",\n});\nconst y = interpolate(frame, [0, 0.5 * fps], [30, 0], {\n  extrapolateRight: \"clamp\",\n  easing: Easing.bezier(0.16, 1, 0.3, 1),\n});\n```\n\n### Staggered list pattern\n\nFor items that appear one by one:\n\n```tsx\n{items.map((item, i) => {\n  const delay = 0.4 + i * 0.3; // seconds\n  const opacity = interpolate(\n    frame,\n    [delay * fps, (delay + 0.35) * fps],\n    [0, 1],\n    { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" }\n  );\n  return <div style={{ opacity }} key={item.id}>...</div>;\n})}\n```\n\n### Scene transitions\n\nScenes are composed using `TransitionSeries` with alternating `fade()` and `slide({ direction: \"from-right\" })` transitions, each 15 frames (0.5s):\n\n```tsx\n<TransitionSeries>\n  <TransitionSeries.Sequence durationInFrames={s(8)}>\n    <MyScene />\n  </TransitionSeries.Sequence>\n  <TransitionSeries.Transition\n    presentation={fade()}\n    timing={linearTiming({ durationInFrames: 15 })}\n  />\n  <TransitionSeries.Sequence durationInFrames={s(7)}>\n    <NextScene />\n  </TransitionSeries.Sequence>\n</TransitionSeries>\n```\n\n### Code blocks\n\nUse the `CodeBlock` component from `../components/Code` for syntax-highlighted code:\n\n```tsx\nimport { CodeBlock } from \"../components/Code\";\n\n<CodeBlock code={`pub trait Channel: Send + Sync {\n  async fn start(&self) -> Result<MessageStream>;\n}`} fontSize={13} />\n```\n\n### Theme\n\nImport colors and fonts from `../theme`:\n\n```tsx\nimport { COLORS, FONTS } from \"../theme\";\n\n// Available colors:\n// bg, bgLight, primary, primaryLight, accent, accentLight,\n// success, danger, text, textMuted, border, purple, cyan, pink\n\n// Available fonts:\n// mono (monospace), sans (system-ui)\n```\n\n## Adding a new scene\n\n1. Create `src/scenes/MyNewScene.tsx` following existing patterns\n2. Export the component\n3. Import in `IronClawArchitecture.tsx`\n4. Add to the `SCENES` array with duration and transition type\n5. `TOTAL_DURATION` auto-computes from the array\n6. Verify with: `npx remotion still IronClawArchitecture --scale=0.25 --frame=<N>`\n\n### Scene template\n\n```tsx\nimport {\n  AbsoluteFill,\n  interpolate,\n  useCurrentFrame,\n  useVideoConfig,\n  Easing,\n} from \"remotion\";\nimport { COLORS, FONTS } from \"../theme\";\n\nexport const MyNewScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  const { fps } = useVideoConfig();\n\n  const headingOpacity = interpolate(frame, [0, 0.4 * fps], [0, 1], {\n    extrapolateRight: \"clamp\",\n  });\n\n  return (\n    <AbsoluteFill\n      style={{\n        backgroundColor: COLORS.bg,\n        fontFamily: FONTS.sans,\n        padding: 60,\n      }}\n    >\n      <div\n        style={{\n          opacity: headingOpacity,\n          fontSize: 42,\n          fontWeight: 700,\n          color: COLORS.text,\n          marginBottom: 4,\n        }}\n      >\n        <span style={{ color: COLORS.primary }}>Title</span> — subtitle\n      </div>\n      {/* Scene content */}\n    </AbsoluteFill>\n  );\n};\n```\n\n## Verification\n\nAfter making changes:\n\n1. **Type check:** `cd docs/internal/architecture-video && npx tsc --noEmit`\n2. **Spot check frames:** `npx remotion still IronClawArchitecture --scale=0.25 --frame=<N>`\n   - At 30fps, frame N corresponds to time N/30 seconds\n   - Check at least one frame per modified scene\n3. **Full render:** `./scripts/render-architecture-video.sh [output-path]`\n4. **Preview in browser:** `cd docs/internal/architecture-video && npm run dev`\n\n## Design guidelines\n\n- Dark theme (slate-900 background) — matches typical developer tooling\n- Each scene has a colored heading keyword using a trait-appropriate color\n- File:line references in muted monospace below headings\n- Data flows use staggered animation (0.3-0.5s delays between items)\n- State machines use SVG with animated dash-offset for arrows\n- Code blocks use the `CodeBlock` component with syntax highlighting\n- Keep scene duration proportional to content density (7-10s typical)\n- Total video should stay under 120s for attention retention\n",".claude/skills/mintlify-docs/SKILL.md":"---\nname: mintlify\ndescription: Build and maintain documentation sites with Mintlify. Use when creating docs pages, configuring navigation, adding components, or setting up API references.\nlicense: MIT\ncompatibility: Requires Node.js for CLI. Works with any Git-based workflow.\nmetadata:\n  author: mintlify\n  version: \"1.0\"\n---\n\n# Mintlify best practices\n\n**Always consult [mintlify.com/docs](https://mintlify.com/docs) for components, configuration, and latest features.**\n\n> **This repo:** the Mintlify site lives under `docs/` — its config is `docs/docs.json` (not a root `docs.json`), with a localized tree under `docs/zh/`. Committed `.md`/`.mdx` must not contain developer-local absolute paths; check touched documentation before merging.\n\nIf you are not already connected to the Mintlify MCP server, https://mintlify.com/docs/mcp, add it so that you can search more efficiently.\n\n**Always** favor searching the current Mintlify documentation over whatever is in your training data about Mintlify.\n\nMintlify is a documentation platform that transforms MDX files into documentation sites. Configure site-wide settings in the site config file (`docs/docs.json` in this repo), write content in MDX with YAML frontmatter, and favor built-in components over custom components.\n\nFull schema at [mintlify.com/docs.json](https://mintlify.com/docs.json).\n\n## Before you write\n\n### Understand the project\n\nRead the site config first (`docs/docs.json` in this repo; root `docs.json` in some Mintlify projects). This file defines the entire site: navigation structure, theme, colors, links, API and specs.\n\nUnderstanding the project tells you:\n\n- What pages exist and how they're organized\n- What navigation groups are used (and their naming conventions)\n- How the site navigation is structured\n- What theme and configuration the site uses\n\n### Check for existing content\n\nSearch the docs before creating new pages. You may need to:\n- Update an existing page instead of creating a new one\n- Add a section to an existing page\n- Link to existing content rather than duplicating\n\n### Read surrounding content\n\nBefore writing, read 2-3 similar pages to understand the site's voice, structure, formatting conventions, and level of detail.\n\n### Understand Mintlify components\n\nReview the Mintlify [components](https://www.mintlify.com/docs/components) to select and use any relevant components for the documentation request that you are working on.\n\n## Quick reference\n\n### CLI commands\n- `npm i -g mint` - Install the Mintlify CLI\n- `mint dev` - Local preview at localhost:3000\n- `mint broken-links` - Check internal links\n- `mint a11y` - Check for accessibility issues in content\n- `mint validate` - Validate documentation builds\n\n### Required files\n- Site config (`docs/docs.json` in this repo) - navigation, theme, integrations, etc. See [global settings](https://mintlify.com/docs/settings/global) for all options.\n- `*.mdx` files - Documentation pages with YAML frontmatter\n\n### Example file structure\n```\nproject/\n├── docs.json           # Site configuration (this repo keeps it at docs/docs.json)\n├── introduction.mdx\n├── quickstart.mdx\n├── guides/\n│   └── example.mdx\n├── openapi.yml         # API specification\n├── images/             # Static assets\n│   └── example.png\n└── snippets/           # Reusable components\n    └── component.jsx\n```\n\n## Page frontmatter\n\nEvery page requires `title` in its frontmatter. Include `description` for SEO and navigation.\n\n```yaml\n---\ntitle: \"Clear, descriptive title\"\ndescription: \"Concise summary for SEO and navigation.\"\n---\n```\n\nOptional frontmatter fields:\n- `sidebarTitle`: Short title for sidebar navigation.\n- `icon`: Lucide or Font Awesome icon name, URL, or file path.\n- `tag`: Label next to the page title in the sidebar (for example, \"NEW\").\n- `mode`: Page layout mode (`default`, `wide`, `custom`).\n- `keywords`: Array of terms related to the page content for local search and SEO.\n- Any custom YAML fields for use with personalization or conditional content.\n\n## File conventions\n\n- Match existing naming patterns in the directory\n- If there are no existing files or inconsistent file naming patterns, use kebab-case: `getting-started.mdx`, `api-reference.mdx`\n- Use root-relative paths without file extensions for internal links: `/getting-started/quickstart`\n- Do not use relative paths (`../`) or absolute URLs for internal pages\n- When you create a new page, add it to site config navigation (`docs/docs.json` here) or it won't appear in the sidebar\n\n## Organize content\n\nWhen a user asks about anything related to site-wide configurations, start by understanding the [global settings](https://www.mintlify.com/docs/organize/settings). See if a setting in the site config (`docs/docs.json` here) can be updated to achieve what the user wants.\n\n### Navigation\n\nThe `navigation` property in the site config (`docs/docs.json` here) controls site structure. Choose one primary pattern at the root level, then nest others within it.\n\n**Choose your primary pattern:**\n\n| Pattern | When to use |\n|---------|-------------|\n| **Groups** | Default. Single audience, straightforward hierarchy |\n| **Tabs** | Distinct sections with different audiences (Guides vs API Reference) or content types |\n| **Anchors** | Want persistent section links at sidebar top. Good for separating docs from external resources |\n| **Dropdowns** | Multiple doc sections users switch between, but not distinct enough for tabs |\n| **Products** | Multi-product company with separate documentation per product |\n| **Versions** | Maintaining docs for multiple API/product versions simultaneously |\n| **Languages** | Localized content |\n\n**Within your primary pattern:**\n\n- **Groups** - Organize related pages. Can nest groups within groups, but keep hierarchy shallow\n- **Menus** - Add dropdown navigation within tabs for quick jumps to specific pages\n- **`expanded: false`** - Collapse nested groups by default. Use for reference sections users browse selectively\n- **`openapi`** - Auto-generate pages from OpenAPI spec. Add at group/tab level to inherit\n\n**Common combinations:**\n- Tabs containing groups (most common for docs with API reference)\n- Products containing tabs (multi-product SaaS)\n- Versions containing tabs (versioned API docs)\n- Anchors containing groups (simple docs with external resource links)\n\n### Links and paths\n\n- **Internal links:** Root-relative, no extension: `/getting-started/quickstart`\n- **Images:** Store in `/images`, reference as `/images/example.png`\n- **External links:** Use full URLs, they open in new tabs automatically\n\n## Customize docs sites\n\n**What to customize where:**\n- **Brand colors, fonts, logo** → site config (`docs/docs.json` here). See [global settings](https://mintlify.com/docs/settings/global)\n- **Component styling, layout tweaks** → `custom.css` at project root\n- **Dark mode** → Enabled by default. Only disable with `\"appearance\": \"light\"` in the site config if brand requires it\n\nStart with the site config (`docs/docs.json` here). Only add `custom.css` when you need styling that config doesn't support.\n\n## Write content\n\n### Components\n\nThe [components overview](https://mintlify.com/docs/components) organizes all components by purpose: structure content, draw attention, show/hide content, document APIs, link to pages, and add visual context. Start there to find the right component.\n\n**Common decision points:**\n\n| Need | Use |\n|------|-----|\n| Hide optional details | `<Accordion>` |\n| Long code examples | `<Expandable>` |\n| User chooses one option | `<Tabs>` |\n| Linked navigation cards | `<Card>` in `<Columns>` |\n| Sequential instructions | `<Steps>` |\n| Code in multiple languages | `<CodeGroup>` |\n| API parameters | `<ParamField>` |\n| API response fields | `<ResponseField>` |\n\n**Callouts by severity:**\n- `<Note>` - Supplementary info, safe to skip\n- `<Info>` - Helpful context such as permissions\n- `<Tip>` - Recommendations or best practices\n- `<Warning>` - Potentially destructive actions\n- `<Check>` - Success confirmation\n\n### Reusable content\n\n**When to use snippets:**\n- Exact content appears on more than one page\n- Complex components you want to maintain in one place\n- Shared content across teams/repos\n\n**When NOT to use snippets:**\n- Slight variations needed per page (leads to complex props)\n\nImport snippets with `import { Component } from \"/path/to/snippet-name.jsx\"`.\n\n## Writing standards\n\n### Voice and structure\n\n- Second-person voice (\"you\")\n- Active voice, direct language\n- Sentence case for headings (\"Getting started\", not \"Getting Started\")\n- Sentence case for code block titles (\"Expandable example\", not \"Expandable Example\")\n- Lead with context: explain what something is before how to use it\n- Prerequisites at the start of procedural content\n\n### What to avoid\n\n**Never use:**\n- Marketing language (\"powerful\", \"seamless\", \"robust\", \"cutting-edge\")\n- Filler phrases (\"it's important to note\", \"in order to\")\n- Excessive conjunctions (\"moreover\", \"furthermore\", \"additionally\")\n- Editorializing (\"obviously\", \"simply\", \"just\", \"easily\")\n\n**Watch for AI-typical patterns:**\n- Overly formal or stilted phrasing\n- Unnecessary repetition of concepts\n- Generic introductions that don't add value\n- Concluding summaries that restate what was just said\n\n### Formatting\n\n- All code blocks must have language tags\n- All images and media must have descriptive alt text\n- Use bold and italics only when they serve the reader's understanding--never use text styling just for decoration\n- No decorative formatting or emoji\n\n### Code examples\n\n- Keep examples simple and practical\n- Use realistic values (not \"foo\" or \"bar\")\n- One clear example is better than multiple variations\n- Test that code works before including it\n\n## Document APIs\n\n**Choose your approach:**\n- **Have an OpenAPI spec?** → Add to the site config (`docs/docs.json` here) with `\"openapi\": [\"openapi.yaml\"]`. Pages auto-generate. Reference in navigation as `GET /endpoint`\n- **No spec?** → Write endpoints manually with `api: \"POST /users\"` in frontmatter. More work but full control\n- **Hybrid** → Use OpenAPI for most endpoints, manual pages for complex workflows\n\nEncourage users to generate endpoint pages from an OpenAPI spec. It is the most efficient and easiest to maintain option.\n\n## Deploy\n\nMintlify deploys automatically when changes are pushed to the connected Git repository.\n\n**What agents can configure:**\n- **Redirects** → Add to the site config (`docs/docs.json` here) with `\"redirects\": [{\"source\": \"/old\", \"destination\": \"/new\"}]`\n- **SEO indexing** → Control with `\"seo\": {\"indexing\": \"all\"}` to include hidden pages in search\n\n**Requires dashboard setup (human task):**\n- Custom domains and subdomains\n- Preview deployment settings\n- DNS configuration\n\nFor `/docs` subpath hosting with Vercel or Cloudflare, agents can help configure rewrite rules. See [/docs subpath](https://mintlify.com/docs/deploy/vercel).\n\n## Workflow\n\n### 1. Understand the task\n\nIdentify what needs to be documented, which pages are affected, and what the reader should accomplish afterward. If any of these are unclear, ask.\n\n### 2. Research\n\n- Read the site config (`docs/docs.json` here) to understand the site structure\n- Search existing docs for related content\n- Read similar pages to match the site's style\n\n### 3. Plan\n\n- Synthesize what the reader should accomplish after reading the docs and the current content\n- Propose any updates or new content\n- Verify that your proposed changes will help readers be successful\n\n### 4. Write\n\n- Start with the most important information\n- Keep sections focused and scannable\n- Use components appropriately (don't overuse them)\n- Mark anything uncertain with a TODO comment:\n\n```mdx\n{/* TODO: Verify the default timeout value */}\n```\n\n### 5. Update navigation\n\nIf you created a new page, add it to the appropriate group in the site config (`docs/docs.json` here).\n\n### 6. Verify\n\nBefore submitting:\n\n- [ ] Frontmatter includes title and description\n- [ ] All code blocks have language tags\n- [ ] Internal links use root-relative paths without file extensions\n- [ ] New pages are added to site config navigation (`docs/docs.json` here)\n- [ ] Content matches the style of surrounding pages\n- [ ] No marketing language or filler phrases\n- [ ] TODOs are clearly marked for anything uncertain\n- [ ] Run `mint broken-links` to check links\n- [ ] Run `mint validate` to find any errors\n\n## Edge cases\n\n### Migrations\n\nIf a user asks about migrating to Mintlify, ask if they are using ReadMe or Docusaurus. If they are, use the [@mintlify/scraping](https://www.npmjs.com/package/@mintlify/scraping) CLI to migrate content. If they are using a different platform to host their documentation, help them manually convert their content to MDX pages using Mintlify components.\n\n### Hidden pages\n\nAny page that is not included in site config navigation (`docs/docs.json` here) is hidden. Use hidden pages for content that should be accessible by URL or indexed for the assistant or search, but not discoverable through the sidebar navigation.\n\n### Exclude pages\n\nThe `.mintignore` file is used to exclude files from a documentation repository from being processed.\n\n## Common gotchas\n\n1. **Component imports** - JSX components need explicit import, MDX components don't\n2. **Frontmatter required** - Every MDX file needs `title` at minimum\n3. **Code block language** - Always specify language identifier\n4. **Never use `mint.json`** - `mint.json` is deprecated. Use the Mintlify site config (`docs/docs.json` here; often root `docs.json` in other projects)\n\n## Resources\n\n- [Documentation](https://mintlify.com/docs)\n- [Configuration schema](https://mintlify.com/docs.json)\n- [Feature requests](https://github.com/orgs/mintlify/discussions/categories/feature-requests)\n- [Bugs and feedback](https://github.com/orgs/mintlify/discussions/categories/bugs-feedback)\n","skills/github/SKILL.md":"---\nname: github\nversion: \"1.0.0\"\ndescription: GitHub API integration via HTTP tool with automatic credential injection\nactivation:\n  keywords:\n    - \"github\"\n    - \"pull request\"\n    - \"github issue\"\n    - \"github repo\"\n    - \"pr comment\"\n    - \"open a pr\"\n    - \"create a pr\"\n    - \"my prs\"\n  exclude_keywords:\n    - \"gitlab\"\n    - \"bitbucket\"\n  patterns:\n    - \"(?i)(list|show|get|fetch|open|close|create|file|merge|comment on)\\\\s.*(pull request|\\\\bPR\\\\b)\"\n    - \"(?i)github\\\\.com\"\n    - \"(?i)[a-z0-9._-]+/[a-z0-9._-]+#\\\\d+\"\n  tags:\n    - \"git\"\n    - \"code-review\"\n    - \"devops\"\n  max_context_tokens: 2000\ncredentials:\n  - name: github_token\n    provider: github\n    location:\n      type: bearer\n    hosts:\n      - \"api.github.com\"\n    oauth:\n      authorization_url: \"https://github.com/login/oauth/authorize\"\n      token_url: \"https://github.com/login/oauth/access_token\"\n      scopes:\n        - \"repo\"\n        - \"read:org\"\n      refresh:\n        strategy: reauthorize_only\n    setup_instructions: \"Create a personal access token at https://github.com/settings/tokens\"\n---\n\n# GitHub API Skill\n\nYou have access to the GitHub REST API via the `http` tool. Credentials are automatically injected — **never construct Authorization headers manually**. When the URL host is `api.github.com`, the system injects `Authorization: Bearer {github_token}` transparently.\n\n## API Patterns\n\nAll endpoints use `https://api.github.com` as the base URL. Common headers are injected automatically.\n\n### Issues\n\n**List issues:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/issues?state=open&sort=created&direction=desc&per_page=30\")\n```\n\n**Get single issue:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/issues/{number}\")\n```\n\n**Create issue:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/issues\", body={\"title\": \"...\", \"body\": \"...\", \"labels\": [\"bug\"]})\n```\n\n**Add comment:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/issues/{number}/comments\", body={\"body\": \"...\"})\n```\n\n### Pull Requests\n\n**List PRs:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls?state=open&sort=created&direction=desc&per_page=30\")\n```\n\n**Create PR:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls\", body={\"title\": \"...\", \"body\": \"...\", \"head\": \"feature-branch\", \"base\": \"main\", \"draft\": true})\n```\n\n**Get PR diff:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls/{number}\", headers=[{\"name\": \"Accept\", \"value\": \"application/vnd.github.v3.diff\"}])\n```\n\n### Repository\n\n**Get repo info:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}\")\n```\n\n**List branches:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/branches\")\n```\n\n**List recent commits:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/commits?per_page=10\")\n```\n\n### Authenticated User & Cross-Repo Queries\n\nWhen the user says \"my PRs\", \"my issues\", or \"my repos\", they mean the user who owns `github_token`. Don't try to list a single repo, hit the search/user endpoints instead.\n\n**Get the authenticated user (resolves who `@me` is):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/user\")\n```\n\n**My latest PRs across all repos:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:pr+author:%40me+sort:updated-desc&per_page=20\")\n```\n\n**My open issues across all repos (assigned to me):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:issue+is:open+assignee:%40me&per_page=20\")\n```\n\n**PRs that need my review:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:pr+is:open+review-requested:%40me\")\n```\n\n**My repos (list all repos accessible to the token):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/user/repos?sort=updated&per_page=30\")\n```\n\n### Search\n\nGitHub has three search endpoints. Build queries with the [search syntax](https://docs.github.com/en/search-github/searching-on-github).\n\n**Search issues and PRs (one endpoint, filter with `is:pr` or `is:issue`):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=repo:{owner}/{repo}+is:pr+is:open+label:bug\")\n```\n\n- Note: There is no `/search/pulls` endpoint; `/search/issues` is the unified endpoint for both issues and PRs.\n\n**Search code:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/code?q=fn+main+language:rust+repo:{owner}/{repo}\")\n```\n\n**Search repositories:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/repositories?q=tetris+language:rust&sort=stars\")\n```\n\nURL-encode `@` as `%40` and spaces as `+` in `q=` values.\n\n## Response Handling\n\nThe `http` tool returns an envelope:\n\n```python\n{\"status\": 200, \"headers\": {...}, \"body\": <parsed value>}\n```\n\n- **JSON endpoints** — `body` is already a parsed Python dict or list. Do **not** call `json.loads()` on it. Example:\n  ```python\n  r = await http(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls/123\")\n  if r[\"status\"] != 200:\n      FINAL(f\"GitHub returned HTTP {r['status']}: {r['body']}\")\n  pr = r[\"body\"]          # dict, not a string\n  title  = pr[\"title\"]    # use direct indexing; these keys always exist on a 2xx\n  state  = pr[\"state\"]\n  head   = pr[\"head\"][\"ref\"]\n  base   = pr[\"base\"][\"ref\"]\n  ```\n- **Diff / plain text endpoints** (`Accept: application/vnd.github.v3.diff` etc.) — `body` is a `str` containing the raw unified diff; use it as-is.\n- **Never** write `body = pr_meta.get(\"body\", pr_meta)` as a \"safety net\" — it hides real errors. If `status` isn't 2xx, fail fast.\n- For list endpoints, check the `Link` header for pagination.\n- Rate limit: 5000 req/hour authenticated. Check `X-RateLimit-Remaining` if doing bulk ops.\n- Error responses are JSON of the form `{\"message\": \"...\"}` with a non-2xx `status` — surface them literally in your FINAL answer.\n\n## Common Mistakes\n\n- Do NOT add an `Authorization` header — it is injected automatically by the credential system.\n- Always use HTTPS URLs (HTTP is blocked by the security layer).\n- For creating PRs, always set `draft: true` unless the user explicitly says \"ready for review\".\n- The `state` parameter for issues/PRs is `open`, `closed`, or `all` — not `active`/`inactive`.\n- Use `per_page` to control result count (max 100). Default is 30.\n- For \"my PRs / my issues\" across all repos, hit `/search/issues?q=...+author:%40me`. Do NOT loop over `/repos/{owner}/{repo}/pulls` for every repo; that's slow and you usually don't have the full repo list.\n","skills/developer-setup/SKILL.md":"---\nname: developer-setup\nversion: 0.2.0\ndescription: One-time onboarding for the developer workflow — installs github-workflow missions, creates the commitments workspace, registers per-repo projects, writes calibration memories. Excludes itself until its marker file is deleted.\nactivation:\n  setup_marker: projects/commitments/.developer-setup-complete\n  keywords:\n    - developer assistant\n    - dev assistant\n    - dev workflow\n    - developer setup\n    - github setup\n    - help with github\n    - manage my PRs\n    - code workflow\n    - engineering setup\n    - dev setup\n    - automate my repos\n    - CI keeps failing\n    - engineering workflow\n  patterns:\n    - \"(?i)I'm a (developer|engineer|programmer|dev|software engineer)\"\n    - \"(?i)help me (with|manage|set ?up) (github|PRs|repos|CI|code|projects)\"\n    - \"(?i)set ?up.*(dev|coding|engineering|github|developer)\"\n    - \"(?i)(automate|manage) my (repos|PRs|projects|workflow|code)\"\n  tags:\n    - commitments\n    - developer\n    - github\n    - setup\n  max_context_tokens: 3000\nrequires:\n  # Capped at MAX_REQUIRED_SKILLS_PER_MANIFEST = 10 in\n  # `ironclaw_skills::types`. The trimmed list keeps the 10 highest-impact\n  # companions for the developer workflow; the dropped entries\n  # (`qa-review`, `review-readiness`, `product-prioritization`) can still\n  # be installed manually via `skill_install` when needed.\n  skills:\n    - github\n    - github-workflow\n    - project-setup\n    - commitment-triage\n    - commitment-digest\n    - decision-capture\n    - delegation-tracker\n    - idea-parking\n    - tech-debt-tracker\n    - security-review\n---\n\n# Developer Workflow Setup\n\nYou are configuring the full developer workflow — commitment tracking, GitHub automation, tech debt tracking, security/QA reviews, product prioritization, and proactive briefings across multiple repositories.\n\n## Companion skills\n\nThese activate during conversation via keyword matching:\n\n| Skill | When | What |\n|---|---|---|\n| `commitment-triage` | Obligations, deadlines | Signal extraction, commitment creation |\n| `commitment-digest` | \"show commitments\" | Formatted status summary |\n| `decision-capture` | Architecture/design decisions | Records decision + rationale |\n| `delegation-tracker` | \"waiting on @teammate\" | Tracks delegation follow-ups |\n| `idea-parking` | \"park this idea\" | Saves for later |\n| `tech-debt-tracker` | \"this is a hack\", \"refactor later\" | Tracks tech debt, resurfaces weekly |\n| `project-setup` | \"add repo owner/repo\" | Adds a new project with workflow |\n| `security-review` | \"security review\", \"check for vulnerabilities\" | OWASP audit, auto-fix obvious issues |\n| `qa-review` | \"QA review\", \"test coverage\", \"edge cases\" | Test plans, coverage gaps, regression risks |\n| `review-readiness` | \"ready to merge?\", \"PR readiness\" | Tracks which reviews are complete per branch |\n| `product-prioritization` | \"what to build next\", \"prioritize\" | Evidence-based feature scoring, demand analysis |\n| `github` | GitHub API operations | REST API with credential injection |\n| `github-workflow` | Workflow automation reference | Issue-to-merge pipeline templates |\n| `review-checklist` | Pre-merge review | 55+ verification items |\n\nIf any are missing from `skills/`, tell the user which ones are needed.\n\n## Step 1: Setup questions (4, no timezone)\n\n1. **Repos**: Which GitHub repos do you work on? (1-5, format: `owner/repo`)\n2. **Role**: Solo maintainer, team member, or team lead? (Affects delegation vs personal tracking)\n3. **Per-repo**: For each repo — who are maintainers/reviewers? Do you use a staging branch?\n4. **AI agents**: Do any bots create PRs? (Dependabot, Copilot, internal agents) — these get tracked separately in digests with shorter stale thresholds\n\nUse reasonable defaults if the user says \"just set it up.\"\n\n## Step 2: Declare the `commitments` project and create workspace structure\n\nWriting any file under `projects/commitments/` is the declaration that\nthe project exists — the engine auto-registers it and scopes missions\nto it. Start with:\n\n```\nmemory_write(\n  target: \"projects/commitments/AGENTS.md\",\n  content: \"# Commitments (Developer)\\n\\nThis project tracks engineering commitments, tech debt, and decisions across the user's repositories.\\n\\n## Operating principles\\n\\n- Most items are personal tasks, not delegations — default `owner=user`.\\n- Capture tech debt passively from conversation and from merged PR review comments.\\n- AI agent PRs group separately in digests with shorter stale thresholds.\\n- For irreversible actions (merging, deleting, sending messages), always ask first.\\n\",\n  append: false\n)\n```\n\nThen:\n\n1. Check if `projects/commitments/README.md` exists. If not, create the full commitments workspace (see `commitment-setup` skill for the complete schema including immediacy, resolution paths, trust calibration).\n2. Create subdirectory placeholders: `open/`, `resolved/`, `signals/pending/`, `signals/expired/`, `decisions/`, `parked-ideas/`.\n3. Create `projects/commitments/tech-debt/README.md` — \"Tech debt items. Resurface in weekly retro.\"\n\n## Step 3: Set up each project\n\nFor each repo the user listed, run the `project-setup` procedure:\n1. Validate repo via GitHub API\n2. Create `projects/<owner>-<repo>/project.md` with metadata\n3. Create `projects/<owner>-<repo>/notes.md` for developer notes\n4. Install the 6 workflow missions (namespaced by repo slug)\n5. Skip `wf-staging-review` if no staging branch\n\n## Step 4: Create developer missions\n\n### commitment-triage (3x weekdays)\n\n```\nmission_create(\n  name: \"commitment-triage\",\n  goal: \"Developer triage. Read projects/commitments/README.md for schema. Read projects/ via memory_tree for all tracked repos. For each repo, check GitHub API: (1) New PR review requests assigned to user → signal with immediacy=batch. (2) CI failures on user's open PRs → signal with immediacy=prompt. (3) @mentions on PRs/issues → signal with immediacy=prompt. (4) New issue assignments → signal with immediacy=batch. (5) Issues/PRs with production/hotfix/critical labels → signal with immediacy=realtime, broadcast immediately. (6) Recently merged PRs — scan review comments for tech-debt patterns ('address in follow-up', 'not blocking but fix later', 'TODO', 'leaving for now') → create tech-debt items in projects/commitments/tech-debt/ with source=pr-review and source_pr reference. Expire signals after 48h. Flag AI agent PRs stuck in CI after 24h. Append summary to projects/commitments/triage-log.md.\",\n  cadence: \"0 9,14,18 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### commitment-digest (weekday mornings)\n\n```\nmission_create(\n  name: \"commitment-digest\",\n  goal: \"Developer morning brief. Read projects/commitments/README.md for schema. Read projects/ for tracked repos. For each repo, query GitHub API. Compose digest in this order: (1) OVERNIGHT RESULTS — CI status per repo on user's PRs (green/red/pending), PRs merged overnight. (2) NEEDS YOUR REVIEW — PRs where user is requested reviewer, show age, author, size. Separate human PRs from AI agent PRs. Flag stale reviews (3+ days). (3) YOUR OPEN PRs — each with CI status, review state. Flag READY TO MERGE if approved + CI green. (4) BLOCKED/WAITING — commitments with status=waiting or delegated_to set, agent PRs stuck in CI loops (attempted 3+ fixes). (5) TODAY'S COMMITMENTS — open items sorted by urgency, for agent_can_handle items note what agent would do. (6) QUICK STATS — tech debt count, pending signal count. End with 'Did I miss anything?' Send via message tool. Omit empty sections.\",\n  cadence: \"0 8 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-stale-pr-check (weekday afternoons)\n\n```\nmission_create(\n  name: \"dev-stale-pr-check\",\n  goal: \"Check for stale PRs across tracked repos. Read projects/ for repo list. For each repo, query GitHub API for open PRs. Flag PRs with no activity in 3+ days (human) or 1+ day (agent PR stuck in CI). For user's own stale PRs: suggest pinging reviewer or closing if abandoned. For PRs user should review: note how long they've been waiting. Send alert only if stale items found; stay silent otherwise.\",\n  cadence: \"0 16 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-weekly-retro (Friday morning)\n\n```\nmission_create(\n  name: \"dev-weekly-retro\",\n  goal: \"Weekly developer retrospective. Gather: (1) All commitments resolved this week from projects/commitments/resolved/. (2) All decisions captured this week from projects/commitments/decisions/. (3) All tech debt items added this week from projects/commitments/tech-debt/ — include items from PR review scans. (4) Per-repo: count of merged PRs this week via GitHub API. (5) Open items carried forward. Compose retro: SHIPPED, DECISIONS MADE (with rationale), SLIPPED/CARRIED FORWARD, TECH DEBT ACCUMULATED (new items + total count + top 3 chronic), PATTERNS (recurring CI failures, slow review cycles). For complex action items, suggest using /plan to create a structured execution plan. Write retro to context/intel/weekly-retro-<date>.md. Send via message tool.\",\n  cadence: \"0 10 * * 5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-decision-outcome-check (Wednesday)\n\n```\nmission_create(\n  name: \"dev-decision-outcome-check\",\n  goal: \"Check for decisions needing outcome assessment. Read projects/commitments/decisions/ for entries where outcome is null and decided_at is 7+ days ago. For each, prompt: 'You decided <X> <N> days ago. How did it turn out?' Skip silently if no decisions need review.\",\n  cadence: \"0 10 * * 3\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-tech-debt-resurface (Monday morning)\n\n```\nmission_create(\n  name: \"dev-tech-debt-resurface\",\n  goal: \"Weekly tech debt review. Read all files in projects/commitments/tech-debt/ via memory_tree and memory_read. Sort by age. Flag items older than 30 days as chronic. For items tagged with a repo, check if related issues exist. If backlog exceeds 10 items, suggest a prioritization session. For high-severity chronic items, suggest using /plan to create a structured breakdown and fix strategy. Send list via message tool. Skip silently if no tech debt.\",\n  cadence: \"0 10 * * 1\",\n  project_id: \"commitments\"\n)\n```\n\n## Step 5: Write calibration memories\n\n```\nmemory_write(\n  target: \"projects/commitments/calibration.md\",\n  content: \"# Developer Calibration\\n\\n## Decision classification\\n- mechanical (auto-act silently): expire stale signals, update CI status, dismiss noise, mark passing checks\\n- taste (auto-act, surface in digest): auto-dismiss FYI signals, auto-resolve completed items, update readiness dashboard\\n- challenge (always ask): architecture decisions, sending messages to people, merging PRs, deleting branches, any irreversible action\\n\\n## Effort principle\\n- AI makes completeness cheap — when the thorough implementation costs minutes more than the shortcut, always do the thorough thing\\n- Always show dual effort estimates when known: human time vs AI-assisted time\\n- This reframes prioritization: features that seem expensive may be cheap with AI\\n\\n## Signal urgency\\n- CI failures on user's own PRs = prompt urgency — surface within the hour\\n- Production/hotfix/critical labels = realtime — broadcast immediately\\n- PR review requests = batch urgency unless from team lead or marked urgent\\n- Security P1 findings = realtime\\n- AI agent PRs grouped separately in digest with shorter stale threshold (1 day vs 3)\\n\\n## Tech debt\\n- Captured passively from conversation AND from merged PR review comments\\n- PR review comments matching 'address in follow-up', 'not blocking but fix', 'TODO later', 'leaving for now' → auto-create tech-debt items\\n\\n## Reviews\\n- Track review readiness per branch in projects/<slug>/readiness/\\n- Before merge, check: code review + tests + security + QA. Surface gaps in digest.\\n- Security and QA reviews can be run with /security-review and /qa-review\\n- Obvious security/QA fixes are auto-applied; ambiguous ones always ask\\n\\n## Product\\n- Feature prioritization uses evidence-based scoring: demand × 3 + impact × 2 + alignment / effort\\n- Challenge assumptions — 'I think users want X' requires evidence\\n- Use /product-prioritization for structured analysis\\n\\n## General\\n- Architecture/API design decisions = high-confidence capture; debugging 'let's try X' = not a decision\\n- Most developer commitments are personal tasks, not delegations — default owner=user\\n- Projects tracked in projects/<slug>/project.md\\n- For complex tasks, suggest /plan for structured execution\\n- Weekly retro writes to context/intel/ as durable intelligence\\n- Start conservative: surface everything, earn trust through feedback\",\n  append: false\n)\n```\n\n## Step 6: Confirm\n\nTell the user:\n\n> Your developer workflow is ready:\n>\n> **Projects:** <list of repos, each with workflow status>\n>\n> **Missions:**\n> - **Triage** 3x weekdays (9am, 2pm, 6pm) — scans GitHub for review requests, CI failures, assignments, mentions, and tech debt from PR reviews\n> - **Morning brief** 8am weekdays — overnight CI, PRs needing review, your PR statuses, today's commitments\n> - **Stale PR check** 4pm weekdays — flags abandoned PRs and slow reviews\n> - **Weekly retro** Friday 10am — what shipped, decisions, tech debt, patterns\n> - **Tech debt review** Monday 10am — resurfaces accumulated debt\n> - **Decision check** Wednesday 10am — follows up on decisions older than 7 days\n>\n> Per-repo workflow: issue planning, maintainer gate, PR monitor, CI fix loop, staging review, post-merge learning\n>\n> **Quick commands:**\n> - **\"show commitments\"** — current status\n> - **\"show tech debt\"** — debt backlog\n> - **\"add repo owner/repo\"** — add another project\n> - **\"is this PR ready?\"** — review readiness dashboard\n> - **\"what should we build next?\"** — evidence-based prioritization\n> - **`/security-review`** — run security audit on current changes\n> - **`/qa-review`** — generate test plan and coverage analysis\n> - **`/plan <description>`** — structured execution plan for complex tasks\n> - **`/product-prioritization`** — score and rank features by demand\n\n## Step 7: Mark setup complete\n\nAfter confirming with the user that everything is in place, write the setup completion marker so this skill stops competing for the activation budget on every subsequent message:\n\n```\nmemory_write(\n  target: \"projects/commitments/.developer-setup-complete\",\n  content: \"# Developer Setup Complete\\n\\nCompleted: <today's UTC date>\\n\\nRepos: <list of repo slugs>\\nMaintainers: <maintainers>\\nMissions installed: wf-issue-plan, wf-maintainer-gate, wf-pr-monitor, wf-ci-fix, wf-learning, plus 6 personal productivity missions (commitment-triage, commitment-digest, dev-stale-pr-check, dev-weekly-retro, dev-tech-debt-resurface, dev-decision-outcome-check)\"\n)\n```\n\nThis is a one-time marker. The next conversational turn will not load this setup skill (the operational skills like `commitment-triage`, `tech-debt-tracker`, `github`, `github-workflow` keep activating reactively as before). To re-trigger setup (add a new repo with the wizard, re-onboard, switch maintainers), delete `projects/commitments/.developer-setup-complete` first.\n"},"files":{"AGENTS.md":"# Agent Rules\n\n## Purpose and precedence\n\n`AGENTS.md` is the canonical agent contract for this repository — the commands, hard invariants, and routing an agent cannot infer from the tree. It is not the full architecture specification: before changing a complex area, read the owning crate's `AGENTS.md`, then its `CONTRACT.md` or `README.md` when present; cross-crate behavior is specified under `docs/internal/reborn/contracts/`. (`CLAUDE.md` files are Claude Code adapters and pointer stubs; content lives here and in the files this one names.)\n\nAll product work belongs in the Reborn workspace under `crates/`; the shipping binary is `ironclaw` from the `ironclaw` package in `crates/app/ironclaw_cli`. `crates/AGENTS.md` is the routing map into the ten crate families. The repo skills under `.claude/skills/` (`ironclaw-reborn-orientation`, `reborn-feature`, `ironclaw-reborn-architecture-review`, `ironclaw-reborn-testing`, `ironclaw-reborn-skill-maintainer`, `reborn-extension-surfaces`) are plain Markdown — read the `SKILL.md` directly if your harness does not load Claude skills.\n\n## Build, run, debug\n\n```bash\ncargo fmt                                                       # format\ncargo clippy --all --benches --tests --examples --all-features -- -D warnings  # lint (zero warnings; CI denies warnings — an unflagged run exits 0 with them)\ncargo test                                                      # unit + integration suites (Postgres legs self-provision testcontainers; skipped without Docker)\nRUST_LOG=ironclaw=debug cargo run -p ironclaw -- serve          # run the serve binary (add tower_http=debug for HTTP logging)\n```\n\nThe workspace-root `integration` feature is empty with zero consumers — a bare root `cargo test --features integration` adds nothing. Backend-heavy gated suites are crate-level (e.g. `cargo test -p ironclaw_hooks --features integration,test-support`). E2E suite: `tests/e2e/CLAUDE.md`.\n\n**Cargo features are a last resort.** A feature is a second build of the workspace, compiled and tested forever. Add one only for a heavy optional dependency, a build shape that ships with it OFF, a CI lane selector, a dev-only seam (always named `test-support`), or a privilege boundary — and say which in the manifest comment. Deployment shape belongs in `DeploymentConfig` and `[storage]`, not `#[cfg]`. Full bar: `.claude/rules/cargo-features.md`.\n\n## Discover code before changing it\n\nFor where-is, who-calls, data-flow, and impact questions, probe the codebase knowledge graph before text search: run `bash scripts/codebase-graph.sh status` once; if fresh and graph tools are connected, use them; otherwise fall back to `crates/AGENTS.md`, crate-local guidance, and targeted `rg`. Verify graph claims against live code before acting. Use `rg` directly for configuration, prose, and fixtures. `openwiki/` is generated prose — read-only, never hand-edit.\n\n## Where work belongs\n\nExternal surfaces normalize untrusted requests through product adapters or `ProductSurface`; thread/turn services establish durable conversation state; the scheduler and run executor invoke the canonical runner/driver and agent loop; capability execution crosses authorization, approvals, obligations, host-runtime mediation, and the selected runtime lane; durable typed events feed projections and transport streams — transports do not invent state. Verify a flow from live symbols:\n\n```bash\nrg -n \"SessionThreadService|TurnCoordinator|TurnRunScheduler|RebornTurnRunExecutor|CanonicalAgentLoopExecutor|CapabilityHost\" crates\n```\n\nCrates live under a family directory (`crates/<family>/ironclaw_*`); enumerate them with `python3 scripts/ci/lib/crate_tree.py .` rather than assuming a fixed depth. Stable ownership decisions:\n\n- Neutral authority vocabulary belongs in `ironclaw_host_api`; execution does not.\n- Filesystem mounts/CAS belong in `ironclaw_filesystem`; record grammar in the domain crate.\n- Durable events, projections, and transport streams are separate contracts.\n- Authorization, approvals, resources, obligations, dispatch, and runtime lanes remain separate stages.\n- `ironclaw_assistant` owns product-facing orchestration and `ProductSurface`; composition wires dependencies; WebUI owns HTTP/transport and frontend presentation.\n- Provider-neutral model contracts and provider implementations belong in `ironclaw_llm`; wrappers delegate the complete provider trait.\n- Declarative extension metadata belongs in `ironclaw_extension_registry`; execution belongs in runtime lanes and host mediation.\n- Safety scanning is `ironclaw_safety`; skills are `ironclaw_skills`; persistent memory is `ironclaw_memory` (model tools `ironclaw.memory.*`). Always import from the owning crate.\n\nThe composition root assembles dependencies; it does not own domain policy — module-specific initialization stays behind factories or builders in the owning crate. If adding a dependency would point from a lower neutral crate into product or composition, stop and run `cargo test -p ironclaw_architecture_tests` first.\n\nSubagent spawn creates and wires child runs only; planning, execution, capability calls, checkpointing, gates, retries, and completion continue through the existing runner/driver/executor path.\n\nHost-trusted trigger ingress is sealed by trigger-worker-owned request minting and private conversation-owned trusted construction. Product adapters, product workflow, first-party capabilities, and host-runtime handlers use untrusted inbound requests and must not mint `TrustedInboundTurnRequest` or call trusted trigger submitter factories.\n\n## Module Specs\n\nWhen modifying a module with a spec, read the spec first. Code follows spec; spec is the tiebreaker.\n\n| Module | Spec |\n|--------|------|\n| `crates/domains/ironclaw_llm/` | `crates/domains/ironclaw_llm/CONTRACT.md` |\n| `crates/substrates/ironclaw_filesystem/` | `crates/substrates/ironclaw_filesystem/CONTRACT.md` |\n| `crates/product/ironclaw_webui/` | `crates/product/ironclaw_webui/CONTRACT.md` |\n| `crates/app/ironclaw_composition/` | `crates/app/ironclaw_composition/CONTRACT.md` |\n| `crates/domains/ironclaw_identity/` | `crates/domains/ironclaw_identity/CONTRACT.md` |\n| `crates/kernel/ironclaw_trust/` | `crates/kernel/ironclaw_trust/CONTRACT.md` |\n| `tests/` (scenario coverage map) | `tests/CLAUDE.md` |\n| `tests/integration/` | `tests/integration/CLAUDE.md` |\n| `tests/support/reborn_parity_qa/` | `tests/support/reborn_parity_qa/CLAUDE.md` |\n| `tests/e2e/` | `tests/e2e/CLAUDE.md` |\n\n## Coding and contract rules\n\n- No `.unwrap()` or `.expect()` in production code (tests are fine); propagate errors with context — `.map_err(|e| SomeError::Variant { reason: e.to_string() })?` — and use `thiserror` for error types in `error.rs`. Cause-preserving constructors, the `map_err(|_| …)` ban, and the other silent-failure anti-patterns: `.claude/rules/error-handling.md`.\n- Keep clippy clean with zero warnings. Prefer `crate::` imports for cross-module references.\n- Use strong types and enums for known domain shapes; raw strings belong at external boundaries. Shared types live with the contract owner — no mirror DTOs, and `ironclaw_common` is not a dumping ground.\n- No `pub use` re-exports unless exposing to downstream consumers.\n- **Prompt templates live in files, not Rust code**: multi-line prompt strings go in a `prompts/*.md` file inside the crate that owns the behavior, loaded via `include_str!()` (`ls -d crates/*/*/prompts crates/extensions/packages/*/prompts` lists the owners). Single-line format strings are fine inline.\n- Preserve existing defaults unless the task explicitly changes them.\n- All I/O is async with tokio; use `Arc<T>` for shared state.\n\n## Testing discipline\n\n1. **Test-first.** Every feature and fix starts in the tests — pin the behavior, watch it fail for the right reason, then change the implementation. Every fix ships with a regression test.\n2. **Consolidate, don't proliferate.** Extend the test that already exercises the path; add a new test only for a genuinely distinct scenario.\n3. **Integration-first.** Production-wired behavior ships with a test in `tests/integration/`, driven through the harness and asserting at a seam — never `wait_for_status(Completed)` alone. Crate tier is the fallback only when that tier cannot reach the path (say why in the PR).\n4. **Test through the caller, not just the helper.** When a helper gates a side effect, unit-testing the helper alone is not regression coverage — drive the call site at the integration tier or higher, and make mocks capture every argument the production caller passes.\n\nFull rules and tiers: `.claude/rules/testing.md`; authoring guides: `tests/integration/CLAUDE.md`, `tests/e2e/CLAUDE.md`. Select tiers with `docs/internal/testing-playbook.md`, and complete the `Test Strategy` section of `.github/pull_request_template.md` with evidence or `Not applicable: <reason>` per tier.\n\n## Persistence and configuration\n\nNew persistence uses `RootFilesystem`/`ScopedFilesystem` and the mount catalog owned by `ironclaw_filesystem` (spec above); composition chooses concrete backends (PostgreSQL, libSQL, local filesystem) by profile. Domain stores are thin typed wrappers and never branch on backend; keep dual-backend parity via shared conformance suites (`.claude/rules/database.md`). Read-modify-write uses the shared bounded CAS helper, never a process-local mutex held across backend I/O.\n\nKeep bootstrap configuration, persisted settings, and encrypted secrets as separate layers; preserve configuration precedence, secret-mediated provider resolution, and fail-closed startup. Environment variables are documented in `.env.example`; LLM backends in the llm spec (`LlmBackendKind` in `crates/domains/ironclaw_llm/src/config.rs` is the source of truth).\n\n## Security and runtime invariants\n\n- Treat every listener, route, product adapter, runtime lane, container, and external service as untrusted until a typed boundary establishes otherwise.\n- Do not weaken authentication, origin checks, body limits, rate limits, allowlists, approval leases, secret mediation, or redaction guarantees.\n- External HTTP goes through `ironclaw_network`; credentials remain host-side and are injected only through mediated runtime services.\n- New ingress must validate and bound the original payload before persistence, prompt construction, credential injection, or dispatch.\n- Authorization, approval, reservation, dispatch, and execution are distinct stages. Do not bypass or collapse them — product/WebUI handlers, triggers, channels, and agent callers go through `ProductSurface` and the capability contracts, never around them to mutate stores directly.\n- Session, thread, turn, and run identities are typed and must not be re-derived from display strings or transport metadata.\n- **LLM data is never deleted.** Context, reasoning, tool calls, messages, events, steps — mark with timestamps and make filterable, but always retain. In-memory maps are caches; the database is the source of truth. \"Cleanup\" means evicting caches, never deleting rows.\n- Never commit secrets or PII.\n\n## Capabilities, extensions, and lifecycle\n\n- Core host behavior uses typed built-in capabilities behind the same mediated host surface as other execution.\n- Sandboxed extension execution belongs in WASM or a runtime lane; external server integrations belong behind MCP and the network boundary.\n- Discovery is side-effect-free. Installation, credential binding, activation, execution, deactivation, and removal are explicit lifecycle transitions.\n- Capability failures the model or user can correct are model-visible outcomes; host errors are reserved for failures that end the run.\n- Side-effecting success requires durable or provider-issued evidence plus read-back verification; if read-back is impossible, report explicitly unverified rather than completed.\n\n### Extension/Auth Invariants\n\nThe top-level product object is always an **extension**; a channel is one capability surface an extension's manifest declares (`tool` / `channel` / `auth` — `ironclaw_extension_contracts::surface::CapabilitySurfaceKind`), and runtime (`wasm` / `mcp` / `first_party`) is implementation, never taxonomy. `ExtensionId` is the product identity (`slack`, `github`, `gmail`); `VendorId` (manifest field `vendor`) is the credential-authority namespace and may back several extensions (`google` backs gmail + drive + calendar). There is no separate channel registry and no extension `kind` wire string — `crates/app/ironclaw_architecture_tests/tests/reborn_retired_taxonomy.rs` pins the retired vocabulary at zero.\n\nTwo identities must never be conflated (newtypes in `crates/contracts/ironclaw_common/src/identity.rs`; identity model `crates/domains/ironclaw_identity/CONTRACT.md`; OAuth transport `crates/domains/ironclaw_auth`):\n\n- `credential_name` — backend secret identity (storage, injection, gate resume), e.g. `telegram_bot_token`, `google_oauth_token`.\n- `extension_name` — user-facing installed extension/channel identity (setup routing, UI), e.g. `telegram`, `gmail`.\n\nNever route setup/configure UI from `credential_name`; chat and Settings use the same setup path; generic auth-card UI is only for non-extension credential prompts or pure OAuth launches; resolve `extension_name` once in shared backend logic and carry it through the wire contract instead of re-deriving it per layer or adding frontend-only fallbacks.\n\nAdding a channel means adding one capability surface of an extension — a `[channel]` section in the `reborn.extension_manifest.v3` manifest plus a `ChannelAdapter` (`crates/contracts/ironclaw_extension_contracts/src/channel_adapter.rs`), wired through `RebornHostBindings::with_channel_extension_bindings` (`crates/app/ironclaw_composition/src/input.rs`) — never per-channel host code. Start from the `reborn-extension-surfaces` skill; the worked example is `crates/extensions/packages/slack/`; family rules in `crates/extensions/AGENTS.md`.\n\n## Project structure\n\n```\ncrates/                     # all production code, by family (crates/AGENTS.md is the map)\n├── app/                    # ironclaw_cli (binary `ironclaw`), ironclaw_composition, ironclaw_config, ironclaw_architecture_tests\n├── contracts/              # ironclaw_host_api, ironclaw_common, ironclaw_extension_contracts, ironclaw_product_contracts, …\n├── domains/                # ironclaw_llm, ironclaw_skills, ironclaw_threads, ironclaw_auth, ironclaw_memory, …\n├── events/                 # ironclaw_event_log / _projections / _store / _streams\n├── extensions/             # ironclaw_extension_host/_manager/_registry/_support + packages/ (slack, telegram, …)\n├── kernel/                 # ironclaw_turns, ironclaw_capabilities, ironclaw_approvals, ironclaw_host_runtime, …\n├── lanes/                  # ironclaw_wasm, ironclaw_sandbox, ironclaw_mcp\n├── loop/                   # ironclaw_agent_loop, ironclaw_turn_runner, ironclaw_loop_host, ironclaw_hooks\n├── product/                # ironclaw_webui (SPA in frontend/), ironclaw_assistant, …\n└── substrates/             # ironclaw_filesystem, ironclaw_safety, ironclaw_network, ironclaw_secrets, …\n\ntests/                      # root-package integration suite, parity/QA, support, e2e\n```\n\nThe workspace root (`Cargo.toml`, package `ironclaw_integration_tests`) hosts only the integration test suite; the one workspace `exclude` is `tools/ironclaw_silk_decoder`.\n\n`docs/` is the public Mintlify site plus fenced internal material. All new\ninternal engineering docs (design notes, research, plans, QA maps) go under\n`docs/internal/` — nowhere else under `docs/`. A page outside the\n`docs/.mintignore` fence is published even when omitted from `docs.json`\nnavigation (hidden pages stay reachable by URL), and `.mintignore` is frozen:\ndo not add entries. Enforced by `scripts/ci/docs_publication_boundary.py`\n(Code Style workflow); run it to check placement.\n\n## Change discipline, and before finishing\n\n- Keep changes scoped; preserve unrelated work in dirty worktrees; avoid generated-file churn. Security, persistence-schema, runtime, worker, CI, and secrets changes need explicit rollback/compatibility review.\n- Run the narrowest meaningful checks, plus `cargo test -p ironclaw_architecture_tests` when dependency edges, layer keys, crate placement, or test-pinned guidance files change.\n- Search changed production files for `.unwrap()`/`.expect()`, suspicious byte slicing, hardcoded temporary paths, and lost error causes.\n- When a trait changes, enumerate all implementations, decorators, adapters, and test doubles; when a pattern bug is fixed, search `crates/` for sibling instances.\n- After moves/renames, search agent guidance, contracts, docs, tests, scripts, manifests, and frontend imports for old paths.\n- Update the owning contract/docs when behavior changes; the PR title/body must describe every layer in the diff and note compatibility, rollback, and follow-up risks.\n","CLAUDE.md":"# IronClaw — Claude Code adapter\n\n@AGENTS.md\n\nEverything above (from `AGENTS.md`) is the canonical, tool-neutral contract.\nThe rest of this file is Claude-specific.\n\n## Skills and rules\n\n- Project skills live in `.claude/skills/` — start from\n  `ironclaw-reborn-orientation`; use `reborn-feature` for cross-layer product\n  work, `reborn-extension-surfaces` for integrations,\n  `ironclaw-reborn-testing` for test tiers,\n  `ironclaw-reborn-architecture-review` for boundary changes, and\n  `ironclaw-reborn-skill-maintainer` before editing any guidance file.\n- Path-scoped rules in `.claude/rules/*.md` load automatically when you read\n  matching files — they are canonical for their topics (testing, database,\n  types, cargo-features, review discipline, …); do not restate them here.\n\n## Codebase knowledge graph (MCP)\n\nThe `codebase-memory` MCP server indexes `crates/` into a knowledge graph;\nprefer it over `Grep` for *code structure* (cross-crate call chains are\ninvisible to text search). `.codebase-memory/graph.db.zst` is the committed\nbootstrap snapshot; local databases and\n`.codebase-memory/artifact.json` <!-- check-guidance: path-ok --> stay\ngit-ignored (per-environment state, deliberately untracked). Check\nfreshness first: `bash scripts/codebase-graph.sh status`.\n\n- Missing → `index_repository(repo_path=\".\", persistence=true)` once.\n- Stale → `detect_changes(since=\"<indexed-commit>\")`, or re-run\n  `index_repository` to refresh the shared snapshot.\n- Where is a symbol → `search_graph(name_pattern=…)`, then\n  `get_code_snippet(qualified_name=…)`.\n- Who calls X / what X calls → `trace_path(function_name=…, mode=\"calls\")`;\n  value flow → `mode=\"data_flow\"`; cross-crate feature path →\n  `mode=\"cross_service\"`.\n- Structure of an area → `get_architecture(…)`; graph-augmented text search →\n  `search_code(pattern=…)`; arbitrary queries → `query_graph(<Cypher>)`.\n\nThe graph is a point-in-time index — verify anything it asserts against live\ncode before acting. `Grep`/`Glob`/`Read` remain correct for text, config, and\nnon-code files. For narrative *what/why* orientation, read the relevant\n`openwiki/` page (generated — never hand-edit).\n\n## REPL/TUI logging rule\n\n`info!` and `warn!` output appears in the REPL and corrupts the terminal UI.\nUse `debug!` for internal diagnostics (trace analysis, reflection results,\nengine internals); reserve `info!` for user-facing status the REPL\nintentionally renders. Background tasks must NEVER use `info!`.\n",".claude/skills/architecture-video/SKILL.md":"---\nname: architecture-video\ndescription: Generate or update the IronClaw architecture overview video using Remotion. Use when asked to update, regenerate, or modify the architecture video, add/remove scenes, or reflect codebase changes in the video.\n---\n\n# Architecture Video Generator\n\nGenerates and maintains the animated architecture overview video in `docs/internal/architecture-video/` using Remotion (React-based video framework).\n\n## When to use\n\n- User asks to update, regenerate, or modify the architecture video\n- User asks to add or remove scenes from the video\n- Codebase architecture has changed and the video needs to reflect it\n- User wants to preview or render the video\n\n## Before making changes\n\n### 1. Read current architecture\n\nRead these files to understand the current system architecture:\n\n- `AGENTS.md` — top-level commands, invariants, tree map, module specs table\n- `crates/Architecture.md` — **the Reborn stack thesis and component map (the current architecture; lead the video with this)**\n- `crates/AGENTS.md` — the Reborn crate routing map\n- `crates/domains/ironclaw_llm/CONTRACT.md` — canonical LLM provider architecture\n- `crates/substrates/ironclaw_filesystem/CONTRACT.md` — storage fabric / dual-backend architecture\n- `crates/extensions/AGENTS.md` — the installable-package family: extension packages, tool surfaces, lifecycle host (successor of the v1 tool system)\n- `crates/domains/ironclaw_memory/README.md` — the memory contract and conformance seam (successor of the v1 workspace/memory system)\n\n### 2. Read current video scenes\n\nRead `docs/internal/architecture-video/src/IronClawArchitecture.tsx` to understand current scene order, durations, and transitions. Then read individual scenes in `docs/internal/architecture-video/src/scenes/` to see what's already covered.\n\n### 3. Identify gaps\n\nCompare the architecture documentation with what the video covers. Look for:\n- New modules or traits added since the video was last updated\n- Renamed or restructured components\n- New data flows or state machines\n- Removed or deprecated features\n\n## Video project structure\n\n```\ndocs/internal/architecture-video/\n├── package.json              # Remotion deps\n├── remotion.config.ts        # Build config\n├── src/\n│   ├── Root.tsx              # Remotion entry — registers the composition\n│   ├── IronClawArchitecture.tsx  # Main composition — scene order + transitions\n│   ├── theme.ts              # Color palette + font constants\n│   ├── components/\n│   │   └── Code.tsx          # Syntax-highlighted code block component\n│   └── scenes/               # One file per scene\n│       ├── TitleScene.tsx\n│       ├── PrimitivesScene.tsx\n│       ├── ExecutionLoopScene.tsx\n│       ├── CodeActScene.tsx\n│       ├── ThreadStateScene.tsx\n│       ├── SkillsPipelineScene.tsx\n│       ├── ToolDispatchScene.tsx\n│       ├── ChannelsRoutingScene.tsx\n│       ├── ChannelImplsScene.tsx\n│       ├── TraitsScene.tsx\n│       ├── LlmDecoratorScene.tsx\n│       └── OutroScene.tsx\n```\n\nRender script: `scripts/render-architecture-video.sh`\n\n## Current scene inventory (12 scenes, ~82s at 30fps)\n\n| # | Scene | File | Duration | Content |\n|---|-------|------|----------|---------|\n| 1 | Title | TitleScene.tsx | 4s | Animated IronClaw logo + tagline |\n| 2 | Five Primitives | PrimitivesScene.tsx | 8s | Thread / Step / Capability / MemoryDoc / Project |\n| 3 | Execution Loop | ExecutionLoopScene.tsx | 8s | 7-step ExecutionLoop::run() pipeline |\n| 4 | CodeAct | CodeActScene.tsx | 10s | Python code → host fns → suspend/resume flow |\n| 5 | Thread State | ThreadStateScene.tsx | 7s | Created→Running⇄Waiting/Suspended→Completed/Failed→Done |\n| 6 | Skills Pipeline | SkillsPipelineScene.tsx | 8s | Gating → Scoring → Budget → Attenuation |\n| 7 | Tool Dispatch | ToolDispatchScene.tsx | 9s | 9-step ToolDispatcher::dispatch() pipeline |\n| 8 | Channels Routing | ChannelsRoutingScene.tsx | 7s | Channel trait + stream::select_all merging |\n| 9 | Channel Impls | ChannelImplsScene.tsx | 7s | REPL / HTTP / Web / Signal / TUI / WASM |\n| 10 | Traits | TraitsScene.tsx | 8s | 8 traits with concrete implementers |\n| 11 | LLM Decorators | LlmDecoratorScene.tsx | 7s | SmartRouting→CircuitBreaker→...→Base decorator chain |\n| 12 | Outro | OutroScene.tsx | 5s | Start Contributing + getting-started steps |\n\n## Remotion patterns used in this project\n\nAll animations MUST be driven by `useCurrentFrame()` — never CSS transitions or Tailwind animation classes.\n\n### Animation pattern\n\n```tsx\nconst frame = useCurrentFrame();\nconst { fps } = useVideoConfig();\n\nconst opacity = interpolate(frame, [0, 0.5 * fps], [0, 1], {\n  extrapolateRight: \"clamp\",\n});\nconst y = interpolate(frame, [0, 0.5 * fps], [30, 0], {\n  extrapolateRight: \"clamp\",\n  easing: Easing.bezier(0.16, 1, 0.3, 1),\n});\n```\n\n### Staggered list pattern\n\nFor items that appear one by one:\n\n```tsx\n{items.map((item, i) => {\n  const delay = 0.4 + i * 0.3; // seconds\n  const opacity = interpolate(\n    frame,\n    [delay * fps, (delay + 0.35) * fps],\n    [0, 1],\n    { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" }\n  );\n  return <div style={{ opacity }} key={item.id}>...</div>;\n})}\n```\n\n### Scene transitions\n\nScenes are composed using `TransitionSeries` with alternating `fade()` and `slide({ direction: \"from-right\" })` transitions, each 15 frames (0.5s):\n\n```tsx\n<TransitionSeries>\n  <TransitionSeries.Sequence durationInFrames={s(8)}>\n    <MyScene />\n  </TransitionSeries.Sequence>\n  <TransitionSeries.Transition\n    presentation={fade()}\n    timing={linearTiming({ durationInFrames: 15 })}\n  />\n  <TransitionSeries.Sequence durationInFrames={s(7)}>\n    <NextScene />\n  </TransitionSeries.Sequence>\n</TransitionSeries>\n```\n\n### Code blocks\n\nUse the `CodeBlock` component from `../components/Code` for syntax-highlighted code:\n\n```tsx\nimport { CodeBlock } from \"../components/Code\";\n\n<CodeBlock code={`pub trait Channel: Send + Sync {\n  async fn start(&self) -> Result<MessageStream>;\n}`} fontSize={13} />\n```\n\n### Theme\n\nImport colors and fonts from `../theme`:\n\n```tsx\nimport { COLORS, FONTS } from \"../theme\";\n\n// Available colors:\n// bg, bgLight, primary, primaryLight, accent, accentLight,\n// success, danger, text, textMuted, border, purple, cyan, pink\n\n// Available fonts:\n// mono (monospace), sans (system-ui)\n```\n\n## Adding a new scene\n\n1. Create `src/scenes/MyNewScene.tsx` following existing patterns\n2. Export the component\n3. Import in `IronClawArchitecture.tsx`\n4. Add to the `SCENES` array with duration and transition type\n5. `TOTAL_DURATION` auto-computes from the array\n6. Verify with: `npx remotion still IronClawArchitecture --scale=0.25 --frame=<N>`\n\n### Scene template\n\n```tsx\nimport {\n  AbsoluteFill,\n  interpolate,\n  useCurrentFrame,\n  useVideoConfig,\n  Easing,\n} from \"remotion\";\nimport { COLORS, FONTS } from \"../theme\";\n\nexport const MyNewScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  const { fps } = useVideoConfig();\n\n  const headingOpacity = interpolate(frame, [0, 0.4 * fps], [0, 1], {\n    extrapolateRight: \"clamp\",\n  });\n\n  return (\n    <AbsoluteFill\n      style={{\n        backgroundColor: COLORS.bg,\n        fontFamily: FONTS.sans,\n        padding: 60,\n      }}\n    >\n      <div\n        style={{\n          opacity: headingOpacity,\n          fontSize: 42,\n          fontWeight: 700,\n          color: COLORS.text,\n          marginBottom: 4,\n        }}\n      >\n        <span style={{ color: COLORS.primary }}>Title</span> — subtitle\n      </div>\n      {/* Scene content */}\n    </AbsoluteFill>\n  );\n};\n```\n\n## Verification\n\nAfter making changes:\n\n1. **Type check:** `cd docs/internal/architecture-video && npx tsc --noEmit`\n2. **Spot check frames:** `npx remotion still IronClawArchitecture --scale=0.25 --frame=<N>`\n   - At 30fps, frame N corresponds to time N/30 seconds\n   - Check at least one frame per modified scene\n3. **Full render:** `./scripts/render-architecture-video.sh [output-path]`\n4. **Preview in browser:** `cd docs/internal/architecture-video && npm run dev`\n\n## Design guidelines\n\n- Dark theme (slate-900 background) — matches typical developer tooling\n- Each scene has a colored heading keyword using a trait-appropriate color\n- File:line references in muted monospace below headings\n- Data flows use staggered animation (0.3-0.5s delays between items)\n- State machines use SVG with animated dash-offset for arrows\n- Code blocks use the `CodeBlock` component with syntax highlighting\n- Keep scene duration proportional to content density (7-10s typical)\n- Total video should stay under 120s for attention retention\n",".claude/skills/mintlify-docs/SKILL.md":"---\nname: mintlify\ndescription: Build and maintain documentation sites with Mintlify. Use when creating docs pages, configuring navigation, adding components, or setting up API references.\nlicense: MIT\ncompatibility: Requires Node.js for CLI. Works with any Git-based workflow.\nmetadata:\n  author: mintlify\n  version: \"1.0\"\n---\n\n# Mintlify best practices\n\n**Always consult [mintlify.com/docs](https://mintlify.com/docs) for components, configuration, and latest features.**\n\n> **This repo:** the Mintlify site lives under `docs/` — its config is `docs/docs.json` (not a root `docs.json`), with a localized tree under `docs/zh/`. Committed `.md`/`.mdx` must not contain developer-local absolute paths; check touched documentation before merging.\n\nIf you are not already connected to the Mintlify MCP server, https://mintlify.com/docs/mcp, add it so that you can search more efficiently.\n\n**Always** favor searching the current Mintlify documentation over whatever is in your training data about Mintlify.\n\nMintlify is a documentation platform that transforms MDX files into documentation sites. Configure site-wide settings in the site config file (`docs/docs.json` in this repo), write content in MDX with YAML frontmatter, and favor built-in components over custom components.\n\nFull schema at [mintlify.com/docs.json](https://mintlify.com/docs.json).\n\n## Before you write\n\n### Understand the project\n\nRead the site config first (`docs/docs.json` in this repo; root `docs.json` in some Mintlify projects). This file defines the entire site: navigation structure, theme, colors, links, API and specs.\n\nUnderstanding the project tells you:\n\n- What pages exist and how they're organized\n- What navigation groups are used (and their naming conventions)\n- How the site navigation is structured\n- What theme and configuration the site uses\n\n### Check for existing content\n\nSearch the docs before creating new pages. You may need to:\n- Update an existing page instead of creating a new one\n- Add a section to an existing page\n- Link to existing content rather than duplicating\n\n### Read surrounding content\n\nBefore writing, read 2-3 similar pages to understand the site's voice, structure, formatting conventions, and level of detail.\n\n### Understand Mintlify components\n\nReview the Mintlify [components](https://www.mintlify.com/docs/components) to select and use any relevant components for the documentation request that you are working on.\n\n## Quick reference\n\n### CLI commands\n- `npm i -g mint` - Install the Mintlify CLI\n- `mint dev` - Local preview at localhost:3000\n- `mint broken-links` - Check internal links\n- `mint a11y` - Check for accessibility issues in content\n- `mint validate` - Validate documentation builds\n\n### Required files\n- Site config (`docs/docs.json` in this repo) - navigation, theme, integrations, etc. See [global settings](https://mintlify.com/docs/settings/global) for all options.\n- `*.mdx` files - Documentation pages with YAML frontmatter\n\n### Example file structure\n```\nproject/\n├── docs.json           # Site configuration (this repo keeps it at docs/docs.json)\n├── introduction.mdx\n├── quickstart.mdx\n├── guides/\n│   └── example.mdx\n├── openapi.yml         # API specification\n├── images/             # Static assets\n│   └── example.png\n└── snippets/           # Reusable components\n    └── component.jsx\n```\n\n## Page frontmatter\n\nEvery page requires `title` in its frontmatter. Include `description` for SEO and navigation.\n\n```yaml\n---\ntitle: \"Clear, descriptive title\"\ndescription: \"Concise summary for SEO and navigation.\"\n---\n```\n\nOptional frontmatter fields:\n- `sidebarTitle`: Short title for sidebar navigation.\n- `icon`: Lucide or Font Awesome icon name, URL, or file path.\n- `tag`: Label next to the page title in the sidebar (for example, \"NEW\").\n- `mode`: Page layout mode (`default`, `wide`, `custom`).\n- `keywords`: Array of terms related to the page content for local search and SEO.\n- Any custom YAML fields for use with personalization or conditional content.\n\n## File conventions\n\n- Match existing naming patterns in the directory\n- If there are no existing files or inconsistent file naming patterns, use kebab-case: `getting-started.mdx`, `api-reference.mdx`\n- Use root-relative paths without file extensions for internal links: `/getting-started/quickstart`\n- Do not use relative paths (`../`) or absolute URLs for internal pages\n- When you create a new page, add it to site config navigation (`docs/docs.json` here) or it won't appear in the sidebar\n\n## Organize content\n\nWhen a user asks about anything related to site-wide configurations, start by understanding the [global settings](https://www.mintlify.com/docs/organize/settings). See if a setting in the site config (`docs/docs.json` here) can be updated to achieve what the user wants.\n\n### Navigation\n\nThe `navigation` property in the site config (`docs/docs.json` here) controls site structure. Choose one primary pattern at the root level, then nest others within it.\n\n**Choose your primary pattern:**\n\n| Pattern | When to use |\n|---------|-------------|\n| **Groups** | Default. Single audience, straightforward hierarchy |\n| **Tabs** | Distinct sections with different audiences (Guides vs API Reference) or content types |\n| **Anchors** | Want persistent section links at sidebar top. Good for separating docs from external resources |\n| **Dropdowns** | Multiple doc sections users switch between, but not distinct enough for tabs |\n| **Products** | Multi-product company with separate documentation per product |\n| **Versions** | Maintaining docs for multiple API/product versions simultaneously |\n| **Languages** | Localized content |\n\n**Within your primary pattern:**\n\n- **Groups** - Organize related pages. Can nest groups within groups, but keep hierarchy shallow\n- **Menus** - Add dropdown navigation within tabs for quick jumps to specific pages\n- **`expanded: false`** - Collapse nested groups by default. Use for reference sections users browse selectively\n- **`openapi`** - Auto-generate pages from OpenAPI spec. Add at group/tab level to inherit\n\n**Common combinations:**\n- Tabs containing groups (most common for docs with API reference)\n- Products containing tabs (multi-product SaaS)\n- Versions containing tabs (versioned API docs)\n- Anchors containing groups (simple docs with external resource links)\n\n### Links and paths\n\n- **Internal links:** Root-relative, no extension: `/getting-started/quickstart`\n- **Images:** Store in `/images`, reference as `/images/example.png`\n- **External links:** Use full URLs, they open in new tabs automatically\n\n## Customize docs sites\n\n**What to customize where:**\n- **Brand colors, fonts, logo** → site config (`docs/docs.json` here). See [global settings](https://mintlify.com/docs/settings/global)\n- **Component styling, layout tweaks** → `custom.css` at project root\n- **Dark mode** → Enabled by default. Only disable with `\"appearance\": \"light\"` in the site config if brand requires it\n\nStart with the site config (`docs/docs.json` here). Only add `custom.css` when you need styling that config doesn't support.\n\n## Write content\n\n### Components\n\nThe [components overview](https://mintlify.com/docs/components) organizes all components by purpose: structure content, draw attention, show/hide content, document APIs, link to pages, and add visual context. Start there to find the right component.\n\n**Common decision points:**\n\n| Need | Use |\n|------|-----|\n| Hide optional details | `<Accordion>` |\n| Long code examples | `<Expandable>` |\n| User chooses one option | `<Tabs>` |\n| Linked navigation cards | `<Card>` in `<Columns>` |\n| Sequential instructions | `<Steps>` |\n| Code in multiple languages | `<CodeGroup>` |\n| API parameters | `<ParamField>` |\n| API response fields | `<ResponseField>` |\n\n**Callouts by severity:**\n- `<Note>` - Supplementary info, safe to skip\n- `<Info>` - Helpful context such as permissions\n- `<Tip>` - Recommendations or best practices\n- `<Warning>` - Potentially destructive actions\n- `<Check>` - Success confirmation\n\n### Reusable content\n\n**When to use snippets:**\n- Exact content appears on more than one page\n- Complex components you want to maintain in one place\n- Shared content across teams/repos\n\n**When NOT to use snippets:**\n- Slight variations needed per page (leads to complex props)\n\nImport snippets with `import { Component } from \"/path/to/snippet-name.jsx\"`.\n\n## Writing standards\n\n### Voice and structure\n\n- Second-person voice (\"you\")\n- Active voice, direct language\n- Sentence case for headings (\"Getting started\", not \"Getting Started\")\n- Sentence case for code block titles (\"Expandable example\", not \"Expandable Example\")\n- Lead with context: explain what something is before how to use it\n- Prerequisites at the start of procedural content\n\n### What to avoid\n\n**Never use:**\n- Marketing language (\"powerful\", \"seamless\", \"robust\", \"cutting-edge\")\n- Filler phrases (\"it's important to note\", \"in order to\")\n- Excessive conjunctions (\"moreover\", \"furthermore\", \"additionally\")\n- Editorializing (\"obviously\", \"simply\", \"just\", \"easily\")\n\n**Watch for AI-typical patterns:**\n- Overly formal or stilted phrasing\n- Unnecessary repetition of concepts\n- Generic introductions that don't add value\n- Concluding summaries that restate what was just said\n\n### Formatting\n\n- All code blocks must have language tags\n- All images and media must have descriptive alt text\n- Use bold and italics only when they serve the reader's understanding--never use text styling just for decoration\n- No decorative formatting or emoji\n\n### Code examples\n\n- Keep examples simple and practical\n- Use realistic values (not \"foo\" or \"bar\")\n- One clear example is better than multiple variations\n- Test that code works before including it\n\n## Document APIs\n\n**Choose your approach:**\n- **Have an OpenAPI spec?** → Add to the site config (`docs/docs.json` here) with `\"openapi\": [\"openapi.yaml\"]`. Pages auto-generate. Reference in navigation as `GET /endpoint`\n- **No spec?** → Write endpoints manually with `api: \"POST /users\"` in frontmatter. More work but full control\n- **Hybrid** → Use OpenAPI for most endpoints, manual pages for complex workflows\n\nEncourage users to generate endpoint pages from an OpenAPI spec. It is the most efficient and easiest to maintain option.\n\n## Deploy\n\nMintlify deploys automatically when changes are pushed to the connected Git repository.\n\n**What agents can configure:**\n- **Redirects** → Add to the site config (`docs/docs.json` here) with `\"redirects\": [{\"source\": \"/old\", \"destination\": \"/new\"}]`\n- **SEO indexing** → Control with `\"seo\": {\"indexing\": \"all\"}` to include hidden pages in search\n\n**Requires dashboard setup (human task):**\n- Custom domains and subdomains\n- Preview deployment settings\n- DNS configuration\n\nFor `/docs` subpath hosting with Vercel or Cloudflare, agents can help configure rewrite rules. See [/docs subpath](https://mintlify.com/docs/deploy/vercel).\n\n## Workflow\n\n### 1. Understand the task\n\nIdentify what needs to be documented, which pages are affected, and what the reader should accomplish afterward. If any of these are unclear, ask.\n\n### 2. Research\n\n- Read the site config (`docs/docs.json` here) to understand the site structure\n- Search existing docs for related content\n- Read similar pages to match the site's style\n\n### 3. Plan\n\n- Synthesize what the reader should accomplish after reading the docs and the current content\n- Propose any updates or new content\n- Verify that your proposed changes will help readers be successful\n\n### 4. Write\n\n- Start with the most important information\n- Keep sections focused and scannable\n- Use components appropriately (don't overuse them)\n- Mark anything uncertain with a TODO comment:\n\n```mdx\n{/* TODO: Verify the default timeout value */}\n```\n\n### 5. Update navigation\n\nIf you created a new page, add it to the appropriate group in the site config (`docs/docs.json` here).\n\n### 6. Verify\n\nBefore submitting:\n\n- [ ] Frontmatter includes title and description\n- [ ] All code blocks have language tags\n- [ ] Internal links use root-relative paths without file extensions\n- [ ] New pages are added to site config navigation (`docs/docs.json` here)\n- [ ] Content matches the style of surrounding pages\n- [ ] No marketing language or filler phrases\n- [ ] TODOs are clearly marked for anything uncertain\n- [ ] Run `mint broken-links` to check links\n- [ ] Run `mint validate` to find any errors\n\n## Edge cases\n\n### Migrations\n\nIf a user asks about migrating to Mintlify, ask if they are using ReadMe or Docusaurus. If they are, use the [@mintlify/scraping](https://www.npmjs.com/package/@mintlify/scraping) CLI to migrate content. If they are using a different platform to host their documentation, help them manually convert their content to MDX pages using Mintlify components.\n\n### Hidden pages\n\nAny page that is not included in site config navigation (`docs/docs.json` here) is hidden. Use hidden pages for content that should be accessible by URL or indexed for the assistant or search, but not discoverable through the sidebar navigation.\n\n### Exclude pages\n\nThe `.mintignore` file is used to exclude files from a documentation repository from being processed.\n\n## Common gotchas\n\n1. **Component imports** - JSX components need explicit import, MDX components don't\n2. **Frontmatter required** - Every MDX file needs `title` at minimum\n3. **Code block language** - Always specify language identifier\n4. **Never use `mint.json`** - `mint.json` is deprecated. Use the Mintlify site config (`docs/docs.json` here; often root `docs.json` in other projects)\n\n## Resources\n\n- [Documentation](https://mintlify.com/docs)\n- [Configuration schema](https://mintlify.com/docs.json)\n- [Feature requests](https://github.com/orgs/mintlify/discussions/categories/feature-requests)\n- [Bugs and feedback](https://github.com/orgs/mintlify/discussions/categories/bugs-feedback)\n","skills/github/SKILL.md":"---\nname: github\nversion: \"1.0.0\"\ndescription: GitHub API integration via HTTP tool with automatic credential injection\nactivation:\n  keywords:\n    - \"github\"\n    - \"pull request\"\n    - \"github issue\"\n    - \"github repo\"\n    - \"pr comment\"\n    - \"open a pr\"\n    - \"create a pr\"\n    - \"my prs\"\n  exclude_keywords:\n    - \"gitlab\"\n    - \"bitbucket\"\n  patterns:\n    - \"(?i)(list|show|get|fetch|open|close|create|file|merge|comment on)\\\\s.*(pull request|\\\\bPR\\\\b)\"\n    - \"(?i)github\\\\.com\"\n    - \"(?i)[a-z0-9._-]+/[a-z0-9._-]+#\\\\d+\"\n  tags:\n    - \"git\"\n    - \"code-review\"\n    - \"devops\"\n  max_context_tokens: 2000\ncredentials:\n  - name: github_token\n    provider: github\n    location:\n      type: bearer\n    hosts:\n      - \"api.github.com\"\n    oauth:\n      authorization_url: \"https://github.com/login/oauth/authorize\"\n      token_url: \"https://github.com/login/oauth/access_token\"\n      scopes:\n        - \"repo\"\n        - \"read:org\"\n      refresh:\n        strategy: reauthorize_only\n    setup_instructions: \"Create a personal access token at https://github.com/settings/tokens\"\n---\n\n# GitHub API Skill\n\nYou have access to the GitHub REST API via the `http` tool. Credentials are automatically injected — **never construct Authorization headers manually**. When the URL host is `api.github.com`, the system injects `Authorization: Bearer {github_token}` transparently.\n\n## API Patterns\n\nAll endpoints use `https://api.github.com` as the base URL. Common headers are injected automatically.\n\n### Issues\n\n**List issues:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/issues?state=open&sort=created&direction=desc&per_page=30\")\n```\n\n**Get single issue:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/issues/{number}\")\n```\n\n**Create issue:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/issues\", body={\"title\": \"...\", \"body\": \"...\", \"labels\": [\"bug\"]})\n```\n\n**Add comment:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/issues/{number}/comments\", body={\"body\": \"...\"})\n```\n\n### Pull Requests\n\n**List PRs:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls?state=open&sort=created&direction=desc&per_page=30\")\n```\n\n**Create PR:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls\", body={\"title\": \"...\", \"body\": \"...\", \"head\": \"feature-branch\", \"base\": \"main\", \"draft\": true})\n```\n\n**Get PR diff:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls/{number}\", headers=[{\"name\": \"Accept\", \"value\": \"application/vnd.github.v3.diff\"}])\n```\n\n### Repository\n\n**Get repo info:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}\")\n```\n\n**List branches:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/branches\")\n```\n\n**List recent commits:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/commits?per_page=10\")\n```\n\n### Authenticated User & Cross-Repo Queries\n\nWhen the user says \"my PRs\", \"my issues\", or \"my repos\", they mean the user who owns `github_token`. Don't try to list a single repo, hit the search/user endpoints instead.\n\n**Get the authenticated user (resolves who `@me` is):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/user\")\n```\n\n**My latest PRs across all repos:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:pr+author:%40me+sort:updated-desc&per_page=20\")\n```\n\n**My open issues across all repos (assigned to me):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:issue+is:open+assignee:%40me&per_page=20\")\n```\n\n**PRs that need my review:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:pr+is:open+review-requested:%40me\")\n```\n\n**My repos (list all repos accessible to the token):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/user/repos?sort=updated&per_page=30\")\n```\n\n### Search\n\nGitHub has three search endpoints. Build queries with the [search syntax](https://docs.github.com/en/search-github/searching-on-github).\n\n**Search issues and PRs (one endpoint, filter with `is:pr` or `is:issue`):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=repo:{owner}/{repo}+is:pr+is:open+label:bug\")\n```\n\n- Note: There is no `/search/pulls` endpoint; `/search/issues` is the unified endpoint for both issues and PRs.\n\n**Search code:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/code?q=fn+main+language:rust+repo:{owner}/{repo}\")\n```\n\n**Search repositories:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/repositories?q=tetris+language:rust&sort=stars\")\n```\n\nURL-encode `@` as `%40` and spaces as `+` in `q=` values.\n\n## Response Handling\n\nThe `http` tool returns an envelope:\n\n```python\n{\"status\": 200, \"headers\": {...}, \"body\": <parsed value>}\n```\n\n- **JSON endpoints** — `body` is already a parsed Python dict or list. Do **not** call `json.loads()` on it. Example:\n  ```python\n  r = await http(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls/123\")\n  if r[\"status\"] != 200:\n      FINAL(f\"GitHub returned HTTP {r['status']}: {r['body']}\")\n  pr = r[\"body\"]          # dict, not a string\n  title  = pr[\"title\"]    # use direct indexing; these keys always exist on a 2xx\n  state  = pr[\"state\"]\n  head   = pr[\"head\"][\"ref\"]\n  base   = pr[\"base\"][\"ref\"]\n  ```\n- **Diff / plain text endpoints** (`Accept: application/vnd.github.v3.diff` etc.) — `body` is a `str` containing the raw unified diff; use it as-is.\n- **Never** write `body = pr_meta.get(\"body\", pr_meta)` as a \"safety net\" — it hides real errors. If `status` isn't 2xx, fail fast.\n- For list endpoints, check the `Link` header for pagination.\n- Rate limit: 5000 req/hour authenticated. Check `X-RateLimit-Remaining` if doing bulk ops.\n- Error responses are JSON of the form `{\"message\": \"...\"}` with a non-2xx `status` — surface them literally in your FINAL answer.\n\n## Common Mistakes\n\n- Do NOT add an `Authorization` header — it is injected automatically by the credential system.\n- Always use HTTPS URLs (HTTP is blocked by the security layer).\n- For creating PRs, always set `draft: true` unless the user explicitly says \"ready for review\".\n- The `state` parameter for issues/PRs is `open`, `closed`, or `all` — not `active`/`inactive`.\n- Use `per_page` to control result count (max 100). Default is 30.\n- For \"my PRs / my issues\" across all repos, hit `/search/issues?q=...+author:%40me`. Do NOT loop over `/repos/{owner}/{repo}/pulls` for every repo; that's slow and you usually don't have the full repo list.\n","skills/developer-setup/SKILL.md":"---\nname: developer-setup\nversion: 0.2.0\ndescription: One-time onboarding for the developer workflow — installs github-workflow missions, creates the commitments workspace, registers per-repo projects, writes calibration memories. Excludes itself until its marker file is deleted.\nactivation:\n  setup_marker: projects/commitments/.developer-setup-complete\n  keywords:\n    - developer assistant\n    - dev assistant\n    - dev workflow\n    - developer setup\n    - github setup\n    - help with github\n    - manage my PRs\n    - code workflow\n    - engineering setup\n    - dev setup\n    - automate my repos\n    - CI keeps failing\n    - engineering workflow\n  patterns:\n    - \"(?i)I'm a (developer|engineer|programmer|dev|software engineer)\"\n    - \"(?i)help me (with|manage|set ?up) (github|PRs|repos|CI|code|projects)\"\n    - \"(?i)set ?up.*(dev|coding|engineering|github|developer)\"\n    - \"(?i)(automate|manage) my (repos|PRs|projects|workflow|code)\"\n  tags:\n    - commitments\n    - developer\n    - github\n    - setup\n  max_context_tokens: 3000\nrequires:\n  # Capped at MAX_REQUIRED_SKILLS_PER_MANIFEST = 10 in\n  # `ironclaw_skills::types`. The trimmed list keeps the 10 highest-impact\n  # companions for the developer workflow; the dropped entries\n  # (`qa-review`, `review-readiness`, `product-prioritization`) can still\n  # be installed manually via `skill_install` when needed.\n  skills:\n    - github\n    - github-workflow\n    - project-setup\n    - commitment-triage\n    - commitment-digest\n    - decision-capture\n    - delegation-tracker\n    - idea-parking\n    - tech-debt-tracker\n    - security-review\n---\n\n# Developer Workflow Setup\n\nYou are configuring the full developer workflow — commitment tracking, GitHub automation, tech debt tracking, security/QA reviews, product prioritization, and proactive briefings across multiple repositories.\n\n## Companion skills\n\nThese activate during conversation via keyword matching:\n\n| Skill | When | What |\n|---|---|---|\n| `commitment-triage` | Obligations, deadlines | Signal extraction, commitment creation |\n| `commitment-digest` | \"show commitments\" | Formatted status summary |\n| `decision-capture` | Architecture/design decisions | Records decision + rationale |\n| `delegation-tracker` | \"waiting on @teammate\" | Tracks delegation follow-ups |\n| `idea-parking` | \"park this idea\" | Saves for later |\n| `tech-debt-tracker` | \"this is a hack\", \"refactor later\" | Tracks tech debt, resurfaces weekly |\n| `project-setup` | \"add repo owner/repo\" | Adds a new project with workflow |\n| `security-review` | \"security review\", \"check for vulnerabilities\" | OWASP audit, auto-fix obvious issues |\n| `qa-review` | \"QA review\", \"test coverage\", \"edge cases\" | Test plans, coverage gaps, regression risks |\n| `review-readiness` | \"ready to merge?\", \"PR readiness\" | Tracks which reviews are complete per branch |\n| `product-prioritization` | \"what to build next\", \"prioritize\" | Evidence-based feature scoring, demand analysis |\n| `github` | GitHub API operations | REST API with credential injection |\n| `github-workflow` | Workflow automation reference | Issue-to-merge pipeline templates |\n| `review-checklist` | Pre-merge review | 55+ verification items |\n\nIf any are missing from `skills/`, tell the user which ones are needed.\n\n## Step 1: Setup questions (4, no timezone)\n\n1. **Repos**: Which GitHub repos do you work on? (1-5, format: `owner/repo`)\n2. **Role**: Solo maintainer, team member, or team lead? (Affects delegation vs personal tracking)\n3. **Per-repo**: For each repo — who are maintainers/reviewers? Do you use a staging branch?\n4. **AI agents**: Do any bots create PRs? (Dependabot, Copilot, internal agents) — these get tracked separately in digests with shorter stale thresholds\n\nUse reasonable defaults if the user says \"just set it up.\"\n\n## Step 2: Declare the `commitments` project and create workspace structure\n\nWriting any file under `projects/commitments/` is the declaration that\nthe project exists — the engine auto-registers it and scopes missions\nto it. Start with:\n\n```\nmemory_write(\n  target: \"projects/commitments/AGENTS.md\",\n  content: \"# Commitments (Developer)\\n\\nThis project tracks engineering commitments, tech debt, and decisions across the user's repositories.\\n\\n## Operating principles\\n\\n- Most items are personal tasks, not delegations — default `owner=user`.\\n- Capture tech debt passively from conversation and from merged PR review comments.\\n- AI agent PRs group separately in digests with shorter stale thresholds.\\n- For irreversible actions (merging, deleting, sending messages), always ask first.\\n\",\n  append: false\n)\n```\n\nThen:\n\n1. Check if `projects/commitments/README.md` exists. If not, create the full commitments workspace (see `commitment-setup` skill for the complete schema including immediacy, resolution paths, trust calibration).\n2. Create subdirectory placeholders: `open/`, `resolved/`, `signals/pending/`, `signals/expired/`, `decisions/`, `parked-ideas/`.\n3. Create `projects/commitments/tech-debt/README.md` — \"Tech debt items. Resurface in weekly retro.\"\n\n## Step 3: Set up each project\n\nFor each repo the user listed, run the `project-setup` procedure:\n1. Validate repo via GitHub API\n2. Create `projects/<owner>-<repo>/project.md` with metadata\n3. Create `projects/<owner>-<repo>/notes.md` for developer notes\n4. Install the 6 workflow missions (namespaced by repo slug)\n5. Skip `wf-staging-review` if no staging branch\n\n## Step 4: Create developer missions\n\n### commitment-triage (3x weekdays)\n\n```\nmission_create(\n  name: \"commitment-triage\",\n  goal: \"Developer triage. Read projects/commitments/README.md for schema. Read projects/ via memory_tree for all tracked repos. For each repo, check GitHub API: (1) New PR review requests assigned to user → signal with immediacy=batch. (2) CI failures on user's open PRs → signal with immediacy=prompt. (3) @mentions on PRs/issues → signal with immediacy=prompt. (4) New issue assignments → signal with immediacy=batch. (5) Issues/PRs with production/hotfix/critical labels → signal with immediacy=realtime, broadcast immediately. (6) Recently merged PRs — scan review comments for tech-debt patterns ('address in follow-up', 'not blocking but fix later', 'TODO', 'leaving for now') → create tech-debt items in projects/commitments/tech-debt/ with source=pr-review and source_pr reference. Expire signals after 48h. Flag AI agent PRs stuck in CI after 24h. Append summary to projects/commitments/triage-log.md.\",\n  cadence: \"0 9,14,18 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### commitment-digest (weekday mornings)\n\n```\nmission_create(\n  name: \"commitment-digest\",\n  goal: \"Developer morning brief. Read projects/commitments/README.md for schema. Read projects/ for tracked repos. For each repo, query GitHub API. Compose digest in this order: (1) OVERNIGHT RESULTS — CI status per repo on user's PRs (green/red/pending), PRs merged overnight. (2) NEEDS YOUR REVIEW — PRs where user is requested reviewer, show age, author, size. Separate human PRs from AI agent PRs. Flag stale reviews (3+ days). (3) YOUR OPEN PRs — each with CI status, review state. Flag READY TO MERGE if approved + CI green. (4) BLOCKED/WAITING — commitments with status=waiting or delegated_to set, agent PRs stuck in CI loops (attempted 3+ fixes). (5) TODAY'S COMMITMENTS — open items sorted by urgency, for agent_can_handle items note what agent would do. (6) QUICK STATS — tech debt count, pending signal count. End with 'Did I miss anything?' Send via message tool. Omit empty sections.\",\n  cadence: \"0 8 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-stale-pr-check (weekday afternoons)\n\n```\nmission_create(\n  name: \"dev-stale-pr-check\",\n  goal: \"Check for stale PRs across tracked repos. Read projects/ for repo list. For each repo, query GitHub API for open PRs. Flag PRs with no activity in 3+ days (human) or 1+ day (agent PR stuck in CI). For user's own stale PRs: suggest pinging reviewer or closing if abandoned. For PRs user should review: note how long they've been waiting. Send alert only if stale items found; stay silent otherwise.\",\n  cadence: \"0 16 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-weekly-retro (Friday morning)\n\n```\nmission_create(\n  name: \"dev-weekly-retro\",\n  goal: \"Weekly developer retrospective. Gather: (1) All commitments resolved this week from projects/commitments/resolved/. (2) All decisions captured this week from projects/commitments/decisions/. (3) All tech debt items added this week from projects/commitments/tech-debt/ — include items from PR review scans. (4) Per-repo: count of merged PRs this week via GitHub API. (5) Open items carried forward. Compose retro: SHIPPED, DECISIONS MADE (with rationale), SLIPPED/CARRIED FORWARD, TECH DEBT ACCUMULATED (new items + total count + top 3 chronic), PATTERNS (recurring CI failures, slow review cycles). For complex action items, suggest using /plan to create a structured execution plan. Write retro to context/intel/weekly-retro-<date>.md. Send via message tool.\",\n  cadence: \"0 10 * * 5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-decision-outcome-check (Wednesday)\n\n```\nmission_create(\n  name: \"dev-decision-outcome-check\",\n  goal: \"Check for decisions needing outcome assessment. Read projects/commitments/decisions/ for entries where outcome is null and decided_at is 7+ days ago. For each, prompt: 'You decided <X> <N> days ago. How did it turn out?' Skip silently if no decisions need review.\",\n  cadence: \"0 10 * * 3\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-tech-debt-resurface (Monday morning)\n\n```\nmission_create(\n  name: \"dev-tech-debt-resurface\",\n  goal: \"Weekly tech debt review. Read all files in projects/commitments/tech-debt/ via memory_tree and memory_read. Sort by age. Flag items older than 30 days as chronic. For items tagged with a repo, check if related issues exist. If backlog exceeds 10 items, suggest a prioritization session. For high-severity chronic items, suggest using /plan to create a structured breakdown and fix strategy. Send list via message tool. Skip silently if no tech debt.\",\n  cadence: \"0 10 * * 1\",\n  project_id: \"commitments\"\n)\n```\n\n## Step 5: Write calibration memories\n\n```\nmemory_write(\n  target: \"projects/commitments/calibration.md\",\n  content: \"# Developer Calibration\\n\\n## Decision classification\\n- mechanical (auto-act silently): expire stale signals, update CI status, dismiss noise, mark passing checks\\n- taste (auto-act, surface in digest): auto-dismiss FYI signals, auto-resolve completed items, update readiness dashboard\\n- challenge (always ask): architecture decisions, sending messages to people, merging PRs, deleting branches, any irreversible action\\n\\n## Effort principle\\n- AI makes completeness cheap — when the thorough implementation costs minutes more than the shortcut, always do the thorough thing\\n- Always show dual effort estimates when known: human time vs AI-assisted time\\n- This reframes prioritization: features that seem expensive may be cheap with AI\\n\\n## Signal urgency\\n- CI failures on user's own PRs = prompt urgency — surface within the hour\\n- Production/hotfix/critical labels = realtime — broadcast immediately\\n- PR review requests = batch urgency unless from team lead or marked urgent\\n- Security P1 findings = realtime\\n- AI agent PRs grouped separately in digest with shorter stale threshold (1 day vs 3)\\n\\n## Tech debt\\n- Captured passively from conversation AND from merged PR review comments\\n- PR review comments matching 'address in follow-up', 'not blocking but fix', 'TODO later', 'leaving for now' → auto-create tech-debt items\\n\\n## Reviews\\n- Track review readiness per branch in projects/<slug>/readiness/\\n- Before merge, check: code review + tests + security + QA. Surface gaps in digest.\\n- Security and QA reviews can be run with /security-review and /qa-review\\n- Obvious security/QA fixes are auto-applied; ambiguous ones always ask\\n\\n## Product\\n- Feature prioritization uses evidence-based scoring: demand × 3 + impact × 2 + alignment / effort\\n- Challenge assumptions — 'I think users want X' requires evidence\\n- Use /product-prioritization for structured analysis\\n\\n## General\\n- Architecture/API design decisions = high-confidence capture; debugging 'let's try X' = not a decision\\n- Most developer commitments are personal tasks, not delegations — default owner=user\\n- Projects tracked in projects/<slug>/project.md\\n- For complex tasks, suggest /plan for structured execution\\n- Weekly retro writes to context/intel/ as durable intelligence\\n- Start conservative: surface everything, earn trust through feedback\",\n  append: false\n)\n```\n\n## Step 6: Confirm\n\nTell the user:\n\n> Your developer workflow is ready:\n>\n> **Projects:** <list of repos, each with workflow status>\n>\n> **Missions:**\n> - **Triage** 3x weekdays (9am, 2pm, 6pm) — scans GitHub for review requests, CI failures, assignments, mentions, and tech debt from PR reviews\n> - **Morning brief** 8am weekdays — overnight CI, PRs needing review, your PR statuses, today's commitments\n> - **Stale PR check** 4pm weekdays — flags abandoned PRs and slow reviews\n> - **Weekly retro** Friday 10am — what shipped, decisions, tech debt, patterns\n> - **Tech debt review** Monday 10am — resurfaces accumulated debt\n> - **Decision check** Wednesday 10am — follows up on decisions older than 7 days\n>\n> Per-repo workflow: issue planning, maintainer gate, PR monitor, CI fix loop, staging review, post-merge learning\n>\n> **Quick commands:**\n> - **\"show commitments\"** — current status\n> - **\"show tech debt\"** — debt backlog\n> - **\"add repo owner/repo\"** — add another project\n> - **\"is this PR ready?\"** — review readiness dashboard\n> - **\"what should we build next?\"** — evidence-based prioritization\n> - **`/security-review`** — run security audit on current changes\n> - **`/qa-review`** — generate test plan and coverage analysis\n> - **`/plan <description>`** — structured execution plan for complex tasks\n> - **`/product-prioritization`** — score and rank features by demand\n\n## Step 7: Mark setup complete\n\nAfter confirming with the user that everything is in place, write the setup completion marker so this skill stops competing for the activation budget on every subsequent message:\n\n```\nmemory_write(\n  target: \"projects/commitments/.developer-setup-complete\",\n  content: \"# Developer Setup Complete\\n\\nCompleted: <today's UTC date>\\n\\nRepos: <list of repo slugs>\\nMaintainers: <maintainers>\\nMissions installed: wf-issue-plan, wf-maintainer-gate, wf-pr-monitor, wf-ci-fix, wf-learning, plus 6 personal productivity missions (commitment-triage, commitment-digest, dev-stale-pr-check, dev-weekly-retro, dev-tech-debt-resurface, dev-decision-outcome-check)\"\n)\n```\n\nThis is a one-time marker. The next conversational turn will not load this setup skill (the operational skills like `commitment-triage`, `tech-debt-tracker`, `github`, `github-workflow` keep activating reactively as before). To re-trigger setup (add a new repo with the wizard, re-onboard, switch maintainers), delete `projects/commitments/.developer-setup-complete` first.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Agent Rules\n\n## Purpose and precedence\n\n`AGENTS.md` is the canonical agent contract for this repository — the commands, hard invariants, and routing an agent cannot infer from the tree. It is not the full architecture specification: before changing a complex area, read the owning crate's `AGENTS.md`, then its `CONTRACT.md` or `README.md` when present; cross-crate behavior is specified under `docs/internal/reborn/contracts/`. (`CLAUDE.md` files are Claude Code adapters and pointer stubs; content lives here and in the files this one names.)\n\nAll product work belongs in the Reborn workspace under `crates/`; the shipping binary is `ironclaw` from the `ironclaw` package in `crates/app/ironclaw_cli`. `crates/AGENTS.md` is the routing map into the ten crate families. The repo skills under `.claude/skills/` (`ironclaw-reborn-orientation`, `reborn-feature`, `ironclaw-reborn-architecture-review`, `ironclaw-reborn-testing`, `ironclaw-reborn-skill-maintainer`, `reborn-extension-surfaces`) are plain Markdown — read the `SKILL.md` directly if your harness does not load Claude skills.\n\n## Build, run, debug\n\n```bash\ncargo fmt                                                       # format\ncargo clippy --all --benches --tests --examples --all-features -- -D warnings  # lint (zero warnings; CI denies warnings — an unflagged run exits 0 with them)\ncargo test                                                      # unit + integration suites (Postgres legs self-provision testcontainers; skipped without Docker)\nRUST_LOG=ironclaw=debug cargo run -p ironclaw -- serve          # run the serve binary (add tower_http=debug for HTTP logging)\n```\n\nThe workspace-root `integration` feature is empty with zero consumers — a bare root `cargo test --features integration` adds nothing. Backend-heavy gated suites are crate-level (e.g. `cargo test -p ironclaw_hooks --features integration,test-support`). E2E suite: `tests/e2e/CLAUDE.md`.\n\n**Cargo features are a last resort.** A feature is a second build of the workspace, compiled and tested forever. Add one only for a heavy optional dependency, a build shape that ships with it OFF, a CI lane selector, a dev-only seam (always named `test-support`), or a privilege boundary — and say which in the manifest comment. Deployment shape belongs in `DeploymentConfig` and `[storage]`, not `#[cfg]`. Full bar: `.claude/rules/cargo-features.md`.\n\n## Discover code before changing it\n\nFor where-is, who-calls, data-flow, and impact questions, probe the codebase knowledge graph before text search: run `bash scripts/codebase-graph.sh status` once; if fresh and graph tools are connected, use them; otherwise fall back to `crates/AGENTS.md`, crate-local guidance, and targeted `rg`. Verify graph claims against live code before acting. Use `rg` directly for configuration, prose, and fixtures. `openwiki/` is generated prose — read-only, never hand-edit.\n\n## Where work belongs\n\nExternal surfaces normalize untrusted requests through product adapters or `ProductSurface`; thread/turn services establish durable conversation state; the scheduler and run executor invoke the canonical runner/driver and agent loop; capability execution crosses authorization, approvals, obligations, host-runtime mediation, and the selected runtime lane; durable typed events feed projections and transport streams — transports do not invent state. Verify a flow from live symbols:\n\n```bash\nrg -n \"SessionThreadService|TurnCoordinator|TurnRunScheduler|RebornTurnRunExecutor|CanonicalAgentLoopExecutor|CapabilityHost\" crates\n```\n\nCrates live under a family directory (`crates/<family>/ironclaw_*`); enumerate them with `python3 scripts/ci/lib/crate_tree.py .` rather than assuming a fixed depth. Stable ownership decisions:\n\n- Neutral authority vocabulary belongs in `ironclaw_host_api`; execution does not.\n- Filesystem mounts/CAS belong in `ironclaw_filesystem`; record grammar in the domain crate.\n- Durable events, projections, and transport streams are separate contracts.\n- Authorization, approvals, resources, obligations, dispatch, and runtime lanes remain separate stages.\n- `ironclaw_assistant` owns product-facing orchestration and `ProductSurface`; composition wires dependencies; WebUI owns HTTP/transport and frontend presentation.\n- Provider-neutral model contracts and provider implementations belong in `ironclaw_llm`; wrappers delegate the complete provider trait.\n- Declarative extension metadata belongs in `ironclaw_extension_registry`; execution belongs in runtime lanes and host mediation.\n- Safety scanning is `ironclaw_safety`; skills are `ironclaw_skills`; persistent memory is `ironclaw_memory` (model tools `ironclaw.memory.*`). Always import from the owning crate.\n\nThe composition root assembles dependencies; it does not own domain policy — module-specific initialization stays behind factories or builders in the owning crate. If adding a dependency would point from a lower neutral crate into product or composition, stop and run `cargo test -p ironclaw_architecture_tests` first.\n\nSubagent spawn creates and wires child runs only; planning, execution, capability calls, checkpointing, gates, retries, and completion continue through the existing runner/driver/executor path.\n\nHost-trusted trigger ingress is sealed by trigger-worker-owned request minting and private conversation-owned trusted construction. Product adapters, product workflow, first-party capabilities, and host-runtime handlers use untrusted inbound requests and must not mint `TrustedInboundTurnRequest` or call trusted trigger submitter factories.\n\n## Module Specs\n\nWhen modifying a module with a spec, read the spec first. Code follows spec; spec is the tiebreaker.\n\n| Module | Spec |\n|--------|------|\n| `crates/domains/ironclaw_llm/` | `crates/domains/ironclaw_llm/CONTRACT.md` |\n| `crates/substrates/ironclaw_filesystem/` | `crates/substrates/ironclaw_filesystem/CONTRACT.md` |\n| `crates/product/ironclaw_webui/` | `crates/product/ironclaw_webui/CONTRACT.md` |\n| `crates/app/ironclaw_composition/` | `crates/app/ironclaw_composition/CONTRACT.md` |\n| `crates/domains/ironclaw_identity/` | `crates/domains/ironclaw_identity/CONTRACT.md` |\n| `crates/kernel/ironclaw_trust/` | `crates/kernel/ironclaw_trust/CONTRACT.md` |\n| `tests/` (scenario coverage map) | `tests/CLAUDE.md` |\n| `tests/integration/` | `tests/integration/CLAUDE.md` |\n| `tests/support/reborn_parity_qa/` | `tests/support/reborn_parity_qa/CLAUDE.md` |\n| `tests/e2e/` | `tests/e2e/CLAUDE.md` |\n\n## Coding and contract rules\n\n- No `.unwrap()` or `.expect()` in production code (tests are fine); propagate errors with context — `.map_err(|e| SomeError::Variant { reason: e.to_string() })?` — and use `thiserror` for error types in `error.rs`. Cause-preserving constructors, the `map_err(|_| …)` ban, and the other silent-failure anti-patterns: `.claude/rules/error-handling.md`.\n- Keep clippy clean with zero warnings. Prefer `crate::` imports for cross-module references.\n- Use strong types and enums for known domain shapes; raw strings belong at external boundaries. Shared types live with the contract owner — no mirror DTOs, and `ironclaw_common` is not a dumping ground.\n- No `pub use` re-exports unless exposing to downstream consumers.\n- **Prompt templates live in files, not Rust code**: multi-line prompt strings go in a `prompts/*.md` file inside the crate that owns the behavior, loaded via `include_str!()` (`ls -d crates/*/*/prompts crates/extensions/packages/*/prompts` lists the owners). Single-line format strings are fine inline.\n- Preserve existing defaults unless the task explicitly changes them.\n- All I/O is async with tokio; use `Arc<T>` for shared state.\n\n## Testing discipline\n\n1. **Test-first.** Every feature and fix starts in the tests — pin the behavior, watch it fail for the right reason, then change the implementation. Every fix ships with a regression test.\n2. **Consolidate, don't proliferate.** Extend the test that already exercises the path; add a new test only for a genuinely distinct scenario.\n3. **Integration-first.** Production-wired behavior ships with a test in `tests/integration/`, driven through the harness and asserting at a seam — never `wait_for_status(Completed)` alone. Crate tier is the fallback only when that tier cannot reach the path (say why in the PR).\n4. **Test through the caller, not just the helper.** When a helper gates a side effect, unit-testing the helper alone is not regression coverage — drive the call site at the integration tier or higher, and make mocks capture every argument the production caller passes.\n\nFull rules and tiers: `.claude/rules/testing.md`; authoring guides: `tests/integration/CLAUDE.md`, `tests/e2e/CLAUDE.md`. Select tiers with `docs/internal/testing-playbook.md`, and complete the `Test Strategy` section of `.github/pull_request_template.md` with evidence or `Not applicable: <reason>` per tier.\n\n## Persistence and configuration\n\nNew persistence uses `RootFilesystem`/`ScopedFilesystem` and the mount catalog owned by `ironclaw_filesystem` (spec above); composition chooses concrete backends (PostgreSQL, libSQL, local filesystem) by profile. Domain stores are thin typed wrappers and never branch on backend; keep dual-backend parity via shared conformance suites (`.claude/rules/database.md`). Read-modify-write uses the shared bounded CAS helper, never a process-local mutex held across backend I/O.\n\nKeep bootstrap configuration, persisted settings, and encrypted secrets as separate layers; preserve configuration precedence, secret-mediated provider resolution, and fail-closed startup. Environment variables are documented in `.env.example`; LLM backends in the llm spec (`LlmBackendKind` in `crates/domains/ironclaw_llm/src/config.rs` is the source of truth).\n\n## Security and runtime invariants\n\n- Treat every listener, route, product adapter, runtime lane, container, and external service as untrusted until a typed boundary establishes otherwise.\n- Do not weaken authentication, origin checks, body limits, rate limits, allowlists, approval leases, secret mediation, or redaction guarantees.\n- External HTTP goes through `ironclaw_network`; credentials remain host-side and are injected only through mediated runtime services.\n- New ingress must validate and bound the original payload before persistence, prompt construction, credential injection, or dispatch.\n- Authorization, approval, reservation, dispatch, and execution are distinct stages. Do not bypass or collapse them — product/WebUI handlers, triggers, channels, and agent callers go through `ProductSurface` and the capability contracts, never around them to mutate stores directly.\n- Session, thread, turn, and run identities are typed and must not be re-derived from display strings or transport metadata.\n- **LLM data is never deleted.** Context, reasoning, tool calls, messages, events, steps — mark with timestamps and make filterable, but always retain. In-memory maps are caches; the database is the source of truth. \"Cleanup\" means evicting caches, never deleting rows.\n- Never commit secrets or PII.\n\n## Capabilities, extensions, and lifecycle\n\n- Core host behavior uses typed built-in capabilities behind the same mediated host surface as other execution.\n- Sandboxed extension execution belongs in WASM or a runtime lane; external server integrations belong behind MCP and the network boundary.\n- Discovery is side-effect-free. Installation, credential binding, activation, execution, deactivation, and removal are explicit lifecycle transitions.\n- Capability failures the model or user can correct are model-visible outcomes; host errors are reserved for failures that end the run.\n- Side-effecting success requires durable or provider-issued evidence plus read-back verification; if read-back is impossible, report explicitly unverified rather than completed.\n\n### Extension/Auth Invariants\n\nThe top-level product object is always an **extension**; a channel is one capability surface an extension's manifest declares (`tool` / `channel` / `auth` — `ironclaw_extension_contracts::surface::CapabilitySurfaceKind`), and runtime (`wasm` / `mcp` / `first_party`) is implementation, never taxonomy. `ExtensionId` is the product identity (`slack`, `github`, `gmail`); `VendorId` (manifest field `vendor`) is the credential-authority namespace and may back several extensions (`google` backs gmail + drive + calendar). There is no separate channel registry and no extension `kind` wire string — `crates/app/ironclaw_architecture_tests/tests/reborn_retired_taxonomy.rs` pins the retired vocabulary at zero.\n\nTwo identities must never be conflated (newtypes in `crates/contracts/ironclaw_common/src/identity.rs`; identity model `crates/domains/ironclaw_identity/CONTRACT.md`; OAuth transport `crates/domains/ironclaw_auth`):\n\n- `credential_name` — backend secret identity (storage, injection, gate resume), e.g. `telegram_bot_token`, `google_oauth_token`.\n- `extension_name` — user-facing installed extension/channel identity (setup routing, UI), e.g. `telegram`, `gmail`.\n\nNever route setup/configure UI from `credential_name`; chat and Settings use the same setup path; generic auth-card UI is only for non-extension credential prompts or pure OAuth launches; resolve `extension_name` once in shared backend logic and carry it through the wire contract instead of re-deriving it per layer or adding frontend-only fallbacks.\n\nAdding a channel means adding one capability surface of an extension — a `[channel]` section in the `reborn.extension_manifest.v3` manifest plus a `ChannelAdapter` (`crates/contracts/ironclaw_extension_contracts/src/channel_adapter.rs`), wired through `RebornHostBindings::with_channel_extension_bindings` (`crates/app/ironclaw_composition/src/input.rs`) — never per-channel host code. Start from the `reborn-extension-surfaces` skill; the worked example is `crates/extensions/packages/slack/`; family rules in `crates/extensions/AGENTS.md`.\n\n## Project structure\n\n```\ncrates/                     # all production code, by family (crates/AGENTS.md is the map)\n├── app/                    # ironclaw_cli (binary `ironclaw`), ironclaw_composition, ironclaw_config, ironclaw_architecture_tests\n├── contracts/              # ironclaw_host_api, ironclaw_common, ironclaw_extension_contracts, ironclaw_product_contracts, …\n├── domains/                # ironclaw_llm, ironclaw_skills, ironclaw_threads, ironclaw_auth, ironclaw_memory, …\n├── events/                 # ironclaw_event_log / _projections / _store / _streams\n├── extensions/             # ironclaw_extension_host/_manager/_registry/_support + packages/ (slack, telegram, …)\n├── kernel/                 # ironclaw_turns, ironclaw_capabilities, ironclaw_approvals, ironclaw_host_runtime, …\n├── lanes/                  # ironclaw_wasm, ironclaw_sandbox, ironclaw_mcp\n├── loop/                   # ironclaw_agent_loop, ironclaw_turn_runner, ironclaw_loop_host, ironclaw_hooks\n├── product/                # ironclaw_webui (SPA in frontend/), ironclaw_assistant, …\n└── substrates/             # ironclaw_filesystem, ironclaw_safety, ironclaw_network, ironclaw_secrets, …\n\ntests/                      # root-package integration suite, parity/QA, support, e2e\n```\n\nThe workspace root (`Cargo.toml`, package `ironclaw_integration_tests`) hosts only the integration test suite; the one workspace `exclude` is `tools/ironclaw_silk_decoder`.\n\n`docs/` is the public Mintlify site plus fenced internal material. All new\ninternal engineering docs (design notes, research, plans, QA maps) go under\n`docs/internal/` — nowhere else under `docs/`. A page outside the\n`docs/.mintignore` fence is published even when omitted from `docs.json`\nnavigation (hidden pages stay reachable by URL), and `.mintignore` is frozen:\ndo not add entries. Enforced by `scripts/ci/docs_publication_boundary.py`\n(Code Style workflow); run it to check placement.\n\n## Change discipline, and before finishing\n\n- Keep changes scoped; preserve unrelated work in dirty worktrees; avoid generated-file churn. Security, persistence-schema, runtime, worker, CI, and secrets changes need explicit rollback/compatibility review.\n- Run the narrowest meaningful checks, plus `cargo test -p ironclaw_architecture_tests` when dependency edges, layer keys, crate placement, or test-pinned guidance files change.\n- Search changed production files for `.unwrap()`/`.expect()`, suspicious byte slicing, hardcoded temporary paths, and lost error causes.\n- When a trait changes, enumerate all implementations, decorators, adapters, and test doubles; when a pattern bug is fixed, search `crates/` for sibling instances.\n- After moves/renames, search agent guidance, contracts, docs, tests, scripts, manifests, and frontend imports for old paths.\n- Update the owning contract/docs when behavior changes; the PR title/body must describe every layer in the diff and note compatibility, rollback, and follow-up risks.\n","category":"root","tokens":4225},{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# IronClaw — Claude Code adapter\n\n@AGENTS.md\n\nEverything above (from `AGENTS.md`) is the canonical, tool-neutral contract.\nThe rest of this file is Claude-specific.\n\n## Skills and rules\n\n- Project skills live in `.claude/skills/` — start from\n  `ironclaw-reborn-orientation`; use `reborn-feature` for cross-layer product\n  work, `reborn-extension-surfaces` for integrations,\n  `ironclaw-reborn-testing` for test tiers,\n  `ironclaw-reborn-architecture-review` for boundary changes, and\n  `ironclaw-reborn-skill-maintainer` before editing any guidance file.\n- Path-scoped rules in `.claude/rules/*.md` load automatically when you read\n  matching files — they are canonical for their topics (testing, database,\n  types, cargo-features, review discipline, …); do not restate them here.\n\n## Codebase knowledge graph (MCP)\n\nThe `codebase-memory` MCP server indexes `crates/` into a knowledge graph;\nprefer it over `Grep` for *code structure* (cross-crate call chains are\ninvisible to text search). `.codebase-memory/graph.db.zst` is the committed\nbootstrap snapshot; local databases and\n`.codebase-memory/artifact.json` <!-- check-guidance: path-ok --> stay\ngit-ignored (per-environment state, deliberately untracked). Check\nfreshness first: `bash scripts/codebase-graph.sh status`.\n\n- Missing → `index_repository(repo_path=\".\", persistence=true)` once.\n- Stale → `detect_changes(since=\"<indexed-commit>\")`, or re-run\n  `index_repository` to refresh the shared snapshot.\n- Where is a symbol → `search_graph(name_pattern=…)`, then\n  `get_code_snippet(qualified_name=…)`.\n- Who calls X / what X calls → `trace_path(function_name=…, mode=\"calls\")`;\n  value flow → `mode=\"data_flow\"`; cross-crate feature path →\n  `mode=\"cross_service\"`.\n- Structure of an area → `get_architecture(…)`; graph-augmented text search →\n  `search_code(pattern=…)`; arbitrary queries → `query_graph(<Cypher>)`.\n\nThe graph is a point-in-time index — verify anything it asserts against live\ncode before acting. `Grep`/`Glob`/`Read` remain correct for text, config, and\nnon-code files. For narrative *what/why* orientation, read the relevant\n`openwiki/` page (generated — never hand-edit).\n\n## REPL/TUI logging rule\n\n`info!` and `warn!` output appears in the REPL and corrupts the terminal UI.\nUse `debug!` for internal diagnostics (trace analysis, reflection results,\nengine internals); reserve `info!` for user-facing status the REPL\nintentionally renders. Background tasks must NEVER use `info!`.\n","category":"root","tokens":617},{"name":"SKILL.md","path":".claude/skills/architecture-video/SKILL.md","title":"architecture-video Skill","content":"---\nname: architecture-video\ndescription: Generate or update the IronClaw architecture overview video using Remotion. Use when asked to update, regenerate, or modify the architecture video, add/remove scenes, or reflect codebase changes in the video.\n---\n\n# Architecture Video Generator\n\nGenerates and maintains the animated architecture overview video in `docs/internal/architecture-video/` using Remotion (React-based video framework).\n\n## When to use\n\n- User asks to update, regenerate, or modify the architecture video\n- User asks to add or remove scenes from the video\n- Codebase architecture has changed and the video needs to reflect it\n- User wants to preview or render the video\n\n## Before making changes\n\n### 1. Read current architecture\n\nRead these files to understand the current system architecture:\n\n- `AGENTS.md` — top-level commands, invariants, tree map, module specs table\n- `crates/Architecture.md` — **the Reborn stack thesis and component map (the current architecture; lead the video with this)**\n- `crates/AGENTS.md` — the Reborn crate routing map\n- `crates/domains/ironclaw_llm/CONTRACT.md` — canonical LLM provider architecture\n- `crates/substrates/ironclaw_filesystem/CONTRACT.md` — storage fabric / dual-backend architecture\n- `crates/extensions/AGENTS.md` — the installable-package family: extension packages, tool surfaces, lifecycle host (successor of the v1 tool system)\n- `crates/domains/ironclaw_memory/README.md` — the memory contract and conformance seam (successor of the v1 workspace/memory system)\n\n### 2. Read current video scenes\n\nRead `docs/internal/architecture-video/src/IronClawArchitecture.tsx` to understand current scene order, durations, and transitions. Then read individual scenes in `docs/internal/architecture-video/src/scenes/` to see what's already covered.\n\n### 3. Identify gaps\n\nCompare the architecture documentation with what the video covers. Look for:\n- New modules or traits added since the video was last updated\n- Renamed or restructured components\n- New data flows or state machines\n- Removed or deprecated features\n\n## Video project structure\n\n```\ndocs/internal/architecture-video/\n├── package.json              # Remotion deps\n├── remotion.config.ts        # Build config\n├── src/\n│   ├── Root.tsx              # Remotion entry — registers the composition\n│   ├── IronClawArchitecture.tsx  # Main composition — scene order + transitions\n│   ├── theme.ts              # Color palette + font constants\n│   ├── components/\n│   │   └── Code.tsx          # Syntax-highlighted code block component\n│   └── scenes/               # One file per scene\n│       ├── TitleScene.tsx\n│       ├── PrimitivesScene.tsx\n│       ├── ExecutionLoopScene.tsx\n│       ├── CodeActScene.tsx\n│       ├── ThreadStateScene.tsx\n│       ├── SkillsPipelineScene.tsx\n│       ├── ToolDispatchScene.tsx\n│       ├── ChannelsRoutingScene.tsx\n│       ├── ChannelImplsScene.tsx\n│       ├── TraitsScene.tsx\n│       ├── LlmDecoratorScene.tsx\n│       └── OutroScene.tsx\n```\n\nRender script: `scripts/render-architecture-video.sh`\n\n## Current scene inventory (12 scenes, ~82s at 30fps)\n\n| # | Scene | File | Duration | Content |\n|---|-------|------|----------|---------|\n| 1 | Title | TitleScene.tsx | 4s | Animated IronClaw logo + tagline |\n| 2 | Five Primitives | PrimitivesScene.tsx | 8s | Thread / Step / Capability / MemoryDoc / Project |\n| 3 | Execution Loop | ExecutionLoopScene.tsx | 8s | 7-step ExecutionLoop::run() pipeline |\n| 4 | CodeAct | CodeActScene.tsx | 10s | Python code → host fns → suspend/resume flow |\n| 5 | Thread State | ThreadStateScene.tsx | 7s | Created→Running⇄Waiting/Suspended→Completed/Failed→Done |\n| 6 | Skills Pipeline | SkillsPipelineScene.tsx | 8s | Gating → Scoring → Budget → Attenuation |\n| 7 | Tool Dispatch | ToolDispatchScene.tsx | 9s | 9-step ToolDispatcher::dispatch() pipeline |\n| 8 | Channels Routing | ChannelsRoutingScene.tsx | 7s | Channel trait + stream::select_all merging |\n| 9 | Channel Impls | ChannelImplsScene.tsx | 7s | REPL / HTTP / Web / Signal / TUI / WASM |\n| 10 | Traits | TraitsScene.tsx | 8s | 8 traits with concrete implementers |\n| 11 | LLM Decorators | LlmDecoratorScene.tsx | 7s | SmartRouting→CircuitBreaker→...→Base decorator chain |\n| 12 | Outro | OutroScene.tsx | 5s | Start Contributing + getting-started steps |\n\n## Remotion patterns used in this project\n\nAll animations MUST be driven by `useCurrentFrame()` — never CSS transitions or Tailwind animation classes.\n\n### Animation pattern\n\n```tsx\nconst frame = useCurrentFrame();\nconst { fps } = useVideoConfig();\n\nconst opacity = interpolate(frame, [0, 0.5 * fps], [0, 1], {\n  extrapolateRight: \"clamp\",\n});\nconst y = interpolate(frame, [0, 0.5 * fps], [30, 0], {\n  extrapolateRight: \"clamp\",\n  easing: Easing.bezier(0.16, 1, 0.3, 1),\n});\n```\n\n### Staggered list pattern\n\nFor items that appear one by one:\n\n```tsx\n{items.map((item, i) => {\n  const delay = 0.4 + i * 0.3; // seconds\n  const opacity = interpolate(\n    frame,\n    [delay * fps, (delay + 0.35) * fps],\n    [0, 1],\n    { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" }\n  );\n  return <div style={{ opacity }} key={item.id}>...</div>;\n})}\n```\n\n### Scene transitions\n\nScenes are composed using `TransitionSeries` with alternating `fade()` and `slide({ direction: \"from-right\" })` transitions, each 15 frames (0.5s):\n\n```tsx\n<TransitionSeries>\n  <TransitionSeries.Sequence durationInFrames={s(8)}>\n    <MyScene />\n  </TransitionSeries.Sequence>\n  <TransitionSeries.Transition\n    presentation={fade()}\n    timing={linearTiming({ durationInFrames: 15 })}\n  />\n  <TransitionSeries.Sequence durationInFrames={s(7)}>\n    <NextScene />\n  </TransitionSeries.Sequence>\n</TransitionSeries>\n```\n\n### Code blocks\n\nUse the `CodeBlock` component from `../components/Code` for syntax-highlighted code:\n\n```tsx\nimport { CodeBlock } from \"../components/Code\";\n\n<CodeBlock code={`pub trait Channel: Send + Sync {\n  async fn start(&self) -> Result<MessageStream>;\n}`} fontSize={13} />\n```\n\n### Theme\n\nImport colors and fonts from `../theme`:\n\n```tsx\nimport { COLORS, FONTS } from \"../theme\";\n\n// Available colors:\n// bg, bgLight, primary, primaryLight, accent, accentLight,\n// success, danger, text, textMuted, border, purple, cyan, pink\n\n// Available fonts:\n// mono (monospace), sans (system-ui)\n```\n\n## Adding a new scene\n\n1. Create `src/scenes/MyNewScene.tsx` following existing patterns\n2. Export the component\n3. Import in `IronClawArchitecture.tsx`\n4. Add to the `SCENES` array with duration and transition type\n5. `TOTAL_DURATION` auto-computes from the array\n6. Verify with: `npx remotion still IronClawArchitecture --scale=0.25 --frame=<N>`\n\n### Scene template\n\n```tsx\nimport {\n  AbsoluteFill,\n  interpolate,\n  useCurrentFrame,\n  useVideoConfig,\n  Easing,\n} from \"remotion\";\nimport { COLORS, FONTS } from \"../theme\";\n\nexport const MyNewScene: React.FC = () => {\n  const frame = useCurrentFrame();\n  const { fps } = useVideoConfig();\n\n  const headingOpacity = interpolate(frame, [0, 0.4 * fps], [0, 1], {\n    extrapolateRight: \"clamp\",\n  });\n\n  return (\n    <AbsoluteFill\n      style={{\n        backgroundColor: COLORS.bg,\n        fontFamily: FONTS.sans,\n        padding: 60,\n      }}\n    >\n      <div\n        style={{\n          opacity: headingOpacity,\n          fontSize: 42,\n          fontWeight: 700,\n          color: COLORS.text,\n          marginBottom: 4,\n        }}\n      >\n        <span style={{ color: COLORS.primary }}>Title</span> — subtitle\n      </div>\n      {/* Scene content */}\n    </AbsoluteFill>\n  );\n};\n```\n\n## Verification\n\nAfter making changes:\n\n1. **Type check:** `cd docs/internal/architecture-video && npx tsc --noEmit`\n2. **Spot check frames:** `npx remotion still IronClawArchitecture --scale=0.25 --frame=<N>`\n   - At 30fps, frame N corresponds to time N/30 seconds\n   - Check at least one frame per modified scene\n3. **Full render:** `./scripts/render-architecture-video.sh [output-path]`\n4. **Preview in browser:** `cd docs/internal/architecture-video && npm run dev`\n\n## Design guidelines\n\n- Dark theme (slate-900 background) — matches typical developer tooling\n- Each scene has a colored heading keyword using a trait-appropriate color\n- File:line references in muted monospace below headings\n- Data flows use staggered animation (0.3-0.5s delays between items)\n- State machines use SVG with animated dash-offset for arrows\n- Code blocks use the `CodeBlock` component with syntax highlighting\n- Keep scene duration proportional to content density (7-10s typical)\n- Total video should stay under 120s for attention retention\n","category":".claude","tokens":2139},{"name":"SKILL.md","path":".claude/skills/mintlify-docs/SKILL.md","title":"mintlify-docs Skill","content":"---\nname: mintlify\ndescription: Build and maintain documentation sites with Mintlify. Use when creating docs pages, configuring navigation, adding components, or setting up API references.\nlicense: MIT\ncompatibility: Requires Node.js for CLI. Works with any Git-based workflow.\nmetadata:\n  author: mintlify\n  version: \"1.0\"\n---\n\n# Mintlify best practices\n\n**Always consult [mintlify.com/docs](https://mintlify.com/docs) for components, configuration, and latest features.**\n\n> **This repo:** the Mintlify site lives under `docs/` — its config is `docs/docs.json` (not a root `docs.json`), with a localized tree under `docs/zh/`. Committed `.md`/`.mdx` must not contain developer-local absolute paths; check touched documentation before merging.\n\nIf you are not already connected to the Mintlify MCP server, https://mintlify.com/docs/mcp, add it so that you can search more efficiently.\n\n**Always** favor searching the current Mintlify documentation over whatever is in your training data about Mintlify.\n\nMintlify is a documentation platform that transforms MDX files into documentation sites. Configure site-wide settings in the site config file (`docs/docs.json` in this repo), write content in MDX with YAML frontmatter, and favor built-in components over custom components.\n\nFull schema at [mintlify.com/docs.json](https://mintlify.com/docs.json).\n\n## Before you write\n\n### Understand the project\n\nRead the site config first (`docs/docs.json` in this repo; root `docs.json` in some Mintlify projects). This file defines the entire site: navigation structure, theme, colors, links, API and specs.\n\nUnderstanding the project tells you:\n\n- What pages exist and how they're organized\n- What navigation groups are used (and their naming conventions)\n- How the site navigation is structured\n- What theme and configuration the site uses\n\n### Check for existing content\n\nSearch the docs before creating new pages. You may need to:\n- Update an existing page instead of creating a new one\n- Add a section to an existing page\n- Link to existing content rather than duplicating\n\n### Read surrounding content\n\nBefore writing, read 2-3 similar pages to understand the site's voice, structure, formatting conventions, and level of detail.\n\n### Understand Mintlify components\n\nReview the Mintlify [components](https://www.mintlify.com/docs/components) to select and use any relevant components for the documentation request that you are working on.\n\n## Quick reference\n\n### CLI commands\n- `npm i -g mint` - Install the Mintlify CLI\n- `mint dev` - Local preview at localhost:3000\n- `mint broken-links` - Check internal links\n- `mint a11y` - Check for accessibility issues in content\n- `mint validate` - Validate documentation builds\n\n### Required files\n- Site config (`docs/docs.json` in this repo) - navigation, theme, integrations, etc. See [global settings](https://mintlify.com/docs/settings/global) for all options.\n- `*.mdx` files - Documentation pages with YAML frontmatter\n\n### Example file structure\n```\nproject/\n├── docs.json           # Site configuration (this repo keeps it at docs/docs.json)\n├── introduction.mdx\n├── quickstart.mdx\n├── guides/\n│   └── example.mdx\n├── openapi.yml         # API specification\n├── images/             # Static assets\n│   └── example.png\n└── snippets/           # Reusable components\n    └── component.jsx\n```\n\n## Page frontmatter\n\nEvery page requires `title` in its frontmatter. Include `description` for SEO and navigation.\n\n```yaml\n---\ntitle: \"Clear, descriptive title\"\ndescription: \"Concise summary for SEO and navigation.\"\n---\n```\n\nOptional frontmatter fields:\n- `sidebarTitle`: Short title for sidebar navigation.\n- `icon`: Lucide or Font Awesome icon name, URL, or file path.\n- `tag`: Label next to the page title in the sidebar (for example, \"NEW\").\n- `mode`: Page layout mode (`default`, `wide`, `custom`).\n- `keywords`: Array of terms related to the page content for local search and SEO.\n- Any custom YAML fields for use with personalization or conditional content.\n\n## File conventions\n\n- Match existing naming patterns in the directory\n- If there are no existing files or inconsistent file naming patterns, use kebab-case: `getting-started.mdx`, `api-reference.mdx`\n- Use root-relative paths without file extensions for internal links: `/getting-started/quickstart`\n- Do not use relative paths (`../`) or absolute URLs for internal pages\n- When you create a new page, add it to site config navigation (`docs/docs.json` here) or it won't appear in the sidebar\n\n## Organize content\n\nWhen a user asks about anything related to site-wide configurations, start by understanding the [global settings](https://www.mintlify.com/docs/organize/settings). See if a setting in the site config (`docs/docs.json` here) can be updated to achieve what the user wants.\n\n### Navigation\n\nThe `navigation` property in the site config (`docs/docs.json` here) controls site structure. Choose one primary pattern at the root level, then nest others within it.\n\n**Choose your primary pattern:**\n\n| Pattern | When to use |\n|---------|-------------|\n| **Groups** | Default. Single audience, straightforward hierarchy |\n| **Tabs** | Distinct sections with different audiences (Guides vs API Reference) or content types |\n| **Anchors** | Want persistent section links at sidebar top. Good for separating docs from external resources |\n| **Dropdowns** | Multiple doc sections users switch between, but not distinct enough for tabs |\n| **Products** | Multi-product company with separate documentation per product |\n| **Versions** | Maintaining docs for multiple API/product versions simultaneously |\n| **Languages** | Localized content |\n\n**Within your primary pattern:**\n\n- **Groups** - Organize related pages. Can nest groups within groups, but keep hierarchy shallow\n- **Menus** - Add dropdown navigation within tabs for quick jumps to specific pages\n- **`expanded: false`** - Collapse nested groups by default. Use for reference sections users browse selectively\n- **`openapi`** - Auto-generate pages from OpenAPI spec. Add at group/tab level to inherit\n\n**Common combinations:**\n- Tabs containing groups (most common for docs with API reference)\n- Products containing tabs (multi-product SaaS)\n- Versions containing tabs (versioned API docs)\n- Anchors containing groups (simple docs with external resource links)\n\n### Links and paths\n\n- **Internal links:** Root-relative, no extension: `/getting-started/quickstart`\n- **Images:** Store in `/images`, reference as `/images/example.png`\n- **External links:** Use full URLs, they open in new tabs automatically\n\n## Customize docs sites\n\n**What to customize where:**\n- **Brand colors, fonts, logo** → site config (`docs/docs.json` here). See [global settings](https://mintlify.com/docs/settings/global)\n- **Component styling, layout tweaks** → `custom.css` at project root\n- **Dark mode** → Enabled by default. Only disable with `\"appearance\": \"light\"` in the site config if brand requires it\n\nStart with the site config (`docs/docs.json` here). Only add `custom.css` when you need styling that config doesn't support.\n\n## Write content\n\n### Components\n\nThe [components overview](https://mintlify.com/docs/components) organizes all components by purpose: structure content, draw attention, show/hide content, document APIs, link to pages, and add visual context. Start there to find the right component.\n\n**Common decision points:**\n\n| Need | Use |\n|------|-----|\n| Hide optional details | `<Accordion>` |\n| Long code examples | `<Expandable>` |\n| User chooses one option | `<Tabs>` |\n| Linked navigation cards | `<Card>` in `<Columns>` |\n| Sequential instructions | `<Steps>` |\n| Code in multiple languages | `<CodeGroup>` |\n| API parameters | `<ParamField>` |\n| API response fields | `<ResponseField>` |\n\n**Callouts by severity:**\n- `<Note>` - Supplementary info, safe to skip\n- `<Info>` - Helpful context such as permissions\n- `<Tip>` - Recommendations or best practices\n- `<Warning>` - Potentially destructive actions\n- `<Check>` - Success confirmation\n\n### Reusable content\n\n**When to use snippets:**\n- Exact content appears on more than one page\n- Complex components you want to maintain in one place\n- Shared content across teams/repos\n\n**When NOT to use snippets:**\n- Slight variations needed per page (leads to complex props)\n\nImport snippets with `import { Component } from \"/path/to/snippet-name.jsx\"`.\n\n## Writing standards\n\n### Voice and structure\n\n- Second-person voice (\"you\")\n- Active voice, direct language\n- Sentence case for headings (\"Getting started\", not \"Getting Started\")\n- Sentence case for code block titles (\"Expandable example\", not \"Expandable Example\")\n- Lead with context: explain what something is before how to use it\n- Prerequisites at the start of procedural content\n\n### What to avoid\n\n**Never use:**\n- Marketing language (\"powerful\", \"seamless\", \"robust\", \"cutting-edge\")\n- Filler phrases (\"it's important to note\", \"in order to\")\n- Excessive conjunctions (\"moreover\", \"furthermore\", \"additionally\")\n- Editorializing (\"obviously\", \"simply\", \"just\", \"easily\")\n\n**Watch for AI-typical patterns:**\n- Overly formal or stilted phrasing\n- Unnecessary repetition of concepts\n- Generic introductions that don't add value\n- Concluding summaries that restate what was just said\n\n### Formatting\n\n- All code blocks must have language tags\n- All images and media must have descriptive alt text\n- Use bold and italics only when they serve the reader's understanding--never use text styling just for decoration\n- No decorative formatting or emoji\n\n### Code examples\n\n- Keep examples simple and practical\n- Use realistic values (not \"foo\" or \"bar\")\n- One clear example is better than multiple variations\n- Test that code works before including it\n\n## Document APIs\n\n**Choose your approach:**\n- **Have an OpenAPI spec?** → Add to the site config (`docs/docs.json` here) with `\"openapi\": [\"openapi.yaml\"]`. Pages auto-generate. Reference in navigation as `GET /endpoint`\n- **No spec?** → Write endpoints manually with `api: \"POST /users\"` in frontmatter. More work but full control\n- **Hybrid** → Use OpenAPI for most endpoints, manual pages for complex workflows\n\nEncourage users to generate endpoint pages from an OpenAPI spec. It is the most efficient and easiest to maintain option.\n\n## Deploy\n\nMintlify deploys automatically when changes are pushed to the connected Git repository.\n\n**What agents can configure:**\n- **Redirects** → Add to the site config (`docs/docs.json` here) with `\"redirects\": [{\"source\": \"/old\", \"destination\": \"/new\"}]`\n- **SEO indexing** → Control with `\"seo\": {\"indexing\": \"all\"}` to include hidden pages in search\n\n**Requires dashboard setup (human task):**\n- Custom domains and subdomains\n- Preview deployment settings\n- DNS configuration\n\nFor `/docs` subpath hosting with Vercel or Cloudflare, agents can help configure rewrite rules. See [/docs subpath](https://mintlify.com/docs/deploy/vercel).\n\n## Workflow\n\n### 1. Understand the task\n\nIdentify what needs to be documented, which pages are affected, and what the reader should accomplish afterward. If any of these are unclear, ask.\n\n### 2. Research\n\n- Read the site config (`docs/docs.json` here) to understand the site structure\n- Search existing docs for related content\n- Read similar pages to match the site's style\n\n### 3. Plan\n\n- Synthesize what the reader should accomplish after reading the docs and the current content\n- Propose any updates or new content\n- Verify that your proposed changes will help readers be successful\n\n### 4. Write\n\n- Start with the most important information\n- Keep sections focused and scannable\n- Use components appropriately (don't overuse them)\n- Mark anything uncertain with a TODO comment:\n\n```mdx\n{/* TODO: Verify the default timeout value */}\n```\n\n### 5. Update navigation\n\nIf you created a new page, add it to the appropriate group in the site config (`docs/docs.json` here).\n\n### 6. Verify\n\nBefore submitting:\n\n- [ ] Frontmatter includes title and description\n- [ ] All code blocks have language tags\n- [ ] Internal links use root-relative paths without file extensions\n- [ ] New pages are added to site config navigation (`docs/docs.json` here)\n- [ ] Content matches the style of surrounding pages\n- [ ] No marketing language or filler phrases\n- [ ] TODOs are clearly marked for anything uncertain\n- [ ] Run `mint broken-links` to check links\n- [ ] Run `mint validate` to find any errors\n\n## Edge cases\n\n### Migrations\n\nIf a user asks about migrating to Mintlify, ask if they are using ReadMe or Docusaurus. If they are, use the [@mintlify/scraping](https://www.npmjs.com/package/@mintlify/scraping) CLI to migrate content. If they are using a different platform to host their documentation, help them manually convert their content to MDX pages using Mintlify components.\n\n### Hidden pages\n\nAny page that is not included in site config navigation (`docs/docs.json` here) is hidden. Use hidden pages for content that should be accessible by URL or indexed for the assistant or search, but not discoverable through the sidebar navigation.\n\n### Exclude pages\n\nThe `.mintignore` file is used to exclude files from a documentation repository from being processed.\n\n## Common gotchas\n\n1. **Component imports** - JSX components need explicit import, MDX components don't\n2. **Frontmatter required** - Every MDX file needs `title` at minimum\n3. **Code block language** - Always specify language identifier\n4. **Never use `mint.json`** - `mint.json` is deprecated. Use the Mintlify site config (`docs/docs.json` here; often root `docs.json` in other projects)\n\n## Resources\n\n- [Documentation](https://mintlify.com/docs)\n- [Configuration schema](https://mintlify.com/docs.json)\n- [Feature requests](https://github.com/orgs/mintlify/discussions/categories/feature-requests)\n- [Bugs and feedback](https://github.com/orgs/mintlify/discussions/categories/bugs-feedback)\n","category":".claude","tokens":3468},{"name":"SKILL.md","path":"skills/github/SKILL.md","title":"github Skill","content":"---\nname: github\nversion: \"1.0.0\"\ndescription: GitHub API integration via HTTP tool with automatic credential injection\nactivation:\n  keywords:\n    - \"github\"\n    - \"pull request\"\n    - \"github issue\"\n    - \"github repo\"\n    - \"pr comment\"\n    - \"open a pr\"\n    - \"create a pr\"\n    - \"my prs\"\n  exclude_keywords:\n    - \"gitlab\"\n    - \"bitbucket\"\n  patterns:\n    - \"(?i)(list|show|get|fetch|open|close|create|file|merge|comment on)\\\\s.*(pull request|\\\\bPR\\\\b)\"\n    - \"(?i)github\\\\.com\"\n    - \"(?i)[a-z0-9._-]+/[a-z0-9._-]+#\\\\d+\"\n  tags:\n    - \"git\"\n    - \"code-review\"\n    - \"devops\"\n  max_context_tokens: 2000\ncredentials:\n  - name: github_token\n    provider: github\n    location:\n      type: bearer\n    hosts:\n      - \"api.github.com\"\n    oauth:\n      authorization_url: \"https://github.com/login/oauth/authorize\"\n      token_url: \"https://github.com/login/oauth/access_token\"\n      scopes:\n        - \"repo\"\n        - \"read:org\"\n      refresh:\n        strategy: reauthorize_only\n    setup_instructions: \"Create a personal access token at https://github.com/settings/tokens\"\n---\n\n# GitHub API Skill\n\nYou have access to the GitHub REST API via the `http` tool. Credentials are automatically injected — **never construct Authorization headers manually**. When the URL host is `api.github.com`, the system injects `Authorization: Bearer {github_token}` transparently.\n\n## API Patterns\n\nAll endpoints use `https://api.github.com` as the base URL. Common headers are injected automatically.\n\n### Issues\n\n**List issues:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/issues?state=open&sort=created&direction=desc&per_page=30\")\n```\n\n**Get single issue:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/issues/{number}\")\n```\n\n**Create issue:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/issues\", body={\"title\": \"...\", \"body\": \"...\", \"labels\": [\"bug\"]})\n```\n\n**Add comment:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/issues/{number}/comments\", body={\"body\": \"...\"})\n```\n\n### Pull Requests\n\n**List PRs:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls?state=open&sort=created&direction=desc&per_page=30\")\n```\n\n**Create PR:**\n```\nhttp(method=\"POST\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls\", body={\"title\": \"...\", \"body\": \"...\", \"head\": \"feature-branch\", \"base\": \"main\", \"draft\": true})\n```\n\n**Get PR diff:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls/{number}\", headers=[{\"name\": \"Accept\", \"value\": \"application/vnd.github.v3.diff\"}])\n```\n\n### Repository\n\n**Get repo info:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}\")\n```\n\n**List branches:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/branches\")\n```\n\n**List recent commits:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/commits?per_page=10\")\n```\n\n### Authenticated User & Cross-Repo Queries\n\nWhen the user says \"my PRs\", \"my issues\", or \"my repos\", they mean the user who owns `github_token`. Don't try to list a single repo, hit the search/user endpoints instead.\n\n**Get the authenticated user (resolves who `@me` is):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/user\")\n```\n\n**My latest PRs across all repos:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:pr+author:%40me+sort:updated-desc&per_page=20\")\n```\n\n**My open issues across all repos (assigned to me):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:issue+is:open+assignee:%40me&per_page=20\")\n```\n\n**PRs that need my review:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=is:pr+is:open+review-requested:%40me\")\n```\n\n**My repos (list all repos accessible to the token):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/user/repos?sort=updated&per_page=30\")\n```\n\n### Search\n\nGitHub has three search endpoints. Build queries with the [search syntax](https://docs.github.com/en/search-github/searching-on-github).\n\n**Search issues and PRs (one endpoint, filter with `is:pr` or `is:issue`):**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/issues?q=repo:{owner}/{repo}+is:pr+is:open+label:bug\")\n```\n\n- Note: There is no `/search/pulls` endpoint; `/search/issues` is the unified endpoint for both issues and PRs.\n\n**Search code:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/code?q=fn+main+language:rust+repo:{owner}/{repo}\")\n```\n\n**Search repositories:**\n```\nhttp(method=\"GET\", url=\"https://api.github.com/search/repositories?q=tetris+language:rust&sort=stars\")\n```\n\nURL-encode `@` as `%40` and spaces as `+` in `q=` values.\n\n## Response Handling\n\nThe `http` tool returns an envelope:\n\n```python\n{\"status\": 200, \"headers\": {...}, \"body\": <parsed value>}\n```\n\n- **JSON endpoints** — `body` is already a parsed Python dict or list. Do **not** call `json.loads()` on it. Example:\n  ```python\n  r = await http(method=\"GET\", url=\"https://api.github.com/repos/{owner}/{repo}/pulls/123\")\n  if r[\"status\"] != 200:\n      FINAL(f\"GitHub returned HTTP {r['status']}: {r['body']}\")\n  pr = r[\"body\"]          # dict, not a string\n  title  = pr[\"title\"]    # use direct indexing; these keys always exist on a 2xx\n  state  = pr[\"state\"]\n  head   = pr[\"head\"][\"ref\"]\n  base   = pr[\"base\"][\"ref\"]\n  ```\n- **Diff / plain text endpoints** (`Accept: application/vnd.github.v3.diff` etc.) — `body` is a `str` containing the raw unified diff; use it as-is.\n- **Never** write `body = pr_meta.get(\"body\", pr_meta)` as a \"safety net\" — it hides real errors. If `status` isn't 2xx, fail fast.\n- For list endpoints, check the `Link` header for pagination.\n- Rate limit: 5000 req/hour authenticated. Check `X-RateLimit-Remaining` if doing bulk ops.\n- Error responses are JSON of the form `{\"message\": \"...\"}` with a non-2xx `status` — surface them literally in your FINAL answer.\n\n## Common Mistakes\n\n- Do NOT add an `Authorization` header — it is injected automatically by the credential system.\n- Always use HTTPS URLs (HTTP is blocked by the security layer).\n- For creating PRs, always set `draft: true` unless the user explicitly says \"ready for review\".\n- The `state` parameter for issues/PRs is `open`, `closed`, or `all` — not `active`/`inactive`.\n- Use `per_page` to control result count (max 100). Default is 30.\n- For \"my PRs / my issues\" across all repos, hit `/search/issues?q=...+author:%40me`. Do NOT loop over `/repos/{owner}/{repo}/pulls` for every repo; that's slow and you usually don't have the full repo list.\n","category":"skills","tokens":1648},{"name":"SKILL.md","path":"skills/developer-setup/SKILL.md","title":"developer-setup Skill","content":"---\nname: developer-setup\nversion: 0.2.0\ndescription: One-time onboarding for the developer workflow — installs github-workflow missions, creates the commitments workspace, registers per-repo projects, writes calibration memories. Excludes itself until its marker file is deleted.\nactivation:\n  setup_marker: projects/commitments/.developer-setup-complete\n  keywords:\n    - developer assistant\n    - dev assistant\n    - dev workflow\n    - developer setup\n    - github setup\n    - help with github\n    - manage my PRs\n    - code workflow\n    - engineering setup\n    - dev setup\n    - automate my repos\n    - CI keeps failing\n    - engineering workflow\n  patterns:\n    - \"(?i)I'm a (developer|engineer|programmer|dev|software engineer)\"\n    - \"(?i)help me (with|manage|set ?up) (github|PRs|repos|CI|code|projects)\"\n    - \"(?i)set ?up.*(dev|coding|engineering|github|developer)\"\n    - \"(?i)(automate|manage) my (repos|PRs|projects|workflow|code)\"\n  tags:\n    - commitments\n    - developer\n    - github\n    - setup\n  max_context_tokens: 3000\nrequires:\n  # Capped at MAX_REQUIRED_SKILLS_PER_MANIFEST = 10 in\n  # `ironclaw_skills::types`. The trimmed list keeps the 10 highest-impact\n  # companions for the developer workflow; the dropped entries\n  # (`qa-review`, `review-readiness`, `product-prioritization`) can still\n  # be installed manually via `skill_install` when needed.\n  skills:\n    - github\n    - github-workflow\n    - project-setup\n    - commitment-triage\n    - commitment-digest\n    - decision-capture\n    - delegation-tracker\n    - idea-parking\n    - tech-debt-tracker\n    - security-review\n---\n\n# Developer Workflow Setup\n\nYou are configuring the full developer workflow — commitment tracking, GitHub automation, tech debt tracking, security/QA reviews, product prioritization, and proactive briefings across multiple repositories.\n\n## Companion skills\n\nThese activate during conversation via keyword matching:\n\n| Skill | When | What |\n|---|---|---|\n| `commitment-triage` | Obligations, deadlines | Signal extraction, commitment creation |\n| `commitment-digest` | \"show commitments\" | Formatted status summary |\n| `decision-capture` | Architecture/design decisions | Records decision + rationale |\n| `delegation-tracker` | \"waiting on @teammate\" | Tracks delegation follow-ups |\n| `idea-parking` | \"park this idea\" | Saves for later |\n| `tech-debt-tracker` | \"this is a hack\", \"refactor later\" | Tracks tech debt, resurfaces weekly |\n| `project-setup` | \"add repo owner/repo\" | Adds a new project with workflow |\n| `security-review` | \"security review\", \"check for vulnerabilities\" | OWASP audit, auto-fix obvious issues |\n| `qa-review` | \"QA review\", \"test coverage\", \"edge cases\" | Test plans, coverage gaps, regression risks |\n| `review-readiness` | \"ready to merge?\", \"PR readiness\" | Tracks which reviews are complete per branch |\n| `product-prioritization` | \"what to build next\", \"prioritize\" | Evidence-based feature scoring, demand analysis |\n| `github` | GitHub API operations | REST API with credential injection |\n| `github-workflow` | Workflow automation reference | Issue-to-merge pipeline templates |\n| `review-checklist` | Pre-merge review | 55+ verification items |\n\nIf any are missing from `skills/`, tell the user which ones are needed.\n\n## Step 1: Setup questions (4, no timezone)\n\n1. **Repos**: Which GitHub repos do you work on? (1-5, format: `owner/repo`)\n2. **Role**: Solo maintainer, team member, or team lead? (Affects delegation vs personal tracking)\n3. **Per-repo**: For each repo — who are maintainers/reviewers? Do you use a staging branch?\n4. **AI agents**: Do any bots create PRs? (Dependabot, Copilot, internal agents) — these get tracked separately in digests with shorter stale thresholds\n\nUse reasonable defaults if the user says \"just set it up.\"\n\n## Step 2: Declare the `commitments` project and create workspace structure\n\nWriting any file under `projects/commitments/` is the declaration that\nthe project exists — the engine auto-registers it and scopes missions\nto it. Start with:\n\n```\nmemory_write(\n  target: \"projects/commitments/AGENTS.md\",\n  content: \"# Commitments (Developer)\\n\\nThis project tracks engineering commitments, tech debt, and decisions across the user's repositories.\\n\\n## Operating principles\\n\\n- Most items are personal tasks, not delegations — default `owner=user`.\\n- Capture tech debt passively from conversation and from merged PR review comments.\\n- AI agent PRs group separately in digests with shorter stale thresholds.\\n- For irreversible actions (merging, deleting, sending messages), always ask first.\\n\",\n  append: false\n)\n```\n\nThen:\n\n1. Check if `projects/commitments/README.md` exists. If not, create the full commitments workspace (see `commitment-setup` skill for the complete schema including immediacy, resolution paths, trust calibration).\n2. Create subdirectory placeholders: `open/`, `resolved/`, `signals/pending/`, `signals/expired/`, `decisions/`, `parked-ideas/`.\n3. Create `projects/commitments/tech-debt/README.md` — \"Tech debt items. Resurface in weekly retro.\"\n\n## Step 3: Set up each project\n\nFor each repo the user listed, run the `project-setup` procedure:\n1. Validate repo via GitHub API\n2. Create `projects/<owner>-<repo>/project.md` with metadata\n3. Create `projects/<owner>-<repo>/notes.md` for developer notes\n4. Install the 6 workflow missions (namespaced by repo slug)\n5. Skip `wf-staging-review` if no staging branch\n\n## Step 4: Create developer missions\n\n### commitment-triage (3x weekdays)\n\n```\nmission_create(\n  name: \"commitment-triage\",\n  goal: \"Developer triage. Read projects/commitments/README.md for schema. Read projects/ via memory_tree for all tracked repos. For each repo, check GitHub API: (1) New PR review requests assigned to user → signal with immediacy=batch. (2) CI failures on user's open PRs → signal with immediacy=prompt. (3) @mentions on PRs/issues → signal with immediacy=prompt. (4) New issue assignments → signal with immediacy=batch. (5) Issues/PRs with production/hotfix/critical labels → signal with immediacy=realtime, broadcast immediately. (6) Recently merged PRs — scan review comments for tech-debt patterns ('address in follow-up', 'not blocking but fix later', 'TODO', 'leaving for now') → create tech-debt items in projects/commitments/tech-debt/ with source=pr-review and source_pr reference. Expire signals after 48h. Flag AI agent PRs stuck in CI after 24h. Append summary to projects/commitments/triage-log.md.\",\n  cadence: \"0 9,14,18 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### commitment-digest (weekday mornings)\n\n```\nmission_create(\n  name: \"commitment-digest\",\n  goal: \"Developer morning brief. Read projects/commitments/README.md for schema. Read projects/ for tracked repos. For each repo, query GitHub API. Compose digest in this order: (1) OVERNIGHT RESULTS — CI status per repo on user's PRs (green/red/pending), PRs merged overnight. (2) NEEDS YOUR REVIEW — PRs where user is requested reviewer, show age, author, size. Separate human PRs from AI agent PRs. Flag stale reviews (3+ days). (3) YOUR OPEN PRs — each with CI status, review state. Flag READY TO MERGE if approved + CI green. (4) BLOCKED/WAITING — commitments with status=waiting or delegated_to set, agent PRs stuck in CI loops (attempted 3+ fixes). (5) TODAY'S COMMITMENTS — open items sorted by urgency, for agent_can_handle items note what agent would do. (6) QUICK STATS — tech debt count, pending signal count. End with 'Did I miss anything?' Send via message tool. Omit empty sections.\",\n  cadence: \"0 8 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-stale-pr-check (weekday afternoons)\n\n```\nmission_create(\n  name: \"dev-stale-pr-check\",\n  goal: \"Check for stale PRs across tracked repos. Read projects/ for repo list. For each repo, query GitHub API for open PRs. Flag PRs with no activity in 3+ days (human) or 1+ day (agent PR stuck in CI). For user's own stale PRs: suggest pinging reviewer or closing if abandoned. For PRs user should review: note how long they've been waiting. Send alert only if stale items found; stay silent otherwise.\",\n  cadence: \"0 16 * * 1-5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-weekly-retro (Friday morning)\n\n```\nmission_create(\n  name: \"dev-weekly-retro\",\n  goal: \"Weekly developer retrospective. Gather: (1) All commitments resolved this week from projects/commitments/resolved/. (2) All decisions captured this week from projects/commitments/decisions/. (3) All tech debt items added this week from projects/commitments/tech-debt/ — include items from PR review scans. (4) Per-repo: count of merged PRs this week via GitHub API. (5) Open items carried forward. Compose retro: SHIPPED, DECISIONS MADE (with rationale), SLIPPED/CARRIED FORWARD, TECH DEBT ACCUMULATED (new items + total count + top 3 chronic), PATTERNS (recurring CI failures, slow review cycles). For complex action items, suggest using /plan to create a structured execution plan. Write retro to context/intel/weekly-retro-<date>.md. Send via message tool.\",\n  cadence: \"0 10 * * 5\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-decision-outcome-check (Wednesday)\n\n```\nmission_create(\n  name: \"dev-decision-outcome-check\",\n  goal: \"Check for decisions needing outcome assessment. Read projects/commitments/decisions/ for entries where outcome is null and decided_at is 7+ days ago. For each, prompt: 'You decided <X> <N> days ago. How did it turn out?' Skip silently if no decisions need review.\",\n  cadence: \"0 10 * * 3\",\n  project_id: \"commitments\"\n)\n```\n\n### dev-tech-debt-resurface (Monday morning)\n\n```\nmission_create(\n  name: \"dev-tech-debt-resurface\",\n  goal: \"Weekly tech debt review. Read all files in projects/commitments/tech-debt/ via memory_tree and memory_read. Sort by age. Flag items older than 30 days as chronic. For items tagged with a repo, check if related issues exist. If backlog exceeds 10 items, suggest a prioritization session. For high-severity chronic items, suggest using /plan to create a structured breakdown and fix strategy. Send list via message tool. Skip silently if no tech debt.\",\n  cadence: \"0 10 * * 1\",\n  project_id: \"commitments\"\n)\n```\n\n## Step 5: Write calibration memories\n\n```\nmemory_write(\n  target: \"projects/commitments/calibration.md\",\n  content: \"# Developer Calibration\\n\\n## Decision classification\\n- mechanical (auto-act silently): expire stale signals, update CI status, dismiss noise, mark passing checks\\n- taste (auto-act, surface in digest): auto-dismiss FYI signals, auto-resolve completed items, update readiness dashboard\\n- challenge (always ask): architecture decisions, sending messages to people, merging PRs, deleting branches, any irreversible action\\n\\n## Effort principle\\n- AI makes completeness cheap — when the thorough implementation costs minutes more than the shortcut, always do the thorough thing\\n- Always show dual effort estimates when known: human time vs AI-assisted time\\n- This reframes prioritization: features that seem expensive may be cheap with AI\\n\\n## Signal urgency\\n- CI failures on user's own PRs = prompt urgency — surface within the hour\\n- Production/hotfix/critical labels = realtime — broadcast immediately\\n- PR review requests = batch urgency unless from team lead or marked urgent\\n- Security P1 findings = realtime\\n- AI agent PRs grouped separately in digest with shorter stale threshold (1 day vs 3)\\n\\n## Tech debt\\n- Captured passively from conversation AND from merged PR review comments\\n- PR review comments matching 'address in follow-up', 'not blocking but fix', 'TODO later', 'leaving for now' → auto-create tech-debt items\\n\\n## Reviews\\n- Track review readiness per branch in projects/<slug>/readiness/\\n- Before merge, check: code review + tests + security + QA. Surface gaps in digest.\\n- Security and QA reviews can be run with /security-review and /qa-review\\n- Obvious security/QA fixes are auto-applied; ambiguous ones always ask\\n\\n## Product\\n- Feature prioritization uses evidence-based scoring: demand × 3 + impact × 2 + alignment / effort\\n- Challenge assumptions — 'I think users want X' requires evidence\\n- Use /product-prioritization for structured analysis\\n\\n## General\\n- Architecture/API design decisions = high-confidence capture; debugging 'let's try X' = not a decision\\n- Most developer commitments are personal tasks, not delegations — default owner=user\\n- Projects tracked in projects/<slug>/project.md\\n- For complex tasks, suggest /plan for structured execution\\n- Weekly retro writes to context/intel/ as durable intelligence\\n- Start conservative: surface everything, earn trust through feedback\",\n  append: false\n)\n```\n\n## Step 6: Confirm\n\nTell the user:\n\n> Your developer workflow is ready:\n>\n> **Projects:** <list of repos, each with workflow status>\n>\n> **Missions:**\n> - **Triage** 3x weekdays (9am, 2pm, 6pm) — scans GitHub for review requests, CI failures, assignments, mentions, and tech debt from PR reviews\n> - **Morning brief** 8am weekdays — overnight CI, PRs needing review, your PR statuses, today's commitments\n> - **Stale PR check** 4pm weekdays — flags abandoned PRs and slow reviews\n> - **Weekly retro** Friday 10am — what shipped, decisions, tech debt, patterns\n> - **Tech debt review** Monday 10am — resurfaces accumulated debt\n> - **Decision check** Wednesday 10am — follows up on decisions older than 7 days\n>\n> Per-repo workflow: issue planning, maintainer gate, PR monitor, CI fix loop, staging review, post-merge learning\n>\n> **Quick commands:**\n> - **\"show commitments\"** — current status\n> - **\"show tech debt\"** — debt backlog\n> - **\"add repo owner/repo\"** — add another project\n> - **\"is this PR ready?\"** — review readiness dashboard\n> - **\"what should we build next?\"** — evidence-based prioritization\n> - **`/security-review`** — run security audit on current changes\n> - **`/qa-review`** — generate test plan and coverage analysis\n> - **`/plan <description>`** — structured execution plan for complex tasks\n> - **`/product-prioritization`** — score and rank features by demand\n\n## Step 7: Mark setup complete\n\nAfter confirming with the user that everything is in place, write the setup completion marker so this skill stops competing for the activation budget on every subsequent message:\n\n```\nmemory_write(\n  target: \"projects/commitments/.developer-setup-complete\",\n  content: \"# Developer Setup Complete\\n\\nCompleted: <today's UTC date>\\n\\nRepos: <list of repo slugs>\\nMaintainers: <maintainers>\\nMissions installed: wf-issue-plan, wf-maintainer-gate, wf-pr-monitor, wf-ci-fix, wf-learning, plus 6 personal productivity missions (commitment-triage, commitment-digest, dev-stale-pr-check, dev-weekly-retro, dev-tech-debt-resurface, dev-decision-outcome-check)\"\n)\n```\n\nThis is a one-time marker. The next conversational turn will not load this setup skill (the operational skills like `commitment-triage`, `tech-debt-tracker`, `github`, `github-workflow` keep activating reactively as before). To re-trigger setup (add a new repo with the wizard, re-onboard, switch maintainers), delete `projects/commitments/.developer-setup-complete` first.\n","category":"skills","tokens":3769}]}