@reddb-io/red-skills-dev 2.75.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +30 -0
  3. package/package.json +32 -0
  4. package/skills/engineering/README.md +36 -0
  5. package/skills/engineering/_report-runtime/WRAPPER.md +47 -0
  6. package/skills/engineering/afk/AGENT-PROMPT.md +295 -0
  7. package/skills/engineering/afk/SAFETY.md +103 -0
  8. package/skills/engineering/afk/SKILL.md +160 -0
  9. package/skills/engineering/afk/TROUBLESHOOTING.md +260 -0
  10. package/skills/engineering/afk/actions-lane.md +213 -0
  11. package/skills/engineering/afk/bin/README.md +29 -0
  12. package/skills/engineering/afk/bin/afk.mjs +51 -0
  13. package/skills/engineering/afk/defaults/cargo-pre-worktree.sh +37 -0
  14. package/skills/engineering/afk/defaults/envelope-post-attempt.sh +47 -0
  15. package/skills/engineering/afk/defaults/gradle-pre-worktree.sh +42 -0
  16. package/skills/engineering/afk/defaults/heartbeat-post-attempt.sh +43 -0
  17. package/skills/engineering/afk/defaults/validation-post-merge.sh +77 -0
  18. package/skills/engineering/afk/detectors/README.md +72 -0
  19. package/skills/engineering/afk/detectors/cargo.sh +27 -0
  20. package/skills/engineering/afk/detectors/gradle.sh +35 -0
  21. package/skills/engineering/afk/docs/BOOT-SWEEPS.md +81 -0
  22. package/skills/engineering/afk/docs/CONFIG.md +238 -0
  23. package/skills/engineering/afk/docs/ENVELOPE.md +177 -0
  24. package/skills/engineering/afk/docs/HANDOFF.md +70 -0
  25. package/skills/engineering/afk/docs/LIVENESS.md +56 -0
  26. package/skills/engineering/afk/docs/OPERATIONS.md +409 -0
  27. package/skills/engineering/afk/examples/only-mine.sh +32 -0
  28. package/skills/engineering/afk/examples/red-afk-attempt-action.yml +53 -0
  29. package/skills/engineering/afk/examples/rs-afk-attempt.yml +76 -0
  30. package/skills/engineering/afk/fleet.md +127 -0
  31. package/skills/engineering/afk/hooks/red-cargo +44 -0
  32. package/skills/engineering/afk/hooks/red-envelope +50 -0
  33. package/skills/engineering/afk/hooks/red-gradle +50 -0
  34. package/skills/engineering/afk/hooks/red-heartbeat +46 -0
  35. package/skills/engineering/afk/hooks/red-validation +79 -0
  36. package/skills/engineering/afk/monitor.md +170 -0
  37. package/skills/engineering/afk/runner-claude-minimax.md +71 -0
  38. package/skills/engineering/afk/runner-claude.md +67 -0
  39. package/skills/engineering/afk/runner-codex.md +138 -0
  40. package/skills/engineering/afk/runner-hermes.md +40 -0
  41. package/skills/engineering/afk/runner-opencode.md +142 -0
  42. package/skills/engineering/ask-red/SKILL.md +137 -0
  43. package/skills/engineering/audit-skills/SKILL.md +46 -0
  44. package/skills/engineering/code-review/SKILL.md +106 -0
  45. package/skills/engineering/context/SKILL.md +142 -0
  46. package/skills/engineering/curate/SKILL.md +133 -0
  47. package/skills/engineering/daily-review/SKILL.md +68 -0
  48. package/skills/engineering/dashboard/SKILL.md +44 -0
  49. package/skills/engineering/diagnose/SKILL.md +155 -0
  50. package/skills/engineering/diagnose/scripts/hitl-loop.template.sh +41 -0
  51. package/skills/engineering/go/SKILL.md +144 -0
  52. package/skills/engineering/go/TROUBLESHOOTING.md +81 -0
  53. package/skills/engineering/ground-truth/SKILL.md +84 -0
  54. package/skills/engineering/hitl/SKILL.md +171 -0
  55. package/skills/engineering/hitl/TROUBLESHOOTING.md +76 -0
  56. package/skills/engineering/implement/SKILL.md +69 -0
  57. package/skills/engineering/improve-codebase-architecture/DEEPENING.md +37 -0
  58. package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -0
  59. package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +53 -0
  60. package/skills/engineering/improve-codebase-architecture/SKILL.md +81 -0
  61. package/skills/engineering/model-tier-policy/SKILL.md +83 -0
  62. package/skills/engineering/prototype/LOGIC.md +79 -0
  63. package/skills/engineering/prototype/SKILL.md +30 -0
  64. package/skills/engineering/prototype/UI.md +112 -0
  65. package/skills/engineering/red-doctor/APPLY.md +35 -0
  66. package/skills/engineering/red-doctor/SKILL.md +172 -0
  67. package/skills/engineering/red-gains/SKILL.md +49 -0
  68. package/skills/engineering/red-setup/INTERVIEW.md +266 -0
  69. package/skills/engineering/red-setup/ISSUE-SWEEP.md +18 -0
  70. package/skills/engineering/red-setup/REFERENCE.md +35 -0
  71. package/skills/engineering/red-setup/SKILL.md +58 -0
  72. package/skills/engineering/red-setup/WORKFLOWS.md +74 -0
  73. package/skills/engineering/red-setup/WRITE-CONTRACT.md +151 -0
  74. package/skills/engineering/red-setup/config-template.yaml +174 -0
  75. package/skills/engineering/red-setup/domain.md +52 -0
  76. package/skills/engineering/red-setup/issue-tracker-github.md +88 -0
  77. package/skills/engineering/red-setup/rsp-retirement-runbook.md +35 -0
  78. package/skills/engineering/red-setup/scripts/install-runtime-shim.sh +189 -0
  79. package/skills/engineering/red-setup/triage-labels.md +176 -0
  80. package/skills/engineering/red-setup/workflows/red-issues-needs-triage.yml +36 -0
  81. package/skills/engineering/red-statusline/HOST-NOTES.md +180 -0
  82. package/skills/engineering/red-statusline/SKILL.md +58 -0
  83. package/skills/engineering/report-bug/SKILL.md +155 -0
  84. package/skills/engineering/resolving-merge-conflicts/SKILL.md +143 -0
  85. package/skills/engineering/retake/SKILL.md +184 -0
  86. package/skills/engineering/review-adrs/SKILL.md +125 -0
  87. package/skills/engineering/start/ADR-FORMAT.md +47 -0
  88. package/skills/engineering/start/CONTEXT-FORMAT.md +77 -0
  89. package/skills/engineering/start/DOC-LANDING-FINALIZER.md +9 -0
  90. package/skills/engineering/start/SKILL.md +179 -0
  91. package/skills/engineering/tdd/SKILL.md +96 -0
  92. package/skills/engineering/tdd/deep-modules.md +33 -0
  93. package/skills/engineering/tdd/interface-design.md +31 -0
  94. package/skills/engineering/tdd/mocking.md +59 -0
  95. package/skills/engineering/tdd/tests.md +85 -0
  96. package/skills/engineering/to-spec/SKILL.md +104 -0
  97. package/skills/engineering/to-tickets/SKILL.md +158 -0
  98. package/skills/engineering/triage/AGENT-BRIEF.md +207 -0
  99. package/skills/engineering/triage/OUT-OF-SCOPE.md +101 -0
  100. package/skills/engineering/triage/SKILL.md +176 -0
  101. package/skills/engineering/verify/SKILL.md +136 -0
  102. package/skills/engineering/wayfinder/SKILL.md +128 -0
  103. package/skills/engineering/zoom-out/SKILL.md +51 -0
  104. package/skills/engineering/zoom-out/scripts/graph-mode-plumbing.sh +36 -0
  105. package/skills/engineering/zoom-out/scripts/tests/contract.test.sh +168 -0
  106. package/skills/knowledge/README.md +5 -0
  107. package/skills/knowledge/research/SKILL.md +76 -0
  108. package/skills/misc/README.md +8 -0
  109. package/skills/misc/branch-lock/SKILL.md +187 -0
  110. package/skills/misc/branch-lock/scripts/branch-lock-hook.sh +113 -0
  111. package/skills/misc/branch-lock/scripts/branch-lock-session-start.sh +81 -0
  112. package/skills/misc/branch-lock/scripts/branch-lock.sh +68 -0
  113. package/skills/misc/branch-lock/scripts/lib/dev-config.sh +126 -0
  114. package/skills/misc/branch-lock/scripts/lib/git-command-classifier.sh +198 -0
  115. package/skills/misc/branch-lock/scripts/lib/lock-store.sh +67 -0
  116. package/skills/misc/branch-lock/scripts/lib/scope-resolver.sh +43 -0
  117. package/skills/misc/branch-lock/scripts/tests/branch-lock-cli.test.sh +114 -0
  118. package/skills/misc/branch-lock/scripts/tests/claude-plugin-hook.test.sh +117 -0
  119. package/skills/misc/branch-lock/scripts/tests/codex-hook.test.sh +229 -0
  120. package/skills/misc/branch-lock/scripts/tests/dev-config.test.sh +99 -0
  121. package/skills/misc/branch-lock/scripts/tests/git-command-classifier.test.sh +187 -0
  122. package/skills/misc/branch-lock/scripts/tests/lock-store.test.sh +90 -0
  123. package/skills/misc/branch-lock/scripts/tests/scope-resolver.test.sh +63 -0
  124. package/skills/misc/branch-lock/scripts/tests/session-start.test.sh +123 -0
  125. package/skills/misc/git-guardrails-claude-code/SKILL.md +105 -0
  126. package/skills/misc/git-guardrails-claude-code/scripts/block-dangerous-git.sh +231 -0
  127. package/skills/misc/git-guardrails-claude-code/scripts/tests/block-dangerous-git.test.sh +143 -0
  128. package/skills/misc/migrate-to-shoehorn/SKILL.md +96 -0
  129. package/skills/misc/setup-pre-commit/SKILL.md +94 -0
  130. package/skills/productivity/README.md +8 -0
  131. package/skills/productivity/ff/SKILL.md +116 -0
  132. package/skills/productivity/handoff/SKILL.md +37 -0
  133. package/skills/productivity/reflect/SKILL.md +18 -0
  134. package/skills/productivity/write-a-skill/SKILL.md +190 -0
  135. package/skills/productivity/write-a-skill/WRITING-STYLE.md +62 -0
@@ -0,0 +1,35 @@
1
+ # Apply — what `--fix` runs per finding
2
+
3
+ Read this only on the `--fix` (Fix) pass. Each Pass-1 finding maps to a concrete
4
+ action and a gate: **safe** fixes apply in a batch (idempotent, low-blast-radius);
5
+ **confirm-each** fixes show the exact mutation and apply only on an explicit yes;
6
+ **delegate** fixes trigger the single-writer tool that owns the change. The
7
+ findings→owner mapping lives in the *Fix-home* table in `SKILL.md`; this table adds
8
+ the action and gate on top of it.
9
+
10
+ | Finding | `--fix` action | Gate |
11
+ |---|---|---|
12
+ | Missing canonical label | `gh label create <name> --color <c> --description "<d>"` | **safe** (batch) |
13
+ | AGENTS≡CLAUDE Agent-skills / Development-workflow parity | run the development-workflow injector (`inject-development-workflow --root <repo>`) — upserts both blocks in place | **safe** (batch; idempotent) |
14
+ | `dev.lock.primary-branch` unset | same injector (it sets the nested flag) | **safe** (batch) |
15
+ | Statusline drift | rewrite the `.claude/settings.json` `statusLine` to the cached-bundle form (jq merge, preserve other keys) | **safe** (batch) |
16
+ | `.red/.gitignore` self-ignore missing/incomplete | write `.red/.gitignore` (header + `tmp/` + `state/` + `researches/`) if absent, else append only the missing pattern(s) — never reorder or clobber existing lines; don't `git add` it; print a one-line receipt | **safe** (batch; idempotent) |
17
+ | Label synonym / legacy / naming | `gh label rename <old> <new>` (or create canonical + migrate, then retire the old) | **confirm each** — re-tags every issue carrying the old label |
18
+ | Legacy/top-level dev-plugin config (flat `lock-primary-branch`, top-level `dev.lock.*`, top-level `afk:`) | migrate the key(s) into the canonical `plugins.dev.*` namespace + delete the top-level orphan in `.red/config.yaml` (safe: the #697 fold reads both, the namespaced form wins) | **confirm each** |
19
+ | `blocked:*` on a `ready-for-agent`/`running` issue | `gh issue edit <N> --remove-label blocked:<reason>` (rotate the stale reason) | **confirm each** |
20
+ | MCP wiring | add/correct the expected servers in the repo's `.mcp.json` | **confirm each** |
21
+ | Version coherence mismatch | **run** the single-writer version/release tool (ADR 0040); never patch a manifest | **delegate** |
22
+ | Workflow naming-convention drift | `git mv` the file to the prefix its role requires (`reusable-*` / `rs-*` / `red-*`); filename only, body unchanged; then update any `uses:` + doc references to the old name | **confirm each** — renames a CI file |
23
+ | AFK-lane auth gap (`rs-afk-attempt.yml`, no auth secret) | **do not set the secret** — print the per-provider `gh secret set … --repo` guidance + the public-repo org-secret note; delegate to `/red-setup` | **delegate** |
24
+ | AFK hook/backpressure static-validation `❌`/`⚠️` (check 12) | **`--fix` cannot auto-fix operator intent** — it cannot know whether the right repair is to rename the script, restore the file, or drop the command. Flag the finding and point at `/red-setup` (re-seed a library hook) or a manual edit; never rewrite `.red/config.yaml` or `.red/hooks/` here, and never execute the command to "check" it. | **delegate** |
25
+ | Per-plugin runtime distribution `❌`/`⚠️` (check 13) | **re-trigger the launcher fetch** for the plugin (`red-fetch.mjs <plugin> <version>` / rebuild locally) — the cache is launcher-owned, never hand-edited. `cache-corrupt` also removes the bad cached file first so the re-fetch re-downloads. A re-fetch hits the network and rewrites the cache, so it is never a safe batch. | **confirm each** — a network fetch that rewrites the cache |
26
+ | `req:<Spec>` dependency edge (check 14) | **do not silently re-label** — a re-point needs the author to pick the right executable slice(s). Surface each offending edge and delegate to `/triage` (re-point) or `/to-tickets` (author the missing slice); never edit the `req:*` label here. | **delegate** |
27
+ | Native blocked-by vs `req:N` divergence (check 15) | **do not guess the canonical side** — a divergence means the authoring metadata must be refreshed. Surface each missing native edge / missing `req:N` label and delegate to `/triage`; never add/remove labels or native edges in doctor `--fix`. | **delegate** |
28
+ | Native sub-issue vs `spec:N` divergence (check 16) | **run the shared Spec sub-issue reconciler** — attach missing native sub-issue edges for every `spec:N` child and remove stale `needs-slicing` from Specs that already have published slices. Do not remove native-only edges or invent missing labels; surface those as authoring drift. | **safe batch** |
29
+ | ask-red router coverage sync (check 17) | **do not patch the router blindly** — a missing or stale entry means the flow map needs a wording check. Surface the exact skill names and apply the ask-red maintenance rule: update `plugins/dev/skills/engineering/ask-red/SKILL.md`, README/bucket docs if registration changed, and rerun the docs contract. | **confirm each** |
30
+ | Required host binaries `❌` (check 18) | **delegate to `/red-setup`** — install the pinned `tq` with the checksum-verified toon installer and record `host_binaries.tq.version`. Never patch around drift with a jq fallback or silently accept a different version. | **delegate** |
31
+ | `.red` lifecycle taxonomy (check 19); tmp janitor (check 19) | **taxonomy findings:** do not auto-move content; each finding names the offending path and target tier/lane. Delegate to the owning writer, or amend ADR 0098 before accepting a new top-level directory or tmp lane. **tmp janitor findings:** run the wired janitor fixer only on audited targets: expired managed lanes from `planTmpJanitor`, stale worker dirs whose represented issues are closed, and unknown tmp-root entries returned by `auditTmpRoot`; re-check `worker.pid` immediately before deleting any worker dir and skip it if live. | taxonomy: **delegate**; tmp janitor: **safe batch** |
32
+ | Castle state lane (check 20) | **delegate to the dev durable path migration entrypoint** (`red-path-migration` during boot). It must move legacy AFK state into `.red/state/castle/` without overwriting current state, and leave ambiguous legacy residue intact for an operator to inspect. Never hand-delete `.red/state/afk/`, rewrite TOONL history, or patch snapshots in doctor `--fix`. | **delegate** |
33
+ | Unlanded `.red/` docs (check 21) | **run the ADR 0092 doc-landing lane** — from an isolated `.red/tmp/worktrees/docs/<slug>` worktree based on freshly fetched `origin/{base}`, copy only the detected docs, commit one `docs:` change, push a branch, open one docs PR, merge it, then re-fetch/re-check. Reuse the shared Docs Sweep plan; never recompute the file list in the fixer. | **confirm each** — pushes a branch, opens a PR, and merges it |
34
+ | Red operational probe (check 22) | **run the probe's own canonical fixer** from the registry. For the HTTPS-remote proof probe, rewrite each named local HTTPS remote to its SSH form. For `config.coherence`, show the `.red/config.yaml` diff preview first, then relocate confirmed root-level `dev:`/`afk:` blocks under `plugins.dev.*`; malformed parse fallbacks remain red until the offending line/construct is repaired. A decline leaves the target byte-identical and the finding open. | **confirm each** — rewrites git remote configuration or confirmed config blocks |
35
+ | Context-stack gap (check 1) | run the relevant `memory`/context skill | **delegate** |
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: red-doctor
3
+ description: Adoption/process doctor — reports how fully a repo has adopted the RedSkills engineering stack. Read-only by default; `--fix` applies the canonical fix for every finding, gated per hard-to-reverse change. The recurring counterpart to the one-time `/red-setup`. Use when asked "red doctor", "check adoption", before a large `/afk` drain, or to verify a repo against canonical conventions.
4
+ argument-hint: "[--repo <path|owner/name>] [--fix]"
5
+ ---
6
+
7
+ # Doctor (adoption / process)
8
+
9
+ **Run the adoption/process check read-only; apply every canonical fix with `--fix` — never hand-edit what a single-writer tool owns, because each gap's fix-home already exists.**
10
+
11
+ The recurring counterpart to the one-time `/red-setup` — the same split the
12
+ `memory` plugin has between `context-status` (read-only) and its setup. It reports
13
+ how fully a repo adopted the RedSkills stack and **names the fix-home for each gap**.
14
+ **Default is read-only.** With `--fix` it becomes the reconciler that actually heals
15
+ every finding, applying each gap's canonical fix and gating every hard-to-reverse
16
+ change behind explicit per-item confirmation.
17
+
18
+ <what-to-do>
19
+
20
+ **Always run Pass 1 (Diagnose, read-only) and print the scorecard. Then, only when invoked with `--fix`, run Pass 2 (Fix) — apply the canonical fix for every finding, batching the safe ones and confirming each hard-to-reverse one individually.**
21
+
22
+ ### Hard rules
23
+
24
+ - ✅ **Default (no `--fix`) is read-only**: no `gh label create/edit/delete`, no file writes, no `gh issue edit`, no MCP/hook/statusline install. Pass 1 is a pure diagnostic.
25
+ - ✅ **`--fix` is the only mutating path**, and even then: the safe fixes apply in a batch (with a one-line receipt each); every **hard-to-reverse** fix — label rename/retire, config-key migration, `blocked:*` rotation, MCP rewrite — is **confirmed individually before it runs**.
26
+ - ❌ Never hand-edit what a single-writer tool owns: a version mismatch is fixed by **running** the version script (ADR 0040), never by editing a manifest. `--fix` invokes the tool; it does not patch around it.
27
+ - ✅ Compose existing surfaces — `memory context-status`, `/wiki lint`, the development-workflow injector, `gh` — instead of re-implementing them.
28
+ - ✅ Resolve the canonical vocabulary from the **target repo's** `.red/agents/triage-labels.md` (each repo may map roles to its own strings — respect that mapping, don't impose red-skills' defaults).
29
+
30
+ ### Pass 1 — Diagnose (always; read-only)
31
+
32
+ Run the checks against the target repo (cwd by default; `--repo <path|owner/name>` for another, or sweep a list). Read only.
33
+
34
+ 1. **Local context stack** — invoke `memory context-status` (or its CLI) and fold its result in. Do not duplicate its checks (CLAUDE/AGENTS, `.red/CONTEXT(-MAP)`, `.red/adr/*`, memory, wiki).
35
+ 2. **Label conformance** — `gh label list` vs the canonical families in `triage-labels.md`. Classify every label per the *Label classes* table in `<supporting-info>`. Report `❌ synonym` / `⚠️ legacy` / `⚠️ naming` with the suggested rename; in this pass never apply it.
36
+ 3. **`blocked:*` hygiene** — list open issues carrying `ready-for-agent` **or** `running` **together with** any `blocked:*` label (stale reason not rotated on re-queue). Count them.
37
+ 4. **AGENTS ≡ CLAUDE Agent-skills parity** — both files exist **and** both carry the `## Agent skills` block. Report `C/A` (e.g. `1/0` = block in CLAUDE only). Missing files, missing blocks, or unequal treatment are findings tagged `→ /red-setup`.
38
+ 5. **AGENTS ≡ CLAUDE Development-workflow parity** — both files exist **and** both carry the `## Development workflow` block with the same treatment. Report `C/A` for presence (e.g. `1/0` = block in CLAUDE only), and report any missing file, missing block, or out-of-parity block as a finding tagged `→ /red-setup`. During this read-only pass: do not run `inject-development-workflow`, do not create files, do not edit either agent rules file — that is the `--fix` lane's job.
39
+ 6. **Config namespacing + primary-branch guard** — read `.red/config.yaml`, two findings:
40
+ - **Guard flag** — report whether the primary-branch guard resolves to `true`. The canonical key is the namespaced `plugins.dev.lock.primary-branch`; the legacy top-level `dev.lock.primary-branch` and flat `lock-primary-branch` still resolve through the ADR 0042 / PR #697 fold (the whole `plugins.dev.*` block folds onto the `dev.*` accessors, the namespaced form winning). Treat an absent config file, absent block, absent key, or any value other than `true` as "unset" → recommend `→ /red-setup`; report `true` as adopted.
41
+ - **Namespacing conformance** (the strict structural check) — dev-plugin settings belong under `plugins.dev.*`. Flag any **legacy top-level placement** as a migration finding: a top-level `afk:` block (canonical `plugins.dev.afk.*`), a top-level `dev:` block carrying plugin settings such as `dev.lock.*` (canonical `plugins.dev.lock.*`), or the flat `lock-primary-branch`. The fold still reads these, so this is **hygiene, not breakage** — but the canonical written form is namespaced and `/red-setup` now writes it that way, so a top-level form is drift to migrate. Tag `→ /red-setup`.
42
+
43
+ During this read-only pass: never write `.red/config.yaml`.
44
+ 7. **Statusline drift** — the installed `.claude/settings.json` `statusLine` command resolves the **cached bundle** (`~/.cache/red-skills/bundles/dev-*.bundle.min.mjs`), not the OLD launcher form (`…/plugins/cache/red-skills/dev/*/…/afk.mjs`) which blanks on every plugin update.
45
+ 8. **MCP wiring** — does the repo wire the expected MCPs? The `dev` plugin should expose `code-nav`; the `memory` plugin should expose **`red-memory` (the local data MCP, a local server that execs the in-repo `bootstrap.mjs`, built from `apps/memory`, RedDB-backed via `@reddb-io/sdk`) + `red-ui` (the visualizer consumer)** — this local shape is the **intended** wiring, **not** drift (ADR 0041 Amendment 1 reversed the release-fetched migration). What *is* a finding: a server still named **`memory`** that was never renamed to `red-memory`, or a `.mcp.json`/routing-guide that tries to **fetch `red-memory` from a GitHub release** (there is no such release). Also check whether the repo wires `code-nav`/`red-memory` for its **own** dev (root `.mcp.json` or agent-doc reference).
46
+ 9. **Version coherence** — every plugin manifest pair is on the same version: for each `plugins/*/`, `.claude-plugin/plugin.json` `version` **==** `.codex-plugin/plugin.json` `version`. A mismatch is what `validate-install-metadata.sh` rejects and what fails `red-release` (e.g. a stale manifest landed manually). Fix-home = `→ release` (the single-writer version script, ADR 0040).
47
+ 10. **Workflow naming convention** — list `.github/workflows/*.yml` and classify each by **role**, decidable from its content: has `workflow_call:` → must be `reusable-*`; `uses:` a `reusable-*` → must be `rs-*` (a caller / instantiation); otherwise → must be `red-*` (a standalone workflow). Applies both in red-skills itself and in an adopter repo. Two findings, both tagged `→ /red-setup`:
48
+ - **Naming drift** — a file whose filename prefix doesn't match its role: a reusable caller named `red-*` (should be `rs-*`), a standalone named `rs-*`/`reusable-*` (should be `red-*`), a `workflow_call` workflow not named `reusable-*`, or a legacy `red-skills-*` (the retired caller prefix → now `rs-*`). Report the rename to the role-correct prefix. (A `reusable-*` referenced via `uses:` from another repo is exempt — it is *called*, never copied.)
49
+ - **AFK lane auth gap** — if `rs-afk-attempt.yml` (or a drifted copy under another prefix) is installed, best-effort check that an OpenCode auth secret **name** is present via `gh secret list --repo <repo>` (names only — never read or print a value). If none of `MINIMAX_API_KEY`/`OPENAI_API_KEY`/`OPENROUTER_API_KEY` is listed, flag the lane as installed-but-unauthed (the public-repo org-secret gotcha — on a public repo an org secret resolves empty unless its Repository access includes the repo). Skip silently if `gh secret list` 403s (no admin scope); report `unknown`, not a failure.
50
+ 11. **`.red/.gitignore` self-ignore** — only when `.red/` exists: check that `.red/.gitignore` is present **and** ignores `tmp/`, `state/`, and `researches/`, so ephemeral runtime state, durable machine state, and generated research reports can't be committed even if the repo-root `.gitignore` lacks the patterns (ADR 0067 / ADR 0098; `/red-setup` writes this on creation). Report `❌` when `.red/` exists but `.red/.gitignore` is absent or missing any required pattern (one-line evidence: which patterns are missing); `✅` when all three are ignored. Tag `→ /red-setup`. During this read-only pass: never write `.red/.gitignore`. Skip the check silently when `.red/` does not exist.
51
+ 12. **AFK hook / backpressure static validation** — read `.red/config.yaml` (the `plugins.dev.afk.backpressure` list + the `plugins.dev.afk.hooks.<point>` entries, legacy bare `afk.*` fallback) and the `.red/hooks/<point>/` tree, and classify every backpressure command and hook script **statically — never execute one** (the trust model is "scripts in your own repo are trusted"; this check resolves, it does not run). Per command: `❌` when it references a renamed/missing `package.json` script (`pnpm run <gone>`) or a non-existent file path, or a `red-*` library/shadow target that does not resolve; `⚠️` (conservative) when it cannot be statically resolved (a bare PATH binary like `curl`/`make` — maybe valid, never a hard fail); `✅` when it resolves. **Unknown hook names** (today a hard boot error) are pre-caught here read-only and reported `❌` before the next drain parks every issue. Tag `→ /red-setup`. The classifier is `apps/dev/src/core/hook-doctor.ts` (`validateHookConfig`), driven by the canonical hook registry (`hook-registry.ts`, #834). During this read-only pass: never write config and **never execute a command**.
52
+ 13. **Per-plugin runtime distribution** — audit, per plugin (`dev`, `memory`, `brain`), the **ADR 0084 control-plane contract**: a plugin the config marks on **must** have a present, readable, checksum-valid, current cached bundle. This turns the former **silent-no-op class** (`enabled: true` whose runtime never arrived) into visible, named findings. Read the nearest `.red/config.yaml` `plugins.<name>.enabled` flag, the installed version from `.claude-plugin/plugin.json`, and the cached bundle (`~/.cache/red-skills/bundles/<plugin>-<version>.bundle.min.mjs`, ADR 0034/0038). Three failure axes:
53
+ - **Enabled vs runtime present** — `plugins.<name>.enabled: true` but **no cached bundle** → `❌ runtime-missing`; only the **inert marker a failed fetch left behind** → `❌ inert-marker`. The plugin is "on" but does nothing.
54
+ - **Version drift** — the cached bundle is **behind the latest compatible Release**, stale beyond the self-update expectation (#1033) → `⚠️ version-drift`. It still runs, just not the current runtime. **Suppressed when the latest release can't be resolved** (offline / rate-limited) — never a false positive when we could not ask.
55
+ - **Cache integrity** — the cached bundle is **unreadable or its bytes fail the published sha256** → `❌ cache-corrupt` (outranks drift: a bundle whose bytes are wrong has no version to trust).
56
+
57
+ A **disabled** plugin is **inert by design** (the ADR 0067 gate) → never a finding, whatever its cache. A **healthy three-plugin setup produces zero findings**. Every finding's remediation is the **launcher fetch** (`red-fetch.mjs <plugin> <version>`), never a hand edit of a fetched asset. Tag `→ launcher fetch`. The classifier is `apps/dev/src/core/runtime-doctor.ts` (`auditRuntimes`), pure + IO-free like `hook-doctor.ts` (every cache/version fact is injected). During this read-only pass: never fetch a bundle and **never touch the network** — the audit reads observed facts, it does not resolve them.
58
+ 14. **`req:<Spec>` dependency-edge audit** — dependency edges must point at executable slices, never at a Spec (see `triage-labels.md` *Dependency Edges*; #907/#928 incident). List every open issue carrying a `req:N` label whose target #N carries `type:spec`, and emit **one warn line per offending edge** (`⚠️ #<dependent> req:<N> → #<N> is type:spec — re-point at its spec:<N> slices`). Resolve it read-only: for each `req:*` label in use (`gh label list --search req:` or scan `gh issue list --label req:<n>`), check the target's labels with `gh issue view <N> --json labels`; a target with `type:spec` is a finding. Report `✅` when no `req:<Spec>` edge exists, `⚠️` with the count and per-edge lines otherwise. Tag `→ /triage` (re-point each offending edge). During this read-only pass: never edit a label.
59
+ 15. **Native blocked-by vs `req:N` divergence audit** — ADR 0094 deliberately keeps two dependency surfaces: native GitHub blocked-by edges for humans and `req:N` labels for the AFK runtime. Compare them across open Tickets (exclude parent Specs carrying `type:spec`) and emit one warn line per divergent edge in either direction: native blocked-by edge without the matching `req:N` label, or `req:N` label without the matching native blocked-by edge.
60
+
61
+ Concrete read path (read-only GETs only, matching `/red-setup` issue-tracker-github *Dependency & hierarchy operations*):
62
+
63
+ ```bash
64
+ gh issue list --state open --json number,labels \
65
+ --jq '.[] | select(([.labels[].name] | index("type:spec")) | not) | {number, labels: [.labels[].name]}'
66
+
67
+ gh api "repos/{owner}/{repo}/issues/<ticket-number>/dependencies/blocked_by" \
68
+ --jq '.[] | {number, id, state, title}'
69
+ ```
70
+
71
+ Run the second command once for each open non-Spec Ticket from the first command. Build the injected audit input as one object per Ticket:
72
+
73
+ ```ts
74
+ { number: <ticket-number>, labels: ["req:<blocker-number>", ...], nativeBlockedBy: [<blocker-number>, ...] }
75
+ ```
76
+
77
+ `labels` comes from the `gh issue list` row. `nativeBlockedBy` comes from the `number` fields returned by the Ticket's `dependencies/blocked_by` endpoint. Do not use `issue_dependencies_summary.blocked_by` for this check; it is only a count and cannot populate the blocker list. Feed the resulting array to `auditDependencyEdges()` and report `✅` when every open Ticket's native blocked-by set equals its `req:N` label set, or `⚠️` with the count and per-Ticket lines otherwise. Tag `→ /triage` (refresh dependency metadata so both surfaces match). The pure classifier is `apps/dev/src/core/dependency-edge-doctor.ts` (`auditDependencyEdges`); every GitHub fact is injected, and the check is read-only. During this read-only pass: never add/remove labels and never create/delete native edges.
78
+ 16. **Native sub-issue vs `spec:N` divergence audit** — ADR 0094 also keeps two hierarchy surfaces: native GitHub sub-issue edges for humans and `spec:N` labels for the AFK runtime. Walk open plus recently-closed Specs carrying `type:spec`, compare every label-child carrying `spec:<Spec>` against the Spec's native sub-issues, and emit one warn line per divergent edge in either direction: `spec:N` child without the matching native sub-issue edge, or native sub-issue child without the matching `spec:N` label. Also flag a Spec that still carries `needs-slicing` once it has at least one `spec:N` child. Concrete read path (read-only GETs only):
79
+
80
+ ```bash
81
+ gh issue list --label type:spec --state all --json number,state,closedAt,labels
82
+ gh issue list --label spec:<spec-number> --state all --json number,labels
83
+ gh api "repos/{owner}/{repo}/issues/<spec-number>/sub_issues" \
84
+ --jq '.[] | {number, id, state, title}'
85
+ ```
86
+
87
+ Build the injected audit input as one object per Spec:
88
+
89
+ ```ts
90
+ { number: <spec-number>, labels: ["type:spec", ...], labelChildren: [<ticket-number>, ...], nativeSubIssues: [<ticket-number>, ...] }
91
+ ```
92
+
93
+ Feed the resulting array to `auditSpecSubIssueEdges()` and report `✅` when every Spec's `spec:N` child set equals its native sub-issue set, or `⚠️` with the count and per-Spec lines otherwise. Tag `→ Spec sub-issue reconciler`. The pure classifier and fixer live in `apps/dev/src/core/spec-subissue-reconciler.ts` (`auditSpecSubIssueEdges`, `executeSpecSubIssueReconcile`); every GitHub fact is injected. During this read-only pass: never add/remove labels and never create/delete native edges.
94
+ 17. **ask-red router coverage sync** — compare the registered dev skill names from the plugin manifest with the slash-command names covered by `plugins/dev/skills/engineering/ask-red/SKILL.md`. Emit one warn line for each registered skill missing from the router and each stale router entry that no longer names a registered skill. Report `✅` when both sets match, `⚠️` with the finding count otherwise. Tag `→ ask-red maintenance rule` (update the router's Coverage Inventory and route text). The pure classifier is `apps/dev/src/core/ask-red-router-doctor.ts` (`auditAskRedRouterCoverage`); every manifest and router fact is injected, and the check is read-only. During this read-only pass: never edit manifests and never rewrite `ask-red`.
95
+ 18. **Required host binaries** — verify the host has every required pinned binary recorded by `/red-setup`. For ADR 0097, `tq` is mandatory: compare the catalog-derived pin, recorded config pin, and observed `tq --version` fact by reading the catalog-derived `@reddb-io/toon` version, `.red/config.yaml` `host_binaries.tq.version` (pin `0.3.0`), and the observed `tq --version` fact. Report `❌` when `tq` is absent, or when any pairwise mismatch produces `toolchain-drift`; the drift finding names all three values. Absence or version drift is a red finding, not a warning, because there is no jq fallback for RedSkills-owned TOON/TOONL logs. Tag `→ /red-setup` and print the canonical fix from the catalog-derived v-prefixed tag: `TQ_VERSION=v0.3.0 curl -fsSL https://raw.githubusercontent.com/reddb-io/toon/v0.3.0/install.sh | sh`. The pure classifier is `apps/dev/src/core/host-binary-doctor.ts` (`auditHostBinaries`); every catalog, config, and observed host fact is injected. During this read-only pass: never run installer scripts during Pass 1, never mutate `.red/config.yaml`, and never offer a jq fallback.
96
+ 19. **.red lifecycle taxonomy + tmp janitor** — audit the target repo's `.red/` tree against ADR 0098's lifecycle tiers and named lane registry. Emit one taxonomy finding for each violation: a loose file directly under `.red/tmp/` (target `.red/tmp/scratch/`), a directory directly under `.red/tmp/` that is not in the lane registry (target a registered `.red/tmp` lane or extend ADR 0098), a known durable-state filename still living under `.red/tmp/` (target the matching `.red/state/*` lane or file), and a top-level `.red/` directory not documented by ADR 0098 (target a documented tier or an ADR extension). Also report reclaimable tmp state from the ADR 0098 janitor: stale worker dirs whose represented issues are closed and whose `worker.pid` is not live, expired managed lanes from `planTmpJanitor` (`logs`, `scratch`, `diagnostics`, `worktrees/feedback`), and unknown tmp-root entries from `auditTmpRoot`. Report `✅` when no taxonomy or reclaimable-tmp findings exist, `⚠️`/`❌` with the finding count otherwise. Tag `→ ADR 0098 lane owner`. The pure taxonomy classifier is `apps/dev/src/core/red-taxonomy-doctor.ts` (`auditRedTaxonomy`); the janitor planner is `apps/dev/src/core/tmp-janitor.ts` and runtime adapter is `apps/dev/src/runtime/tmp-janitor.ts`. During the read-only pass: never move, delete, or create files; tmp janitor output is counts plus paths only.
97
+ 20. **Castle state lane** — audit the durable AFK castle state lane after the boot migration. When `.red/state/castle/` is present, validate that present `history.toonl` and `validation.toonl` files are TOON-decodable against the castle contracts, and that `workers/<id>/state.toon` / `supervisors/<id>/state.toon` snapshot directories decode as `red.castle.state.v1` with matching `kind` and `id`. Flag a populated legacy `.red/state/afk/` directory only when a live castle lane also exists — that is post-migration residue, not a repo with no AFK history. Repos with no castle lane and no legacy AFK lane pass clean. Tag `→ red-path-migration`. The classifier is `apps/dev/src/core/castle-state-doctor.ts` (`auditCastleStateLane`). During this read-only pass: never rewrite history, validation, or snapshots; never delete legacy residue.
98
+ 21. **Unlanded `.red/` docs** — detect glossary/ADR docs that exist in the primary checkout but are not landed on `origin/{base}`. Use the shared Docs Sweep detector (`apps/dev/src/core/docs-sweep.ts` via `apps/dev/src/core/unlanded-docs-doctor.ts`); never implement a second `.red/` docs comparison. The read path fetches/verifies `origin/{base}` first, compares the same doc paths as the ADR 0092 finalizer (`.red/CONTEXT.md`, `.red/CONTEXT-MAP.md`, `.red/contexts/**`, `.red/adr/**`), includes untracked files, and reports a scorecard finding with the rendered file list (`state:path`). Report `✅` when the shared detector is clean, `⚠️` when docs can be landed, and `❌` when the detector halts because origin is unreachable or a zero-precedent ignored doc cannot be safely landed. Tag `→ ADR 0092 doc-landing lane`. The doctor helper is pure and IO-free; every git/GitHub fact and the lander are injected. During this read-only pass: never create a branch, push, open a PR, merge, or mutate the primary checkout.
99
+ 22. **Operational probe registry** — run the shared operational probe registry (`apps/dev/src/core/operational-probes.ts`), the same surface fleet boot consumes after precheck. Report one row per probe and one finding per red probe, always naming the probe, evidence, and canonical fix. The first proof probe is the local HTTPS-remote refusal: local AFK boot requires SSH remotes unless the Actions lane explicitly allows HTTPS. Tag `→ operational probe registry`. During this read-only pass: never rewrite remotes and never execute a fix; `--fix` owns gated remediation. AI-facing output is TOON.
100
+
101
+ **Scorecard** (always printed): one row per check (✅/⚠️/❌ + one-line evidence) + a readiness score (count of green checks, like `context-status`) + a prioritized recommendation list, **every recommendation carrying a fix-home tag** from the *Fix-home* table. End with the single highest-impact next step.
102
+
103
+ ### Pass 2 — Fix (only with `--fix`; gated apply)
104
+
105
+ For **every** non-green finding from Pass 1, apply its canonical fix. Running with `--fix` → read [`APPLY.md`](APPLY.md) for the per-finding action and gate. There is no finding the doctor reports but cannot heal: each row maps to a concrete action or a delegation to the single-writer tool that owns it.
106
+
107
+ The loop:
108
+
109
+ 1. **Group the findings** into **safe** (idempotent, low-blast-radius) and **hard-to-reverse** (per the gate column in [`APPLY.md`](APPLY.md)).
110
+ 2. **Apply the safe batch** — run each safe fix, print a one-line receipt per action (`✅ created label needs-triage`, `✅ injected ## Development workflow into AGENTS.md`, …). Re-running is a no-op.
111
+ 3. **Confirm each hard-to-reverse fix individually** — show the exact mutation (the `gh label rename old new` that re-tags N issues, the config-key migration, the `blocked:*` removal on issue #N, the `.mcp.json` edit) and apply only on an explicit yes. A no leaves that finding open and recorded.
112
+ 4. **Delegate** what a single-writer tool owns — a version mismatch runs the version/release tool (never a manual manifest edit); context-stack gaps run the `memory`/context skills. `--fix` triggers the tool, then re-checks.
113
+ 5. **Re-diagnose** the touched checks and print a fix receipt: what was applied, what was confirmed-then-applied, what was skipped (declined), and the new readiness score.
114
+
115
+ </what-to-do>
116
+
117
+ <supporting-info>
118
+
119
+ ### Label classes (check 2)
120
+
121
+ | Class | Meaning | Action |
122
+ |---|---|---|
123
+ | ❌ non-canonical synonym | duplicates a canonical role under a different name (`needs-human-decision` ↔ `ready-for-human`) | rename to the canonical role |
124
+ | ⚠️ legacy / superseded | older form replaced by a newer one (bare `blocked` vs typed `blocked:<reason>`) | migrate + retire |
125
+ | ⚠️ naming violation | not kebab-case nor `prefix:value` (uppercase / CamelCase / snake_case / spaces) | normalize |
126
+ | ✅ accepted aux | outside the triage families but legitimate (language labels, repo-custom like `drill`, `release-blocker`) | none |
127
+ | ✅ GitHub default | `bug`, `enhancement`, `documentation`, `duplicate`, `good first issue`, `help wanted`, `invalid`, `question`, `wontfix` | none |
128
+
129
+ Canonical families live in the target repo's `.red/agents/triage-labels.md`: state (`needs-triage`, `needs-info`, `ready-for-agent`, `running`, `ready-for-human`, `wontfix`), dependency (`blocked:dependency`, `req:N`), typed blocked-reasons (`blocked:quota|runner-transient|merge-conflict|spec|validation|crashed|policy|stalled|infra`), type (`type:spec`, `type:bug`, `needs-slicing`), priority (`priority:high|low|urgent`), relationship (`spec:N`), operational (`runner-error`).
130
+
131
+ ### Operational probe families
132
+
133
+ Check 21 is the shared operational probe registry (`apps/dev/src/core/operational-probes.ts`). The registry is the source of truth for what it checks, the evidence it shows, and the canonical fix text. `/red-doctor` renders the probes read-only by default; destructive fixes are individually gated under `--fix` by each probe's `fix.gate: "confirm"` contract. If a probe has no wired automated fixer, `--fix` reports a `noop` receipt instead of inventing a mutation.
134
+
135
+ | Probe id | Probe name | What it checks | Evidence it shows | Fix authority |
136
+ |---|---|---|---|---|
137
+ | `git.remote.https-forbidden` | SSH-only git remotes | Local AFK boot is not using HTTPS git remotes unless the Actions lane explicitly sets `allowHttpsRemote`. | Count of forbidden HTTPS remotes; named remotes also carry the SSH rewrite target in probe data. | Confirm before rewriting named remotes to SSH; otherwise use SSH manually or run in the Actions lane. |
138
+ | `afk.queue-visibility` | AFK queue visibility | The AFK engine and REST queue readers can both list the open queue and agree on the count. | Transport class (`sso-or-scope`, `rate-limit`, GraphQL/REST/generic transport) or engine-vs-REST counts. | No mutation; repair GitHub auth, SSO, rate limits, or network reachability, then restart `/afk`. |
139
+ | `afk.focal-branch-resolution` | AFK focal branch resolution | The resolved focal branch from branch-lock, pin, or trunk is coherent and any branch-lock target still exists or is live-held. | Resolved branch/source, configured trunk, raw lock value, target existence, and live-holder state. | Confirm before clearing a stale branch-lock; live intentional locks stay in place. |
140
+ | `afk.base-freshness` | AFK local trunk freshness | The local trunk is not behind `origin/<trunk>` before autonomous work starts. | Local/remote SHAs when known, ahead/behind counts, and the shared finalizer guard verdict. | Fleet boot auto-applies the fast-forward when the guard says on-trunk, clean tree, and local ancestor; `red-doctor --fix` still confirms before applying the same guarded repair manually. |
141
+ | `afk.fleet-truth` | AFK fleet truth | The recorded fleet supervisor pid, heartbeat/state freshness, and bundle version describe a live, current fleet. | Pid liveness, heartbeat/state ages, threshold, bundle/latest version, and finding kind (`zombie`, `version-skew`, `version-unknown`). | Confirm before SIGTERM for a zombie supervisor; optional relaunch is separately confirmed. |
142
+ | `afk.bundle-coherence` | AFK bundle coherence | The stable pointer, newest cached lane bundle, npm newest same-major version, and last self-update check are coherent. | Installed, pointer, lane, and npm versions plus stale failed-check evidence. | No mutation; run any dev shim to reconcile pointer-vs-lane, let self-update retry or warm the package cache, then restart stale fleets. |
143
+ | `afk.claim-hygiene` | AFK claim hygiene | Open queue issues do not carry dangling claim markers from this machine's dead workers, foreign namespaces, or unknown own workers. | Issue number, marker comment id, namespace, worker, and pid state, plus live/unknown counts. | Confirm per issue before posting concede markers for dead own-namespace workers; foreign markers are reported only. |
144
+ | `afk.label-body-coherence` | AFK label/body coherence | `ready-for-agent` issues do not still carry an active `Current blocker` section in their body. | Issue number, labels, blocker kind/ref/summary/next. | Confirm per issue before archiving the blocker into resolved history and clearing the current blocker. |
145
+ | `config.coherence` | Config coherence | The real config loader successfully parsed `.red/config.yaml`, did not discard it for defaults, and root-level folded accessor spellings do not shadow the canonical `plugins.dev.*` block. | Loaded file, malformed line/construct when parse fallback happened, off-contract root keys with canonical relocation, or healthy resolved trunk/gate/lock values. | Confirm after diff preview before relocating root-level blocks to `plugins.dev.*`; malformed syntax is reported with the offending line/construct and must be repaired before boot. |
146
+
147
+ **Fleet boot refusal.** The fleet boot path runs the same operational probe registry after precheck. If `afk.base-freshness` is red and its own shared finalizer guard already passed, boot auto-applies that fast-forward, logs the before/after SHAs, and continues. If any other probe is red, or base-freshness is red with a refused guard, boot raises `BootHaltError("operational-probe")`, prints the probe name, evidence, and canonical fix, and refuses to spawn workers. This is intentional: the registry catches operational states that would make a drain misleading or unsafe before the queue is claimed. Doctor can show the same finding without changing anything, and `red-doctor --fix` can apply only the probe-owned, confirmed repairs.
148
+
149
+ ### Fix-home (every Pass-1 recommendation carries one)
150
+
151
+ | Fix-home | Findings it owns |
152
+ |---|---|
153
+ | `→ /red-setup` | AGENTS≡CLAUDE `## Agent skills` parity, AGENTS≡CLAUDE `## Development workflow` parity, `dev.lock.primary-branch` adoption, statusline drift, MCP wiring, label provisioning, `.red/.gitignore` self-ignore, workflow naming-convention drift (`reusable-*`/`rs-*`/`red-*` by role) + AFK-lane auth gap, AFK hook/backpressure static-validation findings (stale `package.json` script, missing file, unknown hook name), required host binaries (`tq` missing or drifted from the pinned `TQ_VERSION`). |
154
+ | `→ AFK runtime` | `blocked:*` accumulation (labels must be rotated/cleared on re-queue, plus the re-claim cap) — a bundle change, not a config edit. |
155
+ | `→ launcher fetch` | per-plugin runtime distribution findings (`runtime-missing`, `inert-marker`, `version-drift`, `cache-corrupt`) — the cache is owned by the launcher (`red-fetch`/`afk.mjs`, ADR 0034/0038), never hand-edited. |
156
+ | `→ /triage` | `req:<Spec>` dependency edges (check 14) — re-point each offending edge at the target Spec's executable slices; native blocked-by vs `req:N` divergence (check 15) — refresh dependency metadata so both surfaces match. `/triage` owns the authoring validation. |
157
+ | `→ Spec sub-issue reconciler` | native sub-issue vs `spec:N` divergence (check 16) — run the shared reconciler to attach missing native sub-issue edges and remove stale `needs-slicing` from Specs that already have slices. |
158
+ | `→ ask-red maintenance rule` | ask-red router coverage sync (check 17) — update `plugins/dev/skills/engineering/ask-red/SKILL.md` when skills or flows change. |
159
+ | `→ ADR 0098 lane owner` | `.red` lifecycle taxonomy (check 19) — move content through the writer that owns the source/target lane, or amend ADR 0098 before introducing a new top-level directory or tmp lane. |
160
+ | `→ red-path-migration` | castle state lane findings (check 20) — run the dev durable path migration entrypoint so `.red/state/castle/` is the single live AFK state lane; never hand-delete ambiguous residue. |
161
+ | `→ ADR 0092 doc-landing lane` | unlanded `.red/` docs (check 21) — land exactly one `docs:` PR from an isolated docs worktree, then merge it so `origin/{base}` carries the docs AFK workers need. |
162
+ | `→ operational probe registry` | red operational probes (check 22) — use the probe's own canonical fix. Adding a probe requires only its module plus one registry entry; doctor and fleet boot consume the registry generically. |
163
+ | `→ manual / maintainer` | label renames (`gh label edit`), retiring legacy labels — the operator decides. |
164
+ | `→ release` | cross-manifest version mismatch — owned by the single-writer version script + `validate-install-metadata.sh` gate (ADR 0040); never hand-edit one manifest. |
165
+
166
+ ### Scope & boundaries
167
+
168
+ - **Single repo** by default; multi-repo sweep is opt-in. With `--fix`, a sweep applies per-repo with the same gating.
169
+ - **Public-repo safe**: reads only conventions already public in the repo; **emits no secret values** (it may list secret *names* via `gh secret list` to detect the AFK-lane auth gap — names are not sensitive — and never reads or prints a value). It does **not** impose RedSkills' own `red-*` CI (release/bench/drift-guard/upstream-watch) onto an adopter repo — that stays out of scope. What it *does* audit is the **adoption coherence of `rs-*` workflows already installed** (correct installed-name + the AFK lane's auth secret), never installing a lane the repo didn't opt into.
170
+ - Pairs with `/review-adrs` (decision-record coherence) and `memory:doctor` (graph health) — three doctors over different axes; this one owns **process/adoption** and is the one that can both diagnose and, with `--fix`, heal.
171
+
172
+ </supporting-info>
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: red-gains
3
+ description: Shows the detailed rsp usage-gains report from the shared RedDB telemetry store. Use when the user invokes `/red-gains`, asks whether rsp is paying for itself, wants token-savings trends, latency percentiles, throughput heatmaps, degradation history, or which wrapped command saves the most tokens.
4
+ argument-hint: "[--since 28d]"
5
+ disable-model-invocation: true
6
+ ---
7
+
8
+ # /red-gains
9
+
10
+ <what-to-do>
11
+
12
+ **Run the shim** — execute `rsp gains [--since 28d]` from the current repo.
13
+
14
+ **Summarize the signal** — render a human-readable report with four highlights:
15
+ trend, anomalies, which command pays the bill, and whether health degraded.
16
+
17
+ **Keep the source visible** — preserve the TOON facts from `rsp gains`; do not
18
+ invent numbers that are absent from the telemetry store.
19
+
20
+ </what-to-do>
21
+
22
+ <supporting-info>
23
+
24
+ ## Report Shape
25
+
26
+ `rsp gains` reads `rsp_telemetry_invocations_v1` and
27
+ `rsp_telemetry_degradations_v1` from the shared RedDB store and emits TOON with:
28
+
29
+ - latency: global and per-command-family wrapper percentiles.
30
+ - throughput: requests per day, active-minute average, peak minute, and
31
+ hour-by-weekday activity.
32
+ - savings: weekly tokens saved, week-over-week delta, elision rate, top command
33
+ families by tokens saved and invocation count, and the single biggest elision.
34
+ - health: degradation timeline plus cold-boot and warm-hit counts when
35
+ telemetry contains enough resident-store metrics.
36
+
37
+ ## Empty And Short Windows
38
+
39
+ Empty stores are definitive states, not errors. Report them as "no rsp telemetry
40
+ in this window".
41
+
42
+ Short windows are normal after setup or pruning. Use the `window.label` value,
43
+ for example "window: 28d, data: 3d", so the reader sees requested history
44
+ versus available history.
45
+
46
+ For rsp hook silence, resident/store splits, and store-growth recovery, see
47
+ [TROUBLESHOOTING.md](../../../../../apps/rsp/docs/TROUBLESHOOTING.md).
48
+
49
+ </supporting-info>
@@ -0,0 +1,266 @@
1
+ # Setup RedSkills Interview Reference
2
+
3
+ ## Present findings and ask
4
+
5
+ Summarise what's present and what's missing. Then walk the user through the sections **one at a time** — present a section, get the user's answer, then move to the next. Don't dump all sections at once.
6
+
7
+ Assume the user does not know what these terms mean. Each section starts with a short explainer (what it is, why these skills need it, what changes if they pick differently). Then show the choices and the default.
8
+
9
+ **Section A0 — Plugin activation — ask first (the per-directory gate)**
10
+
11
+ > Explainer: RedSkills plugins (`dev`, `memory`, `brain`) install their hooks **globally** on every agent (Claude Code, Codex, opencode), but they must only act in repos that explicitly opt in. Each plugin's hook launcher checks, before doing anything, whether the current directory's `.red/config.yaml` sets `plugins.<name>.enabled: true` (ADR 0067, strict opt-in). No `.red/config.yaml` → every RedSkills plugin stays fully inert here (no bundle fetch, no hooks, no side effects). A `plugins.<name>` block alone is **not** enough — the flag must be the explicit `true`.
12
+
13
+ Ask the user which plugins to enable in this repo (multi-select; `dev` is the usual baseline):
14
+
15
+ - **dev** — the engineering stack: `/afk`, `/triage`, `/go`, model-tier routing, branch-lock, statusline. Enabling it is what makes the rest of this setup meaningful; default yes.
16
+ - **memory** — governed operational memory (recall/store/graph). After enabling, run `/memory:init` to choose the storage mode. Default no.
17
+ - **brain** — the agentic command-center context. Default no.
18
+
19
+ Record the choice; it drives the `plugins:` block written in step 4. Disabling a previously-enabled plugin is also valid here — set its flag to absent/`false`. Creating `.red/` (if missing) is authorized by this section; never create it just to host one of the other sections — if the user enables no plugins, write nothing.
20
+
21
+ **Section A — Issue tracker.**
22
+
23
+ > Explainer: In every reddb.io repo, issues and Specs **always** live on GitHub Issues. Skills like `to-tickets`, `triage`, `to-spec`, and `qa` call `gh issue create` / `gh issue edit` directly. There is no local fallback and no support for other trackers — this is a project-wide policy.
24
+
25
+ Confirm that `git remote` points to a GitHub repo, then proceed with the `issue-tracker-github.md` seed. If the repo has no GitHub remote, stop and ask the user to configure one before continuing.
26
+
27
+ **Section B — Triage label vocabulary.**
28
+
29
+ > Explainer: When the `triage` skill processes an incoming issue, it moves it through a state machine — needs evaluation, waiting on reporter, ready for an AFK agent to pick up, ready for human decision/resolution, dependency-blocked, or won't fix. To do that, it needs to apply labels (or the equivalent in your issue tracker) that match strings *you've actually configured*. If your repo already uses different label names (e.g. `bug:triage` instead of `needs-triage`), map them here so the skill applies the right ones instead of creating duplicates. Labels should belong to a clear family: current state, permanent type, priority, relationship/dependency, or operational diagnostic.
30
+
31
+ The canonical state roles:
32
+
33
+ - `needs-triage` — maintainer needs to evaluate
34
+ - `needs-info` — waiting on reporter
35
+ - `ready-for-agent` — fully specified, AFK-ready (an agent can pick it up with no human context)
36
+ - `ready-for-human` — needs human decision/resolution before it can proceed or be delegated
37
+ - `blocked:dependency` — waiting on other issues (via `req:N` edges); never pages a human; auto-unblocks when the last dep closes
38
+ - `wontfix` — will not be actioned
39
+
40
+ Do not provision or preserve labels outside the accepted label families; HITL/AFK routing is represented by `ready-for-human` / `ready-for-agent`.
41
+
42
+ Default: each role's string equals its name. Ask the user if they want to override any. If their issue tracker has no existing labels, the defaults are fine.
43
+
44
+ **Section C — Domain docs.**
45
+
46
+ > Explainer: Some skills (`improve-codebase-architecture`, `diagnose`, `tdd`) read a `.red/CONTEXT.md` file to learn the project's domain language, and `.red/adr/` for past architectural decisions. They need to know whether the repo has one global context or multiple (e.g. a monorepo with separate frontend/backend contexts) so they look in the right place.
47
+
48
+ Confirm the layout:
49
+
50
+ - **Single-context** — one `.red/CONTEXT.md` + `.red/adr/` at the repo root. Most repos are this.
51
+ - **Multi-context** — `.red/CONTEXT-MAP.md` at the root pointing to per-context `.red/CONTEXT.md` files (typically a monorepo).
52
+
53
+ **Section D — Workflows.**
54
+
55
+ > Explainer: RedSkills ships GitHub Actions workflows that close gaps in the manual flow. The most important one is `red-issues-needs-triage.yml` — it auto-applies the `needs-triage` label to any newly opened or reopened issue that has no labels yet, so fresh reports never slip past `/triage` and never sit invisible to `/afk` (which only drains `ready-for-agent`). When we **install** a workflow into a consumer repo we rename it `red-skills-<name>.yml` so the adopter can tell our workflows from its own CI. The rename is filename-only — see [WORKFLOWS.md](./WORKFLOWS.md) for the full three-prefix convention (`reusable-*` reusables / `rs-*` installed copies / `red-*` red-skills' own CI).
56
+
57
+ This section is a **menu, not an all-or-nothing**. Ask the user which workflows they want and, for any opt-in lane, which configs — never install a lane the user didn't pick. Default each workflow as marked below and let them override.
58
+
59
+ Confirm with the user:
60
+
61
+ - Install `red-issues-needs-triage.yml` (verbatim — name unchanged; it is a standalone `red-*` copy-installable, not a reusable caller) into `.github/workflows/`? Default: yes.
62
+ - Does the `needs-triage` label exist in the issue tracker? If not, create it (`gh label create needs-triage --description "Maintainer needs to evaluate"`).
63
+ - Does the `runner-error` label exist? If not, create it (`gh label create runner-error --color B60205 --description "AFK supervisor circuit-tripped; runner was misconfigured"`). The `/afk` fleet supervisor falls back to creating it on the fly during a circuit trip, but provisioning it here keeps colour/description consistent across repos.
64
+ - Does the `blocked:dependency` label exist? If not, create it (`gh label create blocked:dependency --color D4C5F9 --description "Waiting on other issues (req:N edges); auto-unblocks when the last dependency closes"`). `req:N` edge labels are created on demand by `/to-tickets` (`gh label create req:<n>`) like `spec:N`, so they need no upfront provisioning.
65
+ - Provision the Wayfinder labels `/wayfinder` uses to type map and child Tickets: `wayfinder:map`, `wayfinder:research`, `wayfinder:grilling`, `wayfinder:prototype`, and `wayfinder:task` (suggested colour `C5DEF5`). They are descriptive labels: AFK routing still comes only from `ready-for-agent` / `blocked:dependency`, and HITL routing still comes from `ready-for-human`.
66
+ - Provision the typed **blocked-reason** labels `/afk` applies to describe *why* an iteration stopped (it falls back to creating each on the fly, so this only keeps colour/description consistent): `gh label create blocked:quota`, `blocked:runner-transient`, `blocked:merge-conflict`, `blocked:ci`, `blocked:spec`, `blocked:validation`, `blocked:crashed`, `blocked:policy`, `blocked:stalled`, `blocked:infra` (suggested colour `E99695`, descriptions per the *Blocked Reasons* table in triage-labels). These are descriptive (added alongside the routing label) — see triage-labels.
67
+ - Does the `landing:manual` label exist? If not, create it idempotently (`gh label create landing:manual --color FBCA04 --description "AFK runs the full pipeline + opens the PR, then holds for a human's merge click (no auto-merge)"`). A `ready-for-agent` issue carrying it stays in the autonomous `/afk` lane but parks `ready-for-human` with the open PR instead of auto-merging — so agent-codable slices that must not be auto-merged (e.g. changes to AFK's own landing/claim machinery) no longer have to be hand-dispatched via `/go` (issue #1049). `/triage` may set it at brief-writing time; `/hitl`'s **delegable-manual-landing** disposition routes an issue here.
68
+
69
+ **Autonomous AFK execution lane (opt-in — default NO).** Beyond auto-triage, RedSkills can run `/afk` itself **from GitHub Actions** — one attempt per issue, opening a PR with no human at a terminal (the "offline" / headless lane, ADR 0059/0062). This is a bigger commitment than auto-triage, so it is **off by default**. Offer it, defaulting to no:
70
+
71
+ - Install the AFK Actions lane (the caller, as `rs-afk-attempt.yml`) into `.github/workflows/`? **Default: no.** Explain the prerequisites before a yes, and ask which configs to use:
72
+ - **Secrets** — one OpenCode auth key as a repo secret. Ask which provider the user runs, then which key to wire (first set wins): `MINIMAX_API_KEY` (`minimax/<model>`), `OPENAI_API_KEY` (`openai/<model>`), or `OPENROUTER_API_KEY` (`openrouter/<vendor>/<model>`). Without one the lane fires but the agent fails auth. **Public-repo gotcha:** org secrets are *not* shared with public repos by default — if the repo is public, the key must be a **repo secret** or an org secret whose "Repository access" includes this repo, else it resolves empty with no error. Full secret guide: [`../afk/actions-lane.md`](../afk/actions-lane.md#configuring-secrets-per-provider).
73
+ - **Model** — ask which `<provider>/<model>` slug to pin in the caller (e.g. `minimax/MiniMax-M3`), or leave empty to use the repo's `.red/config.yaml` model config.
74
+ - **Trust gate** — ask for the allowlisted issue-author + label-applier logins (you set them). Public repos: keep the allowlist to yourself + your bot.
75
+ - **Triggers** — ask whether they want the manual `workflow_dispatch` caller, the `issues: labeled` auto-trigger, or both. Fires on `ready-for-agent` (labeled, or an issue opened already carrying it) / manual dispatch.
76
+ - Full reference: [`../afk/actions-lane.md`](../afk/actions-lane.md).
77
+
78
+ Future RedSkills workflows land in this same step, following the same three-prefix convention ([WORKFLOWS.md](./WORKFLOWS.md)).
79
+
80
+ **Section E — Token efficiency (strongly recommended).**
81
+
82
+ > Explainer: A huge fraction of an agent's token budget gets burned on noisy CLI output — `git status` on a dirty branch, large `git diff` / `git log` output, verbose `gh` lists, and long test failures. `rsp` is the repo-owned token-efficiency surface: explicit wrappers for supported commands, reversible elision handles for lossy summaries, and an opt-in hook rewrite table that lives in the same binary as the wrappers.
83
+
84
+ Strong recommendation: enable `rsp` whenever `dev` is enabled. The hook remains inert unless this repo's `.red/config.yaml` has `rsp.enabled: true`; absent that opt-in, agents can still call the explicit wrappers.
85
+
86
+ Teach the user the wrapper surface:
87
+
88
+ ```bash
89
+ rsp git status
90
+ rsp git diff --brief
91
+ rsp git log --terse
92
+ rsp gh pr list --query open
93
+ rsp gh issue view 123
94
+ rsp vitest --terse
95
+ rsp cargo test --brief
96
+ rsp show el:<id>
97
+ ```
98
+
99
+ The loss levels are:
100
+
101
+ 1. **Default/lossless.** Emit TOON summaries for supported commands. Large `git diff` and `git log` output is threshold-gated and truncates by default when it exceeds the configured byte threshold.
102
+ 2. **`--brief`.** Prefer a compact inline summary for normal debugging.
103
+ 3. **`--terse`.** Keep only the smallest useful inline view and mint an `el:<id>` handle for the omitted bytes. `rsp show el:<id>` writes the original bytes verbatim to stdout; expired handles print the original command to re-run.
104
+
105
+ Three things to verify after setup:
106
+
107
+ 1. **Repo store is provisioned.** `rsp` with no arguments should print store stats. If it says the repo store is not provisioned, finish `/red-setup` so `.red/state/red-skills.rdb` exists.
108
+ 2. **Config opt-in is explicit.** `.red/config.yaml` should carry `rsp.enabled: true`, `rsp.ttlDays: 7`, `rsp.ephemeralTtlHours: 6`, and `rsp.byteBudget: 67108864` unless the operator deliberately changed retention.
109
+ 3. **Hook behavior is scoped.** In opted-in repos, the pre-exec hook may rewrite simple supported commands such as `git status`, `gh pr list`, `vitest`, and `cargo test` to their `rsp` forms. In non-opted-in repos, the hook is inert and agents should call `rsp` explicitly only when available.
110
+
111
+ The per-host ambient instruction surface that replaces legacy host-local terminal guidance is tracked in #1415 and generated from `apps/rsp/generated/AMBIENT-SKILL.md`; do not block setup on it.
112
+
113
+ **Section E1 — Runtime launcher (strongly recommended).**
114
+
115
+ > Explainer: `CLAUDE_PLUGIN_ROOT`, `CODEX_PLUGIN_ROOT`, and similar variables are plugin/hook environment variables. They are not guaranteed in the interactive shell where an agent runs `/afk`, `/go`, `/dashboard`, or `/retake`. Setting those names globally is brittle because they point at versioned plugin-cache directories and can become stale after an update. The cross-CLI surface should be a stable command, not a global fake plugin-root variable.
116
+
117
+ Offer to install the host-level runtime shim:
118
+
119
+ ```bash
120
+ bash plugins/dev/skills/engineering/red-setup/scripts/install-runtime-shim.sh
121
+ ```
122
+
123
+ The script writes `${XDG_BIN_HOME:-$HOME/.local/bin}/red-skills-dev` and `${XDG_BIN_HOME:-$HOME/.local/bin}/rsp`. The `red-skills-dev` shim:
124
+
125
+ - prefers the active CLI plugin-root env var when the host exposes one;
126
+ - otherwise finds the latest installed dev plugin under `~/.codex/plugins/cache/red-skills/dev/*` or `~/.claude/plugins/cache/red-skills/dev/*`;
127
+ - falls back to the latest warmed dev bundle under `~/.cache/red-skills/bundles/`;
128
+ - forwards all arguments to the dev runtime, so skills can say `red-skills-dev go ...`, `red-skills-dev dashboard`, or `RED_AFK_RUNNER=codex red-skills-dev monitor --once`;
129
+ - stores no secrets and does not replace the `.red/config.yaml` opt-in gate.
130
+
131
+ The `rsp` shim uses the same local-first shape: active plugin-root env var, installed host plugin cache, then the warmed rsp bundle under `${RED_SKILLS_CACHE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/red-skills/bundles}`. It never runs npm, installs a global package, or performs network resolution during session startup.
132
+
133
+ After installing, verify:
134
+
135
+ ```bash
136
+ command -v red-skills-dev
137
+ command -v rsp
138
+ red-skills-dev dashboard --json
139
+ rsp git status
140
+ ```
141
+
142
+ If `command -v` cannot find it, add `${XDG_BIN_HOME:-$HOME/.local/bin}` to the shell `PATH`. Do not export `CLAUDE_PLUGIN_ROOT` or `CODEX_PLUGIN_ROOT` globally as a substitute.
143
+
144
+ **Section E2 — Required host binaries (mandatory).**
145
+
146
+ > Explainer: TOON/TOONL files are first-class RedSkills state. `tq` is the jq-for-TOON CLI from `github:reddb-io/toon`; after ADR 0097 there is no jq fallback for RedSkills-owned TOON/TOONL logs. A host without the pinned `tq` cannot inspect its own TOONL state, so setup installs the binary and records the expected version for `/red-doctor`.
147
+
148
+ Install the pinned `tq` through the toon repo's checksum-verified installer:
149
+
150
+ ```bash
151
+ TQ_VERSION=v0.3.0 curl -fsSL https://raw.githubusercontent.com/reddb-io/toon/v0.3.0/install.sh | sh
152
+ ```
153
+
154
+ Then verify:
155
+
156
+ ```bash
157
+ tq --version
158
+ ```
159
+
160
+ The installed version must be `0.3.0`. Record the same pin in `.red/config.yaml` under `host_binaries.tq.version` so `/red-doctor` can red-flag absence or drift and print the same canonical installer fix. Do not document or offer a jq fallback.
161
+
162
+ **Section F — RedSkills statusline (optional).**
163
+
164
+ > Explainer: RedSkills has one shared statusline producer in the dev bundle: the `statusline` subcommand reads each worker's `.red/tmp/workers/*/*/afk.state.json`, filters by `kill -0` liveness, sums diffstats locally, and caches GitHub-derived counts for 60 s to stay under the ~100 ms refresh budget. Host adapters differ. Claude Code can run that producer through a command-backed `statusLine`, so it can show live worker count, queue depth, and aggregated diffstat at a glance. Codex currently exposes native `tui.status_line` footer widgets instead of a command hook; under Codex, use `$red-statusline` to inspect or configure the footer and rely on `/afk monitor` for the live AFK block.
165
+
166
+ Decide whether to wire it up for this project:
167
+
168
+ - **Skip when** the per-project plugin config (`.red/config.yaml`) sets `afk.statusline: false`. Detect with `grep -qE '^[[:space:]]*statusline:[[:space:]]*false[[:space:]]*$'` on the `afk:` block (or use `yq` if available). When skipped, log a one-line notice (`afk.statusline: false in .red/config.yaml — skipping statusline wiring`) and move on.
169
+ - **Skip when** a `statusLine` entry is already present in `.claude/settings.json`. Do **not** overwrite — log a one-line notice (`statusLine already configured in .claude/settings.json — leaving as-is`) so the user can decide. Idempotency rule: re-running `/dev:red-setup` must never clobber a hand-edited statusline.
170
+ - **Otherwise** write the entry into `.claude/settings.json` (create the file if missing, merge with existing keys via `jq` if present):
171
+
172
+ ```json
173
+ {
174
+ "statusLine": {
175
+ "type": "command",
176
+ "command": "sh -c 'N=$(command -v node 2>/dev/null || ls -1 /usr/local/bin/node /opt/homebrew/bin/node /usr/bin/node \"$HOME\"/.volta/bin/node \"$HOME\"/.asdf/shims/node \"$HOME\"/.nodenv/shims/node \"$HOME\"/.nvm/versions/node/*/bin/node \"$HOME\"/.local/share/fnm/node-versions/*/installation/bin/node \"$HOME\"/.fnm/node-versions/*/installation/bin/node 2>/dev/null | sort -V | tail -1); b=$(ls -1 \"$HOME\"/.cache/red-skills/bundles/dev-*.bundle.min.mjs 2>/dev/null | sort -V | tail -1); [ -z \"$b\" ] && b=$(ls -1 \"$HOME\"/.claude/plugins/cache/red-skills/dev/*/skills/engineering/afk/bin/afk.mjs 2>/dev/null | sort -V | tail -1); [ -n \"$b\" ] && [ -n \"$N\" ] && exec \"$N\" \"$b\" statusline'",
177
+ "refreshInterval": 5
178
+ }
179
+ }
180
+ ```
181
+
182
+ Do **not** use `$CLAUDE_PLUGIN_ROOT` here: Claude Code does not export it (nor `$CLAUDE_PROJECT_DIR`) to a `statusLine` command — only to plugin hooks and MCP/LSP subprocesses — so that form expands to an empty path and renders blank. Likewise, the command resolves `node` explicitly rather than a bare `exec node`: Claude Code runs the statusLine in a **non-interactive shell** that does not source the user's shell rc, so a Node installed through a version manager (nvm, fnm, volta, asdf, nodenv, …) is off `PATH` and bare `exec node` fails with `node: not found` — another silent blank. `command -v node` covers every host with Node on `PATH` (system package, Homebrew, no version manager); only when that misses does it scan the common install roots, newest wins. The command above is **cached-bundle-first**: it resolves the **highest-version already-fetched runtime bundle** (`ls -1 …/.cache/red-skills/bundles/dev-*.bundle.min.mjs | sort -V | tail -1` — `sort -V` picks the highest semver, NOT `ls -t | head -1` which picks newest-by-mtime and can resolve an OLD version when an older dir was touched/re-extracted more recently), and only falls back to the launcher `afk.mjs` from the plugin cache when no bundle is cached yet (first-ever install). Resolving the cached bundle directly keeps the network out of the hot path: since ADR 0038 the launcher does a synchronous download on a cold cache, so pointing the statusline straight at it means **every plugin update** blanks the line until the new bundle is fetched. The cached-bundle-first form keeps showing the last good bundle across updates without pinning a version. The project root is read from `workspace.project_dir` in the JSON Claude Code pipes on stdin (no argument needed). This subsection writes only the Claude Code adapter; the shared producer remains host-agnostic, and Codex's adapter lives in the `red-statusline` skill because it edits global `~/.codex/config.toml` rather than repo-local `.claude/settings.json`.
183
+
184
+ The script is no-op outside `/afk` sessions (it prints nothing when no live workers exist), so leaving the statusline wired up in non-AFK projects is harmless.
185
+
186
+ **Section G — `.red/config.yaml` template (automatic).**
187
+
188
+ > Explainer: `.red/config.yaml` is the per-project knob file that `/afk` and friends read at runtime. It holds the project's fallback runner, default fleet target, and per-detector opt-outs. The schema is documented by the loader shipped in PRD #16 and is forward-compatible (unknown keys are ignored). A fresh repo should land with a *commented* template of every v1 knob so the user discovers the available settings without reading docs — the file is a no-op until lines are uncommented.
189
+
190
+ No user decision here for the template itself — the skill scaffolds it whenever the file is missing. The one piece that is **not** optional is the `plugins:` activation block from Section A0: the file must carry `plugins.<name>.enabled: true` for each plugin the user enabled, or the globally-installed hooks stay inert (ADR 0067). If `.red/config.yaml` already exists, leave its existing content alone (any prior edits are project state — never clobbered) **except** for surgically adding/updating the `plugins.<name>.enabled` flags to match Section A0 — that targeted merge is the sole allowed exception to the no-clobber rule, since it is the whole point of re-running this skill to enable a plugin. See step 4 for the write rule.
191
+
192
+ The template carries a **commented `afk.backpressure`** block (#430 / PRD #429): an ordered list of shell commands (`npm run test`, `npm run lint`, …) AFK runs after the built-in feedback gate on every successful iteration — DONE and salvaged no-sentinel alike — where any non-zero exit blocks the merge and parks the issue to `ready-for-human`. It ships commented (a no-op until uncommented). **One optional offer:** when scaffolding a fresh template into a repo whose root (or a clearly primary package) `package.json` declares `test` and/or `lint` scripts, surface them and ask whether to pre-fill the block with the matching `npm run <script>` (or `pnpm`) lines — uncommented — instead of the commented placeholder. Only pre-fill on explicit confirmation; otherwise leave the block commented. Never touch an existing `.red/config.yaml` (the clobber rule wins over this offer).
193
+
194
+ **Section G1 — Command guards (offer-only).**
195
+
196
+ > Explainer: RedSkills ships the maximum practical shell-command hook coverage for each supported CLI (Claude Code, Codex, and opencode). Those hooks are **proxy guarantees**, not the policy source: they extract the command and cwd, find the repo root, read `.red/config.yaml`, then evaluate `command_guard`. This keeps AFK workers and the main interactive session on the same repo-owned policy, and it keeps per-CLI hook files as thin adapters instead of places where safety rules drift.
197
+
198
+ Built-in invariant: when `plugins.dev.enabled: true`, the dev proxy always enforces the RedSkills worktree boundary before any repo-authored `command_guard` rule runs. Agent-created `git worktree add` destinations must resolve under a registered lane in the repo's `.red/tmp/`, and branch-moving commands in the primary checkout (`git switch`, `git checkout <branch>`, `git checkout -b`, `git switch -c`, `gh pr checkout`) are blocked so interactive work starts with `git worktree add .red/tmp/worktrees/manual/<slug> -b <branch> ...`. This invariant is not written into `command_guard` and has no example defaults to copy; it is part of enabling `dev`.
199
+
200
+ Offer to configure additional `command_guard` rules now. Default: **no extra active rules** unless the user confirms specific commands. Examples are examples only — do not write them as defaults.
201
+
202
+ Explain the scopes:
203
+
204
+ - `global` — blocks in both the main session and `/afk`/`/go` worktrees.
205
+ - `main` — blocks only in the primary interactive session scope. This does **not** mean the Git branch named `main`.
206
+ - `worktree` — blocks only in RedSkills runtime worktrees under `.red/tmp/`, including AFK workers.
207
+ - `deny` — legacy alias for `global`; keep it readable but prefer writing new config as `global`.
208
+
209
+ Explain the matcher forms:
210
+
211
+ - Bare strings match the exact command, a command prefix, or a command suffix at a shell-command boundary.
212
+ - Bare strings with `*`, `?`, or `[` are Bash globs.
213
+ - Explicit modes are `regex:<pattern>`, `re:<pattern>`, `prefix:<literal>`, `suffix:<literal>`, `exact:<literal>`, and `glob:<pattern>`.
214
+
215
+ When the user wants starter examples, present a draft like this and let them edit before writing:
216
+
217
+ ```yaml
218
+ command_guard:
219
+ global:
220
+ - "rm -Rf /*"
221
+ - "git stash"
222
+ main:
223
+ - "git rebase"
224
+ - "git checkout -b"
225
+ worktree:
226
+ - "git clean"
227
+ ```
228
+
229
+ Do not write the example blindly. The right policy is repo-specific.
230
+
231
+ **Section H — Development workflow.**
232
+
233
+ > Explainer: RedSkills' interactive dev loop assumes agents work from isolated worktrees, leave the primary checkout's branch alone, push their branch early, and land via a PR — with one-off concrete work dispatched through `/go` rather than hand-rolled worktrees. With `plugins.dev.enabled: true`, the shell proxy already blocks agent-created worktrees outside registered `.red/tmp/` lanes and branch movement in the primary checkout. Turning on `plugins.dev.lock.primary-branch: true` in `.red/config.yaml` also activates the branch-lock compatibility flag used by older adapters and base-pinning integrations; the runtime folds it onto the legacy `dev.lock.primary-branch` accessor for back-compat. The shared development-workflow injector writes the same `## Development workflow` rules into both `AGENTS.md` and `CLAUDE.md`, updating an existing block in place on rerun.
234
+
235
+ Confirm with the user:
236
+
237
+ - Activate the development workflow? Default: yes.
238
+ - This sets the canonical `plugins.dev.lock.primary-branch: true` flag in `.red/config.yaml`.
239
+ - This writes or updates `## Development workflow` in both `AGENTS.md` and `CLAUDE.md` via the shared injector.
240
+ - Recap that one-off concrete work is dispatched with `/go "<demand>"` (worktree + gate + PR handled by the engine), and that hand-worked branches land via a normal PR.
241
+
242
+ **Section I — Hook scripts from repo signals (offer-only).**
243
+
244
+ > Explainer: RedSkills hook scripts run at fixed AFK lifecycle points — before merging (`pre_merge`), after merging (`post_merge`), etc. — letting you gate or react to each iteration without editing the AFK runtime. Rather than asking you to configure these from scratch, this step scans your repo for concrete signals (a `package.json` with test/lint scripts, a `Makefile`, a Slack webhook env var, and so on) and offers to seed matching `red-*.sh` scripts into `.red/hooks/<point>/`. Each confirmed script is also registered in `.red/config.yaml` under `afk.hooks.<point>`. Nothing is written without explicit confirmation; no existing script is ever overwritten; nothing is `git add`ed. If no signals are found, this section is silent — absence of signals means no offer.
245
+
246
+ Scan for concrete repo signals in this order:
247
+
248
+ 1. **`package.json` `scripts.*`** — look for keys named `test`, `typecheck`, `type-check`, `lint`, `build`, `e2e`, or `test:e2e`. Infer the package manager from the first lockfile found (`pnpm-lock.yaml` → `pnpm run`, `yarn.lock` → `yarn run`, else `npm run`). `e2e`/`test:e2e` goes to `post_merge` (too costly as a pre-merge gate); all others go to `pre_merge`.
249
+ 2. **`Makefile`** — parse top-level targets; offer `pre_merge` hooks for any target named `test`, `check`, `verify`, `lint`, or `build`.
250
+ 3. **`Cargo.toml`** — offer a `pre_merge` hook running `cargo test` (the built-in default handles Rust worktree isolation; this adds the test run).
251
+ 4. **`build.gradle` / `build.gradle.kts`** — offer a `pre_merge` hook running `./gradlew check` (the built-in default handles Gradle isolation; this adds the check step).
252
+ 5. **`.husky/` directory** — offer a `pre_merge` hook running `npx lint-staged`.
253
+ 6. **`.pre-commit-config.yaml`** — offer a `pre_merge` hook running `pre-commit run --all-files`.
254
+ 7. **`.env.example`** — scan for `SLACK_WEBHOOK_URL` or `SLACK_INCOMING_WEBHOOK`; offer a `post_merge` Slack notification hook.
255
+
256
+ If no signals are detected, skip this section entirely — present no table, ask nothing.
257
+
258
+ If signals are found, present an offer table listing each suggestion:
259
+
260
+ | Point | Script | Signal |
261
+ |-------|--------|--------|
262
+ | `pre_merge` | `.red/hooks/pre_merge/red-run-tests.sh` | `package.json scripts.test = "vitest"` |
263
+ | `pre_merge` | `.red/hooks/pre_merge/red-lint.sh` | `package.json scripts.lint = "eslint ."` |
264
+ | `post_merge` | `.red/hooks/post_merge/red-slack-notify.sh` | `SLACK_WEBHOOK_URL in .env.example` |
265
+
266
+ Ask the user which to confirm (all, none, or pick by number). Skip the offer for any path that already exists — log a notice and move on (no-clobber, no overwrite, no second ask).
@@ -0,0 +1,18 @@
1
+ # Setup RedSkills Issue Sweep
2
+
3
+ ## Sweep existing issues
4
+
5
+ If the repo already has open issues, the new label vocabulary won't apply itself. Help the user backfill so `/triage` and `/afk` see a coherent state.
6
+
7
+ Run `gh issue list --state open --limit 200 --json number,title,labels` and group:
8
+
9
+ - **Unlabelled / missing triage role** — candidates for `needs-triage`
10
+ - **Labelled with legacy names** — map to the canonical vocabulary from Section B
11
+ - **Labels outside the accepted families** — remove them; do not map historical routing labels to another label
12
+ - **Already correct** — skip
13
+
14
+ Skip the sweep entirely if `gh issue list` returns 0 open issues.
15
+
16
+ Present the grouping to the user as a compact table (number, title, current labels, proposed labels) and ask for batch approval. Don't apply per-issue — one confirmation, then loop `gh issue edit <n> --add-label ... --remove-label ...`. If the list is large (>30), offer to do only the first N and stop.
17
+
18
+ Never close, reassign, or edit issue bodies in this step — labels only.