@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.
Files changed (203) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/.codex-plugin/plugin.json +28 -0
  3. package/CHANGELOG.md +591 -0
  4. package/README.md +107 -0
  5. package/docs/ARCHITECTURE.md +716 -0
  6. package/docs/MIGRATION.md +419 -0
  7. package/docs/PRINCIPLES.md +464 -0
  8. package/docs/ROADMAP.md +95 -0
  9. package/docs/SPEC.md +855 -0
  10. package/docs/VISION.md +106 -0
  11. package/extensions/agile-workflow.test.ts +419 -0
  12. package/extensions/agile-workflow.ts +467 -0
  13. package/hooks/hooks.json +52 -0
  14. package/hooks/scripts/prompt-context.py +628 -0
  15. package/hooks/scripts/substrate-maintainer.py +359 -0
  16. package/hooks/scripts/test_prompt_context.py +757 -0
  17. package/package.json +30 -0
  18. package/scripts/install-work-view.sh +165 -0
  19. package/scripts/tests/agent-metadata.test.sh +75 -0
  20. package/scripts/tests/bump-version.test.sh +552 -0
  21. package/scripts/tests/channel-parity.test.sh +117 -0
  22. package/scripts/tests/convert-content-integrity.test.sh +246 -0
  23. package/scripts/tests/convert-install-routing.test.sh +159 -0
  24. package/scripts/tests/install-work-view.test.sh +411 -0
  25. package/scripts/tests/pi-package-metadata.test.sh +119 -0
  26. package/scripts/tests/work-board-shim.test.sh +239 -0
  27. package/scripts/tests/work-view-dist-version.test.sh +105 -0
  28. package/scripts/work-board.sh +64 -0
  29. package/scripts/work-view.sh +423 -0
  30. package/skills/autopilot/SKILL.md +330 -0
  31. package/skills/autopilot/agents/openai.yaml +6 -0
  32. package/skills/board/SKILL.md +62 -0
  33. package/skills/board/agents/openai.yaml +6 -0
  34. package/skills/bold-refactor/SKILL.md +244 -0
  35. package/skills/bold-refactor/agents/openai.yaml +6 -0
  36. package/skills/bug-scan/SKILL.md +378 -0
  37. package/skills/bug-scan/agents/openai.yaml +6 -0
  38. package/skills/bug-scan/references/async-promises.md +119 -0
  39. package/skills/bug-scan/references/concurrency-races.md +148 -0
  40. package/skills/bug-scan/references/data-layer.md +167 -0
  41. package/skills/bug-scan/references/error-handling.md +197 -0
  42. package/skills/bug-scan/references/gate-item-template.md +94 -0
  43. package/skills/bug-scan/references/language-footguns.md +219 -0
  44. package/skills/bug-scan/references/parked-item-template.md +103 -0
  45. package/skills/bug-scan/references/report-template.md +115 -0
  46. package/skills/bug-scan/references/resource-leaks.md +199 -0
  47. package/skills/bug-scan/references/state-closures.md +148 -0
  48. package/skills/bug-scan/references/time-numbers.md +158 -0
  49. package/skills/convert/SKILL.md +1463 -0
  50. package/skills/convert/agents/openai.yaml +6 -0
  51. package/skills/convert/references/legacy-overlap-migration.md +179 -0
  52. package/skills/deep-code-scan/SKILL.md +378 -0
  53. package/skills/deep-code-scan/agents/openai.yaml +6 -0
  54. package/skills/deep-code-scan/references/artifact-ledger.md +148 -0
  55. package/skills/deep-code-scan/references/consolidation.md +91 -0
  56. package/skills/deep-code-scan/references/decomposition.md +127 -0
  57. package/skills/deep-code-scan/references/item-templates.md +263 -0
  58. package/skills/deep-code-scan/references/lane-catalog.md +129 -0
  59. package/skills/deep-code-scan/references/review-gauntlet.md +108 -0
  60. package/skills/deep-code-scan/references/scanner-brief.md +152 -0
  61. package/skills/e2e-test-design/SKILL.md +517 -0
  62. package/skills/e2e-test-design/references/anti-tautology.md +261 -0
  63. package/skills/e2e-test-design/references/service-mocks.md +234 -0
  64. package/skills/e2e-test-design/references/test-taxonomy.md +211 -0
  65. package/skills/epic-design/SKILL.md +476 -0
  66. package/skills/epicize/SKILL.md +210 -0
  67. package/skills/epicize/agents/openai.yaml +6 -0
  68. package/skills/feature-design/SKILL.md +472 -0
  69. package/skills/fix/SKILL.md +173 -0
  70. package/skills/gate-cruft/SKILL.md +258 -0
  71. package/skills/gate-docs/SKILL.md +278 -0
  72. package/skills/gate-patterns/SKILL.md +389 -0
  73. package/skills/gate-refactor/SKILL.md +408 -0
  74. package/skills/gate-security/SKILL.md +275 -0
  75. package/skills/gate-tests/SKILL.md +367 -0
  76. package/skills/groom/SKILL.md +162 -0
  77. package/skills/groom/agents/openai.yaml +6 -0
  78. package/skills/ideate/SKILL.md +185 -0
  79. package/skills/ideate/agents/openai.yaml +6 -0
  80. package/skills/implement/SKILL.md +288 -0
  81. package/skills/implement-orchestrator/SKILL.md +604 -0
  82. package/skills/park/SKILL.md +111 -0
  83. package/skills/perf-design/SKILL.md +427 -0
  84. package/skills/perf-scout/SKILL.md +404 -0
  85. package/skills/perf-scout/agents/openai.yaml +6 -0
  86. package/skills/perf-scout/references/algorithmic-and-data-structures.md +126 -0
  87. package/skills/perf-scout/references/approximation-and-precomputation.md +136 -0
  88. package/skills/perf-scout/references/caching-and-memoization.md +123 -0
  89. package/skills/perf-scout/references/compiler-runtime-and-language.md +136 -0
  90. package/skills/perf-scout/references/database-and-storage-internals.md +144 -0
  91. package/skills/perf-scout/references/distributed-systems.md +150 -0
  92. package/skills/perf-scout/references/game-engine-and-realtime.md +136 -0
  93. package/skills/perf-scout/references/gpu-and-accelerators.md +130 -0
  94. package/skills/perf-scout/references/idea-ranking.md +75 -0
  95. package/skills/perf-scout/references/io-and-batching.md +135 -0
  96. package/skills/perf-scout/references/memory-and-data-locality.md +137 -0
  97. package/skills/perf-scout/references/parallelism-and-vectorization.md +126 -0
  98. package/skills/perf-scout/references/parked-item-template.md +117 -0
  99. package/skills/perf-scout/references/peer-review-pass.md +150 -0
  100. package/skills/perf-scout/references/report-template.md +148 -0
  101. package/skills/principles/SKILL.md +678 -0
  102. package/skills/principles/references/models.md +191 -0
  103. package/skills/principles/references/subagents.md +158 -0
  104. package/skills/prose-author/SKILL.md +185 -0
  105. package/skills/refactor-conventions-creator/SKILL.md +359 -0
  106. package/skills/refactor-conventions-creator/agents/openai.yaml +6 -0
  107. package/skills/refactor-conventions-creator/references/common-structures.md +91 -0
  108. package/skills/refactor-conventions-creator/references/common-styles.md +90 -0
  109. package/skills/refactor-design/SKILL.md +384 -0
  110. package/skills/release-deploy/SKILL.md +667 -0
  111. package/skills/release-deploy/agents/openai.yaml +6 -0
  112. package/skills/research/SKILL.md +166 -0
  113. package/skills/research/agents/openai.yaml +6 -0
  114. package/skills/review/SKILL.md +267 -0
  115. package/skills/review/references/deep-review.md +98 -0
  116. package/skills/review/references/review-lenses.md +68 -0
  117. package/skills/review/references/substrate-side-effects.md +161 -0
  118. package/skills/review/references/target-resolution.md +52 -0
  119. package/skills/scope/SKILL.md +486 -0
  120. package/work-view/Cargo.lock +486 -0
  121. package/work-view/Cargo.toml +9 -0
  122. package/work-view/crates/cli/.work-view-version +1 -0
  123. package/work-view/crates/cli/Cargo.toml +18 -0
  124. package/work-view/crates/cli/src/actionable.rs +500 -0
  125. package/work-view/crates/cli/src/args.rs +792 -0
  126. package/work-view/crates/cli/src/board/assets/board.css +855 -0
  127. package/work-view/crates/cli/src/board/assets/board.js +259 -0
  128. package/work-view/crates/cli/src/board/assets/card.js +139 -0
  129. package/work-view/crates/cli/src/board/assets/components.css +290 -0
  130. package/work-view/crates/cli/src/board/assets/dependency.js +1193 -0
  131. package/work-view/crates/cli/src/board/assets/detail.js +256 -0
  132. package/work-view/crates/cli/src/board/assets/filters.js +389 -0
  133. package/work-view/crates/cli/src/board/assets/index.html +77 -0
  134. package/work-view/crates/cli/src/board/assets/kanban.js +231 -0
  135. package/work-view/crates/cli/src/board/assets/markdown.js +260 -0
  136. package/work-view/crates/cli/src/board/assets/motion.css +131 -0
  137. package/work-view/crates/cli/src/board/assets/state.js +245 -0
  138. package/work-view/crates/cli/src/board/assets/table.js +304 -0
  139. package/work-view/crates/cli/src/board/assets/tokens.css +602 -0
  140. package/work-view/crates/cli/src/board/assets/views.js +41 -0
  141. package/work-view/crates/cli/src/board/assets.rs +162 -0
  142. package/work-view/crates/cli/src/board/feed.rs +204 -0
  143. package/work-view/crates/cli/src/board/mod.rs +246 -0
  144. package/work-view/crates/cli/src/board/open.rs +144 -0
  145. package/work-view/crates/cli/src/board/server.rs +407 -0
  146. package/work-view/crates/cli/src/main.rs +195 -0
  147. package/work-view/crates/cli/src/render.rs +354 -0
  148. package/work-view/crates/cli/src/scope.rs +157 -0
  149. package/work-view/crates/cli/src/stale.rs +581 -0
  150. package/work-view/crates/cli/tests/board-js/dependency-table.test.mjs +64 -0
  151. package/work-view/crates/cli/tests/board-js/expanded-browsing.test.mjs +79 -0
  152. package/work-view/crates/cli/tests/board-js/harness-smoke.test.mjs +11 -0
  153. package/work-view/crates/cli/tests/board-js/harness.mjs +437 -0
  154. package/work-view/crates/cli/tests/board-js/kanban-detail.test.mjs +75 -0
  155. package/work-view/crates/cli/tests/board-js/markdown-filter.test.mjs +60 -0
  156. package/work-view/crates/cli/tests/fixtures/golden/.work/CONVENTIONS.md +3 -0
  157. package/work-view/crates/cli/tests/fixtures/golden/.work/active/epics/epic-alpha.md +16 -0
  158. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-a.md +16 -0
  159. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-b.md +16 -0
  160. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-alpha-1.md +16 -0
  161. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-research-1.md +19 -0
  162. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-done.md +16 -0
  163. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-shipped.md +18 -0
  164. package/work-view/crates/cli/tests/fixtures/golden/.work/backlog/idea-backlog.md +7 -0
  165. package/work-view/crates/cli/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  166. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/CONVENTIONS.md +6 -0
  167. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-dep-done.md +17 -0
  168. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-design-ready.md +17 -0
  169. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-impl-ready.md +17 -0
  170. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/stories/story-review-ready.md +17 -0
  171. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/CONVENTIONS.md +4 -0
  172. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/epics/malformed-no-closing-fence.md +8 -0
  173. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/features/good-item.md +16 -0
  174. package/work-view/crates/cli/tests/integration.rs +2833 -0
  175. package/work-view/crates/core/Cargo.toml +13 -0
  176. package/work-view/crates/core/src/error.rs +61 -0
  177. package/work-view/crates/core/src/filter.rs +804 -0
  178. package/work-view/crates/core/src/graph.rs +324 -0
  179. package/work-view/crates/core/src/index.rs +590 -0
  180. package/work-view/crates/core/src/lib.rs +54 -0
  181. package/work-view/crates/core/src/model.rs +202 -0
  182. package/work-view/crates/core/src/parse.rs +494 -0
  183. package/work-view/crates/core/tests/fixtures/golden/.work/CONVENTIONS.md +15 -0
  184. package/work-view/crates/core/tests/fixtures/golden/.work/active/epics/epic-core.md +16 -0
  185. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-parser.md +16 -0
  186. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-query.md +16 -0
  187. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/malformed-no-id.md +15 -0
  188. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-parse-unit.md +16 -0
  189. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-security-gate.md +16 -0
  190. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-old.md +16 -0
  191. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-parser.md +17 -0
  192. package/work-view/crates/core/tests/fixtures/golden/.work/backlog/idea-future-board.md +7 -0
  193. package/work-view/crates/core/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  194. package/work-view/crates/core/tests/fixtures/precedence/.work/CONVENTIONS.md +10 -0
  195. package/work-view/crates/core/tests/fixtures/precedence/.work/archive/dup-item.md +18 -0
  196. package/work-view/crates/core/tests/fixtures/precedence/.work/releases/v2.0/dup-item.md +18 -0
  197. package/work-view/crates/core/tests/integration.rs +541 -0
  198. package/work-view/dist/.gitattributes +1 -0
  199. package/work-view/dist/README.md +42 -0
  200. package/work-view/dist/aarch64-apple-darwin/work-view +0 -0
  201. package/work-view/dist/aarch64-unknown-linux-musl/work-view +0 -0
  202. package/work-view/dist/x86_64-apple-darwin/work-view +0 -0
  203. package/work-view/dist/x86_64-unknown-linux-musl/work-view +0 -0
@@ -0,0 +1,678 @@
1
+ ---
2
+ name: principles
3
+ description: >
4
+ agile-workflow principles — code-design (Ports & Adapters, Single Source of Truth, Generated
5
+ Contracts, Fail Fast) and substrate-execution (Item-IS-the-Work, Rolling-Foundation, Late-Binding).
6
+ Auto-loads when designing modules, defining interfaces, writing or implementing code, scoping work
7
+ in the substrate, advancing stages, scoping releases, or any time the agile-workflow
8
+ design/implement/review skills are active.
9
+ ---
10
+
11
+ # Principles
12
+
13
+ Two paradigms operate together during agile-workflow work:
14
+
15
+ - **Code-design principles** (Part I) — how to write good code at design time and
16
+ implementation time. Carried from `workflow:principles`.
17
+ - **Substrate-execution principles** (Part II) — how work moves through the
18
+ `.work/` substrate. New for agile-workflow.
19
+
20
+ Each principle has guidance for design time and implementation time.
21
+
22
+ ---
23
+
24
+ # Part I — Code-Design Principles
25
+
26
+ ## 1. Ports & Adapters
27
+
28
+ Core domain logic must not depend on infrastructure. Infrastructure depends on the domain.
29
+
30
+ **Ports** are interfaces defined in the domain layer that describe what the domain needs (a database, a file store, an HTTP client, a clock). **Adapters** are infrastructure implementations of those interfaces.
31
+
32
+ ### At design time
33
+
34
+ - Identify every external dependency the feature touches (DB, filesystem, HTTP, queues, time, randomness)
35
+ - Define an interface (port) for each one in the domain layer
36
+ - Infrastructure modules implement those interfaces
37
+ - The domain function signature takes the port as a parameter or receives it via dependency injection — it never imports the adapter directly
38
+
39
+ **Example structure:**
40
+ ```
41
+ src/
42
+ domain/
43
+ user.ts # core logic — imports only domain types and ports
44
+ ports.ts # UserRepository interface, EmailSender interface
45
+ infrastructure/
46
+ db/user-repo.ts # implements UserRepository using Drizzle
47
+ email/smtp.ts # implements EmailSender using nodemailer
48
+ app/
49
+ wire.ts # assembles: new UserService(new DbUserRepo(), new SmtpEmailSender())
50
+ ```
51
+
52
+ **Design checklist:**
53
+ - [ ] Every external dependency has an interface in the domain layer
54
+ - [ ] No `import { db }` or `import { fs }` in domain modules
55
+ - [ ] Infrastructure modules are only referenced in composition roots (wire-up / entry points)
56
+
57
+ ### At implementation time
58
+
59
+ When implementing domain logic, enforce the boundary: domain code receives infrastructure as a typed parameter, never imports it directly.
60
+
61
+ **Good:**
62
+ ```typescript
63
+ // domain/user-service.ts
64
+ export function createUser(repo: UserRepository, email: string): Promise<User> {
65
+ return repo.insert({ email })
66
+ }
67
+
68
+ // app/wire.ts (entry point)
69
+ import { createUser } from '../domain/user-service'
70
+ import { DrizzleUserRepo } from '../infrastructure/db/user-repo'
71
+ const repo = new DrizzleUserRepo(db)
72
+ app.post('/users', (c) => createUser(repo, c.req.body.email))
73
+ ```
74
+
75
+ **Bad:**
76
+ ```typescript
77
+ // domain/user-service.ts
78
+ import { db } from '../infrastructure/db' // NEVER — domain imports infra
79
+
80
+ export function createUser(email: string) {
81
+ return db.insert(users).values({ email })
82
+ }
83
+ ```
84
+
85
+ If you find yourself needing to import infrastructure into domain, that's the signal to add a port interface instead.
86
+
87
+ ---
88
+
89
+ ## 2. Single Source of Truth (Data-Driven Extensibility)
90
+
91
+ When a concept can have multiple variants that may grow over time (roles, statuses, event types, providers, feature flags), define that set of variants **once** as a data structure. All logic — types, validation, routing, display — derives from that single definition.
92
+
93
+ ### At design time
94
+
95
+ - Identify enumerations that classes of things fall into
96
+ - Design a central registry: a typed constant, a config map, or a schema object
97
+ - Derive all downstream types and logic from that registry rather than re-enumerating variants in each consumer
98
+
99
+ **Example structure:**
100
+ ```typescript
101
+ // Defined once
102
+ const ROLES = ['admin', 'editor', 'viewer'] as const
103
+ type Role = typeof ROLES[number]
104
+
105
+ // Or richer: a config map where behavior flows from data
106
+ const ROLE_CONFIG = {
107
+ admin: { level: 2, label: 'Admin' },
108
+ editor: { level: 1, label: 'Editor' },
109
+ viewer: { level: 0, label: 'Viewer' },
110
+ } satisfies Record<string, RoleConfig>
111
+ type Role = keyof typeof ROLE_CONFIG
112
+ ```
113
+
114
+ **Design checklist:**
115
+ - [ ] Extensible sets of variants are defined as a single authoritative constant/schema
116
+ - [ ] Downstream types are derived from the registry (not duplicated)
117
+ - [ ] Adding a new variant requires changing only the registry definition
118
+
119
+ ### At implementation time
120
+
121
+ Implement extensible variant sets as a single typed constant. Derive all downstream behavior from it — do not re-enumerate variants in switch statements, conditionals, or validation schemas.
122
+
123
+ **Good:**
124
+ ```typescript
125
+ const ROLE_CONFIG = {
126
+ admin: { level: 2, canDelete: true },
127
+ editor: { level: 1, canDelete: false },
128
+ viewer: { level: 0, canDelete: false },
129
+ } as const satisfies Record<string, RoleConfig>
130
+
131
+ type Role = keyof typeof ROLE_CONFIG
132
+ const ROLES = Object.keys(ROLE_CONFIG) as Role[]
133
+ const RoleSchema = z.enum(ROLES as [Role, ...Role[]])
134
+
135
+ // Adding 'owner' role = one change, in one place
136
+ ```
137
+
138
+ **Bad:**
139
+ ```typescript
140
+ type Role = 'admin' | 'editor' | 'viewer' // defined here
141
+ const roles = ['admin', 'editor', 'viewer'] // re-enumerated here
142
+ const RoleSchema = z.enum(['admin', 'editor', 'viewer']) // again here
143
+ switch (role) {
144
+ case 'admin': ... // and again here
145
+ case 'editor': ...
146
+ case 'viewer': ...
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## 3. Generated Contracts
153
+
154
+ When designing a boundary between two systems (client/server, package/consumer, service/service), prefer generating the contract from the source of truth rather than hand-authoring both sides.
155
+
156
+ ### At design time
157
+
158
+ **Common approaches by boundary type:**
159
+ - **HTTP API → client**: OpenAPI schema → generated client types (openapi-typescript, orval)
160
+ - **tRPC router → client**: router type is the contract, shared directly
161
+ - **Database schema → app types**: Drizzle/Prisma inferred types, not hand-written interfaces
162
+ - **GraphQL schema → types**: codegen from SDL
163
+
164
+ - Identify every cross-boundary interface in the feature
165
+ - For each one, choose a single source of truth (schema file, router definition, DB schema)
166
+ - Design the generation step into the build pipeline — not a manual step
167
+ - Consumers import generated types, not hand-written duplicates
168
+
169
+ **Design checklist:**
170
+ - [ ] Every client-facing contract has a designated source of truth
171
+ - [ ] A generation step is identified (codegen tool, shared type import, inferred type)
172
+ - [ ] No hand-written types that mirror types defined elsewhere
173
+
174
+ ### At implementation time
175
+
176
+ Do not hand-write types that are derivable from a schema, router, or database definition. Import or generate them.
177
+
178
+ **Good:**
179
+ ```typescript
180
+ import type { AppRouter } from '../../server/router'
181
+ // type-safe from the source
182
+
183
+ const { data } = useQuery<InferSelectModel<typeof users>>( ... )
184
+ ```
185
+
186
+ **Bad:**
187
+ ```typescript
188
+ // Hand-written duplicate of what Drizzle already knows
189
+ interface User {
190
+ id: number
191
+ email: string
192
+ createdAt: Date
193
+ }
194
+ ```
195
+
196
+ If a generated type needs extending, use `type MyType = GeneratedType & { extra: string }` — extend the source of truth, don't replace it.
197
+
198
+ ---
199
+
200
+ ## 4. Fail Fast (implementation only)
201
+
202
+ Catch bad data at the door, not three calls deep where the stack trace is useless. Validate inputs at the entry point of every function or system boundary.
203
+
204
+ - At system boundaries (HTTP handlers, CLI args, external API responses, config files): parse with Zod or equivalent before any logic runs
205
+ - At internal function boundaries: assert preconditions at the top of the function — guard clauses, not nested ifs
206
+ - Prefer `throw`/`return early` over propagating bad state deep into call chains
207
+ - Errors should be loud and specific at the point of violation — "expected positive number, got -3" beats a cryptic null reference five layers down
208
+
209
+ **Good:**
210
+ ```typescript
211
+ function processOrder(input: unknown) {
212
+ const order = OrderSchema.parse(input) // throws immediately if invalid
213
+ return computeTotal(order)
214
+ }
215
+
216
+ function applyDiscount(order: Order, pct: number) {
217
+ if (pct < 0 || pct > 1) throw new Error(`Invalid discount: ${pct}`)
218
+ // ... rest of logic
219
+ }
220
+ ```
221
+
222
+ **Bad:**
223
+ ```typescript
224
+ function processOrder(input: any) {
225
+ // passes raw input through, blows up 5 calls deep
226
+ return computeTotal(input)
227
+ }
228
+ ```
229
+
230
+ ---
231
+
232
+ # Part II — Substrate-Execution Principles
233
+
234
+ These principles govern how work moves through the substrate. They shape stage
235
+ transitions, item bodies, foundation-doc evolution, release binding, and agent
236
+ dispatch. The agent applies these whenever operating on `.work/` or `docs/`,
237
+ and whenever choosing discovery or implementation dispatch during substrate
238
+ work.
239
+
240
+ ## 5. Item-IS-the-Work
241
+
242
+ The unit of work is its file. The brief, the design, the implementation notes, and the review findings all accumulate in the item's body as stages advance. Reading the file IS reading the state of the work.
243
+
244
+ ### What this forbids
245
+
246
+ - Parallel design docs that exist alongside item files (no `docs/designs/<name>.md`)
247
+ - Separate progress files (no `PROGRESS.md` tracking what's in flight)
248
+ - Work memory that lives outside the substrate — chat history, user memory, an external board
249
+ - Code comments that duplicate item context (`// see story-foo for background`) — code references logical concepts, not tracking IDs
250
+
251
+ ### What this enables
252
+
253
+ - Cross-session continuity without re-feeding context: a new session reads `.work/active/`, finds the item at `stage: implementing`, reads its body for the design, picks up where the last session left off
254
+ - Single source of truth for "what is the state of this work" — the item file
255
+ - Git as the audit trail — every state change is a commit on the file
256
+ - The agent's amnesia stops being a tax on the user
257
+
258
+ ### At design time
259
+
260
+ - When designing a feature, write the design INTO the feature item's body. Do not create a separate `docs/designs/<name>.md`.
261
+ - When designing child stories under a feature, write each story's body inline as you spawn it. Each story file is self-contained.
262
+ - When implementation surfaces a discovery (a constraint, a discovered library, a forced pivot), edit the item's body to record it alongside the design.
263
+
264
+ ### At implementation time
265
+
266
+ - Read the item file at start. The design is in there.
267
+ - Update the item's body as you work — discoveries, deviations from the design, integration notes
268
+ - After completing, the item's body is a complete record: brief → design → implementation notes → completion. A future agent reading it has the full story.
269
+ - Don't write `// see story-foo for context` in code. The story's context lives in the story's file.
270
+
271
+ ### Design checklist
272
+
273
+ - [ ] No parallel design doc; design lives in feature/epic body
274
+ - [ ] No progress file; the substrate IS the progress
275
+ - [ ] Item body at completion is a complete record
276
+ - [ ] Code does not reference item IDs; only logical concepts
277
+
278
+ ---
279
+
280
+ ## 6. Rolling-Foundation
281
+
282
+ Foundation docs (`docs/VISION.md`, `docs/SPEC.md`, `docs/ARCHITECTURE.md`, and any others) describe the project's vision (future-looking) and current intent — what is true now, OR what will be true once in-flight design lands. They roll forward in place as either evolves. No legacy comments. Git carries history; the doc carries truth.
283
+
284
+ ### Two timing styles
285
+
286
+ Both are legitimate; the project picks one or mixes per change size:
287
+
288
+ - **Code-first (default for routine features):** docs update at implementation merge, in the same commit set as the code that lands the change.
289
+ - **Design-first (for large scope, initial ideation, architectural shifts):** docs preflight-update at scope time, leading the code through the implementation window. The doc temporarily describes an intended near-future state. The agile-workflow `scope` skill operates this way for large scope; `ideate` operates this way at project bootstrap.
290
+
291
+ The discipline is identical in both styles: replace stale assertions in place, never accumulate "previously" / "in v1.x" / migration prose. `gate-docs` at release-deploy time is the backstop — it catches drift between intent and reality regardless of which timing style was used.
292
+
293
+ ### What this forbids
294
+
295
+ - "Note: in v1.2 this was X" footnotes
296
+ - "Previously" / "originally" / "we used to" prose
297
+ - A "Migration notes" section retaining old behavior descriptions
298
+ - Compatibility shims documented in foundation docs (those go in code comments only)
299
+ - Changelog-style entries inside foundation docs
300
+
301
+ ### What this enables
302
+
303
+ - A new contributor reads the doc and learns the system as it IS or as it is meant to imminently become — not as it was
304
+ - Foundation docs stay short and current rather than growing with every change
305
+ - `git log docs/<file>.md` shows every rolling-forward edit — perfect audit trail
306
+ - Discrepancies between intent (what the doc asserts) and reality (what code does) become bugs that gate-docs surfaces, not historical artifacts
307
+
308
+ ### At design time
309
+
310
+ - When scoping a feature that changes a foundation-doc assertion, decide the timing: code-first (defer the doc update) or design-first (preflight the update as part of scope)
311
+ - For large-scope `scope` operations, design-first is the default — `scope` rolls foundation docs forward as part of the same operation
312
+ - Identify which foundation doc(s) need rolling forward; reading them at design time prevents stale assumptions
313
+ - If a feature's design contradicts a foundation doc, EITHER the design is wrong OR the doc is. Resolve before designing the implementation.
314
+
315
+ ### At implementation time
316
+
317
+ - If working code-first: after implementing a change, ask "what does a foundation doc now say that's no longer true?" — update assertions in place, commit with the implementation
318
+ - If working design-first: the doc was preflight-updated at scope time. Verify the implementation matches the doc's assertion; if it deviates, adjust whichever was wrong (implementation or assertion).
319
+ - Replace stale assertions in place. Delete the old text. Never append.
320
+ - The `gate-docs` skill runs at release-deploy time and produces items for any remaining drift — but the goal is to leave it nothing to find.
321
+
322
+ ### Design checklist
323
+
324
+ - [ ] Every assertion in SPEC and ARCHITECTURE reflects current code OR imminent in-flight design (no stale assertions from cancelled work)
325
+ - [ ] VISION.md reflects the project's current direction, not past direction
326
+ - [ ] No "previously" / "originally" / "in v1.x" prose anywhere in `docs/`
327
+ - [ ] When a feature changes behavior or direction, foundation docs update in the same commit set as the change (code-first) or were preflight-updated and are still accurate (design-first)
328
+ - [ ] `git log docs/<file>.md` shows the audit trail; the doc shows the present
329
+
330
+ ---
331
+
332
+ ## 7. Late-Binding
333
+
334
+ Items advance stages when work actually completes. Releases bind items only when the user cuts a version. Foundation docs are not pre-decided into a phase plan. Work happens, then commitments crystallize — not the other way around.
335
+
336
+ ### What this forbids
337
+
338
+ - Pre-populated `stage:` values that don't reflect actual progress
339
+ - Pre-set `release_binding:` on items the user hasn't yet decided to ship
340
+ - A `ROADMAP.md` that pre-commits features to releases
341
+ - A "Sprint 3 backlog" promising specific items by a date
342
+ - Phase numbering that assigns items to a temporal slot upfront
343
+
344
+ ### What this enables
345
+
346
+ - Items advance based on real completion, not a stale plan
347
+ - Releases capture what's ACTUALLY ready, not what was supposed to be ready
348
+ - Backlog items don't accumulate stale tags or premature decisions
349
+ - Pivots are cheap — change of plan doesn't require unwinding pre-bound items
350
+
351
+ ### At design time
352
+
353
+ - When epicizing, declare epic dependencies via `depends_on`, NOT release bundling
354
+ - When scoping a feature, leave `release_binding: null` until a release is cut
355
+ - When designing child stories, declare sequencing via `depends_on`, NOT by pre-committing them to a release
356
+
357
+ ### At implementation time
358
+
359
+ - Advance `stage:` only when the work for that stage actually completes
360
+ - Don't bind items to a release until the user invokes `/release-deploy`
361
+ - When work shifts (a feature gets postponed, a story gets cut), simply leave the item where it is — its current state is its truth
362
+
363
+ ### Design checklist
364
+
365
+ - [ ] No pre-populated `stage` values
366
+ - [ ] No `release_binding` set without an active release-deploy
367
+ - [ ] Dependencies expressed via `depends_on`, not by ordering in any external plan
368
+ - [ ] No ROADMAP.md or equivalent that pre-commits work to releases
369
+
370
+ ---
371
+
372
+ ## 8. Agent Dispatch Economy
373
+
374
+ Sub-agents are for breadth, isolation, independent judgment, or parallel
375
+ implementation with clear write ownership. They are not a replacement for
376
+ reading, and they are not automatically better than local read-oriented tools.
377
+
378
+ Agile-workflow does not ship custom subagent definitions. When delegation is
379
+ useful, prompt the host's existing generic/general-purpose subagent mechanism
380
+ with a structured, task-specific brief. A same-harness subagent is
381
+ fresh-context by default; call it cross-model only when the harness explicitly
382
+ spawns it with a different model class (for example, Pi selecting another
383
+ provider/model for the subagent). Keep `peeragent` for cross-model or
384
+ cross-harness advisory/review paths when the harness cannot provide the needed
385
+ different model class itself, and fall back to direct single-agent execution
386
+ when no suitable subagent adapter is available. For the prompt skeleton and
387
+ posture capsules, load [references/subagents.md](references/subagents.md).
388
+
389
+ Before spawning read-only exploratory/discovery sub-agents, do a local scope-size probe:
390
+
391
+ - List likely roots with `rg --files`, Glob, manifests, route maps, package
392
+ metadata, or `.work/bin/work-view`.
393
+ - Search obvious symbols, ids, and terms with `rg`/Grep.
394
+ - Read the item body, relevant foundation docs, `AGENTS.md` / `CLAUDE.md`, and
395
+ 2-5 representative source or test files.
396
+ - Name the unknowns that remain. If you cannot name a distinct unknown, do not
397
+ spawn an agent just to feel thorough.
398
+
399
+ For implementation waves, the same sizing note feeds write-ownership and
400
+ dependency-layer decisions before choosing fan-out width.
401
+
402
+ Choose the lightest mechanism that will produce better evidence:
403
+
404
+ | Scope signal | Dispatch choice |
405
+ |---|---|
406
+ | Known file(s), one module, or a handful of obvious integration points | Read directly with Read/Grep/Glob; skip exploratory fanout. |
407
+ | One bounded area but uncertain patterns or call sites | Use one focused exploratory sub-agent, then spot-check key files yourself. |
408
+ | Several independent surfaces with different questions | Use parallel exploratory sub-agents, one per surface/question. |
409
+ | Implementation work with independent write ownership | Fan out by ownership and dependency layer; do not use item count alone as the parallelism signal. |
410
+ | Deep audit/review where fresh context is the point | Spawn a generic sub-agent with the skill's reviewer/scanner prompt posture and explicit output schema; if unavailable, use the skill's inline fallback. |
411
+
412
+ Parallel Explore only pays for itself when the prompts are genuinely different.
413
+ Three agents asking the same broad question usually return duplicated shallow
414
+ maps. Prefer one precise prompt or direct reading.
415
+
416
+ Record the dispatch rationale in run notes or the item body when it affects
417
+ scope, bundling, or wave width: "direct-read only", "one Explore for breadth",
418
+ or "parallel Explore across X/Y/Z surfaces". This makes the orchestration call
419
+ auditable later.
420
+
421
+ ---
422
+
423
+ # Part III — Caller Awareness
424
+
425
+ **The rule:** If an active agile-workflow autopilot run or harness goal is
426
+ driving this skill, no structured question tool and no halts on ordinary ambiguity.
427
+ Resolve with judgment and log the rationale in the item body. Otherwise,
428
+ asking the user is fine and often helpful.
429
+
430
+ This is binary and detectable. Autopilot mode is on when the current skill was
431
+ delegated by an explicit autopilot invocation, an active autopilot harness goal,
432
+ or a prompt that clearly says it is continuing/draining an autopilot scope.
433
+ Autopilot includes a caller note when delegating work; treat that note as the
434
+ strongest signal. If no active autopilot driver exists, you are interactive.
435
+
436
+ ## What does NOT count as autopilot
437
+
438
+ Judgment-mode is triggered only by an active autopilot driver. In particular:
439
+
440
+ - **General harness "auto mode"** — a reminder to work without unnecessary
441
+ clarification does **not** suppress `structured question tool` inside these skills.
442
+ It shapes default conversational tone; it does not mean an autopilot queue
443
+ goal is active.
444
+ - **A user saying "just decide" earlier in the conversation** — that applies
445
+ to whatever was being discussed at the time, not to a later explicit skill
446
+ invocation.
447
+ - **A previous autopilot run that has already ended** — autopilot mode lasts
448
+ only while autopilot itself is the active driver of the queue. Once the goal
449
+ completes, blocks, or is interrupted, subsequent direct skill invocations are
450
+ interactive again.
451
+
452
+ When a user types `/agile-workflow:feature-design <id>` (or any other
453
+ design/implement/review skill) directly, they want a collaborator at the
454
+ checkpoints. Use `structured question tool` unless the direct prompt also makes clear it
455
+ is part of an active autopilot goal.
456
+
457
+ The disambiguation test: *"Is an active autopilot queue goal currently driving
458
+ this skill?"* If you cannot point to that active driver or caller note, you are
459
+ interactive.
460
+
461
+ ## What still warrants a hard halt (autopilot or not)
462
+
463
+ - Substrate not bootstrapped (no `.work/CONVENTIONS.md`)
464
+ - Foundation docs missing for a foundation-required workflow
465
+ - `depends_on` cycle detected when writing items
466
+ - Genuinely contradictory state the skill cannot recover from
467
+
468
+ Everything else should resolve via judgment under autopilot. When in doubt,
469
+ prefer the simpler option and log the rationale in the item body so the user
470
+ can review later.
471
+
472
+ ## Worked examples (autopilot mode)
473
+
474
+ | Situation | Judgment-mode action |
475
+ |---|---|
476
+ | Two architectural options both look valid | Pick the one with fewer moving parts; log "Chose X over Y because: simpler surface" |
477
+ | Brief is vague, several plausible interpretations | Pick the one most consistent with foundation docs; log under `## Design decisions` |
478
+ | Multiple candidate items at a stage and no id was passed | Pick most recent by `updated:`; the next iteration picks the next |
479
+ | Wrong-tag invocation routed to you by mistake | Log a misroute note in the body; return without advancing |
480
+ | Empty diff during review after trying ranges | Advance to `done` with a "No diff found" note; don't block the queue |
481
+ | Item at unexpected stage | Use judgment about what transition makes sense; log it |
482
+
483
+ ## How to phrase decision points
484
+
485
+ > If an active autopilot run or goal is driving this skill, <judgment-mode
486
+ > behavior>. Otherwise, ask the user via structured question tool.
487
+
488
+ Not "halt and tell the user." The first form supports both modes; the second
489
+ silently kills autopilot.
490
+
491
+ ## Skills this applies to
492
+
493
+ Autopilot delegates to: `feature-design`, `epic-design`, `refactor-design`,
494
+ `perf-design`, `implement`, `implement-orchestrator`, `review` — plus, for
495
+ `[research]`-tagged items, the cross-plugin
496
+ `agentic-research:research-orchestrator` (inert without that plugin; the item
497
+ then routes as a plain feature). Every one of those needs caller-aware
498
+ decision points.
499
+
500
+ User-invocable-only skills (`convert`, `epicize`, `ideate`, `bold-refactor`,
501
+ `release-deploy`) can stay interactive-first — autopilot doesn't call them.
502
+
503
+ ---
504
+
505
+ # Part IV — Cross-Model Advisory Review
506
+
507
+ Cross-model review is an advisory signal, not a stage transition. The policy
508
+ below is written in **role and capability** terms so it holds as model
509
+ generations change. For the concrete model-to-capability mapping, the
510
+ host→peer pairing table, and the exact `peeragent` flags, load
511
+ [references/models.md](references/models.md) — that is the single source of
512
+ truth for which models fill each role.
513
+
514
+ Cross-model review is used only when a **different model class** is available
515
+ through an installed peer mechanism such as `peeragent:peer` /
516
+ `peeragent:peer-review`, or through a host sub-agent spawn where the caller can
517
+ select a different model/provider for the reviewer. The value of a peer is
518
+ **independent blind spots**, not a more authoritative answer, so the reviewer
519
+ must be a different class than the host before you label the pass cross-model. If
520
+ `peeragent` would use the same model class, do not use `peer` or `peer-review`;
521
+ instead spawn a **fresh generic sub-agent at the strongest appropriate model
522
+ available to the host**, prompted with the reviewer posture from
523
+ [references/subagents.md](references/subagents.md) — never review inline in the
524
+ host's own context, which is anchored on the work it just produced. Label the
525
+ pass cross-model only when the caller intentionally selected a different model
526
+ class for that subagent; if the spawned reviewer's model class is uncertain,
527
+ label it fresh-context, not cross-model.
528
+
529
+ Explicit user instructions and project-level `AGENTS.md` / `CLAUDE.md` review
530
+ rules override this policy. If they require review, follow them. If they opt out
531
+ or restrict external model egress, do not invoke peeragent.
532
+
533
+ Latency expectation: a top-tier reasoning peer (Opus-class, xhigh Codex/GLM,
534
+ or equivalent) commonly takes 10 to 30 minutes for large reviews and may be
535
+ quiet for most of it. A long quiet period or lack of intermediate output is
536
+ normal. Do not treat "it has not returned in a few minutes" as a hang, and do
537
+ not fall back, mark the peer attempt failed, or block the run unless the process
538
+ exits with an error, reports failure, or exceeds a timeout sized for top-tier
539
+ review work.
540
+
541
+ Default judgment (by scope — see [references/models.md](references/models.md)
542
+ for the model classes that fill each role):
543
+
544
+ - Small, low-risk work: skip cross-model review.
545
+ - Small/medium work with real uncertainty: optionally use one focused `peer`
546
+ pass.
547
+ - Large, risky, or architectural design points under autopilot: use one focused
548
+ `peer` pass when no prior `--only-questions` / `## Design decisions`
549
+ alignment exists.
550
+ - **Deep or complex work** (architectural design, large/risky features or
551
+ epics, the final autopilot completion review, whole-repo scans): **if two
552
+ different model classes are available, use both**, paired across the two
553
+ review phases below. Two distinct training lineages catch more than one, and
554
+ their disagreements are themselves signal.
555
+ - Reviewing a completed **feature or epic** at `stage: review` (the `review`
556
+ skill's deep lane): run the lens review in a fresh context — a different-class
557
+ `peer-review` when reachable; otherwise a generic sub-agent prompted with the
558
+ reviewer posture from [references/subagents.md](references/subagents.md),
559
+ cross-model only when the host can spawn it with a different model class;
560
+ otherwise the strongest same-harness fresh-context reviewer available.
561
+ **Stories skip this** entirely; they fast-advance on `implement`'s
562
+ verification.
563
+ - End of an autopilot run, after the scoped queue appears drained and before
564
+ reporting `complete`: run a final `peer-review` loop when a different model
565
+ class is available; otherwise use the freshest reviewer role available,
566
+ labeling it cross-model only if spawned with a different model class. Fix or
567
+ file accepted findings before completion.
568
+ - Completed substantial artifacts, or explicit user requests for review: use
569
+ `peer-review` only when the full iterative loop is appropriate.
570
+
571
+ Designs and reviews are both evaluated in a fixed **two-phase order**
572
+ (full mechanics in [references/models.md](references/models.md) §6):
573
+
574
+ 1. **Phase 1 — Completeness / Complementary / Advisory.** Augmentation, not
575
+ judgment. Ask a different-class peer what is missing, what alternatives
576
+ strengthen it, and what questions/risks should be weighed. The loop shape
577
+ depends on the artifact: **designs (open)** get a **single pass** before
578
+ decisions lock; **reviews (complete artifact)** get a **multi-step
579
+ convergence loop to nits** — the ideal is the full `peer-review` loop
580
+ (≥3 passes, stop on nits, cap ~5) when `peer-review` is available.
581
+ 2. **Phase 2 — Adversarial.** Attack posture. Ask a **different** peer
582
+ (ideally a different class than Phase 1, per the 2-class rule) what is
583
+ broken, contradictory, built on a false assumption, or will fail in
584
+ operation. For reviews this is the same convergence loop in the attack
585
+ posture; for designs it is a focused adversarial pass. Verify concrete
586
+ claims before accepting.
587
+
588
+ Never reverse the phases and never skip Phase 1 to jump straight to attack. For
589
+ autopilot-driven design work, the default peer ask is **augmentation before
590
+ decisions are locked**, not validation after the host has already decided.
591
+
592
+ Design-time advisory peer failures are non-blocking under autopilot. If the
593
+ peer wrapper is missing, the executable cannot be resolved, the invocation
594
+ fails, or the call would use the same model class, continue with host judgment
595
+ and log the reason briefly. A top-tier reasoning peer still running after only
596
+ a few minutes is not a failure. Do not halt the queue for an advisory review
597
+ failure.
598
+
599
+ The final autopilot completion review is stricter: it must succeed through a
600
+ different-model `peer-review` loop, a generic sub-agent prompted as a
601
+ fresh-context reviewer (cross-model when the caller selects a different model
602
+ class, otherwise same-harness), or another supported fresh-context fallback
603
+ before the run reports `complete`. For deep/complex scope that means clearing
604
+ through at least one cross-class pass per phase in §6 where two classes are
605
+ available; if the selected final-review path fails, the run is blocked on final
606
+ review rather than complete.
607
+
608
+ When invoked, summarize the result in the item body without dumping transcripts:
609
+
610
+ ```markdown
611
+ ## Other agent review
612
+ - Invoked because: <large/risky/deep-complex/autopilot/no prior alignment>
613
+ - Scope: <single peer | two-class — list classes>
614
+ - Reviewer (Phase 1 — advisory/completeness): <class, if known>
615
+ - Gaps / missing requirements / alternatives considered:
616
+ - <summary>
617
+ - Reviewer (Phase 2 — adversarial): <class, if known; different from Phase 1>
618
+ - Broken assumptions / failure modes / rejected points:
619
+ - <summary>
620
+ - Accepted:
621
+ - <decision or adjustment> (phase N)
622
+ - Rejected:
623
+ - <point> — <reason> (phase N)
624
+ ```
625
+
626
+ If only one peer class was available (or only one phase was warranted by scope),
627
+ fill only the phase that ran and note the other was skipped and why.
628
+
629
+ Limit autopilot to one advisory pass per item per design stage. Do not run a
630
+ multi-pass `peer-review` loop inside routine autopilot design unless the user or
631
+ project instructions explicitly require it. The final completion review at the
632
+ end of autopilot is separate from these design-time advisory passes.
633
+
634
+ ---
635
+
636
+ # Part V — Skill invocation patterns
637
+
638
+ Three arg shapes recur across the plugin. New skills should pick the one that
639
+ fits their role rather than inventing a fresh shape.
640
+
641
+ ## Orchestration verbs (drain a queue)
642
+
643
+ `scope`, `implement-orchestrator`, `autopilot`, `review`
644
+
645
+ | Arg | Behavior |
646
+ |---|---|
647
+ | `<id>` or `<id-list>` | Operate on those items |
648
+ | `--all` or no arg | Operate on the full queue (default) |
649
+ | `<NL filter>` | Interpret free text against the queue; log the interpretation |
650
+
651
+ ## Discovery + emit verbs (scan code, produce items)
652
+
653
+ `refactor-design`, `perf-design`, `bold-refactor`, and the gate
654
+ family (`gate-cruft`, `gate-security`, `gate-tests`, `gate-docs`,
655
+ `gate-patterns`)
656
+
657
+ | Arg | Behavior |
658
+ |---|---|
659
+ | no arg / `--all` | Sweep the relevant scope (whole codebase, or release bundle for gates) |
660
+ | `<path>` | Scope to that subtree |
661
+ | `<NL scope>` | Interpret free text against the codebase; log the interpretation |
662
+ | `<feature-id>` (where applicable) | Per-feature design mode (refactor-design, perf-design) |
663
+
664
+ These skills *emit substrate items as findings* rather than gating pass/fail.
665
+
666
+ ## Per-item design verbs
667
+
668
+ `feature-design`, `epic-design`, `refactor-design`, `perf-design`
669
+
670
+ | Arg | Behavior |
671
+ |---|---|
672
+ | `<id>` | Full design pass on that item (default) |
673
+ | `--only-questions <id>` | Question-only alignment pass; captures answers under `## Design decisions`; does NOT design or advance stage |
674
+ | `--only-questions <id-list>` | Question-only pass over each listed item |
675
+ | `--only-questions --all` | Question-only pass over every drafting item of the matching kind/tags |
676
+
677
+ `--only-questions` always requires interactive mode and refuses to run under
678
+ autopilot.