@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.
Files changed (121) hide show
  1. package/AGENTS.md +155 -0
  2. package/LICENSE +14 -0
  3. package/README.md +57 -0
  4. package/TODO.md +40 -0
  5. package/dist/filter/context-bundle.d.ts +81 -0
  6. package/dist/filter/context-bundle.d.ts.map +1 -0
  7. package/dist/filter/context-bundle.js +230 -0
  8. package/dist/filter/index.d.ts +85 -0
  9. package/dist/filter/index.d.ts.map +1 -0
  10. package/dist/filter/index.js +169 -0
  11. package/dist/index.d.ts +16 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +15 -0
  14. package/dist/loader/index.d.ts +80 -0
  15. package/dist/loader/index.d.ts.map +1 -0
  16. package/dist/loader/index.js +253 -0
  17. package/dist/parser/index.d.ts +24 -0
  18. package/dist/parser/index.d.ts.map +1 -0
  19. package/dist/parser/index.js +22 -0
  20. package/dist/parser/parse-document.d.ts +17 -0
  21. package/dist/parser/parse-document.d.ts.map +1 -0
  22. package/dist/parser/parse-document.js +219 -0
  23. package/dist/parser/parse-index.d.ts +31 -0
  24. package/dist/parser/parse-index.d.ts.map +1 -0
  25. package/dist/parser/parse-index.js +251 -0
  26. package/dist/parser/parse-task.d.ts +30 -0
  27. package/dist/parser/parse-task.d.ts.map +1 -0
  28. package/dist/parser/parse-task.js +261 -0
  29. package/dist/state/index.d.ts +307 -0
  30. package/dist/state/index.d.ts.map +1 -0
  31. package/dist/state/index.js +689 -0
  32. package/dist/templates/generator.d.ts +71 -0
  33. package/dist/templates/generator.d.ts.map +1 -0
  34. package/dist/templates/generator.js +723 -0
  35. package/dist/templates/index.d.ts +5 -0
  36. package/dist/templates/index.d.ts.map +1 -0
  37. package/dist/templates/index.js +4 -0
  38. package/dist/types/index.d.ts +131 -0
  39. package/dist/types/index.d.ts.map +1 -0
  40. package/dist/types/index.js +107 -0
  41. package/dist/validator/index.d.ts +83 -0
  42. package/dist/validator/index.d.ts.map +1 -0
  43. package/dist/validator/index.js +611 -0
  44. package/docs/APS-Anvil-Integration.md +750 -0
  45. package/docs/APS-Conventions.md +635 -0
  46. package/docs/APS-NonGoals.md +455 -0
  47. package/docs/APS-Planning-Spec-v0.1.md +362 -0
  48. package/examples/README.md +170 -0
  49. package/examples/feature-auth.aps.md +87 -0
  50. package/examples/refactor-error-handling.aps.md +119 -0
  51. package/examples/system-ecommerce/APS.md +57 -0
  52. package/examples/system-ecommerce/modules/auth.aps.md +38 -0
  53. package/examples/system-ecommerce/modules/cart.aps.md +53 -0
  54. package/examples/system-ecommerce/modules/payments.aps.md +68 -0
  55. package/examples/system-ecommerce/modules/products.aps.md +53 -0
  56. package/package.json +34 -0
  57. package/project.json +37 -0
  58. package/scripts/generate-templates.js +33 -0
  59. package/src/filter/context-bundle.ts +312 -0
  60. package/src/filter/filter.test.ts +317 -0
  61. package/src/filter/index.ts +249 -0
  62. package/src/index.ts +16 -0
  63. package/src/loader/index.ts +364 -0
  64. package/src/loader/loader.test.ts +224 -0
  65. package/src/parser/__fixtures__/invalid-task-id-not-padded.aps.md +7 -0
  66. package/src/parser/__fixtures__/invalid-task-id.aps.md +8 -0
  67. package/src/parser/__fixtures__/minimal-task.aps.md +7 -0
  68. package/src/parser/__fixtures__/non-scope-hyphenated.aps.md +10 -0
  69. package/src/parser/__fixtures__/simple-index.aps.md +35 -0
  70. package/src/parser/__fixtures__/simple-plan.aps.md +19 -0
  71. package/src/parser/index.ts +30 -0
  72. package/src/parser/parse-document.test.ts +603 -0
  73. package/src/parser/parse-document.ts +262 -0
  74. package/src/parser/parse-index.test.ts +316 -0
  75. package/src/parser/parse-index.ts +298 -0
  76. package/src/parser/parse-task.test.ts +476 -0
  77. package/src/parser/parse-task.ts +325 -0
  78. package/src/state/__fixtures__/invalid-plan.aps.md +9 -0
  79. package/src/state/__fixtures__/test-plan.aps.md +20 -0
  80. package/src/state/index.ts +879 -0
  81. package/src/state/state.test.ts +645 -0
  82. package/src/templates/generator.test.ts +378 -0
  83. package/src/templates/generator.ts +776 -0
  84. package/src/templates/index.ts +5 -0
  85. package/src/types/index.ts +168 -0
  86. package/src/validator/__fixtures__/broken-links.aps.md +10 -0
  87. package/src/validator/__fixtures__/circular-deps-index.aps.md +26 -0
  88. package/src/validator/__fixtures__/circular-modules/module-a.aps.md +9 -0
  89. package/src/validator/__fixtures__/circular-modules/module-b.aps.md +9 -0
  90. package/src/validator/__fixtures__/circular-modules/module-c.aps.md +9 -0
  91. package/src/validator/__fixtures__/dup-modules/module-a.aps.md +9 -0
  92. package/src/validator/__fixtures__/dup-modules/module-b.aps.md +9 -0
  93. package/src/validator/__fixtures__/duplicate-ids-index.aps.md +15 -0
  94. package/src/validator/__fixtures__/invalid-task-id.aps.md +17 -0
  95. package/src/validator/__fixtures__/missing-confidence.aps.md +9 -0
  96. package/src/validator/__fixtures__/missing-h1.aps.md +5 -0
  97. package/src/validator/__fixtures__/missing-intent.aps.md +9 -0
  98. package/src/validator/__fixtures__/missing-modules-section.aps.md +7 -0
  99. package/src/validator/__fixtures__/missing-tasks-section.aps.md +7 -0
  100. package/src/validator/__fixtures__/modules/auth.aps.md +17 -0
  101. package/src/validator/__fixtures__/modules/payments.aps.md +13 -0
  102. package/src/validator/__fixtures__/scope-mismatch.aps.md +14 -0
  103. package/src/validator/__fixtures__/valid-index.aps.md +24 -0
  104. package/src/validator/__fixtures__/valid-leaf.aps.md +22 -0
  105. package/src/validator/index.ts +776 -0
  106. package/src/validator/validator.test.ts +269 -0
  107. package/templates/index-full.md +94 -0
  108. package/templates/index-minimal.md +16 -0
  109. package/templates/index-template.md +63 -0
  110. package/templates/leaf-full.md +76 -0
  111. package/templates/leaf-minimal.md +14 -0
  112. package/templates/leaf-template.md +55 -0
  113. package/templates/simple-full.md +56 -0
  114. package/templates/simple-minimal.md +14 -0
  115. package/templates/simple-template.md +30 -0
  116. package/tsconfig.json +19 -0
  117. package/tsconfig.lib.json +14 -0
  118. package/tsconfig.lib.tsbuildinfo +1 -0
  119. package/tsconfig.spec.json +9 -0
  120. package/tsconfig.tsbuildinfo +1 -0
  121. 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