@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,96 @@
1
+ ---
2
+ name: tdd
3
+ description: Test-driven development with a red → green loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green", wants integration tests, or asks for test-first development.
4
+ ---
5
+
6
+ # Test-Driven Development
7
+
8
+ <what-to-do>
9
+
10
+ **Loop rule: red before green, one slice at a time, tests only at pre-agreed seams.** One failing test, the minimum code to pass it, nothing more; repeat until every listed behaviour is covered.
11
+
12
+ The loop has no prescribed steps — pick the next uncovered behaviour, write one failing test, write the minimum code to pass it, check the cycle checklist, move on.
13
+
14
+ ### Seams
15
+
16
+ A **seam** is the public boundary you test at. Agree on seams before writing the first test — no test at an unconfirmed seam. Each seam carries one behaviour per cycle.
17
+
18
+ ### Hard rules — do not break these
19
+
20
+ - ❌ Do **not** write all tests first then all implementation ("horizontal slicing"). This produces tests of *imagined* behaviour, not *actual* behaviour. See `<supporting-info>` for why.
21
+ - ❌ Do **not** write more code than the current test requires. No speculative features, no anticipating the next test.
22
+ - ❌ Do **not** test private methods or mock internal collaborators. Tests must go through the public interface.
23
+ - ❌ Do **not** verify behaviour through external means (querying the database directly when an API exists, etc.).
24
+ - ❌ Do **not** write tautological assertions — expected values must come from an independent source of truth (a literal, a worked example, the spec), not by recomputing the same way the code does. `expect(add(a, b)).toBe(a + b)` always passes and can never catch a bug.
25
+ - ✅ **Do** confirm seams before writing the first test — no test at an unconfirmed seam.
26
+ - ✅ **Do** check each cycle against the per-cycle checklist before moving to the next test.
27
+ - ✅ **Do** keep tests focused on observable behaviour through public interfaces.
28
+ - ✅ **Do** use the project's domain vocabulary in test names and interface design.
29
+
30
+ ### Per-cycle checklist
31
+
32
+ Before declaring a cycle done, confirm every box:
33
+
34
+ ```
35
+ [ ] A reader can tell what the system does from this test alone — not how it does it
36
+ [ ] The test reaches the system only through its public interface
37
+ [ ] This test would still pass if the internal implementation were replaced entirely
38
+ [ ] No code was added beyond what this test required
39
+ [ ] No features were anticipated beyond the current test
40
+ [ ] Expected values come from a literal, worked example, or spec — not recomputed the way the code computes them
41
+ ```
42
+
43
+ If any box is unchecked, the cycle isn't done — fix it before moving on.
44
+
45
+ Once all tests are GREEN, refactoring is a separate concern — run `/code-review` on the branch to clean up.
46
+
47
+ </what-to-do>
48
+
49
+ <supporting-info>
50
+
51
+ ## Philosophy
52
+
53
+ **Core principle**: Tests verify behaviour through public interfaces, not implementation details. Code can change entirely; tests shouldn't.
54
+
55
+ **Good tests** are integration-style: they exercise real code paths through public APIs. They describe *what* the system does, not *how*. A good test reads like a specification — *"user can checkout with valid cart"* tells you exactly what capability exists. These tests survive refactors because they don't care about internal structure.
56
+
57
+ **Implementation-coupled tests** are the first bad-test pattern: they mock internal collaborators, test private methods, or verify through external means (like querying a database directly instead of using the interface). The warning sign: your test breaks when you refactor, but behaviour hasn't changed.
58
+
59
+ **Tautological tests** are the second bad-test pattern: a test whose assertion is recomputed the way the code computes it passes by construction and proves nothing. `expect(add(a, b)).toBe(a + b)` will always pass regardless of what `add` does — the assertion restates the implementation instead of verifying it against an independent expected value. Expected values must come from a literal, a worked example, or the spec.
60
+
61
+ See [tests.md](tests.md) for examples of both anti-patterns, [mocking.md](mocking.md) for mocking guidelines, [interface-design.md](interface-design.md) for designing for testability.
62
+
63
+ ## Seams
64
+
65
+ A **seam** is the public boundary you test at: the interface where you observe behaviour without reaching inside the implementation. Tests live at seams, never against internals.
66
+
67
+ Confirming seams before the first test is how testing effort lands on critical paths and complex logic — not on every edge case. One seam, one test, one implementation per cycle.
68
+
69
+ ## Why horizontal slicing is forbidden
70
+
71
+ Treating RED as "write all tests" and GREEN as "write all code" produces **crap tests**:
72
+
73
+ - Tests written in bulk test *imagined* behaviour, not *actual* behaviour
74
+ - You end up testing the *shape* of things (data structures, signatures) rather than user-facing behaviour
75
+ - Tests become insensitive to real changes — they pass when behaviour breaks, fail when behaviour is fine
76
+ - You outrun your headlights, committing to test structure before understanding the implementation
77
+
78
+ ```
79
+ WRONG (horizontal):
80
+ RED: test1, test2, test3, test4, test5
81
+ GREEN: impl1, impl2, impl3, impl4, impl5
82
+
83
+ RIGHT (vertical):
84
+ RED→GREEN: test1→impl1
85
+ RED→GREEN: test2→impl2
86
+ RED→GREEN: test3→impl3
87
+
88
+ ```
89
+
90
+ Each test responds to what you learned from the previous cycle. Because you just wrote the code, you know exactly what behaviour matters and how to verify it.
91
+
92
+ ## Planning aids
93
+
94
+ When listing behaviours, also identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation) and design interfaces for [testability](interface-design.md). These choices are easier to make before any code exists.
95
+
96
+ </supporting-info>
@@ -0,0 +1,33 @@
1
+ # Deep Modules
2
+
3
+ From "A Philosophy of Software Design":
4
+
5
+ **Deep module** = small interface + lots of implementation
6
+
7
+ ```
8
+ ┌─────────────────────┐
9
+ │ Small Interface │ ← Few methods, simple params
10
+ ├─────────────────────┤
11
+ │ │
12
+ │ │
13
+ │ Deep Implementation│ ← Complex logic hidden
14
+ │ │
15
+ │ │
16
+ └─────────────────────┘
17
+ ```
18
+
19
+ **Shallow module** = large interface + little implementation (avoid)
20
+
21
+ ```
22
+ ┌─────────────────────────────────┐
23
+ │ Large Interface │ ← Many methods, complex params
24
+ ├─────────────────────────────────┤
25
+ │ Thin Implementation │ ← Just passes through
26
+ └─────────────────────────────────┘
27
+ ```
28
+
29
+ When designing interfaces, ask:
30
+
31
+ - Can I reduce the number of methods?
32
+ - Can I simplify the parameters?
33
+ - Can I hide more complexity inside?
@@ -0,0 +1,31 @@
1
+ # Interface Design for Testability
2
+
3
+ Good interfaces make testing natural:
4
+
5
+ 1. **Accept dependencies, don't create them**
6
+
7
+ ```typescript
8
+ // Testable
9
+ function processOrder(order, paymentGateway) {}
10
+
11
+ // Hard to test
12
+ function processOrder(order) {
13
+ const gateway = new StripeGateway();
14
+ }
15
+ ```
16
+
17
+ 2. **Return results, don't produce side effects**
18
+
19
+ ```typescript
20
+ // Testable
21
+ function calculateDiscount(cart): Discount {}
22
+
23
+ // Hard to test
24
+ function applyDiscount(cart): void {
25
+ cart.total -= discount;
26
+ }
27
+ ```
28
+
29
+ 3. **Small surface area**
30
+ - Fewer methods = fewer tests needed
31
+ - Fewer params = simpler test setup
@@ -0,0 +1,59 @@
1
+ # When to Mock
2
+
3
+ Mock at **system boundaries** only:
4
+
5
+ - External APIs (payment, email, etc.)
6
+ - Databases (sometimes - prefer test DB)
7
+ - Time/randomness
8
+ - File system (sometimes)
9
+
10
+ Don't mock:
11
+
12
+ - Your own classes/modules
13
+ - Internal collaborators
14
+ - Anything you control
15
+
16
+ ## Designing for Mockability
17
+
18
+ At system boundaries, design interfaces that are easy to mock:
19
+
20
+ **1. Use dependency injection**
21
+
22
+ Pass external dependencies in rather than creating them internally:
23
+
24
+ ```typescript
25
+ // Easy to mock
26
+ function processPayment(order, paymentClient) {
27
+ return paymentClient.charge(order.total);
28
+ }
29
+
30
+ // Hard to mock
31
+ function processPayment(order) {
32
+ const client = new StripeClient(process.env.STRIPE_KEY);
33
+ return client.charge(order.total);
34
+ }
35
+ ```
36
+
37
+ **2. Prefer SDK-style interfaces over generic fetchers**
38
+
39
+ Create specific functions for each external operation instead of one generic function with conditional logic:
40
+
41
+ ```typescript
42
+ // GOOD: Each function is independently mockable
43
+ const api = {
44
+ getUser: (id) => fetch(`/users/${id}`),
45
+ getOrders: (userId) => fetch(`/users/${userId}/orders`),
46
+ createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
47
+ };
48
+
49
+ // BAD: Mocking requires conditional logic inside the mock
50
+ const api = {
51
+ fetch: (endpoint, options) => fetch(endpoint, options),
52
+ };
53
+ ```
54
+
55
+ The SDK approach means:
56
+ - Each mock returns one specific shape
57
+ - No conditional logic in test setup
58
+ - Easier to see which endpoints a test exercises
59
+ - Type safety per endpoint
@@ -0,0 +1,85 @@
1
+ # Good and Bad Tests
2
+
3
+ ## Good Tests
4
+
5
+ **Integration-style**: Test through real interfaces, not mocks of internal parts.
6
+
7
+ ```typescript
8
+ // GOOD: Tests observable behavior
9
+ test("user can checkout with valid cart", async () => {
10
+ const cart = createCart();
11
+ cart.add(product);
12
+ const result = await checkout(cart, paymentMethod);
13
+ expect(result.status).toBe("confirmed");
14
+ });
15
+ ```
16
+
17
+ Characteristics:
18
+
19
+ - Tests behavior users/callers care about
20
+ - Uses public API only
21
+ - Survives internal refactors
22
+ - Describes WHAT, not HOW
23
+ - One logical assertion per test
24
+
25
+ ## Bad Tests
26
+
27
+ **Implementation-detail tests**: Coupled to internal structure.
28
+
29
+ ```typescript
30
+ // BAD: Tests implementation details
31
+ test("checkout calls paymentService.process", async () => {
32
+ const mockPayment = jest.mock(paymentService);
33
+ await checkout(cart, payment);
34
+ expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
35
+ });
36
+ ```
37
+
38
+ Red flags:
39
+
40
+ - Mocking internal collaborators
41
+ - Testing private methods
42
+ - Asserting on call counts/order
43
+ - Test breaks when refactoring without behavior change
44
+ - Test name describes HOW not WHAT
45
+ - Verifying through external means instead of interface
46
+
47
+ ```typescript
48
+ // BAD: Bypasses interface to verify
49
+ test("createUser saves to database", async () => {
50
+ await createUser({ name: "Alice" });
51
+ const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
52
+ expect(row).toBeDefined();
53
+ });
54
+
55
+ // GOOD: Verifies through interface
56
+ test("createUser makes user retrievable", async () => {
57
+ const user = await createUser({ name: "Alice" });
58
+ const retrieved = await getUser(user.id);
59
+ expect(retrieved.name).toBe("Alice");
60
+ });
61
+ ```
62
+
63
+ ## Tautological Tests
64
+
65
+ **Tautological assertion**: expected value recomputed the way the code computes it — passes by construction and proves nothing.
66
+
67
+ ```typescript
68
+ // BAD: tautological — assertion mirrors the implementation
69
+ test("add returns the sum", () => {
70
+ const a = 3;
71
+ const b = 4;
72
+ expect(add(a, b)).toBe(a + b); // always true regardless of what add does
73
+ });
74
+
75
+ // GOOD: expected value from an independent source of truth
76
+ test("add returns the sum", () => {
77
+ expect(add(3, 4)).toBe(7); // 7 is a literal from a worked example
78
+ });
79
+ ```
80
+
81
+ Red flags:
82
+
83
+ - Expected value is computed using the same operator/function as the implementation
84
+ - Swapping the implementation for any expression that satisfies the same type would still pass
85
+ - The test can never catch an off-by-one or wrong-operator bug
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: to-spec
3
+ description: Turn the current conversation context into a Spec and publish it to the project issue tracker. Use when user wants to create a Spec from the current context.
4
+ ---
5
+
6
+ **Synthesize the current conversation into a Spec and publish it — no interview, no implementation.** Just synthesize what you already know from the conversation.
7
+
8
+ The issue tracker and triage label vocabulary should have been provided to you — run `/red-setup` if not.
9
+
10
+ <what-to-do>
11
+
12
+ ## Process
13
+
14
+ 1. Explore the repo to understand the current state of the codebase, if you haven't already. Use the project's domain glossary vocabulary throughout the Spec, and respect any ADRs in the area you're touching.
15
+
16
+ 2. Sketch out the testing seams for the feature. Prefer existing, high-level seams over new low-level ones. If new seams are needed, propose them at the highest point that can exercise the behavior.
17
+
18
+ Check with the user that these seams match their expectations.
19
+
20
+ **Capture every HITL call** made during the conversation that led to this Spec — testing seam choices, module shape choices, trade-offs the user took a side on, alternatives they rejected, constraints they imposed. These go into the `Human Decisions` section of the template. Do not silently fold them into `Implementation Decisions` — once `/to-tickets` slices this Spec and `/afk` picks up the children, the human's calls become indistinguishable from agent inference unless they are flagged here.
21
+
22
+ 3. **Cascade gate — run before publishing.** AFK workers branch from `origin/{base}` and cannot see the primary checkout's working-tree edits, so never publish while docs are unlanded.
23
+
24
+ a. `git fetch origin`, then compare the `.red/` docs (`.red/CONTEXT.md`, `.red/CONTEXT-MAP.md`, `.red/contexts/**`, `.red/adr/**`) between the primary working tree and `origin/{base}` (base resolved lock > pin > main). "Landed" means reachable from `origin/{base}`, not merely present on disk — origin-first comparison, mirroring the `/review-adrs` convention.
25
+ b. **On mismatch:** run the doc-landing procedure from the `/start` end-of-session finalizer (canonized by ADR 0092) first, then continue to step 4.
26
+ c. **If landing is impossible** (no network, no push access): abort — never publish while docs are unlanded. State clearly which files must be landed and stop.
27
+
28
+ 4. Write the Spec using the template below, then publish it to the project issue tracker.
29
+
30
+ **Labels on publish:** apply `type:spec` and `needs-slicing`. **Do not apply `ready-for-agent` to a Spec — a Spec is not an implementable unit; `/to-tickets` must slice it first.** `/afk` hard-filters anything tagged `type:spec` so an accidental `ready-for-agent` will be ignored, but the right pre-condition is to not set it in the first place.
31
+
32
+ The next step after publish is `/to-tickets` (manual or scheduled) which consumes `needs-slicing` Specs, generates child issues with `spec:{N}` + `ready-for-agent`, and removes `needs-slicing` from the parent.
33
+
34
+ </what-to-do>
35
+
36
+ <supporting-info>
37
+
38
+ <spec-template>
39
+
40
+ ## Problem Statement
41
+
42
+ The problem that the user is facing, from the user's perspective.
43
+
44
+ ## Solution
45
+
46
+ The solution to the problem, from the user's perspective.
47
+
48
+ ## User Stories
49
+
50
+ A LONG, numbered list of user stories. Each user story should be in the format of:
51
+
52
+ 1. As an <actor>, I want a <feature>, so that <benefit>
53
+
54
+ <user-story-example>
55
+ 1. As a mobile bank customer, I want to see balance on my accounts, so that I can make better informed decisions about my spending
56
+ </user-story-example>
57
+
58
+ This list of user stories should be extremely extensive and cover all aspects of the feature.
59
+
60
+ ## Human Decisions
61
+
62
+ Calls the human made during the conversation that produced this Spec. These are load-bearing — they reflect judgement that the agent could not have inferred on its own and must survive into the slicing + implementation phases. One bullet per decision, in this shape:
63
+
64
+ - **Decision:** what was decided
65
+ - **Why:** the reason the human gave
66
+ - **Alternatives considered:** options that were rejected and why (omit if not applicable)
67
+
68
+ If a decision is genuinely just agent inference, it does not belong here — put it in `Implementation Decisions` instead.
69
+
70
+ ## Implementation Decisions
71
+
72
+ A list of implementation decisions that were made. This can include:
73
+
74
+ - The modules that will be built/modified
75
+ - The interfaces of those modules that will be modified
76
+ - Technical clarifications from the developer
77
+ - Architectural decisions
78
+ - Schema changes
79
+ - API contracts
80
+ - Specific interactions
81
+
82
+ Do NOT include specific file paths or code snippets. They may end up being outdated very quickly.
83
+
84
+ Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it within the relevant decision and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
85
+
86
+ ## Testing Decisions
87
+
88
+ A list of testing decisions that were made. Include:
89
+
90
+ - A description of what makes a good test (only test external behavior, not implementation details)
91
+ - Which seams or modules will be tested
92
+ - Prior art for the tests (i.e. similar types of tests in the codebase)
93
+
94
+ ## Out of Scope
95
+
96
+ A description of the things that are out of scope for this Spec.
97
+
98
+ ## Further Notes
99
+
100
+ Any further notes about the feature.
101
+
102
+ </spec-template>
103
+
104
+ </supporting-info>
@@ -0,0 +1,158 @@
1
+ ---
2
+ name: to-tickets
3
+ description: Break a plan or Spec into independently-grabbable Tickets on the project issue tracker using tracer-bullet vertical slices. Use when user wants to convert a plan into Tickets, create implementation Tickets, or break down work into Tickets.
4
+ ---
5
+
6
+ # To Tickets
7
+
8
+ **Break a plan into independently-grabbable vertical slices and publish them to the issue tracker.**
9
+
10
+ The issue tracker and triage label vocabulary should have been provided to you — if not, ask the user to run `/red-setup` and stop.
11
+
12
+ <what-to-do>
13
+
14
+ ### Step 1 — Gather context
15
+
16
+ Work from whatever is already in the conversation context. If the user passes an issue reference (issue number, URL, or path) as an argument, fetch it from the issue tracker and read its **full body and all comments** before continuing.
17
+
18
+ ### Step 2 — Explore the codebase (only if you haven't already)
19
+
20
+ Skip if the current conversation already explored. Otherwise: read enough to understand the current state. Issue titles and descriptions **must** use the project's domain glossary vocabulary. Respect ADRs in the area you're touching.
21
+
22
+ ### Step 3 — Draft vertical slices
23
+
24
+ Break the plan into **tracer-bullet** issues. Each slice cuts end-to-end through every layer.
25
+
26
+ Apply the rules in `<supporting-info>` literally. The cardinal one: **vertical, not horizontal.**
27
+
28
+ Mark each slice with its routing class:
29
+
30
+ (i) **AFK** — mergeable without human decision
31
+ (ii) **HITL** — requires an architecture call or human judgment (design review, external access)
32
+
33
+ Prefer AFK over HITL wherever possible.
34
+
35
+ **File disjunction check — serialize entangled slices.** After assigning routing classes, inspect every pair of parallel slices (those with no `req:N` edge between them) for file-set overlap. Two slices are *entangled* when they both write to the same file(s). Entangled concurrent slices produce a merge conflict that no runtime resolves — the conflict is inherent, not recoverable. Serialize them: add a `req:N` dependency edge from the later slice to the earlier one so only one is `ready-for-agent` at a time. Parallel slots belong exclusively to *file-disjoint* slices that touch non-overlapping file sets. This is the canonical serialization mechanism; the AFK fleet width is calibrated from the resulting disjunction structure (see `/afk fleet` docs).
36
+
37
+ ### Step 4 — Quiz the user (mandatory — do not skip)
38
+
39
+ Present the proposed breakdown as a numbered list. For each slice show:
40
+
41
+ - **Title** — short descriptive name
42
+ - **Type** — HITL / AFK
43
+ - **Blocked by** — which other slices (if any) must complete first
44
+ - **User stories covered** — which user stories this addresses (if the source has them)
45
+
46
+ Then ask, **explicitly**:
47
+
48
+ - Does the granularity feel right? (too coarse / too fine)
49
+ - Are the dependency relationships correct?
50
+ - Should any slices be merged or split further?
51
+ - Are the correct slices marked HITL vs AFK?
52
+
53
+ **Iterate until the user approves the breakdown.** Do not advance to Step 5 on silence or implicit approval.
54
+
55
+ ### Step 5 — Cascade gate
56
+
57
+ **Verify referenced `.red/` docs are landed on `origin/{base}` before publishing** — AFK workers branch from `origin/{base}` and cannot see the primary checkout's working-tree edits, so never publish while docs are unlanded.
58
+
59
+ 1. `git fetch origin`, then compare the `.red/` docs (`.red/CONTEXT.md`, `.red/CONTEXT-MAP.md`, `.red/contexts/**`, `.red/adr/**`) between the primary working tree and `origin/{base}` (base resolved lock > pin > main). "Landed" means reachable from `origin/{base}`, not merely present on disk — origin-first comparison, mirroring the `/review-adrs` convention.
60
+ 2. **On mismatch:** run the doc-landing procedure from the `/start` end-of-session finalizer (canonized by ADR 0092) first, then continue to Step 6.
61
+ 3. **If landing is impossible** (no network, no push access): abort — never publish while docs are unlanded. State clearly which files must be landed and stop.
62
+
63
+ ### Step 6 — Publish in dependency order
64
+
65
+ For each approved slice, publish a new issue. Use the issue template in `<supporting-info>`.
66
+
67
+ - Publish in **dependency order** (blockers first) so you can reference real issue identifiers in each "Blocked by" field
68
+ - Tag only currently-unblocked AFK slices with the canonical `ready-for-agent` triage label (mapped string from `/red-setup`).
69
+ - If an AFK slice has open blockers, publish it as `blocked:dependency` + one `req:N` label **per blocker** (NOT `ready-for-human` — a dependency-blocked slice is healthy and must never page a human). Also create the tracker-native blocked-by relationship for each blocker using `/red-setup` issue-tracker-github *Dependency & hierarchy operations*. The native blocked-by relationship is the human surface; req:N labels remain the machine truth for `/afk` close cascade, boot sweep, and gate census. Keep the strict `## Blocked by` task list in the body as the ADR 0094 AFK boot-sweep fallback and human-facing mirror. `req:N` labels are created on demand (`gh label create req:<n>` if missing). `/afk` auto-promotes the issue to `ready-for-agent` the moment its last dependency closes (event-driven close cascade, with the boot sweep as a safety net). See `/red-setup` triage-labels *Dependency Edges* and ADR 0094.
70
+ - **`req:N` targets must be executable slices, never a Spec** (authoritative statement + rationale in Hard rules below). Before creating each `req:N` label, check the target with `gh issue view N --json labels`: if #N carries `type:spec`, **refuse the edge** and re-point it at the Spec's concrete executable slice(s) instead (the child issues carrying `spec:N`); when the Spec has no slices yet, first create the concrete slice the dependent actually waits on, then point `req:N` at that slice.
71
+ - If a slice is HITL, publish it as `ready-for-human`. Do **not** include a literal `## Blocked by` section unless it should be auto-promoted to AFK after blockers close; use `## Current blocker` / `## Human decision needed` for gates, measurements, and decisions where closing a referenced issue is not enough to make the slice delegable.
72
+ - If the parent is a Spec (carries `type:spec` + `needs-slicing`), tag every child with `spec:{N}` referencing the parent and create the tracker-native sub-issue relationship from the parent Spec to the child Ticket using `/red-setup` issue-tracker-github *Dependency & hierarchy operations*. The native sub-issue relationship is the human surface; `spec:{N}` remains the label contract. After all slices are published, remove `needs-slicing` from the parent Spec. Never remove `type:spec` — it is a permanent type marker. Never apply `ready-for-agent` to the parent Spec itself.
73
+
74
+ ### Hard rules — do not break these
75
+
76
+ - ❌ Do **not** mark two slices as parallelizable when they write to the same file(s) — that is a file-entanglement merge conflict waiting to happen at landing. Add `req:N` edges to serialize them instead; file-disjoint slices run in parallel, entangled ones run serial.
77
+ - ❌ Do **not** publish until the user explicitly approved the breakdown in Step 4
78
+ - ❌ Do **not** modify or close any parent issue
79
+ - ❌ Do **not** create horizontal-slice issues ("the schema layer", "the API layer", "the UI layer")
80
+ - ❌ Do **not** invent label strings — use the mapping from `/red-setup`
81
+ - ❌ Do **not** create a `req:N` edge whose target #N is a `type:spec` — dependency edges must point at executable slices. A Spec closes only after a manual bookkeeping step long after its substance ships (#907/#928: 46/46 children closed, Specs still open), so a `req:<Spec>` edge strands the dependent in `blocked:dependency` forever. Re-point at the Spec's `spec:N` children, or, when the Spec has no slices yet, first create the concrete slice the dependent waits on and point `req:N` at that.
82
+ - ❌ Do **not** "clean up" controlled redundancy between native tracker edges and labels/body text. Do not clean up either side: native sub-issue relationship and native blocked-by relationship edges are for humans; req:N labels remain the machine truth; the `## Blocked by` body fallback stays for compatibility.
83
+ - ❌ Do **not** inline file paths or code snippets in issue bodies — they go stale. The one exception is in `<supporting-info>` (decision-rich prototype output)
84
+ - ✅ **Do** publish in dependency order so "Blocked by" fields point at real issue IDs
85
+ - ✅ **Do** prefer many thin slices over few thick ones
86
+
87
+ </what-to-do>
88
+
89
+ <supporting-info>
90
+
91
+ ## Vertical-slice rules
92
+
93
+ <vertical-slice-rules>
94
+ - Each slice delivers a narrow but COMPLETE path through every layer (schema, API, UI, tests)
95
+ - A completed slice is demoable or verifiable on its own
96
+ - Prefer many thin slices over few thick ones
97
+ - Parallel slices must be file-disjoint; file-overlapping slices get `req:N` serialization edges so they run serial, not concurrent
98
+ </vertical-slice-rules>
99
+
100
+ A horizontal slice ("build the schema for all tables") cannot be demoed and cannot be merged independently — it produces issues that block each other unnecessarily and tests imagined behaviour.
101
+
102
+ ## Issue body template
103
+
104
+ <issue-template>
105
+ ## Parent
106
+
107
+ A reference to the parent Spec on the issue tracker, written as a literal `Spec #N` line (if the source was an existing Spec, otherwise omit this section). The `/afk` pin-reader parses this exact `Spec #N` form to inherit the parent's `branch:` pin — keep the word `Spec` and the `#N` reference literal.
108
+
109
+ ## What to build
110
+
111
+ A concise description of this vertical slice. Describe the end-to-end behaviour, not layer-by-layer implementation.
112
+
113
+ Avoid specific file paths or code snippets — they go stale fast. **Exception**: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it here and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
114
+
115
+ ## Acceptance criteria
116
+
117
+ - [ ] Criterion 1
118
+ - [ ] Criterion 2
119
+ - [ ] Criterion 3
120
+
121
+ ## Blocked by
122
+
123
+ - [ ] #123
124
+ - [ ] #456
125
+
126
+ Format: one GitHub task-list tracking entry per blocker, `- [ ] #N`. This is not GitHub's issue-dependencies widget. Its job is the ADR 0094 body fallback: the `/afk` boot sweep parses this exact section to auto-promote issues whose blockers have all closed, and humans still get a readable mirror in the issue body. Keep the heading literal (`## Blocked by`, capitalised, no extra punctuation) and the format strict.
127
+
128
+ This section is the body fallback required by ADR 0094. When the tracker supports native edges, publish the native blocked-by relationship too; keep this section anyway so older paths and audits retain the same source shape.
129
+
130
+ Omit the section entirely (do not write "None") if the slice has no blockers.
131
+
132
+ For a human gate, use this shape instead:
133
+
134
+ ```markdown
135
+ ## Current blocker
136
+
137
+ <!-- red:blocker-state v1 -->
138
+ status: blocked
139
+ kind: decision
140
+ ref: #123
141
+ summary: The dependency closed, but the measurement did not prove the required win.
142
+ next: Human must decide whether to stop, redesign, or continue anyway.
143
+ <!-- /red:blocker-state -->
144
+ ```
145
+
146
+ </issue-template>
147
+
148
+ ## Wide refactors — expand → migrate → contract
149
+
150
+ **When a change is blast-radius-wide** (a rename, signature change, or API move touching dozens of call sites), a single vertical slice cannot both stay small and stay mergeable. Slice it as an **expand–contract** chain instead — three (or more) Tickets that each merge green on their own:
151
+
152
+ 1. **Expand.** Introduce the new form *alongside* the old one — new function/flag/label/type added, old one untouched and still authoritative. Nothing calls the new form yet. This Ticket merges without changing any behaviour.
153
+ 2. **Migrate.** Move call sites onto the new form, in one Ticket per independently-verifiable batch (by package, by layer, or by directory). Each batch merges green because the old form still exists as a fallback. Many thin migration Tickets beat one giant one — a failed batch never blocks the others.
154
+ 3. **Contract.** Once every call site is migrated, remove the old form in a final Ticket. This is the only Ticket that deletes the old vocabulary, and it is `blocked:dependency` on all the migration Tickets (one `req:N` per batch).
155
+
156
+ **Big-bang exception.** Some flips must NOT expand–contract — when the two forms cannot coexist (a single atomic label/flag rename with no transition window, e.g. ADR 0093's vocabulary flip), slice it as one Ticket that changes definition + call sites + tests together, and say so explicitly in the Ticket body so a reviewer does not expect a fallback. Prefer expand–contract; reach for big-bang only when coexistence is genuinely impossible or the maintainer decided against a transition window.
157
+
158
+ </supporting-info>