@nklisch/pi-agile-workflow 0.15.3
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/.claude-plugin/plugin.json +10 -0
- package/.codex-plugin/plugin.json +28 -0
- package/CHANGELOG.md +591 -0
- package/README.md +107 -0
- package/docs/ARCHITECTURE.md +716 -0
- package/docs/MIGRATION.md +419 -0
- package/docs/PRINCIPLES.md +464 -0
- package/docs/ROADMAP.md +95 -0
- package/docs/SPEC.md +855 -0
- package/docs/VISION.md +106 -0
- package/extensions/agile-workflow.test.ts +419 -0
- package/extensions/agile-workflow.ts +467 -0
- package/hooks/hooks.json +52 -0
- package/hooks/scripts/prompt-context.py +628 -0
- package/hooks/scripts/substrate-maintainer.py +359 -0
- package/hooks/scripts/test_prompt_context.py +757 -0
- package/package.json +30 -0
- package/scripts/install-work-view.sh +165 -0
- package/scripts/tests/agent-metadata.test.sh +75 -0
- package/scripts/tests/bump-version.test.sh +552 -0
- package/scripts/tests/channel-parity.test.sh +117 -0
- package/scripts/tests/convert-content-integrity.test.sh +246 -0
- package/scripts/tests/convert-install-routing.test.sh +159 -0
- package/scripts/tests/install-work-view.test.sh +411 -0
- package/scripts/tests/pi-package-metadata.test.sh +119 -0
- package/scripts/tests/work-board-shim.test.sh +239 -0
- package/scripts/tests/work-view-dist-version.test.sh +105 -0
- package/scripts/work-board.sh +64 -0
- package/scripts/work-view.sh +423 -0
- package/skills/autopilot/SKILL.md +330 -0
- package/skills/autopilot/agents/openai.yaml +6 -0
- package/skills/board/SKILL.md +62 -0
- package/skills/board/agents/openai.yaml +6 -0
- package/skills/bold-refactor/SKILL.md +244 -0
- package/skills/bold-refactor/agents/openai.yaml +6 -0
- package/skills/bug-scan/SKILL.md +378 -0
- package/skills/bug-scan/agents/openai.yaml +6 -0
- package/skills/bug-scan/references/async-promises.md +119 -0
- package/skills/bug-scan/references/concurrency-races.md +148 -0
- package/skills/bug-scan/references/data-layer.md +167 -0
- package/skills/bug-scan/references/error-handling.md +197 -0
- package/skills/bug-scan/references/gate-item-template.md +94 -0
- package/skills/bug-scan/references/language-footguns.md +219 -0
- package/skills/bug-scan/references/parked-item-template.md +103 -0
- package/skills/bug-scan/references/report-template.md +115 -0
- package/skills/bug-scan/references/resource-leaks.md +199 -0
- package/skills/bug-scan/references/state-closures.md +148 -0
- package/skills/bug-scan/references/time-numbers.md +158 -0
- package/skills/convert/SKILL.md +1463 -0
- package/skills/convert/agents/openai.yaml +6 -0
- package/skills/convert/references/legacy-overlap-migration.md +179 -0
- package/skills/deep-code-scan/SKILL.md +378 -0
- package/skills/deep-code-scan/agents/openai.yaml +6 -0
- package/skills/deep-code-scan/references/artifact-ledger.md +148 -0
- package/skills/deep-code-scan/references/consolidation.md +91 -0
- package/skills/deep-code-scan/references/decomposition.md +127 -0
- package/skills/deep-code-scan/references/item-templates.md +263 -0
- package/skills/deep-code-scan/references/lane-catalog.md +129 -0
- package/skills/deep-code-scan/references/review-gauntlet.md +108 -0
- package/skills/deep-code-scan/references/scanner-brief.md +152 -0
- package/skills/e2e-test-design/SKILL.md +517 -0
- package/skills/e2e-test-design/references/anti-tautology.md +261 -0
- package/skills/e2e-test-design/references/service-mocks.md +234 -0
- package/skills/e2e-test-design/references/test-taxonomy.md +211 -0
- package/skills/epic-design/SKILL.md +476 -0
- package/skills/epicize/SKILL.md +210 -0
- package/skills/epicize/agents/openai.yaml +6 -0
- package/skills/feature-design/SKILL.md +472 -0
- package/skills/fix/SKILL.md +173 -0
- package/skills/gate-cruft/SKILL.md +258 -0
- package/skills/gate-docs/SKILL.md +278 -0
- package/skills/gate-patterns/SKILL.md +389 -0
- package/skills/gate-refactor/SKILL.md +408 -0
- package/skills/gate-security/SKILL.md +275 -0
- package/skills/gate-tests/SKILL.md +367 -0
- package/skills/groom/SKILL.md +162 -0
- package/skills/groom/agents/openai.yaml +6 -0
- package/skills/ideate/SKILL.md +185 -0
- package/skills/ideate/agents/openai.yaml +6 -0
- package/skills/implement/SKILL.md +288 -0
- package/skills/implement-orchestrator/SKILL.md +604 -0
- package/skills/park/SKILL.md +111 -0
- package/skills/perf-design/SKILL.md +427 -0
- package/skills/perf-scout/SKILL.md +404 -0
- package/skills/perf-scout/agents/openai.yaml +6 -0
- package/skills/perf-scout/references/algorithmic-and-data-structures.md +126 -0
- package/skills/perf-scout/references/approximation-and-precomputation.md +136 -0
- package/skills/perf-scout/references/caching-and-memoization.md +123 -0
- package/skills/perf-scout/references/compiler-runtime-and-language.md +136 -0
- package/skills/perf-scout/references/database-and-storage-internals.md +144 -0
- package/skills/perf-scout/references/distributed-systems.md +150 -0
- package/skills/perf-scout/references/game-engine-and-realtime.md +136 -0
- package/skills/perf-scout/references/gpu-and-accelerators.md +130 -0
- package/skills/perf-scout/references/idea-ranking.md +75 -0
- package/skills/perf-scout/references/io-and-batching.md +135 -0
- package/skills/perf-scout/references/memory-and-data-locality.md +137 -0
- package/skills/perf-scout/references/parallelism-and-vectorization.md +126 -0
- package/skills/perf-scout/references/parked-item-template.md +117 -0
- package/skills/perf-scout/references/peer-review-pass.md +150 -0
- package/skills/perf-scout/references/report-template.md +148 -0
- package/skills/principles/SKILL.md +678 -0
- package/skills/principles/references/models.md +191 -0
- package/skills/principles/references/subagents.md +158 -0
- package/skills/prose-author/SKILL.md +185 -0
- package/skills/refactor-conventions-creator/SKILL.md +359 -0
- package/skills/refactor-conventions-creator/agents/openai.yaml +6 -0
- package/skills/refactor-conventions-creator/references/common-structures.md +91 -0
- package/skills/refactor-conventions-creator/references/common-styles.md +90 -0
- package/skills/refactor-design/SKILL.md +384 -0
- package/skills/release-deploy/SKILL.md +667 -0
- package/skills/release-deploy/agents/openai.yaml +6 -0
- package/skills/research/SKILL.md +166 -0
- package/skills/research/agents/openai.yaml +6 -0
- package/skills/review/SKILL.md +267 -0
- package/skills/review/references/deep-review.md +98 -0
- package/skills/review/references/review-lenses.md +68 -0
- package/skills/review/references/substrate-side-effects.md +161 -0
- package/skills/review/references/target-resolution.md +52 -0
- package/skills/scope/SKILL.md +486 -0
- package/work-view/Cargo.lock +486 -0
- package/work-view/Cargo.toml +9 -0
- package/work-view/crates/cli/.work-view-version +1 -0
- package/work-view/crates/cli/Cargo.toml +18 -0
- package/work-view/crates/cli/src/actionable.rs +500 -0
- package/work-view/crates/cli/src/args.rs +792 -0
- package/work-view/crates/cli/src/board/assets/board.css +855 -0
- package/work-view/crates/cli/src/board/assets/board.js +259 -0
- package/work-view/crates/cli/src/board/assets/card.js +139 -0
- package/work-view/crates/cli/src/board/assets/components.css +290 -0
- package/work-view/crates/cli/src/board/assets/dependency.js +1193 -0
- package/work-view/crates/cli/src/board/assets/detail.js +256 -0
- package/work-view/crates/cli/src/board/assets/filters.js +389 -0
- package/work-view/crates/cli/src/board/assets/index.html +77 -0
- package/work-view/crates/cli/src/board/assets/kanban.js +231 -0
- package/work-view/crates/cli/src/board/assets/markdown.js +260 -0
- package/work-view/crates/cli/src/board/assets/motion.css +131 -0
- package/work-view/crates/cli/src/board/assets/state.js +245 -0
- package/work-view/crates/cli/src/board/assets/table.js +304 -0
- package/work-view/crates/cli/src/board/assets/tokens.css +602 -0
- package/work-view/crates/cli/src/board/assets/views.js +41 -0
- package/work-view/crates/cli/src/board/assets.rs +162 -0
- package/work-view/crates/cli/src/board/feed.rs +204 -0
- package/work-view/crates/cli/src/board/mod.rs +246 -0
- package/work-view/crates/cli/src/board/open.rs +144 -0
- package/work-view/crates/cli/src/board/server.rs +407 -0
- package/work-view/crates/cli/src/main.rs +195 -0
- package/work-view/crates/cli/src/render.rs +354 -0
- package/work-view/crates/cli/src/scope.rs +157 -0
- package/work-view/crates/cli/src/stale.rs +581 -0
- package/work-view/crates/cli/tests/board-js/dependency-table.test.mjs +64 -0
- package/work-view/crates/cli/tests/board-js/expanded-browsing.test.mjs +79 -0
- package/work-view/crates/cli/tests/board-js/harness-smoke.test.mjs +11 -0
- package/work-view/crates/cli/tests/board-js/harness.mjs +437 -0
- package/work-view/crates/cli/tests/board-js/kanban-detail.test.mjs +75 -0
- package/work-view/crates/cli/tests/board-js/markdown-filter.test.mjs +60 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/CONVENTIONS.md +3 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/epics/epic-alpha.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-a.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-b.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-alpha-1.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-research-1.md +19 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-done.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-shipped.md +18 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/backlog/idea-backlog.md +7 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/CONVENTIONS.md +6 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-dep-done.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-design-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-impl-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/stories/story-review-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/CONVENTIONS.md +4 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/epics/malformed-no-closing-fence.md +8 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/features/good-item.md +16 -0
- package/work-view/crates/cli/tests/integration.rs +2833 -0
- package/work-view/crates/core/Cargo.toml +13 -0
- package/work-view/crates/core/src/error.rs +61 -0
- package/work-view/crates/core/src/filter.rs +804 -0
- package/work-view/crates/core/src/graph.rs +324 -0
- package/work-view/crates/core/src/index.rs +590 -0
- package/work-view/crates/core/src/lib.rs +54 -0
- package/work-view/crates/core/src/model.rs +202 -0
- package/work-view/crates/core/src/parse.rs +494 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/CONVENTIONS.md +15 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/epics/epic-core.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-parser.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-query.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/malformed-no-id.md +15 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-parse-unit.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-security-gate.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-old.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-parser.md +17 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/backlog/idea-future-board.md +7 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/CONVENTIONS.md +10 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/archive/dup-item.md +18 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/releases/v2.0/dup-item.md +18 -0
- package/work-view/crates/core/tests/integration.rs +541 -0
- package/work-view/dist/.gitattributes +1 -0
- package/work-view/dist/README.md +42 -0
- package/work-view/dist/aarch64-apple-darwin/work-view +0 -0
- package/work-view/dist/aarch64-unknown-linux-musl/work-view +0 -0
- package/work-view/dist/x86_64-apple-darwin/work-view +0 -0
- package/work-view/dist/x86_64-unknown-linux-musl/work-view +0 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
# PRINCIPLES: agile-workflow
|
|
2
|
+
|
|
3
|
+
The plugin's `principles` skill loads two distinct paradigms:
|
|
4
|
+
|
|
5
|
+
- **Code-design principles** — Ports & Adapters, Single Source of Truth,
|
|
6
|
+
Generated Contracts, Fail Fast. Carried from the `workflow` plugin.
|
|
7
|
+
These tell the agent how to write good code at design time and
|
|
8
|
+
implementation time.
|
|
9
|
+
- **Substrate-execution principles** — Item-IS-the-Work, Rolling-Foundation,
|
|
10
|
+
Late-Binding. New for agile-workflow. These tell the agent how to operate
|
|
11
|
+
the work-tracking substrate.
|
|
12
|
+
|
|
13
|
+
Both paradigms are active throughout agile-workflow work. Each governs a
|
|
14
|
+
different layer: code-design shapes what gets written; substrate-execution
|
|
15
|
+
shapes how work moves through the system.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Part I — Code-Design Principles
|
|
20
|
+
|
|
21
|
+
These four principles govern both architectural decisions and how code is
|
|
22
|
+
written. Each section has guidance for design time and implementation time.
|
|
23
|
+
|
|
24
|
+
## 1. Ports & Adapters
|
|
25
|
+
|
|
26
|
+
Core domain logic must not depend on infrastructure. Infrastructure depends
|
|
27
|
+
on the domain.
|
|
28
|
+
|
|
29
|
+
**Ports** are interfaces defined in the domain layer that describe what the
|
|
30
|
+
domain needs (a database, a file store, an HTTP client, a clock). **Adapters**
|
|
31
|
+
are infrastructure implementations of those interfaces.
|
|
32
|
+
|
|
33
|
+
### At design time
|
|
34
|
+
|
|
35
|
+
- Identify every external dependency the feature touches (DB, filesystem,
|
|
36
|
+
HTTP, queues, time, randomness)
|
|
37
|
+
- Define an interface (port) for each one in the domain layer
|
|
38
|
+
- Infrastructure modules implement those interfaces
|
|
39
|
+
- The domain function signature takes the port as a parameter or receives
|
|
40
|
+
it via dependency injection — it never imports the adapter directly
|
|
41
|
+
|
|
42
|
+
**Example structure:**
|
|
43
|
+
```
|
|
44
|
+
src/
|
|
45
|
+
domain/
|
|
46
|
+
user.ts # core logic — imports only domain types and ports
|
|
47
|
+
ports.ts # UserRepository interface, EmailSender interface
|
|
48
|
+
infrastructure/
|
|
49
|
+
db/user-repo.ts # implements UserRepository using Drizzle
|
|
50
|
+
email/smtp.ts # implements EmailSender using nodemailer
|
|
51
|
+
app/
|
|
52
|
+
wire.ts # assembles: new UserService(new DbUserRepo(), ...)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Design checklist:**
|
|
56
|
+
- [ ] Every external dependency has an interface in the domain layer
|
|
57
|
+
- [ ] No `import { db }` or `import { fs }` in domain modules
|
|
58
|
+
- [ ] Infrastructure modules are only referenced in composition roots
|
|
59
|
+
|
|
60
|
+
### At implementation time
|
|
61
|
+
|
|
62
|
+
When implementing domain logic, enforce the boundary: domain code receives
|
|
63
|
+
infrastructure as a typed parameter, never imports it directly.
|
|
64
|
+
|
|
65
|
+
**Good:**
|
|
66
|
+
```typescript
|
|
67
|
+
// domain/user-service.ts
|
|
68
|
+
export function createUser(repo: UserRepository, email: string): Promise<User> {
|
|
69
|
+
return repo.insert({ email })
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// app/wire.ts (entry point)
|
|
73
|
+
import { createUser } from '../domain/user-service'
|
|
74
|
+
import { DrizzleUserRepo } from '../infrastructure/db/user-repo'
|
|
75
|
+
const repo = new DrizzleUserRepo(db)
|
|
76
|
+
app.post('/users', (c) => createUser(repo, c.req.body.email))
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Bad:**
|
|
80
|
+
```typescript
|
|
81
|
+
// domain/user-service.ts
|
|
82
|
+
import { db } from '../infrastructure/db' // NEVER — domain imports infra
|
|
83
|
+
|
|
84
|
+
export function createUser(email: string) {
|
|
85
|
+
return db.insert(users).values({ email })
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
If you find yourself needing to import infrastructure into domain, that's
|
|
90
|
+
the signal to add a port interface instead.
|
|
91
|
+
|
|
92
|
+
## 2. Single Source of Truth (Data-Driven Extensibility)
|
|
93
|
+
|
|
94
|
+
When a concept can have multiple variants that may grow over time (roles,
|
|
95
|
+
statuses, event types, providers, feature flags), define that set of
|
|
96
|
+
variants **once** as a data structure. All logic — types, validation,
|
|
97
|
+
routing, display — derives from that single definition.
|
|
98
|
+
|
|
99
|
+
### At design time
|
|
100
|
+
|
|
101
|
+
- Identify enumerations that classes of things fall into
|
|
102
|
+
- Design a central registry: a typed constant, a config map, or a schema
|
|
103
|
+
object
|
|
104
|
+
- Derive all downstream types and logic from that registry rather than
|
|
105
|
+
re-enumerating variants in each consumer
|
|
106
|
+
|
|
107
|
+
**Example structure:**
|
|
108
|
+
```typescript
|
|
109
|
+
// Defined once
|
|
110
|
+
const ROLES = ['admin', 'editor', 'viewer'] as const
|
|
111
|
+
type Role = typeof ROLES[number]
|
|
112
|
+
|
|
113
|
+
// Or richer: a config map where behavior flows from data
|
|
114
|
+
const ROLE_CONFIG = {
|
|
115
|
+
admin: { level: 2, label: 'Admin' },
|
|
116
|
+
editor: { level: 1, label: 'Editor' },
|
|
117
|
+
viewer: { level: 0, label: 'Viewer' },
|
|
118
|
+
} satisfies Record<string, RoleConfig>
|
|
119
|
+
type Role = keyof typeof ROLE_CONFIG
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Design checklist:**
|
|
123
|
+
- [ ] Extensible sets of variants are defined as a single authoritative
|
|
124
|
+
constant/schema
|
|
125
|
+
- [ ] Downstream types are derived from the registry (not duplicated)
|
|
126
|
+
- [ ] Adding a new variant requires changing only the registry definition
|
|
127
|
+
|
|
128
|
+
### At implementation time
|
|
129
|
+
|
|
130
|
+
Implement extensible variant sets as a single typed constant. Derive all
|
|
131
|
+
downstream behavior from it — do not re-enumerate variants in switch
|
|
132
|
+
statements, conditionals, or validation schemas.
|
|
133
|
+
|
|
134
|
+
**Good:**
|
|
135
|
+
```typescript
|
|
136
|
+
const ROLE_CONFIG = {
|
|
137
|
+
admin: { level: 2, canDelete: true },
|
|
138
|
+
editor: { level: 1, canDelete: false },
|
|
139
|
+
viewer: { level: 0, canDelete: false },
|
|
140
|
+
} as const satisfies Record<string, RoleConfig>
|
|
141
|
+
|
|
142
|
+
type Role = keyof typeof ROLE_CONFIG
|
|
143
|
+
const ROLES = Object.keys(ROLE_CONFIG) as Role[]
|
|
144
|
+
const RoleSchema = z.enum(ROLES as [Role, ...Role[]])
|
|
145
|
+
|
|
146
|
+
// Adding 'owner' role = one change, in one place
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Bad:**
|
|
150
|
+
```typescript
|
|
151
|
+
type Role = 'admin' | 'editor' | 'viewer' // defined here
|
|
152
|
+
const roles = ['admin', 'editor', 'viewer'] // re-enumerated here
|
|
153
|
+
const RoleSchema = z.enum(['admin', 'editor', 'viewer']) // again here
|
|
154
|
+
switch (role) {
|
|
155
|
+
case 'admin': ... // and again here
|
|
156
|
+
case 'editor': ...
|
|
157
|
+
case 'viewer': ...
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## 3. Generated Contracts
|
|
162
|
+
|
|
163
|
+
When designing a boundary between two systems (client/server,
|
|
164
|
+
package/consumer, service/service), prefer generating the contract from the
|
|
165
|
+
source of truth rather than hand-authoring both sides.
|
|
166
|
+
|
|
167
|
+
### At design time
|
|
168
|
+
|
|
169
|
+
**Common approaches by boundary type:**
|
|
170
|
+
- **HTTP API → client**: OpenAPI schema → generated client types
|
|
171
|
+
(openapi-typescript, orval)
|
|
172
|
+
- **tRPC router → client**: router type is the contract, shared directly
|
|
173
|
+
- **Database schema → app types**: Drizzle/Prisma inferred types, not
|
|
174
|
+
hand-written interfaces
|
|
175
|
+
- **GraphQL schema → types**: codegen from SDL
|
|
176
|
+
|
|
177
|
+
- Identify every cross-boundary interface in the feature
|
|
178
|
+
- For each one, choose a single source of truth (schema file, router
|
|
179
|
+
definition, DB schema)
|
|
180
|
+
- Design the generation step into the build pipeline — not a manual step
|
|
181
|
+
- Consumers import generated types, not hand-written duplicates
|
|
182
|
+
|
|
183
|
+
**Design checklist:**
|
|
184
|
+
- [ ] Every client-facing contract has a designated source of truth
|
|
185
|
+
- [ ] A generation step is identified (codegen tool, shared type import,
|
|
186
|
+
inferred type)
|
|
187
|
+
- [ ] No hand-written types that mirror types defined elsewhere
|
|
188
|
+
|
|
189
|
+
### At implementation time
|
|
190
|
+
|
|
191
|
+
Do not hand-write types that are derivable from a schema, router, or
|
|
192
|
+
database definition. Import or generate them.
|
|
193
|
+
|
|
194
|
+
**Good:**
|
|
195
|
+
```typescript
|
|
196
|
+
import type { AppRouter } from '../../server/router'
|
|
197
|
+
// type-safe from the source
|
|
198
|
+
|
|
199
|
+
const { data } = useQuery<InferSelectModel<typeof users>>( ... )
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Bad:**
|
|
203
|
+
```typescript
|
|
204
|
+
// Hand-written duplicate of what Drizzle already knows
|
|
205
|
+
interface User {
|
|
206
|
+
id: number
|
|
207
|
+
email: string
|
|
208
|
+
createdAt: Date
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
If a generated type needs extending, use
|
|
213
|
+
`type MyType = GeneratedType & { extra: string }` — extend the source of
|
|
214
|
+
truth, don't replace it.
|
|
215
|
+
|
|
216
|
+
## 4. Fail Fast (implementation only)
|
|
217
|
+
|
|
218
|
+
Catch bad data at the door, not three calls deep where the stack trace is
|
|
219
|
+
useless. Validate inputs at the entry point of every function or system
|
|
220
|
+
boundary.
|
|
221
|
+
|
|
222
|
+
- At system boundaries (HTTP handlers, CLI args, external API responses,
|
|
223
|
+
config files): parse with Zod or equivalent before any logic runs
|
|
224
|
+
- At internal function boundaries: assert preconditions at the top of the
|
|
225
|
+
function — guard clauses, not nested ifs
|
|
226
|
+
- Prefer `throw`/`return early` over propagating bad state deep into call
|
|
227
|
+
chains
|
|
228
|
+
- Errors should be loud and specific at the point of violation —
|
|
229
|
+
"expected positive number, got -3" beats a cryptic null reference five
|
|
230
|
+
layers down
|
|
231
|
+
|
|
232
|
+
**Good:**
|
|
233
|
+
```typescript
|
|
234
|
+
function processOrder(input: unknown) {
|
|
235
|
+
const order = OrderSchema.parse(input) // throws immediately if invalid
|
|
236
|
+
return computeTotal(order)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function applyDiscount(order: Order, pct: number) {
|
|
240
|
+
if (pct < 0 || pct > 1) throw new Error(`Invalid discount: ${pct}`)
|
|
241
|
+
// ... rest of logic
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Bad:**
|
|
246
|
+
```typescript
|
|
247
|
+
function processOrder(input: any) {
|
|
248
|
+
// passes raw input through, blows up 5 calls deep
|
|
249
|
+
return computeTotal(input)
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
# Part II — Substrate-Execution Principles
|
|
256
|
+
|
|
257
|
+
These three principles govern how work moves through the substrate. They
|
|
258
|
+
shape stage transitions, item bodies, foundation-doc evolution, and
|
|
259
|
+
release binding. The agent applies these whenever operating on `.work/`
|
|
260
|
+
or `docs/`.
|
|
261
|
+
|
|
262
|
+
## 5. Item-IS-the-Work
|
|
263
|
+
|
|
264
|
+
The unit of work is its file. The brief, the design, the implementation
|
|
265
|
+
notes, and the review findings all accumulate in the item's body as
|
|
266
|
+
stages advance. Reading the file IS reading the state of the work.
|
|
267
|
+
|
|
268
|
+
### What this forbids
|
|
269
|
+
|
|
270
|
+
- Parallel design docs that exist alongside item files
|
|
271
|
+
(no `docs/designs/<name>.md` like in the workflow plugin)
|
|
272
|
+
- Separate progress files (no `PROGRESS.md` tracking what's in flight)
|
|
273
|
+
- Work memory that lives outside the substrate — chat history, user
|
|
274
|
+
memory, an external board, anywhere except the item file itself
|
|
275
|
+
- Code comments that duplicate item context (`// see story-foo for
|
|
276
|
+
background`) — code references logical concepts, not tracking IDs
|
|
277
|
+
|
|
278
|
+
### What this enables
|
|
279
|
+
|
|
280
|
+
- Cross-session continuity without re-feeding context: a new session
|
|
281
|
+
reads `.work/active/`, finds the item at `stage: implementing`, reads
|
|
282
|
+
its body for the design, and picks up where the last session left off
|
|
283
|
+
- A single source of truth for "what is the state of this work" — the
|
|
284
|
+
item file
|
|
285
|
+
- Git as the audit trail — every state change is a commit on the file
|
|
286
|
+
- The agent's amnesia stops being a tax on the user
|
|
287
|
+
|
|
288
|
+
### At design time
|
|
289
|
+
|
|
290
|
+
- When designing a feature, write the design INTO the feature item's
|
|
291
|
+
body. Do not create a separate `docs/designs/<name>.md`.
|
|
292
|
+
- When designing child stories under a feature, write each story's body
|
|
293
|
+
inline as you spawn it. Each story file is self-contained.
|
|
294
|
+
- When implementation surfaces a discovery (a constraint, a discovered
|
|
295
|
+
library, a forced pivot), edit the item's body to record it alongside
|
|
296
|
+
the design.
|
|
297
|
+
|
|
298
|
+
### At implementation time
|
|
299
|
+
|
|
300
|
+
- Read the item file at start. The design is in there.
|
|
301
|
+
- Update the item's body as you work — discoveries, deviations from the
|
|
302
|
+
design, integration notes
|
|
303
|
+
- After completing, the item's body is a complete record: brief → design
|
|
304
|
+
→ implementation notes → completion. A future agent reading it has
|
|
305
|
+
the full story.
|
|
306
|
+
- Don't write `// see story-foo for context` in code. The story's context
|
|
307
|
+
lives in the story's file. Code references logical concepts, not
|
|
308
|
+
tracking IDs.
|
|
309
|
+
|
|
310
|
+
### Design checklist
|
|
311
|
+
|
|
312
|
+
- [ ] No parallel design doc; design lives in feature/epic body
|
|
313
|
+
- [ ] No progress file; the substrate IS the progress
|
|
314
|
+
- [ ] Item body at completion is a complete record
|
|
315
|
+
- [ ] Code does not reference item IDs; only logical concepts
|
|
316
|
+
|
|
317
|
+
## 6. Rolling-Foundation
|
|
318
|
+
|
|
319
|
+
Foundation docs (`docs/VISION.md`, `docs/SPEC.md`, `docs/ARCHITECTURE.md`,
|
|
320
|
+
and any others) describe the project's vision (future-looking) and current
|
|
321
|
+
intent — what is true now, OR what will be true once in-flight design lands.
|
|
322
|
+
They roll forward in place as either evolves. No legacy comments. Git carries
|
|
323
|
+
history; the doc carries truth.
|
|
324
|
+
|
|
325
|
+
### Two timing styles
|
|
326
|
+
|
|
327
|
+
Both are legitimate; the project picks one or mixes per change size:
|
|
328
|
+
|
|
329
|
+
- **Code-first (default for routine features):** docs update at implementation
|
|
330
|
+
merge, in the same commit set as the code that lands the change.
|
|
331
|
+
- **Design-first (for large scope, initial ideation, architectural shifts):**
|
|
332
|
+
docs preflight-update at scope time, leading the code through the
|
|
333
|
+
implementation window. The doc temporarily describes an intended near-future
|
|
334
|
+
state. The agile-workflow `scope` skill operates this way for large scope;
|
|
335
|
+
`ideate` operates this way at project bootstrap.
|
|
336
|
+
|
|
337
|
+
The discipline is identical in both styles: replace stale assertions in
|
|
338
|
+
place, never accumulate "previously" / "in v1.x" / migration prose.
|
|
339
|
+
`gate-docs` at release-deploy time is the backstop — it catches drift between
|
|
340
|
+
intent (what the doc asserts) and reality (what code does) regardless of
|
|
341
|
+
which timing style was used.
|
|
342
|
+
|
|
343
|
+
### What this forbids
|
|
344
|
+
|
|
345
|
+
- "Note: in v1.2 this was X" footnotes
|
|
346
|
+
- "Previously" / "originally" / "we used to" prose
|
|
347
|
+
- A "Migration notes" section retaining old behavior descriptions
|
|
348
|
+
- Compatibility shims documented in foundation docs (those go in code
|
|
349
|
+
comments only, where they live with the workaround)
|
|
350
|
+
- Changelog-style entries inside foundation docs
|
|
351
|
+
(CHANGELOG.md is its own file, separate)
|
|
352
|
+
|
|
353
|
+
### What this enables
|
|
354
|
+
|
|
355
|
+
- A new contributor reads the doc and learns the system as it IS or as
|
|
356
|
+
it is meant to imminently become — not as it was
|
|
357
|
+
- Foundation docs stay short and current rather than growing with every
|
|
358
|
+
change
|
|
359
|
+
- `git log docs/<file>.md` shows every rolling-forward edit — perfect
|
|
360
|
+
audit trail without bloating the doc
|
|
361
|
+
- Discrepancies between intent and reality become bugs that `gate-docs`
|
|
362
|
+
surfaces, not historical artifacts to be reconciled mentally
|
|
363
|
+
|
|
364
|
+
### At design time
|
|
365
|
+
|
|
366
|
+
- When scoping a feature that changes a foundation-doc assertion, decide
|
|
367
|
+
the timing: code-first (defer the doc update) or design-first (preflight
|
|
368
|
+
the update as part of scope)
|
|
369
|
+
- For large-scope `scope` operations, design-first is the default —
|
|
370
|
+
`scope` rolls foundation docs forward as part of the same operation
|
|
371
|
+
- Identify which foundation doc(s) need rolling forward; reading them
|
|
372
|
+
at design time prevents stale assumptions
|
|
373
|
+
- If a feature's design contradicts a foundation doc, EITHER the design
|
|
374
|
+
is wrong OR the doc is. Resolve before designing the implementation.
|
|
375
|
+
|
|
376
|
+
### At implementation time
|
|
377
|
+
|
|
378
|
+
- If working code-first: after implementing a change, ask "what does a
|
|
379
|
+
foundation doc now say that's no longer true?" — update assertions in
|
|
380
|
+
place, commit with the implementation
|
|
381
|
+
- If working design-first: the doc was preflight-updated at scope time.
|
|
382
|
+
Verify the implementation matches the doc's assertion; if it deviates,
|
|
383
|
+
adjust whichever was wrong (implementation or assertion).
|
|
384
|
+
- Replace stale assertions in place. Delete the old text. Never append
|
|
385
|
+
"previously" / "in v1.x" / migration prose.
|
|
386
|
+
- The `gate-docs` runs at release-deploy time and produces items for
|
|
387
|
+
any remaining drift — but the goal is to leave it nothing to find.
|
|
388
|
+
|
|
389
|
+
### Design checklist
|
|
390
|
+
|
|
391
|
+
- [ ] Every assertion in SPEC and ARCHITECTURE reflects current code OR
|
|
392
|
+
imminent in-flight design (no stale assertions from cancelled work)
|
|
393
|
+
- [ ] VISION.md reflects the project's current direction, not past direction
|
|
394
|
+
- [ ] No "previously" / "originally" / "in v1.x" prose anywhere in `docs/`
|
|
395
|
+
- [ ] When a feature changes behavior or direction, foundation docs update
|
|
396
|
+
in the same commit set as the change (code-first) or were preflight-
|
|
397
|
+
updated and are still accurate (design-first)
|
|
398
|
+
- [ ] `git log docs/<file>.md` shows the audit trail; the doc shows the
|
|
399
|
+
present
|
|
400
|
+
|
|
401
|
+
## 7. Late-Binding
|
|
402
|
+
|
|
403
|
+
Items advance stages when work actually completes. Releases bind items
|
|
404
|
+
only when the user cuts a version. Foundation docs are not pre-decided
|
|
405
|
+
into a phase plan. Work happens, then commitments crystallize — not the
|
|
406
|
+
other way around.
|
|
407
|
+
|
|
408
|
+
### What this forbids
|
|
409
|
+
|
|
410
|
+
- Pre-populated `stage:` values that don't reflect actual progress
|
|
411
|
+
- Pre-set `release_binding:` on items the user hasn't yet decided to ship
|
|
412
|
+
- A `ROADMAP.md` that pre-commits features to releases
|
|
413
|
+
- A "Sprint 3 backlog" that promises specific items will land by a date
|
|
414
|
+
- Phase numbering that assigns items to a temporal slot upfront
|
|
415
|
+
|
|
416
|
+
### What this enables
|
|
417
|
+
|
|
418
|
+
- Items advance based on real completion, not on a plan that gets stale
|
|
419
|
+
- Releases capture what's ACTUALLY ready, not what was supposed to be
|
|
420
|
+
ready
|
|
421
|
+
- Backlog items don't accumulate stale tags or premature decisions
|
|
422
|
+
- Pivots are cheap — change of plan doesn't require unwinding pre-bound
|
|
423
|
+
items, because nothing was pre-bound
|
|
424
|
+
|
|
425
|
+
### At design time
|
|
426
|
+
|
|
427
|
+
- When epicizing, declare epic dependencies via `depends_on`, NOT release
|
|
428
|
+
bundling. The graph captures sequence; the release captures shipment.
|
|
429
|
+
- When scoping a feature, leave `release_binding: null` until a release
|
|
430
|
+
is cut and the user explicitly binds.
|
|
431
|
+
- When designing child stories, declare sequencing via `depends_on`, NOT
|
|
432
|
+
by pre-committing them to a release.
|
|
433
|
+
|
|
434
|
+
### At implementation time
|
|
435
|
+
|
|
436
|
+
- Advance `stage:` only when the work for that stage actually completes
|
|
437
|
+
- Don't bind items to a release until the user invokes `/release-deploy`
|
|
438
|
+
and chooses to bind
|
|
439
|
+
- When work shifts (a feature gets postponed, a story gets cut), simply
|
|
440
|
+
leave the item where it is — its current state is its truth. Don't
|
|
441
|
+
update prose anywhere to reflect "we decided to defer this." If it's
|
|
442
|
+
not bound and not done, that's the truth.
|
|
443
|
+
|
|
444
|
+
### Design checklist
|
|
445
|
+
|
|
446
|
+
- [ ] No pre-populated `stage` values
|
|
447
|
+
- [ ] No `release_binding` set without an active release-deploy
|
|
448
|
+
- [ ] Dependencies expressed via `depends_on`, not by ordering in any
|
|
449
|
+
external plan
|
|
450
|
+
- [ ] No ROADMAP.md or equivalent that pre-commits work to releases
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
# How the principles skill uses this
|
|
455
|
+
|
|
456
|
+
The agile-workflow `principles` skill loads this entire document at design
|
|
457
|
+
time, implementation time, and review time. It does not summarize — the
|
|
458
|
+
full content is the reference. New design specializations or substrate
|
|
459
|
+
verbs that need additional principles add them to the relevant Part.
|
|
460
|
+
|
|
461
|
+
The two paradigms operate together: code-design principles shape what
|
|
462
|
+
gets written into code; substrate-execution principles shape how work
|
|
463
|
+
moves through `.work/` and `docs/`. Neither paradigm is optional during
|
|
464
|
+
agile-workflow work.
|
package/docs/ROADMAP.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# agile-workflow v0.1.0 — Build Roadmap
|
|
2
|
+
|
|
3
|
+
**Status: transient.** Plans v0.1.0 only. Deleted after Phase 4 ships in
|
|
4
|
+
keeping with rolling-foundation. Future evolution lives in the plugin's
|
|
5
|
+
own `.work/` substrate.
|
|
6
|
+
|
|
7
|
+
Built solo + autopilot via `/workflow`. Each phase is one
|
|
8
|
+
`/workflow:design → /workflow:implement-orchestrator` cycle.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Phase 1: Plugin foundation + tooling
|
|
13
|
+
|
|
14
|
+
**Goal:** Plugin installs via the marketplace. Scripts run. Hooks fire (silently
|
|
15
|
+
when no substrate). Reference skills and `principles` work on any project.
|
|
16
|
+
|
|
17
|
+
**Build:**
|
|
18
|
+
- Scaffold: `.claude-plugin/plugin.json` (v0.1.0), `README.md`, `CHANGELOG.md`
|
|
19
|
+
- `scripts/work-view.sh` — full flag set per SPEC.md, pure bash with
|
|
20
|
+
optional yq/jq enhancement, exit codes 0/1/2/3
|
|
21
|
+
- `hooks/hooks.json` plus `prompt-context.py` and `substrate-maintainer.py`
|
|
22
|
+
— all flag-gated by `.work/CONVENTIONS.md`
|
|
23
|
+
- `skills/principles/` loading both paradigms from PRINCIPLES.md
|
|
24
|
+
- Reference skills carried from `workflow` (mechanical adaptations):
|
|
25
|
+
`research/`, `repo-eval/`, `tool-evaluator/`, `refactor-conventions-creator/`
|
|
26
|
+
(`repo-eval` later moved to `code-audit`; `tool-evaluator` moved to
|
|
27
|
+
`nates-toolkit` and is now `agent-reflection`)
|
|
28
|
+
- Plugin manifests covering the 5 skills
|
|
29
|
+
|
|
30
|
+
**Test checkpoint:** `bats tests/work-view.bats` passes — covers each flag
|
|
31
|
+
combination, exit codes, and --help. (work-view is the only artifact in
|
|
32
|
+
this phase that warrants real testing; everything else is markdown content
|
|
33
|
+
or thin shell scripts that get verified by use in later phases.)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Phase 2: Substrate operational skills
|
|
38
|
+
|
|
39
|
+
**Goal:** Full lifecycle works on a test repo. A user can ideate → convert
|
|
40
|
+
→ epicize, then park / scope / fix / design / implement / review a feature
|
|
41
|
+
end to end. Self-dogfooding moment: bootstrap agile-workflow's own
|
|
42
|
+
`.work/` substrate.
|
|
43
|
+
|
|
44
|
+
**Build:**
|
|
45
|
+
- Bootstrap: `ideate/`, `convert/` (+ migration-paths reference), `epicize/`
|
|
46
|
+
- Capture: `park/`, `scope/` (+ sizing reference, foundation-doc roll-forward
|
|
47
|
+
for large scope), `fix/`
|
|
48
|
+
- Design family: `design/`, `refactor-design/`, `perf-design/` — all
|
|
49
|
+
tag-routed; descriptions cross-reference each other
|
|
50
|
+
- Production + review: `implement/`, `implement-orchestrator/` (respects
|
|
51
|
+
`depends_on`), `review/`
|
|
52
|
+
- Plugin manifests covering all 12 skills
|
|
53
|
+
- Bootstrap `plugins/agile-workflow/.work/` using the new `convert` skill
|
|
54
|
+
|
|
55
|
+
**Test checkpoint:** Take a fresh test repo through the full cycle by hand:
|
|
56
|
+
ideate → convert → epicize → scope a feature → design it → implement →
|
|
57
|
+
review → done. If the cycle completes and the substrate state looks right,
|
|
58
|
+
phase passes. No mechanical verification matrix.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Phase 3: Release machinery + autonomous ops
|
|
63
|
+
|
|
64
|
+
**Goal:** Releases can be cut with all 5 gates running. Autopilot drains
|
|
65
|
+
queues respecting dependencies. Bold-refactor scopes architectural refactor
|
|
66
|
+
epics on user request.
|
|
67
|
+
|
|
68
|
+
**Build:**
|
|
69
|
+
- `release-deploy/` (+ release-mapping reference)
|
|
70
|
+
- 5 gates: `gate-security/`, `gate-tests/`, `gate-cruft/`, `gate-docs/`,
|
|
71
|
+
`gate-patterns/` — each with reference file
|
|
72
|
+
- `autopilot/` (+ queue-algorithm and harness-goal references)
|
|
73
|
+
- `bold-refactor/` (+ architectural-shifts reference) — user-invocable only
|
|
74
|
+
- Plugin manifests covering all 8 skills
|
|
75
|
+
|
|
76
|
+
**Test checkpoint:** In the test repo from Phase 2, cut a fake release end
|
|
77
|
+
to end with `release-deploy` — gates run, items advance, release ships.
|
|
78
|
+
Run an autopilot goal against an epic with depends_on chains — order is
|
|
79
|
+
respected. That's it.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Phase 4: Real-project dogfooding + ship
|
|
84
|
+
|
|
85
|
+
**Goal:** v0.1.0 has carried a real project of yours through a complete
|
|
86
|
+
cycle and is published.
|
|
87
|
+
|
|
88
|
+
**Build:**
|
|
89
|
+
- Pick a real target project; run the full workflow on it
|
|
90
|
+
- Bump plugin to v0.1.0 (if not already); publish via the marketplace
|
|
91
|
+
- Delete `plugins/agile-workflow/docs/ROADMAP.md`
|
|
92
|
+
|
|
93
|
+
**Test checkpoint:** Target project shipped its own release via
|
|
94
|
+
`/agile-workflow:release-deploy`. Plugin manifest reports v0.1.0. Fresh
|
|
95
|
+
`/plugin install agile-workflow@nklisch-skills` works. ROADMAP.md is gone.
|