@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,88 @@
1
+ # Issue tracker: GitHub
2
+
3
+ Issues and Specs for this repo live as GitHub issues. Use the `gh` CLI for all operations.
4
+
5
+ ## Conventions
6
+
7
+ - **Create an issue**: `gh issue create --title "..." --body "..."`. Use a heredoc for multi-line bodies.
8
+ - **Read an issue**: `gh issue view <number> --comments`, filtering comments by `jq` and also fetching labels.
9
+ - **List issues**: `gh issue list --state open --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'` with appropriate `--label` and `--state` filters.
10
+ - **Comment on an issue**: `gh issue comment <number> --body "..."`
11
+ - **Apply / remove labels**: `gh issue edit <number> --add-label "..."` / `--remove-label "..."`
12
+ - **Close**: `gh issue close <number> --comment "..."`
13
+
14
+ Infer the repo from `git remote -v` — `gh` does this automatically when run inside a clone.
15
+
16
+ ## When a skill says "publish to the issue tracker"
17
+
18
+ Create a GitHub issue.
19
+
20
+ ## When a skill says "fetch the relevant ticket"
21
+
22
+ Run `gh issue view <number> --comments`.
23
+
24
+ ## Dependency & hierarchy operations
25
+
26
+ Use GitHub's native issue relationships for the human-facing graph, and keep the RedSkills labels/body fallback in sync for AFK machinery.
27
+
28
+ ### Create a native sub-issue relationship
29
+
30
+ Create the child issue first, then attach it to its parent Spec or map with the sub-issues endpoint. Pass the child's numeric database id with `-F` (typed field) so `gh` sends it as a JSON integer — `-f` sends a string and the endpoint rejects it with HTTP 422:
31
+
32
+ ```bash
33
+ child_id="$(gh api "repos/{owner}/{repo}/issues/<child-number>" --jq '.id')"
34
+ gh api --method POST "repos/{owner}/{repo}/issues/<parent-number>/sub_issues" \
35
+ -F "sub_issue_id=$child_id"
36
+ ```
37
+
38
+ For Spec slicing, also apply `spec:<parent-number>` to the child. For `/wayfinder`, the parent carries `wayfinder:map` and the child carries exactly one `wayfinder:<type>` label.
39
+
40
+ ### Create a native blocked-by relationship
41
+
42
+ Use the child's dependency endpoint and pass the blocker issue's numeric database id (again with `-F`, for the same reason):
43
+
44
+ ```bash
45
+ blocker_id="$(gh api "repos/{owner}/{repo}/issues/<blocker-number>" --jq '.id')"
46
+ gh api --method POST "repos/{owner}/{repo}/issues/<child-number>/dependencies/blocked_by" \
47
+ -F "issue_id=$blocker_id"
48
+ ```
49
+
50
+ **Trap:** `issue_id` must be the blocker's numeric database id from the REST issue `.id` field. It is never the GitHub issue `#number`, and it is never the GraphQL `node_id`. Passing the wrong value can link the wrong issue silently.
51
+
52
+ For AFK dependencies, also apply `blocked:dependency` plus one `req:<blocker-number>` label per blocker. Keep the strict `## Blocked by` body fallback when the issue should auto-promote after blockers close.
53
+
54
+ ### Read blocked-by edges for audit
55
+
56
+ Audit the actual native blocker list from the child's endpoint:
57
+
58
+ ```bash
59
+ gh api "repos/{owner}/{repo}/issues/<child-number>/dependencies/blocked_by" \
60
+ --jq '.[] | {number, id, state, title}'
61
+ ```
62
+
63
+ Use this list when checking whether native blocked-by edges and `req:N` labels diverge.
64
+
65
+ ### Read dependency summary counts
66
+
67
+ The REST issue payload includes `issue_dependencies_summary`. Its `blocked_by` field is an open-blocker count only:
68
+
69
+ ```bash
70
+ gh api "repos/{owner}/{repo}/issues/<child-number>" \
71
+ --jq '.issue_dependencies_summary.blocked_by'
72
+ ```
73
+
74
+ `issue_dependencies_summary.blocked_by == 0` means no open blockers remain; it does not enumerate blockers and it should not replace the blocked-by audit endpoint above.
75
+
76
+ ## Wayfinding operations
77
+
78
+ This repo expresses `/wayfinder` maps and tickets with GitHub Issues plus the RedSkills label vocabulary:
79
+
80
+ - The map is one GitHub issue labeled `wayfinder:map`.
81
+ - Tickets are native GitHub sub-issues of the map. Each ticket carries exactly one type label: `wayfinder:research`, `wayfinder:prototype`, `wayfinder:grilling`, or `wayfinder:task`.
82
+ - Blocking uses GitHub's native blocked-by relationship. Mirror every native blocking edge as a `req:N` label, per ADR 0094, so existing RedSkills queue and backpressure tools see the same dependency.
83
+ - Create and audit these native relationships with the commands in [Dependency & hierarchy operations](#dependency--hierarchy-operations).
84
+ - The frontier is the set of open child issues whose blockers are all closed and that have no assignee. Claim by assignment: assign yourself before working a ticket, and treat any assigned open ticket as claimed.
85
+ - AFK-typed children (`wayfinder:research` and AFK-safe `wayfinder:task`) enter the autonomous queue with `ready-for-agent` once unblocked. Blocked AFK children use `blocked:dependency` plus their `req:N` labels, not `ready-for-agent`.
86
+ - HITL-typed children (`wayfinder:grilling`, `wayfinder:prototype`, and any human-only `wayfinder:task`) use `ready-for-human` plus assignment to the expected human or role. They move back to the autonomous lane only after `/hitl` or `/retake` determines the blocker is resolved.
87
+ - An unblocked AFK-safe `wayfinder:task` is in `ready-for-agent` and can be dispatched immediately with `/afk --issues <n>`. The wayfinder session must not resolve it inline — route it to the AFK engine instead.
88
+ - If native blocking is unavailable, add a strict `## Blocked by` fallback section to the ticket body and list the blocking issue names with links. Keep the `req:N` labels in sync with that fallback.
@@ -0,0 +1,35 @@
1
+ # rsp Retirement Operator Runbook
2
+
3
+ RTK is retired for live RedSkills guidance after the measured parity decision in #1420. This runbook documents the operator-owned machine cleanup. Repository code must not execute these steps automatically.
4
+
5
+ ## Scope
6
+
7
+ - Live guidance should point at `rsp` wrappers, loss levels, `rsp show`, and the per-repo hook opt-in.
8
+ - Historical ADRs, issue threads, benchmark fixtures, and memory artifacts are history and should not be rewritten only to remove older names.
9
+ - The ambient host-instruction replacement for per-host RTK.md files is tracked in #1415. Treat it as the follow-up deliverable that ships the generated `apps/rsp/generated/AMBIENT-SKILL.md` surface to each host.
10
+
11
+ ## Remove the Pre-Execution Hook
12
+
13
+ Inspect each agent's local settings and remove the RTK pre-execution hook entry. The exact file is host-specific, but the intent is the same: delete only the hook command that invokes the retired binary and keep unrelated hooks intact.
14
+
15
+ After editing settings, open a fresh agent session and confirm routine commands are no longer rewritten by the retired hook. In repos that opt in with `rsp.enabled: true`, the RedSkills hook may still rewrite simple supported commands to `rsp`; that is expected.
16
+
17
+ ## Delete the Binary
18
+
19
+ Remove the retired binary from the operator-managed bin directory or package manager that installed it. Verify that the shell no longer resolves it:
20
+
21
+ ```bash
22
+ command -v <retired-binary>
23
+ ```
24
+
25
+ If another unrelated tool with the same executable name remains on `PATH`, leave that tool alone and document the distinction in local operator notes rather than changing repo guidance.
26
+
27
+ ## Telemetry Database Retention
28
+
29
+ The old telemetry database includes a parse-failure ledger with forensic value. Keeping it, archiving it, or deleting it is an operator decision:
30
+
31
+ - **Keep** when recent failures may still inform `rsp` parity audits or incident review.
32
+ - **Archive** when the ledger is no longer active but may be needed for provenance.
33
+ - **Delete** only when local retention policy says the forensic value has expired.
34
+
35
+ Do not migrate this ledger into repo state. `rsp` stores current reversible elisions in the repo RedDB store under its own collection; the retired telemetry database remains a machine-local artifact.
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ bin_dir="${XDG_BIN_HOME:-$HOME/.local/bin}"
5
+ name="${1:-red-skills-dev}"
6
+ dev_target="$bin_dir/$name"
7
+ rsp_target="$bin_dir/rsp"
8
+
9
+ mkdir -p "$bin_dir"
10
+
11
+ cat >"$dev_target" <<'SH'
12
+ #!/usr/bin/env bash
13
+ set -euo pipefail
14
+
15
+ env_launcher() {
16
+ local root
17
+ for root in \
18
+ "${RED_SKILLS_DEV_PLUGIN_ROOT:-}" \
19
+ "${CLAUDE_PLUGIN_ROOT:-}" \
20
+ "${CODEX_PLUGIN_ROOT:-}" \
21
+ "${OPENCODE_PLUGIN_ROOT:-}"
22
+ do
23
+ [ -n "$root" ] || continue
24
+ if [ -f "$root/skills/engineering/afk/bin/afk.mjs" ]; then
25
+ printf '%s\n' "$root/skills/engineering/afk/bin/afk.mjs"
26
+ return 0
27
+ fi
28
+ done
29
+ return 1
30
+ }
31
+
32
+ latest_cache_launcher() {
33
+ local dir
34
+ for dir in "$HOME"/.codex/plugins/cache/red-skills/dev/* "$HOME"/.claude/plugins/cache/red-skills/dev/*; do
35
+ [ -f "$dir/skills/engineering/afk/bin/afk.mjs" ] &&
36
+ printf '%s\t%s\n' "$(basename "$dir")" "$dir/skills/engineering/afk/bin/afk.mjs"
37
+ done | sort -V | tail -1 | cut -f2-
38
+ }
39
+
40
+ latest_bundle() {
41
+ local bundle
42
+ for bundle in "$HOME"/.cache/red-skills/bundles/dev-*.bundle.min.mjs; do
43
+ [ -f "$bundle" ] || continue
44
+ local version="${bundle##*/dev-}"
45
+ version="${version%.bundle.min.mjs}"
46
+ printf '%s\t%s\n' "$version" "$bundle"
47
+ done | sort -V | tail -1 | cut -f2-
48
+ }
49
+
50
+ launcher="$(env_launcher || true)"
51
+ if [ -n "$launcher" ]; then
52
+ exec node "$launcher" "$@"
53
+ fi
54
+
55
+ launcher="$(latest_cache_launcher || true)"
56
+ if [ -n "$launcher" ]; then
57
+ exec node "$launcher" "$@"
58
+ fi
59
+
60
+ bundle="$(latest_bundle || true)"
61
+ if [ -n "$bundle" ]; then
62
+ exec node "$bundle" "$@"
63
+ fi
64
+
65
+ cat >&2 <<'EOF'
66
+ red-skills-dev: no RedSkills dev runtime found.
67
+
68
+ Expected one of:
69
+ - an installed dev plugin under ~/.codex/plugins/cache/red-skills/dev/*
70
+ - an installed dev plugin under ~/.claude/plugins/cache/red-skills/dev/*
71
+ - a warmed bundle under ~/.cache/red-skills/bundles/dev-*.bundle.min.mjs
72
+
73
+ Fallback:
74
+ npx -y -p @reddb-io/red-skills@<version> red-skills-dev "$@"
75
+
76
+ Run /red-setup in a repo with plugins.dev.enabled: true, then restart the
77
+ agent session so the plugin SessionStart hook can warm the runtime cache, or use
78
+ the npm direct-run fallback above for a fresh machine.
79
+ EOF
80
+ exit 127
81
+ SH
82
+
83
+ cat >"$rsp_target" <<'SH'
84
+ #!/usr/bin/env bash
85
+ set -euo pipefail
86
+
87
+ env_bundle() {
88
+ local root bundle
89
+ for root in \
90
+ "${RED_SKILLS_DEV_PLUGIN_ROOT:-}" \
91
+ "${CLAUDE_PLUGIN_ROOT:-}" \
92
+ "${CODEX_PLUGIN_ROOT:-}" \
93
+ "${OPENCODE_PLUGIN_ROOT:-}"
94
+ do
95
+ [ -n "$root" ] || continue
96
+ for bundle in \
97
+ "$root/../../dist/rsp.bundle.min.mjs" \
98
+ "$root/dist/rsp.bundle.min.mjs"
99
+ do
100
+ if [ -f "$bundle" ]; then
101
+ printf '%s\n' "$bundle"
102
+ return 0
103
+ fi
104
+ done
105
+ done
106
+ return 1
107
+ }
108
+
109
+ latest_cache_bundle() {
110
+ local dir bundle
111
+ for dir in "$HOME"/.codex/plugins/cache/red-skills/dev/* "$HOME"/.claude/plugins/cache/red-skills/dev/*; do
112
+ [ -d "$dir" ] || continue
113
+ for bundle in "$dir/../../dist/rsp.bundle.min.mjs" "$dir/dist/rsp.bundle.min.mjs"; do
114
+ [ -f "$bundle" ] &&
115
+ printf '%s\t%s\n' "$(basename "$dir")" "$bundle"
116
+ done
117
+ done | sort -V | tail -1 | cut -f2-
118
+ }
119
+
120
+ latest_bundle() {
121
+ local cache_root bundle version
122
+ cache_root="${RED_SKILLS_CACHE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/red-skills/bundles}"
123
+
124
+ if [ -f "$cache_root/rsp.bundle.min.mjs" ]; then
125
+ printf '%s\n' "$cache_root/rsp.bundle.min.mjs"
126
+ return 0
127
+ fi
128
+
129
+ for bundle in "$cache_root"/rsp-*.bundle.min.mjs; do
130
+ [ -f "$bundle" ] || continue
131
+ version="${bundle##*/rsp-}"
132
+ version="${version%.bundle.min.mjs}"
133
+ printf '%s\t%s\n' "$version" "$bundle"
134
+ done | sort -V | tail -1 | cut -f2-
135
+ }
136
+
137
+ find_red_binary() {
138
+ local cache_root red version
139
+ cache_root="${RED_SKILLS_CACHE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/red-skills/bundles}"
140
+
141
+ for red in "$cache_root"/reddb/*/red "$cache_root"/reddb/*/red.exe; do
142
+ [ -x "$red" ] || continue
143
+ version="${red%/*}"
144
+ version="${version##*/}"
145
+ printf '%s\t%s\n' "$version" "$red"
146
+ done | sort -V | tail -1 | cut -f2-
147
+ }
148
+
149
+ with_red_binary() {
150
+ local red
151
+ red="$(find_red_binary || true)"
152
+ if [ -n "$red" ]; then
153
+ REDDB_BIN="$red" exec node "$@"
154
+ fi
155
+ exec node "$@"
156
+ }
157
+
158
+ bundle="$(env_bundle || true)"
159
+ if [ -n "$bundle" ]; then
160
+ with_red_binary "$bundle" "$@"
161
+ fi
162
+
163
+ bundle="$(latest_cache_bundle || true)"
164
+ if [ -n "$bundle" ]; then
165
+ with_red_binary "$bundle" "$@"
166
+ fi
167
+
168
+ bundle="$(latest_bundle || true)"
169
+ if [ -n "$bundle" ]; then
170
+ with_red_binary "$bundle" "$@"
171
+ fi
172
+
173
+ cat >&2 <<'EOF'
174
+ rsp: no RedSkills rsp runtime found.
175
+
176
+ Expected one of:
177
+ - an installed dev plugin with dist/rsp.bundle.min.mjs under ~/.codex/plugins/cache/red-skills/dev/*
178
+ - an installed dev plugin with dist/rsp.bundle.min.mjs under ~/.claude/plugins/cache/red-skills/dev/*
179
+ - a warmed rsp bundle under ${RED_SKILLS_CACHE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/red-skills/bundles}
180
+
181
+ Run /red-setup in a repo with plugins.dev.enabled: true, then restart the
182
+ agent session so the plugin SessionStart hook can warm the runtime cache.
183
+ EOF
184
+ exit 127
185
+ SH
186
+
187
+ chmod 0755 "$dev_target" "$rsp_target"
188
+ printf 'installed %s\n' "$dev_target"
189
+ printf 'installed %s\n' "$rsp_target"
@@ -0,0 +1,176 @@
1
+ # Triage Labels
2
+
3
+ Canonical label vocabulary and full issue lifecycle. This is the single source of truth — `/triage`, `/afk`, `/to-tickets`, and `/to-spec` all reference this file.
4
+
5
+ ## Label Mapping
6
+
7
+ The skills speak in terms of canonical triage roles. Map them here to the actual label strings used in this repo's issue tracker.
8
+
9
+ | Canonical role | Label in our tracker | Applied by | Removed by |
10
+ | ------------------ | -------------------- | ------------------------------------- | ----------------------------------- |
11
+ | `needs-triage` | `needs-triage` | `red-issues-needs-triage` workflow, `/triage` | `/triage` (when state transitions) |
12
+ | `needs-info` | `needs-info` | `/triage` | `/triage` (when reporter replies) |
13
+ | `ready-for-agent` | `ready-for-agent` | `/triage`, `/to-tickets` | `/afk` (when claiming) |
14
+ | `running` | `running` | `/afk` (when claiming an issue) | `/afk` (on close, blocker, or release) |
15
+ | `ready-for-human` | `ready-for-human` | `/triage`, `/afk` (on blocker) | maintainer |
16
+ | `wontfix` | `wontfix` | `/triage` (then close) | rarely — usually issue closes |
17
+ | `needs-slicing` | `needs-slicing` | `/to-spec` (on publish) | `/to-tickets` (when slices are created) |
18
+ | `type:spec` | `type:spec` | `/to-spec` (on publish) | never — type marker, permanent |
19
+
20
+ Edit the right-hand column to match whatever vocabulary you actually use.
21
+
22
+ ## Full Lifecycle
23
+
24
+ Every issue moves through this state machine. Arrows show the transitions; the actor on each arrow is the skill or workflow responsible.
25
+
26
+ ```
27
+ ┌─────────────────────┐
28
+ │ issue created │
29
+ │ (any source) │
30
+ └──────────┬──────────┘
31
+
32
+ red-issues-needs-triage workflow
33
+ (auto on opened/reopened, no label)
34
+
35
+ ┌─────────────────────┐
36
+ ┌─────────────│ needs-triage │────────────┐
37
+ │ └──────────┬──────────┘ │
38
+ │ │ │
39
+ /triage: /triage: /triage:
40
+ needs-info wontfix ready-for-*
41
+ │ │ │
42
+ ▼ ▼ │
43
+ ┌──────────────┐ ┌──────────────┐ │
44
+ │ needs-info │ │ wontfix │ │
45
+ │ (await user) │ │ + close │ │
46
+ └──────┬───────┘ └──────────────┘ │
47
+ │ │
48
+ reporter replies │
49
+ → /triage │
50
+ │ │
51
+ └──────────────────► needs-triage │
52
+
53
+ ┌───────────────────────────────────┐
54
+ │ │
55
+ ▼ ▼
56
+ ┌──────────────────────┐ ┌──────────────────────┐
57
+ │ ready-for-agent │ │ ready-for-human │
58
+ │ (## Agent brief │ │ (needs judgment) │
59
+ │ in body) │ └──────────────────────┘
60
+ └──────────┬───────────┘ │
61
+ │ │
62
+ /afk claim: human picks up
63
+ removes ready-for-agent, (manual impl,
64
+ adds running eventually closes)
65
+
66
+
67
+ ┌──────────────────────┐
68
+ │ running │
69
+ │ (worktree active, │
70
+ │ heartbeats post) │
71
+ └──────────┬───────────┘
72
+
73
+ ┌──────────────┼──────────────┐
74
+ │ │ │
75
+ /afk: DONE /afk: BLOCKED /afk: merge conflict
76
+ │ │ │
77
+ ▼ ▼ ▼
78
+ ┌─────────┐ ┌────────────────────────────┐
79
+ │ closed │ │ remove running, │
80
+ │ + merge │ │ add ready-for-human, │
81
+ │ comment │ │ worktree preserved │
82
+ └─────────┘ └────────────────────────────┘
83
+ ```
84
+
85
+ ## State Definitions
86
+
87
+ ### `needs-triage`
88
+ Maintainer has not evaluated the issue yet. **Applied automatically** by `red-issues-needs-triage.yml` workflow on every fresh `opened`/`reopened` issue with no labels. Manual application by `/triage` when the maintainer puts an evaluated issue back into the queue. Removed by `/triage` when the issue transitions to a definitive state.
89
+
90
+ ### `needs-info`
91
+ The triage agent or maintainer needs more information from the reporter before a decision can be made. Removed by `/triage` once the reporter responds and the issue cycles back through `needs-triage`.
92
+
93
+ ### `ready-for-agent`
94
+ The issue body contains a complete `## Agent brief` section (see `triage/AGENT-BRIEF.md`) that forms a contract sufficient for an AFK agent to implement without human context. **This is the only state `/afk` consumes.** Applied by `/triage` (after grilling) or `/to-tickets` (on creation when the slice is AFK-safe).
95
+
96
+ ### `running`
97
+ `/afk` has claimed the issue and is actively executing it. Applied atomically with the removal of `ready-for-agent` so two parallel `/afk` runs cannot race on the same issue. The orchestrator's heartbeat sub-shell posts `:one:` → `:four:` comments every 10 min while this label is present. Removed on close (success), on blocker (replaced with `ready-for-human`), or on graceful release (if the user interrupts the loop).
98
+
99
+ ### `ready-for-human`
100
+ The issue requires human decision or resolution before it can proceed or be delegated. Two sources: `/triage` decides it during evaluation (e.g. architectural call, design review needed), or `/afk` promotes it from `running` after a blocker (inner agent gave up, merge conflict couldn't be auto-resolved, both runners exhausted). When `/afk` promotes, the worktree is **preserved at the moment of blocker** so the human can inspect or resolve the blocker in place.
101
+
102
+ ### `wontfix`
103
+ Will not be actioned. Applied by `/triage`. For bugs, paired with a polite explanation and close. For enhancements, paired with a `.out-of-scope/*.md` entry (see `triage/OUT-OF-SCOPE.md`).
104
+
105
+ ### `type:spec`
106
+ Permanent type marker for Spec issues created by `/to-spec`. A Spec is a planning artifact, **not an implementable slice** — it describes *what* to build at the product level and must be split into child issues by `/to-tickets` before any agent can execute. `/afk` hard-filters issues carrying `type:spec` from its candidate list even if `ready-for-agent` was applied by mistake. Never remove this label.
107
+
108
+ ### `needs-slicing`
109
+ The Spec has been published but `/to-tickets` has not yet split it into child slices. Applied by `/to-spec` on publish, removed by `/to-tickets` once at least one child issue with `spec:{N}` exists. `/afk` counts these in its straggler check so a forgotten Spec surfaces before the loop runs dry.
110
+
111
+ ## Heartbeat Comments
112
+
113
+ While `running`, `/afk` posts a heartbeat comment every 10 minutes so the issue is never silent during long executions:
114
+
115
+ ```
116
+ t=10 min → :one:
117
+ t=20 min → :two:
118
+ t=30 min → :three:
119
+ t=40 min → :four:
120
+ t=50 min → :one: (cycle resets)
121
+ ```
122
+
123
+ Stops on any terminal transition out of `running`.
124
+
125
+ ## Optional Auxiliary Labels
126
+
127
+ These exist for filtering and don't drive lifecycle transitions:
128
+
129
+ | Label | Meaning | Applied by |
130
+ | -------------- | ----------------------------------------------- | -------------------------------- |
131
+ | `bug` | Something is broken | `/triage` |
132
+ | `enhancement` | New feature or improvement | `/triage` |
133
+ | `priority:high` | Urgent / high-impact — `/afk` drains these first | `/triage` or maintainer |
134
+ | `priority:low` | Everything else | `/triage` or maintainer |
135
+ | `spec:{N}` | Issue belongs to Spec #N | `/to-tickets` when splitting a Spec |
136
+ | `wayfinder:map` | Planning map Ticket for work too large for one agent session. Carries `## Destination`, `## Not yet specified`, and `## Out of scope`; the map is an index, not a store. | `/wayfinder` |
137
+ | `wayfinder:research` | Wayfinder child type for AFK-typed research scoped to one session. Unblocked children use `ready-for-agent`; blocked children use `blocked:dependency` plus `req:N`. | `/wayfinder` |
138
+ | `wayfinder:grilling` | Wayfinder child type for HITL-typed decision work routed to a `/start` session and claimed by assignment. | `/wayfinder` |
139
+ | `wayfinder:prototype` | Wayfinder child type for HITL-typed design or logic exploration routed to a `/prototype` session and claimed by assignment. | `/wayfinder` |
140
+ | `wayfinder:task` | Wayfinder child type for AFK-typed implementation/docs work scoped to one session. Unblocked children use `ready-for-agent`; blocked children use `blocked:dependency` plus `req:N`. | `/wayfinder` |
141
+ | `runner-error` | `/afk` fleet supervisor parked a slot after fast-death streak; affected issues were restored to `ready-for-agent` after the runner was discarded | `/afk` fleet supervisor on circuit trip |
142
+ | `landing:manual` | Per-issue **manual-landing** mode (#1049): on a `ready-for-agent` issue, `/afk` runs the full pipeline + opens the PR, then **holds for a human's merge click** (parks `ready-for-human`, never auto-merges, never re-runs the agent). The issue auto-closes on PR merge via `Closes #N`. Lets agent-codable slices that must not be auto-merged stay in the autonomous lane instead of being hand-dispatched via `/go`. | `/triage` at brief time, or `/hitl`'s **delegable-manual-landing** disposition |
143
+
144
+ `runner-error` is the only auxiliary label `/afk` may create autonomously: the fleet supervisor calls `gh label create runner-error` when it trips the circuit breaker, so the cleanup never fails just because the label has not been provisioned. Provision it up front via `/red-setup` to keep colour/description consistent across repos.
145
+
146
+ ## Blocked Reasons (`blocked:<reason>`) — typed, auto-classified
147
+
148
+ `/afk` already computes a precise terminal outcome for every iteration; instead of flattening every failure to one `blocked`, it tags the issue with the matching **`blocked:<reason>`** label so the backlog is filterable by *what kind* of block it is. The reason is derived automatically from the outcome — **no human classification**.
149
+
150
+ | Outcome (runtime) | Label | Recovery | Retry cap (env) |
151
+ | ----------------- | ----- | -------- | --------------- |
152
+ | runner quota / both exhausted | `blocked:quota` | **auto-retry** → ready-for-agent | 3 (`RED_AFK_RETRY_QUOTA`) |
153
+ | runner transport/setup failed | `blocked:runner-transient` | **auto-retry** → ready-for-agent | 3 (`RED_AFK_RETRY_RUNNER_TRANSIENT`) |
154
+ | couldn't integrate or land | `blocked:merge-conflict` | **auto-retry** (base settles) | 3 (`RED_AFK_RETRY_MERGE`) |
155
+ | mergeable PR blocked by CI (required check failed / still pending) | `blocked:ci` | **pages** → ready-for-human / CI-aware finisher (never re-runs the agent) | — (never auto) |
156
+ | agent exited without a sentinel | `blocked:crashed` | **auto-retry once** (transient) | 1 (`RED_AFK_RETRY_CRASH`) |
157
+ | a user `pre_*` guard hook rejected it | `blocked:policy` | **auto-retry once** | 1 (`RED_AFK_RETRY_POLICY`) |
158
+ | agent emitted `<promise>BLOCKED</promise>` | `blocked:spec` | **pages** → ready-for-human (decide/clarify) | — (never auto) |
159
+ | feedback gate failed (test/lint/build) | `blocked:validation` | **pages** → ready-for-human (review diff) | — (never auto) |
160
+ | stall-reaper killed a hung worker | `blocked:stalled` | **auto-retry** → ready-for-agent (clean) | 3 (`RED_AFK_RETRY_STALLED`) |
161
+ | worktree/base/push setup failed | `blocked:infra` | pages → ready-for-human (ops) | — |
162
+
163
+ **Bounded auto-recovery (live).** The recoverable reasons loop back to `ready-for-agent` and are retried, up to their per-reason cap (counting real attempt-ledger attempts); on the cap they **escalate** to `ready-for-human` with a `🤖 /afk escalating … retry budget exhausted (attempt N/cap)` comment. So a transient hiccup self-heals and never pages, but a persistent one still surfaces — bounded, no runaway loop. The supervisor stall-reaper's `blocked:stalled` re-queue is bounded by the **same** policy (`RED_AFK_RETRY_STALLED`, default 3). Caps are env-tunable (non-numeric/0 → default). `spec`, `validation`, and `ci` **always page** (a human must decide / review the diff / drive the open PR to merge); `dependency` waits on its `req:N` edges (never pages). `blocked:ci` (#812) is deliberately non-recoverable: the work is already complete and committed on the open PR, so re-running the agent would re-spend tokens for nothing — a human / CI-aware finisher merges the existing PR once CI is green. **A re-queue is hygienic:** promoting an issue to `ready-for-agent` (auto-retry) or `running` (claim) sheds any `blocked:*` label in the same edit, so no live/queued issue ever carries `ready-for-agent`/`running` together with `blocked:*`. The typed `blocked:<reason>` label rides only the `ready-for-human` escalation.
164
+
165
+ > Not yet wired: time-based backoff (today the re-queue is immediate; the cap is what prevents runaway).
166
+
167
+ All `blocked:*` labels are created on the fly when first applied (mirroring `runner-error`) and provisioned by `/red-setup`.
168
+
169
+ ## Naming Convention
170
+
171
+ All labels follow one of two shapes:
172
+
173
+ - **kebab-case** — `needs-triage`, `ready-for-agent`, `running`, `wontfix`, `bug`.
174
+ - **`prefix:value`** — `priority:high`, `spec:42`.
175
+
176
+ No uppercase, CamelCase, snake_case, or spaces. GitHub matches labels case-insensitively for filtering but stores the case you create them with — keep the tracker clean by normalising on creation. `/red-setup` surfaces non-conforming labels and offers to rename via `gh label edit "Old Name" --name "new-name"`.
@@ -0,0 +1,36 @@
1
+ # Auto-applies the `needs-triage` label to any newly opened or reopened issue
2
+ # that has no labels yet. Keeps fresh issues from slipping past `/triage` and
3
+ # `/afk` (which only consumes `ready-for-agent`).
4
+ #
5
+ # Installed by `/red-setup`. Filename prefix `red-` marks it as belonging
6
+ # to the RedSkills ecosystem.
7
+
8
+ name: red-issues-needs-triage
9
+
10
+ on:
11
+ issues:
12
+ types: [opened, reopened]
13
+
14
+ permissions:
15
+ issues: write
16
+
17
+ jobs:
18
+ label:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/github-script@v7
22
+ with:
23
+ script: |
24
+ const issue = context.payload.issue;
25
+ const labels = (issue.labels || []).map(l => l.name);
26
+ if (labels.length > 0) {
27
+ core.info(`Issue #${issue.number} already labelled (${labels.join(', ')}). Skipping.`);
28
+ return;
29
+ }
30
+ await github.rest.issues.addLabels({
31
+ owner: context.repo.owner,
32
+ repo: context.repo.repo,
33
+ issue_number: issue.number,
34
+ labels: ['needs-triage']
35
+ });
36
+ core.info(`Applied 'needs-triage' to #${issue.number}.`);