@jaybeeuu/agent-cortex 1.20.0
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.
- package/.beads/README.md +81 -0
- package/.beads/config.yaml +1 -0
- package/.beads/issues.jsonl +236 -0
- package/.beads/metadata.json +7 -0
- package/.claude-plugin/marketplace.json +16 -0
- package/.github/workflows/ci.test.ts +217 -0
- package/.github/workflows/ci.yml +35 -0
- package/.github/workflows/publish.yml +36 -0
- package/.junie/guidelines.md +87 -0
- package/.junie/mcp/mcp.json +10 -0
- package/AGENTS.md +102 -0
- package/CHANGELOG.md +705 -0
- package/README.md +209 -0
- package/agents/README.md +235 -0
- package/agents/plan.agent.md +56 -0
- package/agents/ralph-plan.agent.md +119 -0
- package/agents/ralph.agent.md +305 -0
- package/agents/strategy.agent.md +109 -0
- package/agents-native/ralph.md +193 -0
- package/bin/agent-cortex.mjs +27 -0
- package/claude/.claude-plugin/plugin.json +11 -0
- package/claude/.mcp.json +18 -0
- package/claude/agents/plan.md +56 -0
- package/claude/agents/ralph-plan.md +119 -0
- package/claude/agents/ralph.md +193 -0
- package/claude/agents/strategy.md +109 -0
- package/claude/hooks.json +23 -0
- package/claude/scripts/statusline-command.sh +124 -0
- package/docs/ideas/auto-model-selection.md +75 -0
- package/docs/ideas/improve-pi-system-prompt.md +34 -0
- package/docs/ideas/model-selector.md +40 -0
- package/docs/ideas/pi-task-memory.md +34 -0
- package/docs/ideas/qa-extension.md +43 -0
- package/docs/inspirations.md +33 -0
- package/docs/research/gas-city-research.md +256 -0
- package/docs/research/skill-design-research.md +286 -0
- package/docs/research/skill-improvements-analysis.md +117 -0
- package/docs/research/skill-patterns-research.md +24 -0
- package/docs/skills/skill-anatomy.md +149 -0
- package/docs/user-preferences.md +17 -0
- package/extensions/agent-modes/index.ts +507 -0
- package/extensions/auto-name.ts +107 -0
- package/extensions/context-loader.md +35 -0
- package/extensions/context-loader.ts +65 -0
- package/extensions/lib/tiny-model.ts +212 -0
- package/extensions/notify/index.ts +293 -0
- package/extensions/session-start.ts +44 -0
- package/extensions/skill-stats/README.md +74 -0
- package/extensions/skill-stats/context-loader.test.ts +107 -0
- package/extensions/skill-stats/discover.ts +119 -0
- package/extensions/skill-stats/format.ts +13 -0
- package/extensions/skill-stats/index.test.ts +452 -0
- package/extensions/skill-stats/index.ts +222 -0
- package/extensions/skill-stats/package.json +19 -0
- package/extensions/skill-stats/pnpm-lock.yaml +329 -0
- package/extensions/skill-stats/record.ts +48 -0
- package/extensions/skill-stats/store.ts +104 -0
- package/extensions/skill-stats/tsconfig.json +12 -0
- package/extensions/subagent/README.md +175 -0
- package/extensions/subagent/agents/planner.md +37 -0
- package/extensions/subagent/agents/reviewer.md +35 -0
- package/extensions/subagent/agents/scout.md +50 -0
- package/extensions/subagent/agents/worker.md +24 -0
- package/extensions/subagent/agents.ts +126 -0
- package/extensions/subagent/index.ts +1138 -0
- package/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/extensions/subagent/prompts/implement.md +10 -0
- package/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/hooks.json +10 -0
- package/lib/cli.mjs +37 -0
- package/package.json +39 -0
- package/pi/keybindings.json +3 -0
- package/pi/settings.json +29 -0
- package/plugin.json +35 -0
- package/pnpm-workspace.yaml +7 -0
- package/scripts/build-claude-agents.mjs +179 -0
- package/scripts/install-instructions.sh +82 -0
- package/skills/engineering/design-an-interface/SKILL.md +94 -0
- package/skills/engineering/grill-with-docs/SKILL.md +88 -0
- package/skills/engineering/improve-codebase-architecture/REFERENCE.md +78 -0
- package/skills/engineering/improve-codebase-architecture/SKILL.md +81 -0
- package/skills/engineering/tdd/SKILL.md +150 -0
- package/skills/engineering/tdd/deep-modules.md +33 -0
- package/skills/engineering/tdd/interface-design.md +31 -0
- package/skills/engineering/tdd/mocking.md +59 -0
- package/skills/engineering/tdd/refactoring.md +10 -0
- package/skills/engineering/tdd/tests.md +61 -0
- package/skills/engineering/technical-direction/SKILL.md +86 -0
- package/skills/planning/classify-bead/SKILL.md +67 -0
- package/skills/planning/create-task/SKILL.md +96 -0
- package/skills/planning/create-task/pipeline.json +33 -0
- package/skills/planning/create-task/scripts/create-chores.ts +112 -0
- package/skills/planning/create-task/scripts/package.json +14 -0
- package/skills/planning/create-task/scripts/pnpm-lock.yaml +342 -0
- package/skills/planning/create-task/scripts/tsconfig.json +12 -0
- package/skills/planning/create-task/templates/code.md +40 -0
- package/skills/planning/create-task/templates/document.md +40 -0
- package/skills/planning/create-task/templates/fix.md +27 -0
- package/skills/planning/create-task/templates/review.md +36 -0
- package/skills/planning/create-task/templates/verify.md +43 -0
- package/skills/planning/prd-to-tasks/SKILL.md +227 -0
- package/skills/planning/record-idea/SKILL.md +62 -0
- package/skills/planning/record-idea/scripts/new-idea.sh +89 -0
- package/skills/planning/request-refactor-plan/SKILL.md +73 -0
- package/skills/planning/write-a-prd/SKILL.md +74 -0
- package/skills/planning/write-a-ticket/SKILL.md +97 -0
- package/skills/productivity/bd-tool/SKILL.md +90 -0
- package/skills/productivity/grill-me/SKILL.md +10 -0
- package/skills/productivity/handoff/SKILL.md +15 -0
- package/skills/productivity/init-beads/SKILL.md +93 -0
- package/skills/productivity/teach/GLOSSARY-FORMAT.md +35 -0
- package/skills/productivity/teach/LEARNING-RECORD-FORMAT.md +46 -0
- package/skills/productivity/teach/MISSION-FORMAT.md +31 -0
- package/skills/productivity/teach/RESOURCES-FORMAT.md +32 -0
- package/skills/productivity/teach/SKILL.md +109 -0
- package/skills/productivity/validate-agent-dir/scripts/package.json +15 -0
- package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +329 -0
- package/skills/productivity/validate-agent-dir/scripts/pnpm-workspace.yaml +2 -0
- package/skills/productivity/validate-agent-dir/scripts/tsconfig.json +19 -0
- package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.test.ts +317 -0
- package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.ts +127 -0
- package/skills/productivity/write-a-skill/SKILL.md +74 -0
- package/skills/review/maintain-agent-docs/REFERENCE.md +246 -0
- package/skills/review/maintain-agent-docs/SKILL.md +83 -0
- package/skills/review/refactor-skill/EXAMPLES.md +20 -0
- package/skills/review/refactor-skill/SKILL.md +148 -0
- package/skills/review/review-security/SKILL.md +107 -0
- package/skills/review/review-security/scripts/install-gitleaks.sh +43 -0
- package/skills/style/style-code/REFERENCE.md +38 -0
- package/skills/style/style-code/SKILL.md +113 -0
- package/skills/style/style-comms/SKILL.md +93 -0
- package/skills/style/style-documentation/SKILL.md +112 -0
- package/skills/style/style-tests/SKILL.md +97 -0
- package/skills/workflow/git-workflow/SKILL.md +85 -0
- package/skills/workflow/hitl-collab/SKILL.md +29 -0
- package/skills/workflow/plan/SKILL.md +272 -0
- package/skills/workflow/ralph/REFERENCE.md +202 -0
- package/skills/workflow/ralph/SKILL.md +105 -0
- package/skills/workflow/run-pipeline-stage/SKILL.md +151 -0
- package/skills/workflow/run-pipeline-stage/playbooks/code.md +17 -0
- package/skills/workflow/run-pipeline-stage/playbooks/document.md +18 -0
- package/skills/workflow/run-pipeline-stage/playbooks/fix.md +17 -0
- package/skills/workflow/run-pipeline-stage/playbooks/review.md +19 -0
- package/skills/workflow/run-pipeline-stage/playbooks/verify.md +14 -0
- package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +20 -0
- package/skills/workflow/run-pipeline-stage/scripts/generate-progress.test.ts +783 -0
- package/skills/workflow/run-pipeline-stage/scripts/generate-progress.ts +586 -0
- package/skills/workflow/run-pipeline-stage/scripts/package.json +15 -0
- package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +342 -0
- package/skills/workflow/run-pipeline-stage/scripts/pnpm-workspace.yaml +2 -0
- package/skills/workflow/run-pipeline-stage/scripts/tsconfig.json +12 -0
- package/skills/workflow/using-agent-skills/SKILL.md +109 -0
- package/skills/workflow/using-agent-skills/scripts/validate-skill-structure.test.ts +73 -0
- package/test/cli.test.mjs +149 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Reference
|
|
2
|
+
|
|
3
|
+
## Dependency Categories
|
|
4
|
+
|
|
5
|
+
When assessing a candidate for deepening, classify its dependencies:
|
|
6
|
+
|
|
7
|
+
### 1. In-process
|
|
8
|
+
|
|
9
|
+
Pure computation, in-memory state, no I/O. Always deepenable — just merge the modules and test directly.
|
|
10
|
+
|
|
11
|
+
### 2. Local-substitutable
|
|
12
|
+
|
|
13
|
+
Dependencies that have local test stand-ins (e.g., PGLite for Postgres, in-memory filesystem). Deepenable if the test substitute exists. The deepened module is tested with the local stand-in running in the test suite.
|
|
14
|
+
|
|
15
|
+
### 3. Remote but owned (Ports & Adapters)
|
|
16
|
+
|
|
17
|
+
Your own services across a network boundary (microservices, internal APIs). Define a port (interface) at the module boundary. The deep module owns the logic; the transport is injected. Tests use an in-memory adapter. Production uses the real HTTP/gRPC/queue adapter.
|
|
18
|
+
|
|
19
|
+
Recommendation shape: "Define a shared interface (port), implement an HTTP adapter for production and an in-memory adapter for testing, so the logic can be tested as one deep module even though it's deployed across a network boundary."
|
|
20
|
+
|
|
21
|
+
### 4. True external (Mock)
|
|
22
|
+
|
|
23
|
+
Third-party services (Stripe, Twilio, etc.) you don't control. Mock at the boundary. The deepened module takes the external dependency as an injected port, and tests provide a mock implementation.
|
|
24
|
+
|
|
25
|
+
## Testing Strategy
|
|
26
|
+
|
|
27
|
+
The core principle: **replace, don't layer.**
|
|
28
|
+
|
|
29
|
+
- Old unit tests on shallow modules are waste once boundary tests exist — delete them
|
|
30
|
+
- Write new tests at the deepened module's interface boundary
|
|
31
|
+
- Tests assert on observable outcomes through the public interface, not internal state
|
|
32
|
+
- Tests should survive internal refactors — they describe behavior, not implementation
|
|
33
|
+
|
|
34
|
+
## Bead Description Template
|
|
35
|
+
|
|
36
|
+
<bead-template>
|
|
37
|
+
|
|
38
|
+
## Problem
|
|
39
|
+
|
|
40
|
+
Describe the architectural friction:
|
|
41
|
+
|
|
42
|
+
- Which modules are shallow and tightly coupled
|
|
43
|
+
- What integration risk exists in the seams between them
|
|
44
|
+
- Why this makes the codebase harder to navigate and maintain
|
|
45
|
+
|
|
46
|
+
## Proposed Interface
|
|
47
|
+
|
|
48
|
+
The chosen interface design:
|
|
49
|
+
|
|
50
|
+
- Interface signature (types, methods, params)
|
|
51
|
+
- Usage example showing how callers use it
|
|
52
|
+
- What complexity it hides internally
|
|
53
|
+
|
|
54
|
+
## Dependency Strategy
|
|
55
|
+
|
|
56
|
+
Which category applies and how dependencies are handled:
|
|
57
|
+
|
|
58
|
+
- **In-process**: merged directly
|
|
59
|
+
- **Local-substitutable**: tested with [specific stand-in]
|
|
60
|
+
- **Ports & adapters**: port definition, production adapter, test adapter
|
|
61
|
+
- **Mock**: mock boundary for external services
|
|
62
|
+
|
|
63
|
+
## Testing Strategy
|
|
64
|
+
|
|
65
|
+
- **New boundary tests to write**: describe the behaviors to verify at the interface
|
|
66
|
+
- **Old tests to delete**: list the shallow module tests that become redundant
|
|
67
|
+
- **Test environment needs**: any local stand-ins or adapters required
|
|
68
|
+
|
|
69
|
+
## Implementation Recommendations
|
|
70
|
+
|
|
71
|
+
Durable architectural guidance that is NOT coupled to current file paths:
|
|
72
|
+
|
|
73
|
+
- What the module should own (responsibilities)
|
|
74
|
+
- What it should hide (implementation details)
|
|
75
|
+
- What it should expose (the interface contract)
|
|
76
|
+
- How callers should migrate to the new interface
|
|
77
|
+
|
|
78
|
+
</bead-template>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: improve-codebase-architecture
|
|
3
|
+
description: Explore a codebase to find opportunities for architectural improvement, focusing on making the codebase more testable by deepening shallow modules. Use when user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more AI-navigable.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Improve Codebase Architecture
|
|
7
|
+
|
|
8
|
+
Explore a codebase like an AI would, surface architectural friction, discover opportunities for improving testability, and propose module-deepening refactors as beads.
|
|
9
|
+
|
|
10
|
+
A **deep module** (John Ousterhout, "A Philosophy of Software Design") has a small interface hiding a large implementation. Deep modules are more testable, more AI-navigable, and let you test at the boundary instead of inside.
|
|
11
|
+
|
|
12
|
+
## Process
|
|
13
|
+
|
|
14
|
+
### 1. Explore the codebase
|
|
15
|
+
|
|
16
|
+
Explore the codebase using your available tools (bash, rg, view, glob, find). Navigate organically and note where you experience friction:
|
|
17
|
+
|
|
18
|
+
- Where does understanding one concept require bouncing between many small files?
|
|
19
|
+
- Where are modules so shallow that the interface is nearly as complex as the implementation?
|
|
20
|
+
- Where have pure functions been extracted just for testability, but the real bugs hide in how they're called?
|
|
21
|
+
- Where do tightly-coupled modules create integration risk in the seams between them?
|
|
22
|
+
- Which parts of the codebase are untested, or hard to test?
|
|
23
|
+
|
|
24
|
+
The friction you encounter IS the signal.
|
|
25
|
+
|
|
26
|
+
### 2. Present candidates
|
|
27
|
+
|
|
28
|
+
Present a numbered list of deepening opportunities. For each candidate, show:
|
|
29
|
+
|
|
30
|
+
- **Cluster**: Which modules/concepts are involved
|
|
31
|
+
- **Why they're coupled**: Shared types, call patterns, co-ownership of a concept
|
|
32
|
+
- **Dependency category**: See [REFERENCE.md](REFERENCE.md) for the four categories
|
|
33
|
+
- **Test impact**: What existing tests would be replaced by boundary tests
|
|
34
|
+
|
|
35
|
+
Do NOT propose interfaces yet. Ask the user: "Which of these would you like to explore?"
|
|
36
|
+
|
|
37
|
+
### 3. User picks a candidate
|
|
38
|
+
|
|
39
|
+
### 4. Frame the problem space
|
|
40
|
+
|
|
41
|
+
Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate:
|
|
42
|
+
|
|
43
|
+
- The constraints any new interface would need to satisfy
|
|
44
|
+
- The dependencies it would need to rely on
|
|
45
|
+
- A rough illustrative code sketch to make the constraints concrete — this is not a proposal, just a way to ground the constraints
|
|
46
|
+
|
|
47
|
+
Show this to the user, then immediately proceed to Step 5. The user reads and thinks about the problem while the sub-agents work in parallel.
|
|
48
|
+
|
|
49
|
+
### 5. Design multiple interfaces
|
|
50
|
+
|
|
51
|
+
Design multiple radically different interfaces for the deepened module yourself, cycling through different constraints. For each design, write out the complete interface and evaluate it before moving to the next:
|
|
52
|
+
|
|
53
|
+
1. **Minimal interface** — aim for 1-3 entry points max. What complexity can you hide behind a small surface area?
|
|
54
|
+
2. **Flexible interface** — support many use cases and extension. How do you make it open for future needs?
|
|
55
|
+
3. **Caller-optimised** — make the most common calling pattern trivial. What does the primary caller look like?
|
|
56
|
+
4. **Ports & adapters** (if cross-boundary deps) — isolate side effects from pure logic.
|
|
57
|
+
|
|
58
|
+
For each design, output:
|
|
59
|
+
|
|
60
|
+
1. Interface signature (types, methods, params)
|
|
61
|
+
2. Usage example showing how callers use it
|
|
62
|
+
3. What complexity it hides internally
|
|
63
|
+
4. Dependency strategy (how deps are handled — see [REFERENCE.md](REFERENCE.md))
|
|
64
|
+
5. Trade-offs
|
|
65
|
+
|
|
66
|
+
The `design-an-interface` skill provides a structured approach for this step — invoke it if you want a guided parallel-design flow with sub-agents.
|
|
67
|
+
|
|
68
|
+
Present designs sequentially, then compare them in prose.
|
|
69
|
+
|
|
70
|
+
After comparing, give your own recommendation: which design you think is strongest and why. If elements from different designs would combine well, propose a hybrid. Be opinionated — the user wants a strong read, not just a menu.
|
|
71
|
+
|
|
72
|
+
### 6. User picks an interface (or accepts recommendation)
|
|
73
|
+
|
|
74
|
+
### 7. Create refactor bead
|
|
75
|
+
|
|
76
|
+
Invoke the `create-task` skill, passing:
|
|
77
|
+
- **title**: a concise name for the refactor
|
|
78
|
+
- **description**: the bead body using the template in [REFERENCE.md](REFERENCE.md)
|
|
79
|
+
- **priority**: P2
|
|
80
|
+
|
|
81
|
+
**Always use `create-task`** — never call `bd create` directly for tasks. `create-task` classifies the bead and expands AFK tasks into pipeline stage children that ralph can execute. Do NOT ask the user to review before creating — just create it and share the bead ID.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: Test-driven development with red-green-refactor loop. Use when building features or fixing bugs — or when you mention "red-green-refactor", want "test-first development", or need "tracer bullet" implementation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test-Driven Development
|
|
7
|
+
|
|
8
|
+
## When to use
|
|
9
|
+
|
|
10
|
+
- Building features or fixing bugs where correctness matters.
|
|
11
|
+
- Asked for "test-first", "TDD", "red-green-refactor", or "tracer bullets".
|
|
12
|
+
- Designing complex logic where fast feedback on correctness is valuable.
|
|
13
|
+
|
|
14
|
+
## When NOT to use
|
|
15
|
+
|
|
16
|
+
- Prototyping, throwaway code, or exploratory spikes where speed of discovery matters more than correctness.
|
|
17
|
+
- Changes so trivial that tests would duplicate type or lint coverage (rename, pure data shuffle).
|
|
18
|
+
- When the test-to-implementation ratio would be absurdly high — a one-line change requiring extensive test setup.
|
|
19
|
+
- Testing documentation or skill files to prove content exists in markdown. Tests verify executable code, not prose. If you want to validate a SKILL.md structure, use a linter or schema check instead.
|
|
20
|
+
|
|
21
|
+
## Philosophy / rationale
|
|
22
|
+
|
|
23
|
+
- **Tests verify behaviour through public interfaces, not implementation details.** Code can change entirely; tests should not. A passing test should survive a refactor that preserves behaviour.
|
|
24
|
+
- **Vertical tracer bullets beat horizontal slice-and-pray.** One test → one implementation → repeat. Each test responds to what you learned from the previous cycle. Writing all tests first tests imagined behaviour, not actual behaviour.
|
|
25
|
+
- **RED means you have a specification.** GREEN means it works. REFACTOR means make it read well — run `style-code` to guide the refactoring shape. Each state has a purpose; do not skip or blur them.
|
|
26
|
+
|
|
27
|
+
## Workflow
|
|
28
|
+
|
|
29
|
+
### 1. Plan
|
|
30
|
+
|
|
31
|
+
Before writing any code:
|
|
32
|
+
|
|
33
|
+
- Confirm with the user what interface changes are needed.
|
|
34
|
+
- Confirm which behaviours to test and prioritise them.
|
|
35
|
+
- Design interfaces for testability.
|
|
36
|
+
- List the behaviours to test (not implementation steps).
|
|
37
|
+
|
|
38
|
+
You cannot test everything. Focus testing effort on critical paths and complex logic, not every possible edge case.
|
|
39
|
+
|
|
40
|
+
### 2. Tracer bullet
|
|
41
|
+
|
|
42
|
+
Write ONE test that confirms ONE thing about the system:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
RED: Write test for first behaviour → test fails
|
|
46
|
+
GREEN: Write minimal code to pass → test passes
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This is your tracer bullet — it proves the path works end-to-end.
|
|
50
|
+
|
|
51
|
+
### 3. Incremental loop
|
|
52
|
+
|
|
53
|
+
For each remaining behaviour:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
RED: Write next test → fails
|
|
57
|
+
GREEN: Minimal code to pass → passes
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Rules:
|
|
61
|
+
- One test at a time.
|
|
62
|
+
- Only enough code to pass the current test.
|
|
63
|
+
- Do not anticipate future tests.
|
|
64
|
+
- Keep tests focused on observable behaviour.
|
|
65
|
+
|
|
66
|
+
### 4. Refactor
|
|
67
|
+
|
|
68
|
+
After all tests pass, run `style-code` to guide the refactoring shape:
|
|
69
|
+
|
|
70
|
+
- Extract duplication.
|
|
71
|
+
- Deepen modules — move complexity behind simple interfaces.
|
|
72
|
+
- Apply SOLID principles where natural.
|
|
73
|
+
- Consider what the new code reveals about existing code.
|
|
74
|
+
- Run tests after each refactor step.
|
|
75
|
+
|
|
76
|
+
**Never refactor while RED.** Get to GREEN first.
|
|
77
|
+
|
|
78
|
+
## Red Flags
|
|
79
|
+
|
|
80
|
+
- **Horizontal slicing.** Writing all tests first, then all implementation. You end up testing imagined behaviour, commit to test structure before understanding the implementation, and produce tests that pass when behaviour breaks and fail when it is fine.
|
|
81
|
+
- **Refactoring while RED.** The safety net is not up yet. Get to GREEN before restructuring.
|
|
82
|
+
- **Anticipating future tests.** Writing code you do not need yet because a future test will require it. It nearly always guesses the wrong shape.
|
|
83
|
+
- **Testing implementation details.** Coupling tests to internal structure so they break when you rename a private function or restructure internals. Test the public interface.
|
|
84
|
+
|
|
85
|
+
## Common Rationalizations
|
|
86
|
+
|
|
87
|
+
| Rationalization | Rebuttal |
|
|
88
|
+
|---|---|
|
|
89
|
+
| "I will write the tests after" | Tests written after code tend to test what the code does, not what it should do. You lose the specification benefit of TDD. |
|
|
90
|
+
| "TDD is slower" | TDD front-loads time but saves debugging time. Net neutral or faster for anything non-trivial. |
|
|
91
|
+
| "This is too simple for TDD" | The simplest changes often have the most hidden assumptions. TDD surfaces them early. |
|
|
92
|
+
| "I already know what the implementation looks like" | Then write the test first to prove it. If the test forces a different interface, the implementation was wrong. |
|
|
93
|
+
|
|
94
|
+
## Cross-skill references
|
|
95
|
+
|
|
96
|
+
| When you need… | Use this skill |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Test-writing conventions (assertions, mocking, structure) | `style-tests` |
|
|
99
|
+
| Code-level style and conventions | `style-code` |
|
|
100
|
+
| Domain terminology for test names and module boundaries | `grill-with-docs` |
|
|
101
|
+
|
|
102
|
+
Reference docs bundled with this skill: `tests.md`, `mocking.md`, `deep-modules.md`, `interface-design.md`, `refactoring.md`.
|
|
103
|
+
|
|
104
|
+
## Examples
|
|
105
|
+
|
|
106
|
+
### Horizontal vs vertical slicing
|
|
107
|
+
|
|
108
|
+
| Horizontal (wrong) | Vertical (right) |
|
|
109
|
+
|---|---|
|
|
110
|
+
| Write test1, test2, test3, test4, test5 | Write test1 → impl1 |
|
|
111
|
+
| Then write impl1, impl2, impl3, impl4, impl5 | Then test2 → impl2 |
|
|
112
|
+
| Tests test imagined behaviour, not actual | Each test responds to what you just learned |
|
|
113
|
+
|
|
114
|
+
### Test that survives refactor vs one that does not
|
|
115
|
+
|
|
116
|
+
| Instead of… | Write… |
|
|
117
|
+
|---|---|
|
|
118
|
+
| Mocking an internal method and asserting it was called | Calling the public API and asserting on the result |
|
|
119
|
+
| Testing that a private helper returns an intermediate value | Testing that the public function returns the correct output |
|
|
120
|
+
|
|
121
|
+
## Phase-gate checklists
|
|
122
|
+
|
|
123
|
+
### Phase 1: Planning complete
|
|
124
|
+
|
|
125
|
+
- [ ] User approved the interface and prioritised behaviours
|
|
126
|
+
- [ ] Behaviours are listed in terms of observable outcomes, not implementation steps
|
|
127
|
+
|
|
128
|
+
### Phase 2: Tracer bullet done
|
|
129
|
+
|
|
130
|
+
- [ ] End-to-end path proven through the public API
|
|
131
|
+
- [ ] Test passes GREEN with minimal implementation
|
|
132
|
+
|
|
133
|
+
### Phase 3: Incremental loop complete
|
|
134
|
+
|
|
135
|
+
- [ ] All prioritised behaviours tested
|
|
136
|
+
- [ ] All tests GREEN
|
|
137
|
+
|
|
138
|
+
### Phase 4: Refactor complete
|
|
139
|
+
|
|
140
|
+
- [ ] Duplication extracted without changing behaviour
|
|
141
|
+
- [ ] All tests still GREEN after every refactor step
|
|
142
|
+
|
|
143
|
+
## Verification checklist
|
|
144
|
+
|
|
145
|
+
- [ ] Test describes behaviour, not implementation
|
|
146
|
+
- [ ] Test uses public interface only
|
|
147
|
+
- [ ] Test would survive internal refactor
|
|
148
|
+
- [ ] Code is minimal for this test
|
|
149
|
+
- [ ] No speculative features added
|
|
150
|
+
- [ ] Never refactored while RED
|
|
@@ -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,10 @@
|
|
|
1
|
+
# Refactor Candidates
|
|
2
|
+
|
|
3
|
+
After TDD cycle, look for:
|
|
4
|
+
|
|
5
|
+
- **Duplication** → Extract function/class
|
|
6
|
+
- **Long methods** → Break into private helpers (keep tests on public interface)
|
|
7
|
+
- **Shallow modules** → Combine or deepen
|
|
8
|
+
- **Feature envy** → Move logic to where data lives
|
|
9
|
+
- **Primitive obsession** → Introduce value objects
|
|
10
|
+
- **Existing code** the new code reveals as problematic
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
```
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: technical-direction
|
|
3
|
+
description: Drive collaborative technical design by challenging assumptions, mapping constraints, comparing alternatives, and producing a justified recommendation. Use when user wants to decide technical direction after PRD, evaluate architecture/technology choices, or asks to design a solution with tradeoff analysis.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Technical Direction
|
|
7
|
+
|
|
8
|
+
Act like a pragmatic, challenging staff engineer: constructive, direct, evidence-driven.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. **Anchor on problem context**
|
|
13
|
+
- Start from PRD or user brief
|
|
14
|
+
- Confirm technical goals, non-goals, and decision horizon
|
|
15
|
+
|
|
16
|
+
2. **Discover constraints from codebase first**
|
|
17
|
+
- Investigate architecture, existing interfaces, deployment/runtime constraints, data model boundaries, and team conventions
|
|
18
|
+
- Note unknowns and risks
|
|
19
|
+
|
|
20
|
+
3. **Challenge loop (one question at a time)**
|
|
21
|
+
- Ask focused, high-leverage questions
|
|
22
|
+
- Challenge vague claims and hidden assumptions
|
|
23
|
+
- Require explicit justification for each major decision
|
|
24
|
+
- Keep drilling until constraints and tradeoffs are concrete
|
|
25
|
+
|
|
26
|
+
4. **Generate options**
|
|
27
|
+
- Always include Option A (extend current approach), Option B (moderate architectural shift), and Option C (stronger alternative using new tech/pattern)
|
|
28
|
+
- For each option: feasibility, complexity, migration cost, operational impact, testability, performance, and failure modes
|
|
29
|
+
|
|
30
|
+
5. **Use web research when needed**
|
|
31
|
+
- Do this autonomously when codebase evidence is insufficient or a high-impact decision needs external comparison
|
|
32
|
+
- Prefer authoritative sources (official docs, maintainers, widely adopted production guidance)
|
|
33
|
+
- Bring findings back as tradeoffs, and retain source links as references
|
|
34
|
+
|
|
35
|
+
6. **Converge on a recommendation**
|
|
36
|
+
- Select the best-fit option for current constraints
|
|
37
|
+
- Explicitly explain why alternatives were not chosen
|
|
38
|
+
- List decision triggers that would justify revisiting later
|
|
39
|
+
|
|
40
|
+
7. **Write decision memo**
|
|
41
|
+
- Ensure `docs/technical-direction/` exists
|
|
42
|
+
- Save to `docs/technical-direction/<feature-slug>.md` using this template:
|
|
43
|
+
|
|
44
|
+
```md
|
|
45
|
+
# Technical Direction: <Feature Name>
|
|
46
|
+
## Problem and target outcome
|
|
47
|
+
- What we are solving
|
|
48
|
+
- Why this matters now
|
|
49
|
+
## Current-state constraints
|
|
50
|
+
- Architecture and integration constraints
|
|
51
|
+
- Team/runtime/operational constraints
|
|
52
|
+
- Unknowns and assumptions
|
|
53
|
+
## Options considered
|
|
54
|
+
### Option A: <name>
|
|
55
|
+
- Approach
|
|
56
|
+
- Pros
|
|
57
|
+
- Cons
|
|
58
|
+
- Risks
|
|
59
|
+
### Option B: <name>
|
|
60
|
+
...
|
|
61
|
+
### Option C: <name>
|
|
62
|
+
...
|
|
63
|
+
## Recommendation
|
|
64
|
+
- Chosen approach
|
|
65
|
+
- Why this is best under current constraints
|
|
66
|
+
- Why alternatives were not selected
|
|
67
|
+
## Tradeoffs accepted
|
|
68
|
+
- Explicit compromises and consequences
|
|
69
|
+
## Validation plan
|
|
70
|
+
- Fastest experiments/spikes to de-risk decision
|
|
71
|
+
- Success/failure signals
|
|
72
|
+
## Revisit triggers
|
|
73
|
+
- Conditions that should force re-evaluation
|
|
74
|
+
## References
|
|
75
|
+
- Web sources used for decisions (title + URL)
|
|
76
|
+
- Code evidence links (repo path + line range, and permalink URL when available)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Rules
|
|
80
|
+
|
|
81
|
+
- Ask questions one at a time.
|
|
82
|
+
- If the answer exists in the codebase, investigate before asking.
|
|
83
|
+
- Be challenging but collaborative; do not optimize for agreement.
|
|
84
|
+
- Avoid premature implementation details until direction is selected.
|
|
85
|
+
- Every recommendation must include explicit constraints and tradeoffs.
|
|
86
|
+
- When web or code sources materially inform decisions, include them in `## References`.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: classify-bead
|
|
3
|
+
description: Classify a bead as AFK or HITL and apply the implementation-type label. Use when a bead is missing its implementation-type label, when picking up a bead to work on, or when any skill creates a new bead.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Classify Bead
|
|
7
|
+
|
|
8
|
+
Determine whether a bead requires human action (HITL) or can be completed autonomously by an agent (AFK), then persist the result as a label.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
- When picking up a bead that is missing the `implementation-type` label.
|
|
13
|
+
- Immediately after creating a new bead, before claiming or scheduling it.
|
|
14
|
+
- Any time you are unsure of a bead's classification.
|
|
15
|
+
|
|
16
|
+
## Invocation
|
|
17
|
+
|
|
18
|
+
**Always run this skill as a subagent** (background `general-purpose` agent, `model: haiku`) to avoid loading bead content into the calling agent's context. Classification is a rubric lookup, not code generation, so the smaller/cheaper model is sufficient. Pass the bead ID and the `bd prime` output. The subagent runs the procedure below and reports back the classification and the `bd tag` command it applied.
|
|
19
|
+
|
|
20
|
+
Only run inline (without a subagent) if no task-spawning capability is available in the current environment.
|
|
21
|
+
|
|
22
|
+
**Callers should check `bd label list <id>` themselves first.** If `implementation-type` is already present, skip spawning this skill entirely — spawning a subagent purely to re-read a label that's already there wastes a full agent call.
|
|
23
|
+
|
|
24
|
+
## Procedure
|
|
25
|
+
|
|
26
|
+
### 1. Check for an existing label
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bd label list <id>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- If `implementation-type:afk` is present → classification is **AFK**. Stop here.
|
|
33
|
+
- If `implementation-type:hitl` is present → classification is **HITL**. Stop here.
|
|
34
|
+
|
|
35
|
+
### 2. Check the `## Type` field (back-compat)
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
bd show <id>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Locate the `## Type` section in the bead body.
|
|
42
|
+
|
|
43
|
+
- If the value is `HITL` (case-insensitive) → classification is **HITL**. Proceed to step 4.
|
|
44
|
+
- If the value is `AFK` (case-insensitive) → classification is **AFK**. Proceed to step 4.
|
|
45
|
+
|
|
46
|
+
### 3. Classify from first principles
|
|
47
|
+
|
|
48
|
+
If neither the label nor the `## Type` field is present, read the full bead body and apply this rubric:
|
|
49
|
+
|
|
50
|
+
**HITL** — the bead requires a human if at least one of the following is true:
|
|
51
|
+
- The outcome cannot be verified by an agent (e.g. visual review, stakeholder sign-off, UX judgement call).
|
|
52
|
+
- The work requires a manual action only a human can perform (e.g. credential setup, secrets management, external service configuration, infrastructure provisioning outside the codebase).
|
|
53
|
+
- A decision must be made that the agent cannot make unilaterally (e.g. architectural choice between equally valid options, regulatory or legal sign-off).
|
|
54
|
+
|
|
55
|
+
**AFK** — the agent can implement, verify, and complete the task autonomously, and all acceptance criteria are machine-checkable.
|
|
56
|
+
|
|
57
|
+
Prefer AFK. Do not classify as HITL just because the task is complex — only when the agent genuinely cannot complete or verify it without human involvement.
|
|
58
|
+
|
|
59
|
+
### 4. Apply the label
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bd tag <id> implementation-type:afk # or implementation-type:hitl
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 5. Return the classification
|
|
66
|
+
|
|
67
|
+
Report back `AFK` or `HITL` so the calling skill or agent can act on it.
|