@chankov/agent-skills 0.1.0 → 0.2.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/.pi/extensions/agent-skills-update-check/README.md +58 -0
- package/.pi/extensions/agent-skills-update-check/index.ts +161 -0
- package/.pi/extensions/agent-skills-update-check/package.json +6 -0
- package/.versions/0.2.0/.claude/commands/build.md +18 -0
- package/.versions/0.2.0/.claude/commands/code-simplify.md +22 -0
- package/.versions/0.2.0/.claude/commands/design-agent.md +14 -0
- package/.versions/0.2.0/.claude/commands/doctor.md +13 -0
- package/.versions/0.2.0/.claude/commands/plan.md +16 -0
- package/.versions/0.2.0/.claude/commands/prime.md +22 -0
- package/.versions/0.2.0/.claude/commands/review.md +16 -0
- package/.versions/0.2.0/.claude/commands/setup.md +19 -0
- package/.versions/0.2.0/.claude/commands/ship.md +17 -0
- package/.versions/0.2.0/.claude/commands/spec.md +15 -0
- package/.versions/0.2.0/.claude/commands/test.md +19 -0
- package/.versions/0.2.0/.opencode/commands/as-build.md +17 -0
- package/.versions/0.2.0/.opencode/commands/as-code-simplify.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-design-agent.md +15 -0
- package/.versions/0.2.0/.opencode/commands/as-doctor.md +11 -0
- package/.versions/0.2.0/.opencode/commands/as-plan.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-prime.md +22 -0
- package/.versions/0.2.0/.opencode/commands/as-review.md +15 -0
- package/.versions/0.2.0/.opencode/commands/as-setup.md +11 -0
- package/.versions/0.2.0/.opencode/commands/as-ship.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-spec.md +16 -0
- package/.versions/0.2.0/.opencode/commands/as-test.md +21 -0
- package/.versions/0.2.0/.pi/agents/agent-chain.yaml +49 -0
- package/.versions/0.2.0/.pi/agents/bowser.md +19 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/agent-expert.md +98 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/cli-expert.md +41 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/config-expert.md +63 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/ext-expert.md +43 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/keybinding-expert.md +134 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/pi-orchestrator.md +57 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/prompt-expert.md +70 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/skill-expert.md +42 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/theme-expert.md +40 -0
- package/.versions/0.2.0/.pi/agents/pi-pi/tui-expert.md +85 -0
- package/.versions/0.2.0/.pi/agents/teams.yaml +31 -0
- package/.versions/0.2.0/.pi/damage-control-rules.yaml +278 -0
- package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/README.md +58 -0
- package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/index.ts +161 -0
- package/.versions/0.2.0/.pi/extensions/agent-skills-update-check/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/README.md +39 -0
- package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/index.ts +61 -0
- package/.versions/0.2.0/.pi/extensions/chrome-devtools-mcp/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/compact-and-continue/README.md +42 -0
- package/.versions/0.2.0/.pi/extensions/compact-and-continue/index.ts +120 -0
- package/.versions/0.2.0/.pi/extensions/compact-and-continue/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/mcp-bridge/README.md +46 -0
- package/.versions/0.2.0/.pi/extensions/mcp-bridge/index.ts +206 -0
- package/.versions/0.2.0/.pi/extensions/mcp-bridge/package.json +6 -0
- package/.versions/0.2.0/.pi/extensions/package-lock.json +1143 -0
- package/.versions/0.2.0/.pi/extensions/package.json +9 -0
- package/.versions/0.2.0/.pi/harnesses/agent-chain/README.md +37 -0
- package/.versions/0.2.0/.pi/harnesses/agent-chain/index.ts +795 -0
- package/.versions/0.2.0/.pi/harnesses/agent-chain/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/agent-team/README.md +38 -0
- package/.versions/0.2.0/.pi/harnesses/agent-team/index.ts +732 -0
- package/.versions/0.2.0/.pi/harnesses/agent-team/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/coms/README.md +36 -0
- package/.versions/0.2.0/.pi/harnesses/coms/index.ts +1595 -0
- package/.versions/0.2.0/.pi/harnesses/coms/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/coms-net/README.md +46 -0
- package/.versions/0.2.0/.pi/harnesses/coms-net/index.ts +1637 -0
- package/.versions/0.2.0/.pi/harnesses/coms-net/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control/README.md +38 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control/index.ts +207 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control-continue/README.md +37 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control-continue/index.ts +234 -0
- package/.versions/0.2.0/.pi/harnesses/damage-control-continue/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/minimal/README.md +27 -0
- package/.versions/0.2.0/.pi/harnesses/minimal/index.ts +32 -0
- package/.versions/0.2.0/.pi/harnesses/minimal/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/package-lock.json +35 -0
- package/.versions/0.2.0/.pi/harnesses/package.json +9 -0
- package/.versions/0.2.0/.pi/harnesses/pi-pi/README.md +39 -0
- package/.versions/0.2.0/.pi/harnesses/pi-pi/index.ts +631 -0
- package/.versions/0.2.0/.pi/harnesses/pi-pi/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/purpose-gate/README.md +27 -0
- package/.versions/0.2.0/.pi/harnesses/purpose-gate/index.ts +82 -0
- package/.versions/0.2.0/.pi/harnesses/purpose-gate/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/session-replay/README.md +28 -0
- package/.versions/0.2.0/.pi/harnesses/session-replay/index.ts +214 -0
- package/.versions/0.2.0/.pi/harnesses/session-replay/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/subagent-widget/README.md +36 -0
- package/.versions/0.2.0/.pi/harnesses/subagent-widget/index.ts +479 -0
- package/.versions/0.2.0/.pi/harnesses/subagent-widget/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/system-select/README.md +39 -0
- package/.versions/0.2.0/.pi/harnesses/system-select/index.ts +165 -0
- package/.versions/0.2.0/.pi/harnesses/system-select/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/tilldone/README.md +35 -0
- package/.versions/0.2.0/.pi/harnesses/tilldone/index.ts +724 -0
- package/.versions/0.2.0/.pi/harnesses/tilldone/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter/README.md +31 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter/index.ts +100 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter/package.json +6 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/README.md +27 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/index.ts +66 -0
- package/.versions/0.2.0/.pi/harnesses/tool-counter-widget/package.json +6 -0
- package/.versions/0.2.0/.pi/prompts/build.md +24 -0
- package/.versions/0.2.0/.pi/prompts/code-simplify.md +22 -0
- package/.versions/0.2.0/.pi/prompts/doctor.md +13 -0
- package/.versions/0.2.0/.pi/prompts/plan.md +16 -0
- package/.versions/0.2.0/.pi/prompts/review.md +16 -0
- package/.versions/0.2.0/.pi/prompts/setup.md +19 -0
- package/.versions/0.2.0/.pi/prompts/ship.md +17 -0
- package/.versions/0.2.0/.pi/prompts/spec.md +15 -0
- package/.versions/0.2.0/.pi/prompts/test.md +19 -0
- package/.versions/0.2.0/.pi/skills/bowser/SKILL.md +114 -0
- package/.versions/0.2.0/.version +1 -0
- package/.versions/0.2.0/agents/builder.md +6 -0
- package/.versions/0.2.0/agents/code-reviewer.md +93 -0
- package/.versions/0.2.0/agents/documenter.md +6 -0
- package/.versions/0.2.0/agents/plan-reviewer.md +22 -0
- package/.versions/0.2.0/agents/planner.md +6 -0
- package/.versions/0.2.0/agents/scout.md +6 -0
- package/.versions/0.2.0/agents/security-auditor.md +97 -0
- package/.versions/0.2.0/agents/test-engineer.md +89 -0
- package/.versions/0.2.0/hooks/SIMPLIFY-IGNORE.md +90 -0
- package/.versions/0.2.0/hooks/hooks.json +14 -0
- package/.versions/0.2.0/hooks/session-start.sh +74 -0
- package/.versions/0.2.0/hooks/simplify-ignore-test.sh +247 -0
- package/.versions/0.2.0/hooks/simplify-ignore.sh +302 -0
- package/.versions/0.2.0/references/accessibility-checklist.md +159 -0
- package/.versions/0.2.0/references/performance-checklist.md +121 -0
- package/.versions/0.2.0/references/prompting-patterns.md +380 -0
- package/.versions/0.2.0/references/security-checklist.md +134 -0
- package/.versions/0.2.0/references/testing-patterns.md +236 -0
- package/.versions/0.2.0/skills/api-and-interface-design/SKILL.md +294 -0
- package/.versions/0.2.0/skills/browser-testing-with-devtools/SKILL.md +335 -0
- package/.versions/0.2.0/skills/ci-cd-and-automation/SKILL.md +390 -0
- package/.versions/0.2.0/skills/code-review-and-quality/SKILL.md +347 -0
- package/.versions/0.2.0/skills/code-simplification/SKILL.md +331 -0
- package/.versions/0.2.0/skills/context-engineering/SKILL.md +291 -0
- package/.versions/0.2.0/skills/debugging-and-error-recovery/SKILL.md +300 -0
- package/.versions/0.2.0/skills/deprecation-and-migration/SKILL.md +206 -0
- package/.versions/0.2.0/skills/designing-agents/SKILL.md +394 -0
- package/.versions/0.2.0/skills/designing-agents/pi-harness-authoring.md +213 -0
- package/.versions/0.2.0/skills/documentation-and-adrs/SKILL.md +278 -0
- package/.versions/0.2.0/skills/frontend-ui-engineering/SKILL.md +322 -0
- package/.versions/0.2.0/skills/git-workflow-and-versioning/SKILL.md +316 -0
- package/.versions/0.2.0/skills/guided-workspace-setup/SKILL.md +293 -0
- package/.versions/0.2.0/skills/idea-refine/SKILL.md +178 -0
- package/.versions/0.2.0/skills/idea-refine/examples.md +238 -0
- package/.versions/0.2.0/skills/idea-refine/frameworks.md +99 -0
- package/.versions/0.2.0/skills/idea-refine/refinement-criteria.md +113 -0
- package/.versions/0.2.0/skills/idea-refine/scripts/idea-refine.sh +15 -0
- package/.versions/0.2.0/skills/incremental-implementation/SKILL.md +279 -0
- package/.versions/0.2.0/skills/performance-optimization/SKILL.md +350 -0
- package/.versions/0.2.0/skills/planning-and-task-breakdown/SKILL.md +237 -0
- package/.versions/0.2.0/skills/security-and-hardening/SKILL.md +349 -0
- package/.versions/0.2.0/skills/shipping-and-launch/SKILL.md +309 -0
- package/.versions/0.2.0/skills/source-driven-development/SKILL.md +194 -0
- package/.versions/0.2.0/skills/spec-driven-development/SKILL.md +237 -0
- package/.versions/0.2.0/skills/test-driven-development/SKILL.md +379 -0
- package/.versions/0.2.0/skills/using-agent-skills/SKILL.md +176 -0
- package/CHANGELOG.md +36 -0
- package/bin/cli.js +42 -7
- package/bin/lib/update-notifier.js +195 -0
- package/docs/npm-install.md +60 -0
- package/hooks/session-start.sh +66 -12
- package/package.json +1 -1
- package/skills/guided-workspace-setup/SKILL.md +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: planning-and-task-breakdown
|
|
3
|
+
description: Breaks work into ordered tasks. Use when you have a spec or clear requirements and need to break work into implementable tasks. Use when a task feels too large to start, when you need to estimate scope, or when parallel work is possible.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Planning and Task Breakdown
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Decompose work into small, verifiable tasks with explicit acceptance criteria. Good task breakdown is the difference between an agent that completes work reliably and one that produces a tangled mess. Every task should be small enough to implement, test, and verify in a single focused session.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- You have a spec and need to break it into implementable units
|
|
15
|
+
- A task feels too large or vague to start
|
|
16
|
+
- Work needs to be parallelized across multiple agents or sessions
|
|
17
|
+
- You need to communicate scope to a human
|
|
18
|
+
- The implementation order isn't obvious
|
|
19
|
+
|
|
20
|
+
**When NOT to use:** Single-file changes with obvious scope, or when the spec already contains well-defined tasks.
|
|
21
|
+
|
|
22
|
+
## Output Location
|
|
23
|
+
|
|
24
|
+
By default, save the plan to `docs/plans/{area}/PLAN-{prd-name}-{phase}.md`:
|
|
25
|
+
|
|
26
|
+
- `{area}` — the functional area; match the area of the PRD this plan implements.
|
|
27
|
+
- `{prd-name}` — the name of the PRD this plan implements (e.g. `PRD3-tournament-copy`). If there is no PRD, use a short kebab-case topic slug instead.
|
|
28
|
+
- `{phase}` — include a phase suffix **only** when the plan is deliberately split across more than one plan file. For a single-file plan, drop it (`PLAN-{prd-name}.md`).
|
|
29
|
+
|
|
30
|
+
The task list is **embedded** in the plan file as the `## Task List` section. Do **not** create a separate `todo.md`.
|
|
31
|
+
|
|
32
|
+
Match the project's existing `docs` vs `Docs` capitalization, and create the directory if it does not exist.
|
|
33
|
+
|
|
34
|
+
**Project overrides:** if `.ai/agent-skills-overrides.md` has a `## planning-and-task-breakdown` section, its keys (`plan-dir`, `naming`, `todo`) override these defaults — `todo: separate` restores a standalone `todo.md`. See [docs/agent-skills-setup.md](../../docs/agent-skills-setup.md).
|
|
35
|
+
|
|
36
|
+
## The Planning Process
|
|
37
|
+
|
|
38
|
+
### Step 1: Enter Plan Mode
|
|
39
|
+
|
|
40
|
+
Before writing any code, operate in read-only mode:
|
|
41
|
+
|
|
42
|
+
- Read the spec and relevant codebase sections
|
|
43
|
+
- Identify existing patterns and conventions
|
|
44
|
+
- Map dependencies between components
|
|
45
|
+
- Note risks and unknowns
|
|
46
|
+
|
|
47
|
+
**Do NOT write code during planning.** The output is a plan document, not implementation.
|
|
48
|
+
|
|
49
|
+
### Step 2: Identify the Dependency Graph
|
|
50
|
+
|
|
51
|
+
Map what depends on what:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Database schema
|
|
55
|
+
│
|
|
56
|
+
├── API models/types
|
|
57
|
+
│ │
|
|
58
|
+
│ ├── API endpoints
|
|
59
|
+
│ │ │
|
|
60
|
+
│ │ └── Frontend API client
|
|
61
|
+
│ │ │
|
|
62
|
+
│ │ └── UI components
|
|
63
|
+
│ │
|
|
64
|
+
│ └── Validation logic
|
|
65
|
+
│
|
|
66
|
+
└── Seed data / migrations
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Implementation order follows the dependency graph bottom-up: build foundations first.
|
|
70
|
+
|
|
71
|
+
### Step 3: Slice Vertically
|
|
72
|
+
|
|
73
|
+
Instead of building all the database, then all the API, then all the UI — build one complete feature path at a time:
|
|
74
|
+
|
|
75
|
+
**Bad (horizontal slicing):**
|
|
76
|
+
```
|
|
77
|
+
Task 1: Build entire database schema
|
|
78
|
+
Task 2: Build all API endpoints
|
|
79
|
+
Task 3: Build all UI components
|
|
80
|
+
Task 4: Connect everything
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Good (vertical slicing):**
|
|
84
|
+
```
|
|
85
|
+
Task 1: User can create an account (schema + API + UI for registration)
|
|
86
|
+
Task 2: User can log in (auth schema + API + UI for login)
|
|
87
|
+
Task 3: User can create a task (task schema + API + UI for creation)
|
|
88
|
+
Task 4: User can view task list (query + API + UI for list view)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Each vertical slice delivers working, testable functionality.
|
|
92
|
+
|
|
93
|
+
### Step 4: Write Tasks
|
|
94
|
+
|
|
95
|
+
Each task follows this structure:
|
|
96
|
+
|
|
97
|
+
```markdown
|
|
98
|
+
## Task [N]: [Short descriptive title]
|
|
99
|
+
|
|
100
|
+
**Description:** One paragraph explaining what this task accomplishes.
|
|
101
|
+
|
|
102
|
+
**Acceptance criteria:**
|
|
103
|
+
- [ ] [Specific, testable condition]
|
|
104
|
+
- [ ] [Specific, testable condition]
|
|
105
|
+
|
|
106
|
+
**Verification:**
|
|
107
|
+
- [ ] Tests pass: `npm test -- --grep "feature-name"`
|
|
108
|
+
- [ ] Build succeeds: `npm run build`
|
|
109
|
+
- [ ] Manual check: [description of what to verify]
|
|
110
|
+
|
|
111
|
+
**Dependencies:** [Task numbers this depends on, or "None"]
|
|
112
|
+
|
|
113
|
+
**Files likely touched:**
|
|
114
|
+
- `src/path/to/file.ts`
|
|
115
|
+
- `tests/path/to/test.ts`
|
|
116
|
+
|
|
117
|
+
**Estimated scope:** [Small: 1-2 files | Medium: 3-5 files | Large: 5+ files]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 5: Order and Checkpoint
|
|
121
|
+
|
|
122
|
+
Arrange tasks so that:
|
|
123
|
+
|
|
124
|
+
1. Dependencies are satisfied (build foundation first)
|
|
125
|
+
2. Each task leaves the system in a working state
|
|
126
|
+
3. Verification checkpoints occur after every 2-3 tasks
|
|
127
|
+
4. High-risk tasks are early (fail fast)
|
|
128
|
+
|
|
129
|
+
Add explicit checkpoints:
|
|
130
|
+
|
|
131
|
+
```markdown
|
|
132
|
+
## Checkpoint: After Tasks 1-3
|
|
133
|
+
- [ ] All tests pass
|
|
134
|
+
- [ ] Application builds without errors
|
|
135
|
+
- [ ] Core user flow works end-to-end
|
|
136
|
+
- [ ] Review with human before proceeding
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Task Sizing Guidelines
|
|
140
|
+
|
|
141
|
+
| Size | Files | Scope | Example |
|
|
142
|
+
|------|-------|-------|---------|
|
|
143
|
+
| **XS** | 1 | Single function or config change | Add a validation rule |
|
|
144
|
+
| **S** | 1-2 | One component or endpoint | Add a new API endpoint |
|
|
145
|
+
| **M** | 3-5 | One feature slice | User registration flow |
|
|
146
|
+
| **L** | 5-8 | Multi-component feature | Search with filtering and pagination |
|
|
147
|
+
| **XL** | 8+ | **Too large — break it down further** | — |
|
|
148
|
+
|
|
149
|
+
If a task is L or larger, it should be broken into smaller tasks. An agent performs best on S and M tasks.
|
|
150
|
+
|
|
151
|
+
**When to break a task down further:**
|
|
152
|
+
- It would take more than one focused session (roughly 2+ hours of agent work)
|
|
153
|
+
- You cannot describe the acceptance criteria in 3 or fewer bullet points
|
|
154
|
+
- It touches two or more independent subsystems (e.g., auth and billing)
|
|
155
|
+
- You find yourself writing "and" in the task title (a sign it is two tasks)
|
|
156
|
+
|
|
157
|
+
## Plan Document Template
|
|
158
|
+
|
|
159
|
+
```markdown
|
|
160
|
+
# Implementation Plan: [Feature/Project Name]
|
|
161
|
+
|
|
162
|
+
## Overview
|
|
163
|
+
[One paragraph summary of what we're building]
|
|
164
|
+
|
|
165
|
+
## Architecture Decisions
|
|
166
|
+
- [Key decision 1 and rationale]
|
|
167
|
+
- [Key decision 2 and rationale]
|
|
168
|
+
|
|
169
|
+
## Task List
|
|
170
|
+
|
|
171
|
+
### Phase 1: Foundation
|
|
172
|
+
- [ ] Task 1: ...
|
|
173
|
+
- [ ] Task 2: ...
|
|
174
|
+
|
|
175
|
+
### Checkpoint: Foundation
|
|
176
|
+
- [ ] Tests pass, builds clean
|
|
177
|
+
|
|
178
|
+
### Phase 2: Core Features
|
|
179
|
+
- [ ] Task 3: ...
|
|
180
|
+
- [ ] Task 4: ...
|
|
181
|
+
|
|
182
|
+
### Checkpoint: Core Features
|
|
183
|
+
- [ ] End-to-end flow works
|
|
184
|
+
|
|
185
|
+
### Phase 3: Polish
|
|
186
|
+
- [ ] Task 5: ...
|
|
187
|
+
- [ ] Task 6: ...
|
|
188
|
+
|
|
189
|
+
### Checkpoint: Complete
|
|
190
|
+
- [ ] All acceptance criteria met
|
|
191
|
+
- [ ] Ready for review
|
|
192
|
+
|
|
193
|
+
## Risks and Mitigations
|
|
194
|
+
| Risk | Impact | Mitigation |
|
|
195
|
+
|------|--------|------------|
|
|
196
|
+
| [Risk] | [High/Med/Low] | [Strategy] |
|
|
197
|
+
|
|
198
|
+
## Open Questions
|
|
199
|
+
- [Question needing human input]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Parallelization Opportunities
|
|
203
|
+
|
|
204
|
+
When multiple agents or sessions are available:
|
|
205
|
+
|
|
206
|
+
- **Safe to parallelize:** Independent feature slices, tests for already-implemented features, documentation
|
|
207
|
+
- **Must be sequential:** Database migrations, shared state changes, dependency chains
|
|
208
|
+
- **Needs coordination:** Features that share an API contract (define the contract first, then parallelize)
|
|
209
|
+
|
|
210
|
+
## Common Rationalizations
|
|
211
|
+
|
|
212
|
+
| Rationalization | Reality |
|
|
213
|
+
|---|---|
|
|
214
|
+
| "I'll figure it out as I go" | That's how you end up with a tangled mess and rework. 10 minutes of planning saves hours. |
|
|
215
|
+
| "The tasks are obvious" | Write them down anyway. Explicit tasks surface hidden dependencies and forgotten edge cases. |
|
|
216
|
+
| "Planning is overhead" | Planning is the task. Implementation without a plan is just typing. |
|
|
217
|
+
| "I can hold it all in my head" | Context windows are finite. Written plans survive session boundaries and compaction. |
|
|
218
|
+
|
|
219
|
+
## Red Flags
|
|
220
|
+
|
|
221
|
+
- Starting implementation without a written task list
|
|
222
|
+
- Tasks that say "implement the feature" without acceptance criteria
|
|
223
|
+
- No verification steps in the plan
|
|
224
|
+
- All tasks are XL-sized
|
|
225
|
+
- No checkpoints between tasks
|
|
226
|
+
- Dependency order isn't considered
|
|
227
|
+
|
|
228
|
+
## Verification
|
|
229
|
+
|
|
230
|
+
Before starting implementation, confirm:
|
|
231
|
+
|
|
232
|
+
- [ ] Every task has acceptance criteria
|
|
233
|
+
- [ ] Every task has a verification step
|
|
234
|
+
- [ ] Task dependencies are identified and ordered correctly
|
|
235
|
+
- [ ] No task touches more than ~5 files
|
|
236
|
+
- [ ] Checkpoints exist between major phases
|
|
237
|
+
- [ ] The human has reviewed and approved the plan
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-and-hardening
|
|
3
|
+
description: Hardens code against vulnerabilities. Use when handling user input, authentication, data storage, or external integrations. Use when building any feature that accepts untrusted data, manages user sessions, or interacts with third-party services.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Security and Hardening
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Security-first development practices for web applications. Treat every external input as hostile, every secret as sacred, and every authorization check as mandatory. Security isn't a phase — it's a constraint on every line of code that touches user data, authentication, or external systems.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
- Building anything that accepts user input
|
|
15
|
+
- Implementing authentication or authorization
|
|
16
|
+
- Storing or transmitting sensitive data
|
|
17
|
+
- Integrating with external APIs or services
|
|
18
|
+
- Adding file uploads, webhooks, or callbacks
|
|
19
|
+
- Handling payment or PII data
|
|
20
|
+
|
|
21
|
+
## The Three-Tier Boundary System
|
|
22
|
+
|
|
23
|
+
### Always Do (No Exceptions)
|
|
24
|
+
|
|
25
|
+
- **Validate all external input** at the system boundary (API routes, form handlers)
|
|
26
|
+
- **Parameterize all database queries** — never concatenate user input into SQL
|
|
27
|
+
- **Encode output** to prevent XSS (use framework auto-escaping, don't bypass it)
|
|
28
|
+
- **Use HTTPS** for all external communication
|
|
29
|
+
- **Hash passwords** with bcrypt/scrypt/argon2 (never store plaintext)
|
|
30
|
+
- **Set security headers** (CSP, HSTS, X-Frame-Options, X-Content-Type-Options)
|
|
31
|
+
- **Use httpOnly, secure, sameSite cookies** for sessions
|
|
32
|
+
- **Run `npm audit`** (or equivalent) before every release
|
|
33
|
+
|
|
34
|
+
### Ask First (Requires Human Approval)
|
|
35
|
+
|
|
36
|
+
- Adding new authentication flows or changing auth logic
|
|
37
|
+
- Storing new categories of sensitive data (PII, payment info)
|
|
38
|
+
- Adding new external service integrations
|
|
39
|
+
- Changing CORS configuration
|
|
40
|
+
- Adding file upload handlers
|
|
41
|
+
- Modifying rate limiting or throttling
|
|
42
|
+
- Granting elevated permissions or roles
|
|
43
|
+
|
|
44
|
+
### Never Do
|
|
45
|
+
|
|
46
|
+
- **Never commit secrets** to version control (API keys, passwords, tokens)
|
|
47
|
+
- **Never log sensitive data** (passwords, tokens, full credit card numbers)
|
|
48
|
+
- **Never trust client-side validation** as a security boundary
|
|
49
|
+
- **Never disable security headers** for convenience
|
|
50
|
+
- **Never use `eval()` or `innerHTML`** with user-provided data
|
|
51
|
+
- **Never store sessions in client-accessible storage** (localStorage for auth tokens)
|
|
52
|
+
- **Never expose stack traces** or internal error details to users
|
|
53
|
+
|
|
54
|
+
## OWASP Top 10 Prevention
|
|
55
|
+
|
|
56
|
+
### 1. Injection (SQL, NoSQL, OS Command)
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// BAD: SQL injection via string concatenation
|
|
60
|
+
const query = `SELECT * FROM users WHERE id = '${userId}'`;
|
|
61
|
+
|
|
62
|
+
// GOOD: Parameterized query
|
|
63
|
+
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
|
|
64
|
+
|
|
65
|
+
// GOOD: ORM with parameterized input
|
|
66
|
+
const user = await prisma.user.findUnique({ where: { id: userId } });
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. Broken Authentication
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Password hashing
|
|
73
|
+
import { hash, compare } from 'bcrypt';
|
|
74
|
+
|
|
75
|
+
const SALT_ROUNDS = 12;
|
|
76
|
+
const hashedPassword = await hash(plaintext, SALT_ROUNDS);
|
|
77
|
+
const isValid = await compare(plaintext, hashedPassword);
|
|
78
|
+
|
|
79
|
+
// Session management
|
|
80
|
+
app.use(session({
|
|
81
|
+
secret: process.env.SESSION_SECRET, // From environment, not code
|
|
82
|
+
resave: false,
|
|
83
|
+
saveUninitialized: false,
|
|
84
|
+
cookie: {
|
|
85
|
+
httpOnly: true, // Not accessible via JavaScript
|
|
86
|
+
secure: true, // HTTPS only
|
|
87
|
+
sameSite: 'lax', // CSRF protection
|
|
88
|
+
maxAge: 24 * 60 * 60 * 1000, // 24 hours
|
|
89
|
+
},
|
|
90
|
+
}));
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Cross-Site Scripting (XSS)
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// BAD: Rendering user input as HTML
|
|
97
|
+
element.innerHTML = userInput;
|
|
98
|
+
|
|
99
|
+
// GOOD: Use framework auto-escaping (React does this by default)
|
|
100
|
+
return <div>{userInput}</div>;
|
|
101
|
+
|
|
102
|
+
// If you MUST render HTML, sanitize first
|
|
103
|
+
import DOMPurify from 'dompurify';
|
|
104
|
+
const clean = DOMPurify.sanitize(userInput);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 4. Broken Access Control
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// Always check authorization, not just authentication
|
|
111
|
+
app.patch('/api/tasks/:id', authenticate, async (req, res) => {
|
|
112
|
+
const task = await taskService.findById(req.params.id);
|
|
113
|
+
|
|
114
|
+
// Check that the authenticated user owns this resource
|
|
115
|
+
if (task.ownerId !== req.user.id) {
|
|
116
|
+
return res.status(403).json({
|
|
117
|
+
error: { code: 'FORBIDDEN', message: 'Not authorized to modify this task' }
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Proceed with update
|
|
122
|
+
const updated = await taskService.update(req.params.id, req.body);
|
|
123
|
+
return res.json(updated);
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 5. Security Misconfiguration
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Security headers (use helmet for Express)
|
|
131
|
+
import helmet from 'helmet';
|
|
132
|
+
app.use(helmet());
|
|
133
|
+
|
|
134
|
+
// Content Security Policy
|
|
135
|
+
app.use(helmet.contentSecurityPolicy({
|
|
136
|
+
directives: {
|
|
137
|
+
defaultSrc: ["'self'"],
|
|
138
|
+
scriptSrc: ["'self'"],
|
|
139
|
+
styleSrc: ["'self'", "'unsafe-inline'"], // Tighten if possible
|
|
140
|
+
imgSrc: ["'self'", 'data:', 'https:'],
|
|
141
|
+
connectSrc: ["'self'"],
|
|
142
|
+
},
|
|
143
|
+
}));
|
|
144
|
+
|
|
145
|
+
// CORS — restrict to known origins
|
|
146
|
+
app.use(cors({
|
|
147
|
+
origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',
|
|
148
|
+
credentials: true,
|
|
149
|
+
}));
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 6. Sensitive Data Exposure
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// Never return sensitive fields in API responses
|
|
156
|
+
function sanitizeUser(user: UserRecord): PublicUser {
|
|
157
|
+
const { passwordHash, resetToken, ...publicFields } = user;
|
|
158
|
+
return publicFields;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Use environment variables for secrets
|
|
162
|
+
const API_KEY = process.env.STRIPE_API_KEY;
|
|
163
|
+
if (!API_KEY) throw new Error('STRIPE_API_KEY not configured');
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Input Validation Patterns
|
|
167
|
+
|
|
168
|
+
### Schema Validation at Boundaries
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { z } from 'zod';
|
|
172
|
+
|
|
173
|
+
const CreateTaskSchema = z.object({
|
|
174
|
+
title: z.string().min(1).max(200).trim(),
|
|
175
|
+
description: z.string().max(2000).optional(),
|
|
176
|
+
priority: z.enum(['low', 'medium', 'high']).default('medium'),
|
|
177
|
+
dueDate: z.string().datetime().optional(),
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Validate at the route handler
|
|
181
|
+
app.post('/api/tasks', async (req, res) => {
|
|
182
|
+
const result = CreateTaskSchema.safeParse(req.body);
|
|
183
|
+
if (!result.success) {
|
|
184
|
+
return res.status(422).json({
|
|
185
|
+
error: {
|
|
186
|
+
code: 'VALIDATION_ERROR',
|
|
187
|
+
message: 'Invalid input',
|
|
188
|
+
details: result.error.flatten(),
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// result.data is now typed and validated
|
|
193
|
+
const task = await taskService.create(result.data);
|
|
194
|
+
return res.status(201).json(task);
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### File Upload Safety
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// Restrict file types and sizes
|
|
202
|
+
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp'];
|
|
203
|
+
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
|
|
204
|
+
|
|
205
|
+
function validateUpload(file: UploadedFile) {
|
|
206
|
+
if (!ALLOWED_TYPES.includes(file.mimetype)) {
|
|
207
|
+
throw new ValidationError('File type not allowed');
|
|
208
|
+
}
|
|
209
|
+
if (file.size > MAX_SIZE) {
|
|
210
|
+
throw new ValidationError('File too large (max 5MB)');
|
|
211
|
+
}
|
|
212
|
+
// Don't trust the file extension — check magic bytes if critical
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Triaging npm audit Results
|
|
217
|
+
|
|
218
|
+
Not all audit findings require immediate action. Use this decision tree:
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
npm audit reports a vulnerability
|
|
222
|
+
├── Severity: critical or high
|
|
223
|
+
│ ├── Is the vulnerable code reachable in your app?
|
|
224
|
+
│ │ ├── YES --> Fix immediately (update, patch, or replace the dependency)
|
|
225
|
+
│ │ └── NO (dev-only dep, unused code path) --> Fix soon, but not a blocker
|
|
226
|
+
│ └── Is a fix available?
|
|
227
|
+
│ ├── YES --> Update to the patched version
|
|
228
|
+
│ └── NO --> Check for workarounds, consider replacing the dependency, or add to allowlist with a review date
|
|
229
|
+
├── Severity: moderate
|
|
230
|
+
│ ├── Reachable in production? --> Fix in the next release cycle
|
|
231
|
+
│ └── Dev-only? --> Fix when convenient, track in backlog
|
|
232
|
+
└── Severity: low
|
|
233
|
+
└── Track and fix during regular dependency updates
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Key questions:**
|
|
237
|
+
- Is the vulnerable function actually called in your code path?
|
|
238
|
+
- Is the dependency a runtime dependency or dev-only?
|
|
239
|
+
- Is the vulnerability exploitable given your deployment context (e.g., a server-side vulnerability in a client-only app)?
|
|
240
|
+
|
|
241
|
+
When you defer a fix, document the reason and set a review date.
|
|
242
|
+
|
|
243
|
+
## Rate Limiting
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import rateLimit from 'express-rate-limit';
|
|
247
|
+
|
|
248
|
+
// General API rate limit
|
|
249
|
+
app.use('/api/', rateLimit({
|
|
250
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
251
|
+
max: 100, // 100 requests per window
|
|
252
|
+
standardHeaders: true,
|
|
253
|
+
legacyHeaders: false,
|
|
254
|
+
}));
|
|
255
|
+
|
|
256
|
+
// Stricter limit for auth endpoints
|
|
257
|
+
app.use('/api/auth/', rateLimit({
|
|
258
|
+
windowMs: 15 * 60 * 1000,
|
|
259
|
+
max: 10, // 10 attempts per 15 minutes
|
|
260
|
+
}));
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Secrets Management
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
.env files:
|
|
267
|
+
├── .env.example → Committed (template with placeholder values)
|
|
268
|
+
├── .env → NOT committed (contains real secrets)
|
|
269
|
+
└── .env.local → NOT committed (local overrides)
|
|
270
|
+
|
|
271
|
+
.gitignore must include:
|
|
272
|
+
.env
|
|
273
|
+
.env.local
|
|
274
|
+
.env.*.local
|
|
275
|
+
*.pem
|
|
276
|
+
*.key
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**Always check before committing:**
|
|
280
|
+
```bash
|
|
281
|
+
# Check for accidentally staged secrets
|
|
282
|
+
git diff --cached | grep -i "password\|secret\|api_key\|token"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Security Review Checklist
|
|
286
|
+
|
|
287
|
+
```markdown
|
|
288
|
+
### Authentication
|
|
289
|
+
- [ ] Passwords hashed with bcrypt/scrypt/argon2 (salt rounds ≥ 12)
|
|
290
|
+
- [ ] Session tokens are httpOnly, secure, sameSite
|
|
291
|
+
- [ ] Login has rate limiting
|
|
292
|
+
- [ ] Password reset tokens expire
|
|
293
|
+
|
|
294
|
+
### Authorization
|
|
295
|
+
- [ ] Every endpoint checks user permissions
|
|
296
|
+
- [ ] Users can only access their own resources
|
|
297
|
+
- [ ] Admin actions require admin role verification
|
|
298
|
+
|
|
299
|
+
### Input
|
|
300
|
+
- [ ] All user input validated at the boundary
|
|
301
|
+
- [ ] SQL queries are parameterized
|
|
302
|
+
- [ ] HTML output is encoded/escaped
|
|
303
|
+
|
|
304
|
+
### Data
|
|
305
|
+
- [ ] No secrets in code or version control
|
|
306
|
+
- [ ] Sensitive fields excluded from API responses
|
|
307
|
+
- [ ] PII encrypted at rest (if applicable)
|
|
308
|
+
|
|
309
|
+
### Infrastructure
|
|
310
|
+
- [ ] Security headers configured (CSP, HSTS, etc.)
|
|
311
|
+
- [ ] CORS restricted to known origins
|
|
312
|
+
- [ ] Dependencies audited for vulnerabilities
|
|
313
|
+
- [ ] Error messages don't expose internals
|
|
314
|
+
```
|
|
315
|
+
## See Also
|
|
316
|
+
|
|
317
|
+
For detailed security checklists and pre-commit verification steps, see `references/security-checklist.md`.
|
|
318
|
+
|
|
319
|
+
## Common Rationalizations
|
|
320
|
+
|
|
321
|
+
| Rationalization | Reality |
|
|
322
|
+
|---|---|
|
|
323
|
+
| "This is an internal tool, security doesn't matter" | Internal tools get compromised. Attackers target the weakest link. |
|
|
324
|
+
| "We'll add security later" | Security retrofitting is 10x harder than building it in. Add it now. |
|
|
325
|
+
| "No one would try to exploit this" | Automated scanners will find it. Security by obscurity is not security. |
|
|
326
|
+
| "The framework handles security" | Frameworks provide tools, not guarantees. You still need to use them correctly. |
|
|
327
|
+
| "It's just a prototype" | Prototypes become production. Security habits from day one. |
|
|
328
|
+
|
|
329
|
+
## Red Flags
|
|
330
|
+
|
|
331
|
+
- User input passed directly to database queries, shell commands, or HTML rendering
|
|
332
|
+
- Secrets in source code or commit history
|
|
333
|
+
- API endpoints without authentication or authorization checks
|
|
334
|
+
- Missing CORS configuration or wildcard (`*`) origins
|
|
335
|
+
- No rate limiting on authentication endpoints
|
|
336
|
+
- Stack traces or internal errors exposed to users
|
|
337
|
+
- Dependencies with known critical vulnerabilities
|
|
338
|
+
|
|
339
|
+
## Verification
|
|
340
|
+
|
|
341
|
+
After implementing security-relevant code:
|
|
342
|
+
|
|
343
|
+
- [ ] `npm audit` shows no critical or high vulnerabilities
|
|
344
|
+
- [ ] No secrets in source code or git history
|
|
345
|
+
- [ ] All user input validated at system boundaries
|
|
346
|
+
- [ ] Authentication and authorization checked on every protected endpoint
|
|
347
|
+
- [ ] Security headers present in response (check with browser DevTools)
|
|
348
|
+
- [ ] Error responses don't expose internal details
|
|
349
|
+
- [ ] Rate limiting active on auth endpoints
|