@eddacraft/anvil-aps 0.1.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/AGENTS.md +155 -0
- package/LICENSE +14 -0
- package/README.md +57 -0
- package/TODO.md +40 -0
- package/dist/filter/context-bundle.d.ts +81 -0
- package/dist/filter/context-bundle.d.ts.map +1 -0
- package/dist/filter/context-bundle.js +230 -0
- package/dist/filter/index.d.ts +85 -0
- package/dist/filter/index.d.ts.map +1 -0
- package/dist/filter/index.js +169 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/loader/index.d.ts +80 -0
- package/dist/loader/index.d.ts.map +1 -0
- package/dist/loader/index.js +253 -0
- package/dist/parser/index.d.ts +24 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +22 -0
- package/dist/parser/parse-document.d.ts +17 -0
- package/dist/parser/parse-document.d.ts.map +1 -0
- package/dist/parser/parse-document.js +219 -0
- package/dist/parser/parse-index.d.ts +31 -0
- package/dist/parser/parse-index.d.ts.map +1 -0
- package/dist/parser/parse-index.js +251 -0
- package/dist/parser/parse-task.d.ts +30 -0
- package/dist/parser/parse-task.d.ts.map +1 -0
- package/dist/parser/parse-task.js +261 -0
- package/dist/state/index.d.ts +307 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +689 -0
- package/dist/templates/generator.d.ts +71 -0
- package/dist/templates/generator.d.ts.map +1 -0
- package/dist/templates/generator.js +723 -0
- package/dist/templates/index.d.ts +5 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +4 -0
- package/dist/types/index.d.ts +131 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +107 -0
- package/dist/validator/index.d.ts +83 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +611 -0
- package/docs/APS-Anvil-Integration.md +750 -0
- package/docs/APS-Conventions.md +635 -0
- package/docs/APS-NonGoals.md +455 -0
- package/docs/APS-Planning-Spec-v0.1.md +362 -0
- package/examples/README.md +170 -0
- package/examples/feature-auth.aps.md +87 -0
- package/examples/refactor-error-handling.aps.md +119 -0
- package/examples/system-ecommerce/APS.md +57 -0
- package/examples/system-ecommerce/modules/auth.aps.md +38 -0
- package/examples/system-ecommerce/modules/cart.aps.md +53 -0
- package/examples/system-ecommerce/modules/payments.aps.md +68 -0
- package/examples/system-ecommerce/modules/products.aps.md +53 -0
- package/package.json +34 -0
- package/project.json +37 -0
- package/scripts/generate-templates.js +33 -0
- package/src/filter/context-bundle.ts +312 -0
- package/src/filter/filter.test.ts +317 -0
- package/src/filter/index.ts +249 -0
- package/src/index.ts +16 -0
- package/src/loader/index.ts +364 -0
- package/src/loader/loader.test.ts +224 -0
- package/src/parser/__fixtures__/invalid-task-id-not-padded.aps.md +7 -0
- package/src/parser/__fixtures__/invalid-task-id.aps.md +8 -0
- package/src/parser/__fixtures__/minimal-task.aps.md +7 -0
- package/src/parser/__fixtures__/non-scope-hyphenated.aps.md +10 -0
- package/src/parser/__fixtures__/simple-index.aps.md +35 -0
- package/src/parser/__fixtures__/simple-plan.aps.md +19 -0
- package/src/parser/index.ts +30 -0
- package/src/parser/parse-document.test.ts +603 -0
- package/src/parser/parse-document.ts +262 -0
- package/src/parser/parse-index.test.ts +316 -0
- package/src/parser/parse-index.ts +298 -0
- package/src/parser/parse-task.test.ts +476 -0
- package/src/parser/parse-task.ts +325 -0
- package/src/state/__fixtures__/invalid-plan.aps.md +9 -0
- package/src/state/__fixtures__/test-plan.aps.md +20 -0
- package/src/state/index.ts +879 -0
- package/src/state/state.test.ts +645 -0
- package/src/templates/generator.test.ts +378 -0
- package/src/templates/generator.ts +776 -0
- package/src/templates/index.ts +5 -0
- package/src/types/index.ts +168 -0
- package/src/validator/__fixtures__/broken-links.aps.md +10 -0
- package/src/validator/__fixtures__/circular-deps-index.aps.md +26 -0
- package/src/validator/__fixtures__/circular-modules/module-a.aps.md +9 -0
- package/src/validator/__fixtures__/circular-modules/module-b.aps.md +9 -0
- package/src/validator/__fixtures__/circular-modules/module-c.aps.md +9 -0
- package/src/validator/__fixtures__/dup-modules/module-a.aps.md +9 -0
- package/src/validator/__fixtures__/dup-modules/module-b.aps.md +9 -0
- package/src/validator/__fixtures__/duplicate-ids-index.aps.md +15 -0
- package/src/validator/__fixtures__/invalid-task-id.aps.md +17 -0
- package/src/validator/__fixtures__/missing-confidence.aps.md +9 -0
- package/src/validator/__fixtures__/missing-h1.aps.md +5 -0
- package/src/validator/__fixtures__/missing-intent.aps.md +9 -0
- package/src/validator/__fixtures__/missing-modules-section.aps.md +7 -0
- package/src/validator/__fixtures__/missing-tasks-section.aps.md +7 -0
- package/src/validator/__fixtures__/modules/auth.aps.md +17 -0
- package/src/validator/__fixtures__/modules/payments.aps.md +13 -0
- package/src/validator/__fixtures__/scope-mismatch.aps.md +14 -0
- package/src/validator/__fixtures__/valid-index.aps.md +24 -0
- package/src/validator/__fixtures__/valid-leaf.aps.md +22 -0
- package/src/validator/index.ts +776 -0
- package/src/validator/validator.test.ts +269 -0
- package/templates/index-full.md +94 -0
- package/templates/index-minimal.md +16 -0
- package/templates/index-template.md +63 -0
- package/templates/leaf-full.md +76 -0
- package/templates/leaf-minimal.md +14 -0
- package/templates/leaf-template.md +55 -0
- package/templates/simple-full.md +56 -0
- package/templates/simple-minimal.md +14 -0
- package/templates/simple-template.md +30 -0
- package/tsconfig.json +19 -0
- package/tsconfig.lib.json +14 -0
- package/tsconfig.lib.tsbuildinfo +1 -0
- package/tsconfig.spec.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
# APS-Anvil Integration
|
|
2
|
+
|
|
3
|
+
> How Anvil Planning Spec documents become executable plans.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
APS defines **what to do** (planning). Anvil provides **how to execute** it
|
|
8
|
+
(orchestration + LLM agents). This document explains how they integrate.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Architecture
|
|
13
|
+
|
|
14
|
+
### Three Layers
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
┌─────────────────────────────────────────┐
|
|
18
|
+
│ Planning Docs (Source of Truth) │
|
|
19
|
+
│ docs/planning/*.aps.md │
|
|
20
|
+
│ - Defines tasks, intent, dependencies │
|
|
21
|
+
│ - Committed to Git │
|
|
22
|
+
│ - Human-editable Markdown │
|
|
23
|
+
└─────────────────────────────────────────┘
|
|
24
|
+
│
|
|
25
|
+
│ parse + validate
|
|
26
|
+
▼
|
|
27
|
+
┌─────────────────────────────────────────┐
|
|
28
|
+
│ State Management (Derived) │
|
|
29
|
+
│ .anvil/state.json │
|
|
30
|
+
│ - Task status (open/locked/completed) │
|
|
31
|
+
│ - Lock metadata (who, when, hash) │
|
|
32
|
+
│ - Source file pointers │
|
|
33
|
+
└─────────────────────────────────────────┘
|
|
34
|
+
│
|
|
35
|
+
│ lock task
|
|
36
|
+
▼
|
|
37
|
+
┌─────────────────────────────────────────┐
|
|
38
|
+
│ Execution Plans (Generated) │
|
|
39
|
+
│ .anvil/executions/<task-id>.json │
|
|
40
|
+
│ - Snapshot of task definition │
|
|
41
|
+
│ - Scoped context bundle │
|
|
42
|
+
│ - Provenance (hash, commit, timestamp) │
|
|
43
|
+
└─────────────────────────────────────────┘
|
|
44
|
+
│
|
|
45
|
+
│ execute
|
|
46
|
+
▼
|
|
47
|
+
┌─────────────────────────────────────────┐
|
|
48
|
+
│ Anvil Execution Engine │
|
|
49
|
+
│ - LLM agents │
|
|
50
|
+
│ - Gate checks │
|
|
51
|
+
│ - Change validation │
|
|
52
|
+
└─────────────────────────────────────────┘
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Workflow: Planning to Execution
|
|
58
|
+
|
|
59
|
+
### Step 1: Write Planning Doc
|
|
60
|
+
|
|
61
|
+
Create or update a planning document:
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
# Feature: User Authentication
|
|
65
|
+
|
|
66
|
+
**Scope:** AUTH **Owner:** @alice
|
|
67
|
+
|
|
68
|
+
## Tasks
|
|
69
|
+
|
|
70
|
+
### AUTH-001: Implement login endpoint
|
|
71
|
+
|
|
72
|
+
**Intent:** Create POST /auth/login that validates credentials and returns JWT
|
|
73
|
+
**Confidence:** high **Scopes:** AUTH **Tags:** security, api
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Commit to Git:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
git add docs/planning/auth.aps.md
|
|
80
|
+
git commit -m "Add auth planning doc"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Step 2: Validate Planning Doc
|
|
86
|
+
|
|
87
|
+
Before locking tasks, validate the planning doc:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
anvil plan validate docs/planning/auth.aps.md
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Output:**
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
✓ Structure valid
|
|
97
|
+
✓ All required sections present
|
|
98
|
+
✓ No duplicate task IDs
|
|
99
|
+
✓ All links resolve
|
|
100
|
+
⚠ AUTH-002 missing Confidence field
|
|
101
|
+
|
|
102
|
+
Validation passed with 1 warning
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Validation checks:
|
|
106
|
+
|
|
107
|
+
- Required sections (`## Tasks`)
|
|
108
|
+
- Task has Intent
|
|
109
|
+
- Task ID format (`AUTH-001`)
|
|
110
|
+
- No duplicates
|
|
111
|
+
- Links resolve
|
|
112
|
+
- No circular dependencies
|
|
113
|
+
|
|
114
|
+
**Errors block execution. Warnings are non-blocking.**
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### Step 3: Lock Task for Execution
|
|
119
|
+
|
|
120
|
+
When ready to work on a task:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
anvil plan lock --task AUTH-001
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**What happens:**
|
|
127
|
+
|
|
128
|
+
1. **Validate first** — Re-runs validation, fails if errors exist
|
|
129
|
+
2. **Check state** — Verify task is not already locked
|
|
130
|
+
3. **Snapshot task** — Extract full task definition from planning doc
|
|
131
|
+
4. **Resolve context** — Gather related tasks, dependencies, scoped files
|
|
132
|
+
5. **Generate execution plan** — Write to `.anvil/executions/AUTH-001.json`
|
|
133
|
+
6. **Update state** — Mark as `locked` in `.anvil/state.json`
|
|
134
|
+
7. **Compute provenance** — Hash, commit SHA, timestamp, user
|
|
135
|
+
|
|
136
|
+
**State update (`.anvil/state.json`):**
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"AUTH-001": {
|
|
141
|
+
"status": "locked",
|
|
142
|
+
"locked_at": "2025-12-17T10:30:00Z",
|
|
143
|
+
"locked_by": "alice",
|
|
144
|
+
"execution_file": ".anvil/executions/AUTH-001.json",
|
|
145
|
+
"source": {
|
|
146
|
+
"file": "docs/planning/auth.aps.md",
|
|
147
|
+
"line": 23,
|
|
148
|
+
"commit": "abc123def"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Execution plan (`.anvil/executions/AUTH-001.json`):**
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"task_id": "AUTH-001",
|
|
159
|
+
"intent": "Create POST /auth/login that validates credentials and returns JWT",
|
|
160
|
+
"confidence": "high",
|
|
161
|
+
"scopes": ["AUTH"],
|
|
162
|
+
"tags": ["security", "api"],
|
|
163
|
+
"dependencies": [],
|
|
164
|
+
"context": {
|
|
165
|
+
"related_tasks": ["AUTH-002", "AUTH-003"],
|
|
166
|
+
"scoped_files": ["src/auth/**"],
|
|
167
|
+
"planning_doc": "docs/planning/auth.aps.md"
|
|
168
|
+
},
|
|
169
|
+
"provenance": {
|
|
170
|
+
"snapshot_hash": "sha256:...",
|
|
171
|
+
"commit": "abc123def",
|
|
172
|
+
"locked_at": "2025-12-17T10:30:00Z",
|
|
173
|
+
"locked_by": "alice"
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### Step 4: Execute Task
|
|
181
|
+
|
|
182
|
+
Execution happens via Anvil agents (manually or automated):
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
anvil execute .anvil/executions/AUTH-001.json
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**What the agent sees:**
|
|
189
|
+
|
|
190
|
+
- Task intent
|
|
191
|
+
- Scoped files (only `AUTH` scope visible)
|
|
192
|
+
- Related tasks
|
|
193
|
+
- Dependencies
|
|
194
|
+
- Current codebase state
|
|
195
|
+
|
|
196
|
+
**What the agent does:**
|
|
197
|
+
|
|
198
|
+
1. Reads the execution plan
|
|
199
|
+
2. Generates changes (code, tests, docs)
|
|
200
|
+
3. Runs gate checks (tests, linting, type checking)
|
|
201
|
+
4. Validates changes match scopes
|
|
202
|
+
5. Creates a change set
|
|
203
|
+
|
|
204
|
+
**Gate checks:**
|
|
205
|
+
|
|
206
|
+
- Do changes stay within declared scopes?
|
|
207
|
+
- Do tests pass?
|
|
208
|
+
- Does type checking pass?
|
|
209
|
+
- Is the intent satisfied?
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### Step 5: Complete or Unlock Task
|
|
214
|
+
|
|
215
|
+
**On success:**
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
anvil plan complete --task AUTH-001
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Updates state to `completed`:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"AUTH-001": {
|
|
226
|
+
"status": "completed",
|
|
227
|
+
"completed_at": "2025-12-17T11:45:00Z",
|
|
228
|
+
"execution_file": ".anvil/executions/AUTH-001.json"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**On failure or abandonment:**
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
anvil plan unlock --task AUTH-001
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Updates state to `cancelled` and removes execution file.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### Step 6: View Status
|
|
244
|
+
|
|
245
|
+
Check status of all tasks:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
anvil plan status
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**Output:**
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
AUTH-001: ✓ completed
|
|
255
|
+
AUTH-002: ⏸ open
|
|
256
|
+
AUTH-003: 🔒 locked (by bob, 2h ago)
|
|
257
|
+
AUTH-004: ❌ cancelled
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Directory Structure
|
|
263
|
+
|
|
264
|
+
### Before Execution
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
repo/
|
|
268
|
+
docs/
|
|
269
|
+
planning/
|
|
270
|
+
auth.aps.md # Planning doc (source)
|
|
271
|
+
src/
|
|
272
|
+
auth/
|
|
273
|
+
...
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### During Execution
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
repo/
|
|
280
|
+
.anvil/
|
|
281
|
+
state.json # Task states
|
|
282
|
+
executions/
|
|
283
|
+
AUTH-001.json # Execution plan for locked task
|
|
284
|
+
docs/
|
|
285
|
+
planning/
|
|
286
|
+
auth.aps.md # Planning doc (unchanged)
|
|
287
|
+
src/
|
|
288
|
+
auth/
|
|
289
|
+
...
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### After Completion
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
repo/
|
|
296
|
+
.anvil/
|
|
297
|
+
state.json # Updated with 'completed' status
|
|
298
|
+
executions/ # Empty (or archived)
|
|
299
|
+
docs/
|
|
300
|
+
planning/
|
|
301
|
+
auth.aps.md # Planning doc (unchanged)
|
|
302
|
+
src/
|
|
303
|
+
auth/
|
|
304
|
+
login.ts # New code from execution
|
|
305
|
+
login.test.ts # New tests
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## State Management
|
|
311
|
+
|
|
312
|
+
### State File Location
|
|
313
|
+
|
|
314
|
+
`.anvil/state.json` — Single source of truth for task execution state.
|
|
315
|
+
|
|
316
|
+
### State Schema
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
type TaskState = {
|
|
320
|
+
status: 'open' | 'locked' | 'completed' | 'cancelled';
|
|
321
|
+
locked_at?: string; // ISO 8601 timestamp
|
|
322
|
+
locked_by?: string; // Username
|
|
323
|
+
completed_at?: string;
|
|
324
|
+
cancelled_at?: string;
|
|
325
|
+
execution_file?: string; // Path to execution plan
|
|
326
|
+
source: {
|
|
327
|
+
file: string; // Planning doc path
|
|
328
|
+
line: number; // Line number of task heading
|
|
329
|
+
commit?: string; // Git commit SHA
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
type State = {
|
|
334
|
+
[taskId: string]: TaskState;
|
|
335
|
+
};
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Concurrency Model: First Lock Wins
|
|
339
|
+
|
|
340
|
+
When multiple agents/users try to lock the same task:
|
|
341
|
+
|
|
342
|
+
1. Agent A runs `anvil plan lock --task AUTH-001`
|
|
343
|
+
2. Agent B runs `anvil plan lock --task AUTH-001` (simultaneously)
|
|
344
|
+
3. **First write to `.anvil/state.json` wins**
|
|
345
|
+
4. Second attempt fails with:
|
|
346
|
+
`Error: Task AUTH-001 is already locked by agent-a`
|
|
347
|
+
|
|
348
|
+
**No distributed locking needed** — Git + filesystem atomicity handles this.
|
|
349
|
+
|
|
350
|
+
### State Transitions
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
open ──lock──> locked ──complete──> completed
|
|
354
|
+
│
|
|
355
|
+
└──unlock──> cancelled
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Valid transitions:**
|
|
359
|
+
|
|
360
|
+
- `open` → `locked`
|
|
361
|
+
- `locked` → `completed`
|
|
362
|
+
- `locked` → `cancelled`
|
|
363
|
+
|
|
364
|
+
**Invalid transitions:**
|
|
365
|
+
|
|
366
|
+
- `completed` → `locked` (cannot re-lock completed tasks)
|
|
367
|
+
- `open` → `completed` (must lock first)
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Execution Plan Structure
|
|
372
|
+
|
|
373
|
+
### File Location
|
|
374
|
+
|
|
375
|
+
`.anvil/executions/<task-id>.json`
|
|
376
|
+
|
|
377
|
+
**Example:** `.anvil/executions/AUTH-001.json`
|
|
378
|
+
|
|
379
|
+
### Schema
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
type ExecutionPlan = {
|
|
383
|
+
task_id: string;
|
|
384
|
+
intent: string;
|
|
385
|
+
confidence?: 'low' | 'medium' | 'high';
|
|
386
|
+
scopes: string[];
|
|
387
|
+
tags: string[];
|
|
388
|
+
dependencies: string[]; // Task IDs
|
|
389
|
+
inputs?: string[];
|
|
390
|
+
expected_outcome?: string;
|
|
391
|
+
context: {
|
|
392
|
+
related_tasks: string[]; // Task IDs in same module
|
|
393
|
+
scoped_files: string[]; // Glob patterns for scoped files
|
|
394
|
+
planning_doc: string; // Path to source planning doc
|
|
395
|
+
module?: string;
|
|
396
|
+
};
|
|
397
|
+
provenance: {
|
|
398
|
+
snapshot_hash: string; // Hash of task definition
|
|
399
|
+
commit: string; // Git commit SHA
|
|
400
|
+
locked_at: string; // ISO 8601 timestamp
|
|
401
|
+
locked_by: string; // Username
|
|
402
|
+
plan_version?: string; // APS version
|
|
403
|
+
};
|
|
404
|
+
};
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Context Bundle
|
|
408
|
+
|
|
409
|
+
The execution plan includes a **context bundle** — all information the LLM
|
|
410
|
+
needs:
|
|
411
|
+
|
|
412
|
+
**Included:**
|
|
413
|
+
|
|
414
|
+
- Task intent and metadata
|
|
415
|
+
- Related tasks in the same module
|
|
416
|
+
- Dependencies (with their definitions)
|
|
417
|
+
- Scoped files (glob patterns matching scopes)
|
|
418
|
+
- Planning doc content
|
|
419
|
+
|
|
420
|
+
**Excluded:**
|
|
421
|
+
|
|
422
|
+
- Files outside declared scopes
|
|
423
|
+
- Unrelated modules
|
|
424
|
+
- Completed or cancelled tasks (unless dependencies)
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Scope Enforcement
|
|
429
|
+
|
|
430
|
+
### What Are Scopes?
|
|
431
|
+
|
|
432
|
+
Scopes define **what can be changed** during task execution.
|
|
433
|
+
|
|
434
|
+
**Example:**
|
|
435
|
+
|
|
436
|
+
```markdown
|
|
437
|
+
**Scopes:** AUTH, DB
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
This task can modify:
|
|
441
|
+
|
|
442
|
+
- Files in the `AUTH` scope (e.g., `src/auth/**`)
|
|
443
|
+
- Files in the `DB` scope (e.g., `src/db/**`, `migrations/**`)
|
|
444
|
+
|
|
445
|
+
### Scope-to-File Mapping
|
|
446
|
+
|
|
447
|
+
Scope mapping is configured in `.anvilrc`:
|
|
448
|
+
|
|
449
|
+
```json
|
|
450
|
+
{
|
|
451
|
+
"scopes": {
|
|
452
|
+
"AUTH": ["src/auth/**", "tests/auth/**"],
|
|
453
|
+
"DB": ["src/db/**", "migrations/**"],
|
|
454
|
+
"API": ["src/api/**", "tests/api/**"]
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Enforcement
|
|
460
|
+
|
|
461
|
+
During execution, Anvil agents:
|
|
462
|
+
|
|
463
|
+
1. Read task scopes from execution plan
|
|
464
|
+
2. Resolve scopes to file patterns
|
|
465
|
+
3. **Restrict file access** to only those patterns
|
|
466
|
+
4. Validate all changes stay within scopes
|
|
467
|
+
|
|
468
|
+
**If agent attempts to modify out-of-scope files:**
|
|
469
|
+
|
|
470
|
+
```
|
|
471
|
+
Error: Change validation failed
|
|
472
|
+
Attempted to modify src/payments/charge.ts
|
|
473
|
+
Task AUTH-001 only has scopes: AUTH, DB
|
|
474
|
+
File src/payments/charge.ts is in scope: PAY
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Multi-Scope Tasks
|
|
478
|
+
|
|
479
|
+
Tasks can declare multiple scopes when necessary:
|
|
480
|
+
|
|
481
|
+
```markdown
|
|
482
|
+
### AUTH-001: Migrate user table
|
|
483
|
+
|
|
484
|
+
**Intent:** Add email_verified column to users table **Scopes:** AUTH, DB
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
This allows modifying both auth code and database schema.
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## CLI Commands
|
|
492
|
+
|
|
493
|
+
### `anvil plan validate [path]`
|
|
494
|
+
|
|
495
|
+
Validates a planning document.
|
|
496
|
+
|
|
497
|
+
**Usage:**
|
|
498
|
+
|
|
499
|
+
```bash
|
|
500
|
+
anvil plan validate # Validates default (docs/planning/APS.md)
|
|
501
|
+
anvil plan validate docs/planning/auth.aps.md # Validates specific file
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**Options:**
|
|
505
|
+
|
|
506
|
+
- `--json` — Output as JSON
|
|
507
|
+
- `--strict` — Treat warnings as errors
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
### `anvil plan load [options]`
|
|
512
|
+
|
|
513
|
+
Loads a planning document and outputs context.
|
|
514
|
+
|
|
515
|
+
**Usage:**
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
anvil plan load --scope AUTH # Load all AUTH tasks
|
|
519
|
+
anvil plan load --module auth --depth 2 # Load auth module + 2 levels of dependencies
|
|
520
|
+
anvil plan load --task AUTH-001 # Load single task
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Options:**
|
|
524
|
+
|
|
525
|
+
- `--scope <scope>` — Filter by scope
|
|
526
|
+
- `--module <module>` — Filter by module
|
|
527
|
+
- `--task <task-id>` — Load single task
|
|
528
|
+
- `--owner <owner>` — Filter by owner
|
|
529
|
+
- `--tag <tag>` — Filter by tag
|
|
530
|
+
- `--priority <priority>` — Filter by priority
|
|
531
|
+
- `--depth <n>` — Traverse N levels of dependencies (default: 1)
|
|
532
|
+
- `--json` — Output as JSON
|
|
533
|
+
- `--files-only` — Output only file paths
|
|
534
|
+
|
|
535
|
+
---
|
|
536
|
+
|
|
537
|
+
### `anvil plan lock --task <task-id>`
|
|
538
|
+
|
|
539
|
+
Locks a task for execution.
|
|
540
|
+
|
|
541
|
+
**Usage:**
|
|
542
|
+
|
|
543
|
+
```bash
|
|
544
|
+
anvil plan lock --task AUTH-001
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
**What it does:**
|
|
548
|
+
|
|
549
|
+
1. Validates planning doc
|
|
550
|
+
2. Checks task is not already locked
|
|
551
|
+
3. Generates execution plan
|
|
552
|
+
4. Updates state to `locked`
|
|
553
|
+
|
|
554
|
+
**Fails if:**
|
|
555
|
+
|
|
556
|
+
- Planning doc has validation errors
|
|
557
|
+
- Task already locked
|
|
558
|
+
- Task ID doesn't exist
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
### `anvil plan unlock --task <task-id>`
|
|
563
|
+
|
|
564
|
+
Unlocks a task (abandons work).
|
|
565
|
+
|
|
566
|
+
**Usage:**
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
anvil plan unlock --task AUTH-001
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
**What it does:**
|
|
573
|
+
|
|
574
|
+
1. Updates state to `cancelled`
|
|
575
|
+
2. Removes execution file
|
|
576
|
+
3. Allows re-locking later
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
### `anvil plan complete --task <task-id>`
|
|
581
|
+
|
|
582
|
+
Marks a task as completed.
|
|
583
|
+
|
|
584
|
+
**Usage:**
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
anvil plan complete --task AUTH-001
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
**What it does:**
|
|
591
|
+
|
|
592
|
+
1. Updates state to `completed`
|
|
593
|
+
2. Records completion timestamp
|
|
594
|
+
3. Archives execution file
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
### `anvil plan status [options]`
|
|
599
|
+
|
|
600
|
+
Shows status of all tasks.
|
|
601
|
+
|
|
602
|
+
**Usage:**
|
|
603
|
+
|
|
604
|
+
```bash
|
|
605
|
+
anvil plan status # All tasks
|
|
606
|
+
anvil plan status --module auth # Tasks in auth module
|
|
607
|
+
anvil plan status --json # JSON output
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**Output:**
|
|
611
|
+
|
|
612
|
+
```
|
|
613
|
+
AUTH-001: ✓ completed (2h ago)
|
|
614
|
+
AUTH-002: 🔒 locked (by alice, 30m ago)
|
|
615
|
+
AUTH-003: ⏸ open
|
|
616
|
+
AUTH-004: ❌ cancelled
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## Integration Points
|
|
622
|
+
|
|
623
|
+
### With Git
|
|
624
|
+
|
|
625
|
+
- Planning docs committed to Git
|
|
626
|
+
- `.anvil/state.json` can be committed or gitignored
|
|
627
|
+
- `.anvil/executions/` typically gitignored (ephemeral)
|
|
628
|
+
- Provenance includes Git commit SHA
|
|
629
|
+
|
|
630
|
+
**Recommended `.gitignore`:**
|
|
631
|
+
|
|
632
|
+
```gitignore
|
|
633
|
+
.anvil/executions/
|
|
634
|
+
# .anvil/state.json (optional - commit if tracking state)
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
### With Anvil Execution Engine
|
|
640
|
+
|
|
641
|
+
Anvil agents consume execution plans:
|
|
642
|
+
|
|
643
|
+
```typescript
|
|
644
|
+
import { executePlan } from '@eddacraft/anvil-execution';
|
|
645
|
+
|
|
646
|
+
const plan = await loadExecutionPlan('.anvil/executions/AUTH-001.json');
|
|
647
|
+
const result = await executePlan(plan, {
|
|
648
|
+
scopeMapping: config.scopes,
|
|
649
|
+
gateChecks: ['tests', 'lint', 'typecheck'],
|
|
650
|
+
});
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
### With CI/CD
|
|
656
|
+
|
|
657
|
+
Planning doc validation in CI:
|
|
658
|
+
|
|
659
|
+
```yaml
|
|
660
|
+
name: Validate Planning Docs
|
|
661
|
+
on: [pull_request]
|
|
662
|
+
jobs:
|
|
663
|
+
validate:
|
|
664
|
+
runs-on: ubuntu-latest
|
|
665
|
+
steps:
|
|
666
|
+
- uses: actions/checkout@v4
|
|
667
|
+
- run: anvil plan validate docs/planning/APS.md
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## Example: Full Workflow
|
|
673
|
+
|
|
674
|
+
### 1. Create Planning Doc
|
|
675
|
+
|
|
676
|
+
```markdown
|
|
677
|
+
# Feature: Password Reset
|
|
678
|
+
|
|
679
|
+
**Scope:** AUTH **Owner:** @alice
|
|
680
|
+
|
|
681
|
+
## Tasks
|
|
682
|
+
|
|
683
|
+
### AUTH-010: Add password reset endpoint
|
|
684
|
+
|
|
685
|
+
**Intent:** Create POST /auth/reset-password endpoint **Confidence:** high
|
|
686
|
+
**Scopes:** AUTH, EMAIL **Dependencies:** AUTH-001
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### 2. Commit to Git
|
|
690
|
+
|
|
691
|
+
```bash
|
|
692
|
+
git add docs/planning/auth.aps.md
|
|
693
|
+
git commit -m "Add password reset tasks"
|
|
694
|
+
git push
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### 3. Validate
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
anvil plan validate docs/planning/auth.aps.md
|
|
701
|
+
# ✓ Validation passed
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### 4. Lock Task
|
|
705
|
+
|
|
706
|
+
```bash
|
|
707
|
+
anvil plan lock --task AUTH-010
|
|
708
|
+
# ✓ Task AUTH-010 locked
|
|
709
|
+
# Execution plan: .anvil/executions/AUTH-010.json
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### 5. Execute (via Anvil agent)
|
|
713
|
+
|
|
714
|
+
```bash
|
|
715
|
+
anvil execute .anvil/executions/AUTH-010.json
|
|
716
|
+
# Agent runs, generates changes, passes gate checks
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
### 6. Complete
|
|
720
|
+
|
|
721
|
+
```bash
|
|
722
|
+
anvil plan complete --task AUTH-010
|
|
723
|
+
# ✓ Task AUTH-010 marked as completed
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### 7. Check Status
|
|
727
|
+
|
|
728
|
+
```bash
|
|
729
|
+
anvil plan status --module auth
|
|
730
|
+
# AUTH-001: ✓ completed
|
|
731
|
+
# AUTH-010: ✓ completed
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
---
|
|
735
|
+
|
|
736
|
+
## Design Principles
|
|
737
|
+
|
|
738
|
+
1. **Planning docs are immutable during execution** — Source of truth never
|
|
739
|
+
changes
|
|
740
|
+
2. **State is separate from planning** — `.anvil/state.json` tracks execution
|
|
741
|
+
3. **Execution plans are ephemeral** — Generated, used, then archived
|
|
742
|
+
4. **First lock wins** — Simple concurrency model
|
|
743
|
+
5. **Validation before execution** — Catch errors early
|
|
744
|
+
6. **Scope enforcement** — LLMs see only what they need
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
## Version History
|
|
749
|
+
|
|
750
|
+
- **v0.1** (2025-12-17) — Initial integration spec
|