@use-the-fork/spindle 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/build/Assets/Blueprints/Catalog.js +7 -2
  2. package/build/Assets/Blueprints/agents/sdd-implementer.agent.md +6 -6
  3. package/build/Assets/Blueprints/agents/sdd-orchestrator.agent.md +4 -7
  4. package/build/Assets/Blueprints/skills/author-agent/SKILL.md +2 -2
  5. package/build/Assets/Blueprints/skills/author-instruction/SKILL.md +2 -2
  6. package/build/Assets/Blueprints/skills/author-skill/SKILL.md +2 -2
  7. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/SKILL.md +13 -9
  8. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/assets/implementer-prompt.md +2 -2
  9. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/example-workflow.md +11 -9
  10. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/full-spec.md +33 -13
  11. package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/review-inputs.md +7 -7
  12. package/build/Assets/Blueprints/skills/{asd-ste100 → ref-asd-ste100}/SKILL.md +1 -1
  13. package/build/Assets/Blueprints/skills/sdd-author-design/SKILL.md +2 -2
  14. package/build/Assets/Blueprints/skills/sdd-implement-spec/SKILL.md +4 -6
  15. package/build/Assets/Templates/project/ticket-tracker.md +10 -2
  16. package/build/SubagentDrivenDevelopment/Commands/ChecksRecordCommand.js +27 -5
  17. package/build/SubagentDrivenDevelopment/Commands/ChecksRequireCommand.js +31 -7
  18. package/build/SubagentDrivenDevelopment/Commands/CorrectCommand.js +0 -1
  19. package/build/SubagentDrivenDevelopment/Commands/FinishCommand.js +2 -1
  20. package/build/SubagentDrivenDevelopment/Commands/ImplementCommand.js +2 -0
  21. package/build/SubagentDrivenDevelopment/Commands/{ClaimCommand.js → IntegrateCommand.js} +8 -7
  22. package/build/SubagentDrivenDevelopment/Commands/ReviewCommand.js +9 -9
  23. package/build/SubagentDrivenDevelopment/Commands/StartCommand.js +23 -0
  24. package/build/SubagentDrivenDevelopment/Commands/StatusCommand.js +5 -0
  25. package/build/SubagentDrivenDevelopment/Commands/groups.js +3 -2
  26. package/build/SubagentDrivenDevelopment/Evidence/GitEvidence.js +188 -37
  27. package/build/SubagentDrivenDevelopment/Models/Workflow.js +0 -2
  28. package/build/SubagentDrivenDevelopment/Persistence/AssignmentSchema.js +4 -0
  29. package/build/SubagentDrivenDevelopment/Persistence/CheckSchema.js +4 -13
  30. package/build/SubagentDrivenDevelopment/Persistence/LedgerRepository.js +66 -5
  31. package/build/SubagentDrivenDevelopment/Persistence/ProgressSchema.js +54 -4
  32. package/build/SubagentDrivenDevelopment/Persistence/ReviewSchema.js +4 -0
  33. package/build/SubagentDrivenDevelopment/Policies/AssignmentPolicy.js +0 -3
  34. package/build/SubagentDrivenDevelopment/Policies/CheckPolicy.js +6 -3
  35. package/build/SubagentDrivenDevelopment/Policies/ReadinessPolicy.js +16 -6
  36. package/build/SubagentDrivenDevelopment/Policies/ReviewPolicy.js +16 -2
  37. package/build/SubagentDrivenDevelopment/Policies/WorkflowPolicy.js +8 -8
  38. package/build/SubagentDrivenDevelopment/Services/AssignmentService.js +73 -51
  39. package/build/SubagentDrivenDevelopment/Services/ChecksService.js +376 -21
  40. package/build/SubagentDrivenDevelopment/Services/CorrectionService.js +83 -14
  41. package/build/SubagentDrivenDevelopment/Services/DeliveryCorrectionService.js +3 -7
  42. package/build/SubagentDrivenDevelopment/Services/DeliveryService.js +43 -38
  43. package/build/SubagentDrivenDevelopment/Services/FeatureCreationService.js +1 -1
  44. package/build/SubagentDrivenDevelopment/Services/FeatureFinalizationService.js +1202 -0
  45. package/build/SubagentDrivenDevelopment/Services/FeatureInspectionService.js +41 -49
  46. package/build/SubagentDrivenDevelopment/Services/FeatureWorktreeService.js +544 -0
  47. package/build/SubagentDrivenDevelopment/Services/ReadinessService.js +2 -2
  48. package/build/SubagentDrivenDevelopment/Services/ReviewService.js +39 -3
  49. package/build/SubagentDrivenDevelopment/Services/SubmissionService.js +4 -1
  50. package/build/SubagentDrivenDevelopment/Services/TicketIntegrationService.js +621 -0
  51. package/build/SubagentDrivenDevelopment/Services/TicketService.js +3 -0
  52. package/build/SubagentDrivenDevelopment/Services/TicketWorktreeService.js +317 -0
  53. package/build/SubagentDrivenDevelopment/Services/WorkflowRecordsCommitter.js +336 -0
  54. package/build/SubagentDrivenDevelopment/SubagentDrivenDevelopmentServiceProvider.js +18 -8
  55. package/build/TemplateRendering/Computed/Providers/AuthoringFlowchartProvider.js +1 -1
  56. package/package.json +2 -2
  57. package/build/SubagentDrivenDevelopment/Services/IntegrationService.js +0 -258
  58. /package/build/Assets/Blueprints/skills/{asd-ste100 → ref-asd-ste100}/CREDITS.MD +0 -0
  59. /package/build/Assets/Blueprints/skills/{asd-ste100 → ref-asd-ste100}/examples/before-after.md +0 -0
  60. /package/build/Assets/Blueprints/skills/{asd-ste100 → ref-asd-ste100}/references/writing-rules.md +0 -0
@@ -21,7 +21,12 @@ export const blueprintCatalog = {
21
21
  stacks: [],
22
22
  canReview: true,
23
23
  },
24
- "sdd-task-reviewer": { path: "sdd-task-reviewer.agent.md", status: "active", stacks: [] },
24
+ "sdd-task-reviewer": {
25
+ path: "sdd-task-reviewer.agent.md",
26
+ status: "active",
27
+ stacks: [],
28
+ canReview: true,
29
+ },
25
30
  "shared-explore": { path: "shared-explore.agent.md", status: "active", stacks: [] },
26
31
  "shared-r": { path: "shared-r.agent.md", status: "active", stacks: [] },
27
32
  "shared-rw": { path: "shared-rw.agent.md", status: "active", stacks: [] },
@@ -60,7 +65,7 @@ export const blueprintCatalog = {
60
65
  },
61
66
  },
62
67
  skills: {
63
- "asd-ste100": { path: "asd-ste100/", status: "active", stacks: [] },
68
+ "ref-asd-ste100": { path: "ref-asd-ste100/", status: "active", stacks: [] },
64
69
  "author-agent": { path: "author-agent/", status: "active", stacks: [] },
65
70
  "sdd-author-design": { path: "sdd-author-design/", status: "active", stacks: [] },
66
71
  "author-instruction": { path: "author-instruction/", status: "active", stacks: [] },
@@ -1,17 +1,17 @@
1
1
  ---
2
2
  name: sdd-implementer
3
- description: "Use when an orchestrator assigns one ticket or corrective round for subagent-driven development in an existing shared checkout."
3
+ description: "Use when an orchestrator assigns one ticket or corrective round in its isolated worktree."
4
4
  tools: [read, search, edit, execute, read_skill, list_skills, skill]
5
5
  user-invocable: false
6
6
  agents: []
7
7
  metadata:
8
8
  spindle:
9
- version: 1.4.1
9
+ version: 1.5.0
10
10
  ---
11
11
 
12
12
  # SDD implementer
13
13
 
14
- Implement one orchestrator-assigned ticket in an existing shared checkout. The orchestrator is the controller; it owns dispatch, execution states, acceptance, and the ticket-wide checks. Work sequentially with other editors and return evidence for the assigned ticket.
14
+ Implement one orchestrator-assigned ticket in its isolated worktree. The orchestrator owns dispatch, execution states, acceptance, and the ticket-wide checks. Other tickets may run concurrently in their own worktrees.
15
15
 
16
16
  ## Required assignment gate
17
17
 
@@ -20,14 +20,14 @@ Before entering the flowchart, loading implementation skills, inspecting the che
20
20
  | Field | Required content |
21
21
  | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
22
22
  | `TICKET_ID` | The single assigned ticket identifier. |
23
- | `CHECKOUT` | Absolute path to the existing shared checkout. |
23
+ | `CHECKOUT` | Absolute path to the assigned ticket worktree. |
24
24
  | `ABSOLUTE_SOURCE_POINTERS` | Absolute paths to the canonical ticket, comments, and spec/brief. Explicitly identify any source that does not apply. |
25
25
  | `CRITERIA_AND_SEAMS` | Acceptance criteria and confirmed test seams. |
26
26
  | `DEPENDENCIES_AND_SNAPSHOT` | Completed dependencies and starting revision, including existing dirty/untracked changes. Explicitly state when there are no dependencies or changes. |
27
27
  | `FILE_SCOPE` | Allowed code, test, and `.scratch` files. |
28
28
  | `CHECKS_AND_DIRECTORY` | Approved project checks and their test working directory; identify any checks explicitly scheduled for this worker. |
29
29
  | `PERMISSIONS` | Allowed actions, including explicit commit authorization or denial. |
30
- | `REPORT_PATH` | Assigned `.scratch` report path within `FILE_SCOPE`, absolute or relative to `CHECKOUT`. |
30
+ | `REPORT_PATH` | Assigned absolute report path in the canonical feature workspace, within `FILE_SCOPE`. |
31
31
  | `MODE` | `INITIAL` or `CORRECTIVE`. |
32
32
 
33
33
  Accept populated template labels or equivalent structured fields, including grouped headings with labeled values beneath them. Legacy `For a fix: NONE` selects initial mode; populated fix context selects corrective mode. For `CORRECTIVE`, read `references/implementer-corrections.md` in the `int-subagent-driven-dev` skill before accepting the gate. Initial assignments need no corrective fields or resource.
@@ -74,4 +74,4 @@ Save the report at `REPORT_PATH` with:
74
74
  - For corrective mode, include the finding evidence required by `references/implementer-corrections.md` in the `int-subagent-driven-dev` skill.
75
75
  - A concise hand-back summary; include commit identifiers only when authorized.
76
76
 
77
- Update only assigned tracker files in `.scratch`, preserving history. Failed or unavailable required implementer checks block completion. Return the report path and concise summary, then stop. If the assignment gate is incomplete, return the context request instead of writing a report.
77
+ Write only the assigned report in the canonical feature workspace; the controller owns tracker updates. Failed or unavailable required implementer checks block completion. Return the report path and concise summary, then stop. If the assignment gate is incomplete, return the context request instead of writing a report.
@@ -4,10 +4,10 @@ description: "Use when coordinating feature tickets, implementation, review, and
4
4
  argument-hint: The feature spec, tickets, constraints, and permissions.
5
5
  user-invocable: true
6
6
  tools: [vscode/askQuestions, execute, read, agent, edit, web, todo, read_skill, list_skills, skill]
7
- agents: [sdd-implementer, sdd-reviewer, sdd-code-reviewer, shared-explore]
7
+ agents: [sdd-implementer, sdd-task-reviewer, sdd-reviewer, sdd-code-reviewer, shared-explore]
8
8
  metadata:
9
9
  spindle:
10
- version: 1.2.1
10
+ version: 1.4.0
11
11
  ---
12
12
 
13
13
  You are the SDD orchestration agent for feature tickets and feature-level delivery. Follow the user's scope and permissions.
@@ -23,11 +23,8 @@ the current harness before dispatch. Catalog `canReview: true` establishes
23
23
  eligibility only; it does not establish harness access. Never create an
24
24
  automatic or default specialist batch.
25
25
 
26
- Close a ticket with `sdd ticket update --status closed` after its acceptance
27
- criteria are met. Do not require per-ticket accept or integration commands.
28
- Feature completion requires every ticket closed, current passing feature checks
29
- and reviews, and no unresolved delivery blockers. Use the normal Git workflow;
30
- never ask the CLI to stage, commit, stash, discard, push, or publish.
26
+ Finish only after aggregate review, the final merge, and its declared checks.
27
+ Preserve worktrees and records whenever validation or cleanup is blocked.
31
28
 
32
29
  <communication-style>
33
30
  - **ALWAYS** think and respond in the same spoken language the prompt was written in.
@@ -15,13 +15,13 @@ Create or update a project agent in `.github/agents/<agent-name>.agent.md` based
15
15
 
16
16
  {{ computed.authoring_flowchart }}
17
17
 
18
- Before grilling, read and consider only the `int-writing-for-agents` and `asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
18
+ Before grilling, read and consider only the `int-writing-for-agents` and `ref-asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
19
19
 
20
20
  After the user confirms shared understanding, load and follow:
21
21
 
22
22
  - **REQUIRED:** `int-writing-agents`
23
23
  - **REQUIRED:** `int-testing-agent-guidance`
24
24
 
25
- Apply the clarity rules from the `asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
25
+ Apply the clarity rules from the `ref-asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
26
26
 
27
27
  Do not modify unrelated files. Report the skill changed and validation performed, including any blockers or unverified requirements.
@@ -15,14 +15,14 @@ Create or update a project instruction in `.github/instructions/**/*.instruction
15
15
 
16
16
  {{ computed.authoring_flowchart }}
17
17
 
18
- Before grilling, read and consider only the `int-writing-for-agents` and `asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
18
+ Before grilling, read and consider only the `int-writing-for-agents` and `ref-asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
19
19
 
20
20
  After the user confirms shared understanding, load and follow:
21
21
 
22
22
  - **REQUIRED:** `int-writing-instruction`
23
23
  - **REQUIRED:** `int-testing-agent-guidance`
24
24
 
25
- Apply the clarity rules from the `asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
25
+ Apply the clarity rules from the `ref-asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
26
26
 
27
27
  Verify any `applyTo` glob against concrete in-scope files and near misses; every intended file must match, and out-of-scope files must not.
28
28
 
@@ -15,13 +15,13 @@ Create or update a project skill in `.github/skills/<skill-name>/SKILL.md` based
15
15
 
16
16
  {{ computed.authoring_flowchart }}
17
17
 
18
- Before grilling, read and consider only the `int-writing-for-agents` and `asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
18
+ Before grilling, read and consider only the `int-writing-for-agents` and `ref-asd-ste100` skills. Do not follow their workflows or load skills they reference yet.
19
19
 
20
20
  After the user confirms shared understanding, load and follow:
21
21
 
22
22
  - **REQUIRED:** `int-writing-skills`
23
23
  - **REQUIRED:** `int-testing-agent-guidance`
24
24
 
25
- Apply the clarity rules from the `asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
25
+ Apply the clarity rules from the `ref-asd-ste100` skill. Include a before/after table only when the user requests one. Run the core and expanded testing workflows in `int-testing-agent-guidance` for every authoring request.
26
26
 
27
27
  Do not modify unrelated files. Report the skill changed and validation performed, including any blockers or unverified requirements.
@@ -4,15 +4,13 @@ description: "This is an internal skill do not load it unless explicitly require
4
4
  user-invocable: false
5
5
  metadata:
6
6
  spindle:
7
- version: 1.4.0
7
+ version: 1.6.0
8
8
  ---
9
9
 
10
10
  # Subagent-Driven Development
11
11
 
12
12
  The controller coordinates a feature's tickets, workers, checks, reviews, and completion. The feature workspace and `sdd.json` are the source of truth for structured ticket and delivery state; each ticket Markdown file holds its requirements, acceptance criteria, and discussion.
13
13
 
14
- Use the existing checkout and preserve user changes and report history. TDD is optional; write appropriate tests and record verification evidence. Load and follow `int-verification-before-completion` before claiming work is complete. Serialize implementation and fixes, and keep implementation edits frozen while a review batch is running.
15
-
16
14
  ## Workflow map
17
15
 
18
16
  Before acting on each chart node, announce `Step <node ID> - <node label>`, including initial entries, resumed steps, and loop re-entries. After each decision, state its result and selected branch before entering the target node.
@@ -20,7 +18,7 @@ Before acting on each chart node, announce `Step <node ID> - <node label>`, incl
20
18
  ```mermaid
21
19
  flowchart TD
22
20
  A[Restore feature state and readiness] --> B{Ready ticket available?}
23
- B -- Yes --> C[Claim, implement, verify, submit, close ticket]
21
+ B -- Yes --> C[Implement, review, integrate, and validate tickets]
24
22
  C --> A
25
23
  B -- No --> D{All tickets closed?}
26
24
  D -- No --> E[Resolve prerequisites or record blocker]
@@ -41,11 +39,17 @@ flowchart TD
41
39
 
42
40
  ## Ticket workflow
43
41
 
44
- 1. Read the feature spec, tickets, applicable instructions, glossary, and ADRs. Inspect `{{ computed.spindle_package_manager }} spindle sdd status --spec <path>` and `{{ computed.spindle_package_manager }} spindle sdd ready --spec <path>` to understand blockers, dependencies, and available work.
42
+ 1. Read the feature spec, tickets, applicable instructions, glossary, and ADRs. Inspect `{{ computed.spindle_package_manager }} spindle sdd status --spec <path>` and `{{ computed.spindle_package_manager }} spindle sdd ready --spec <path>` to understand blockers, dependencies, and available work. Inspect feature records for secrets and start the feature worktree with `{{ computed.spindle_package_manager }} spindle sdd start --spec <path> --workspace <external-directory> --confirm-records`. Handle unrelated changes before starting. Run subsequent controller commands in the feature worktree using its returned spec path.
45
43
  2. Create a ticket for independently actionable work with `{{ computed.spindle_package_manager }} spindle sdd ticket create`. Fill its `[REQUIREMENTS]` and `[ACCEPTANCE CRITERIA]` placeholders. Use `{{ computed.spindle_package_manager }} spindle sdd ticket update` for tracker status, explicit blockers, and dependencies; the supported lifecycle is `open`, `in-progress`, and `closed`. Readiness is derived from status, blockers, and dependencies rather than stored as a separate triage state.
46
- 3. Claim a ready ticket with `{{ computed.spindle_package_manager }} spindle sdd claim`. Dispatch implementation with `{{ computed.spindle_package_manager }} spindle sdd implement`; pass the worker the exact assignment and report destination. Submit its report with `{{ computed.spindle_package_manager }} spindle sdd submit --role implementation`.
47
- 4. Run relevant tests and checks and record their actual outcomes against the current snapshot. TDD is not required, but verification is.
48
- 5. Address implementation and verification gaps, then close the ticket with `{{ computed.spindle_package_manager }} spindle sdd ticket update --status closed` once its acceptance criteria are met. Do not use per-ticket accept or integrate steps.
44
+ 3. Choose a safe concurrency limit. Use `{{ computed.spindle_package_manager }} spindle sdd implement --workspace <external-directory>` for each ready ticket and dispatch the returned assignment until capacity is full. As workers finish, dispatch other ready independent tickets without waiting for unrelated work. Inspect changed canonical records for secrets and pass `--confirm-records` before any automatic record commit. Each worker uses its own worktree. Give workers the canonical source and report paths; submit each implementation report with `{{ computed.spindle_package_manager }} spindle sdd submit --role implementation`.
45
+ 4. Have each implementer commit its changes. Record relevant checks and submit reviews against that exact ticket commit. Keep its worktree frozen during review; any changed commit requires fresh checks and review.
46
+ 5. Use `{{ computed.spindle_package_manager }} spindle sdd integrate` to merge reviewed work, inspecting changed canonical records and passing `--confirm-records` before any automatic record commit. Serialize merges and their post-merge checks. Declare the full non-empty check list with `checks require --scope post-merge`, run it in the feature worktree, and record results with `checks record --scope post-merge`. Passing checks close the ticket automatically and unblock eligible dependents.
47
+
48
+ If closure is blocked by a ticket blocker or unmet dependency, resolve it and repeat `checks require --scope post-merge` with the same complete list. Passing evidence is retained; rerun checks if their snapshot became stale.
49
+
50
+ If a post-merge check fails, keep other merges blocked. Fast-forward the clean ticket worktree to the recorded failed merge commit, then use `sdd correct --check-failure <command>` to dispatch a fix. Commit, check, and review the fix before merging it and rerunning the frozen post-merge check list.
51
+
52
+ If integration reports a conflict, rebase the ticket worktree onto the current feature branch, resolve and commit the conflict there, and use `sdd checks require --rebase-baseline` with an existing required command. Run fresh checks and obtain fresh review before retrying integration. Preserve all uncommitted changes and stop if recovery is unsafe.
49
53
 
50
54
  If work is interrupted, inspect `{{ computed.spindle_package_manager }} spindle sdd status` and use `{{ computed.spindle_package_manager }} spindle sdd resume` to restore the recorded assignment. Preserve existing reports, findings, and evidence. Do not invent missing results or reset progress.
51
55
 
@@ -55,7 +59,7 @@ After every ticket is closed, establish current feature-level checks and request
55
59
 
56
60
  Submit every assigned review report against its exact assignment. Register findings from their report and snapshot. A blocking finding can name `--related-ticket`; once the complete review batch is submitted, that ticket is reopened so work can resume. Resolve blocking findings through ticket work and repeat any invalidated checks and reviews.
57
61
 
58
- For detailed review, findings, correction, and finish steps, read [feature delivery](./references/full-spec.md). For feature-level corrective work, follow [corrective rounds](./references/corrective-rounds.md). Feature completion requires all tickets closed, current passing required checks and reviews, and no unresolved delivery blockers. Use the normal Git workflow; SDD does not stage, commit, or publish work and has no per-ticket integration command.
62
+ For detailed review, findings, correction, final merge, checks, and cleanup, read [feature delivery](./references/full-spec.md). For feature-level corrective work, follow [corrective rounds](./references/corrective-rounds.md). Feature completion requires all tickets integrated, current passing required checks and reviews, no unresolved delivery blockers, and passing checks on the final merge. Do not modify the affected checkout concurrently with a Git transition. Never stash, discard, force-delete, push, or publish without authorization.
59
63
 
60
64
  ## Reports and verification
61
65
 
@@ -4,7 +4,7 @@
4
4
  ## Assignment
5
5
 
6
6
  Implement ticket: [TICKET_ID]
7
- Checkout: [CHECKOUT]
7
+ Ticket worktree: [CHECKOUT]
8
8
  Mode: [INITIAL_OR_CORRECTIVE]
9
9
 
10
10
  ## Requirements and starting state
@@ -20,7 +20,7 @@ Completed dependencies and starting snapshot:
20
20
 
21
21
  ## Scope and permissions
22
22
 
23
- Allowed code, test, and `.scratch` files:
23
+ Allowed code and test files in the ticket worktree, and the canonical report path:
24
24
  [FILE_SCOPE]
25
25
 
26
26
  Permissions, including commit authorization:
@@ -9,17 +9,19 @@ status and dependencies.
9
9
  2. Record the dependency with
10
10
  `{{ computed.spindle_package_manager }} spindle sdd ticket update --ticket T-0002 --blocked-by T-0001`. Check `{{ computed.spindle_package_manager }} spindle sdd ready`:
11
11
  the prerequisite is ready and the dependent ticket is not.
12
- 3. Claim and implement `T-0001`, submit its report, run and record relevant
13
- checks, then close it with `{{ computed.spindle_package_manager }} spindle sdd ticket update --status closed`.
14
- 4. `T-0002` becomes ready because its dependency is closed. Implement and
15
- verify it in the same way, then close it.
12
+ 3. Start the feature worktree in the supplied external directory. Implement
13
+ `T-0001` in its ticket worktree, submit its report, review the committed
14
+ change, and merge it into the feature branch. Declare and record passing
15
+ post-merge checks before it closes.
16
+ 4. `T-0002` becomes ready once its dependency is integrated and validated.
17
+ Branch it from the updated feature branch and deliver it in the same way.
16
18
  5. Record current feature-level required checks and request the comprehensive
17
19
  review with `{{ computed.spindle_package_manager }} spindle sdd review --scope delivery`. Add only justified specialists.
18
20
  6. Submit every assigned report. Register findings from their report and
19
21
  snapshot. A blocking finding can reopen its related ticket; complete the
20
22
  correction, close the ticket again, and refresh stale checks and review.
21
- 7. Finish when every ticket is closed, all required checks and reviews pass on
22
- the current feature snapshot, and no delivery blockers remain.
23
-
24
- Use the normal Git workflow for code. There is no per-ticket accept or
25
- integration step; the SDD CLI does not stage or commit changes.
23
+ 7. Inspect canonical records and run `sdd finish --confirm-records` from the
24
+ feature worktree. In the original checkout, declare and run the complete
25
+ `checks require --scope final` list, record results against the returned
26
+ merge and snapshot, then run `sdd finish` again to clean up. The checked
27
+ merge and the later metadata-only commit are reported separately.
@@ -50,21 +50,41 @@ preserve existing assignments, attempts, evidence, and adjudication.
50
50
 
51
51
  ## Finish
52
52
 
53
- Use the normal Git workflow for code changes. SDD does not stage, commit,
54
- publish, or require a per-ticket integration confirmation. A changed code or
53
+ Review each committed ticket before merging it into the feature worktree, then
54
+ record post-merge checks before unblocking dependents. A changed code or
55
55
  requirements snapshot invalidates evidence that no longer covers it.
56
56
 
57
- Legacy feature workspaces without a recorded Git baseline stay blocked until
58
- the original comparison baseline is identified. Do not silently use the
59
- current `HEAD` after implementation; that could omit completed feature work
60
- from review.
61
-
62
- Finish with `{{ computed.spindle_package_manager }} spindle sdd finish --spec <spec> --author <author>`. Completion requires
63
- at least one ticket, every ticket closed, current passing required feature
64
- checks and reviews, and no unresolved delivery blockers. The retrospective
65
- policy is stored at feature creation: when required, attach a Markdown report
66
- with `--report`; otherwise it is optional. Any report must remain inside that
67
- feature's `reports/` directory.
57
+ Do not silently substitute the current `HEAD` for the recorded Git baseline;
58
+ that could omit completed feature work from review.
59
+
60
+ Completion requires at least one ticket, every ticket integrated and validated,
61
+ current passing required feature checks and reviews, and no unresolved delivery
62
+ blockers. The retrospective policy is stored at feature creation: when required,
63
+ attach a Markdown report with `--report`; otherwise it is optional. Any report
64
+ must remain inside that feature's `reports/` directory.
65
+
66
+ Inspect canonical records for sensitive content, then run
67
+ `{{ computed.spindle_package_manager }} spindle sdd finish --spec <feature-spec> --author <controller> --confirm-records`
68
+ from the feature worktree, adding `--report <absolute-report-path>` when needed.
69
+ This merges into the recorded original branch and returns a pending final
70
+ validation, merge SHA, snapshot, and original spec path; it does not yet complete
71
+ the feature.
72
+
73
+ In the original checkout, declare the entire non-empty final list with
74
+ `{{ computed.spindle_package_manager }} spindle sdd checks require --spec <original-spec> --scope final --command <command> --author <controller>`,
75
+ repeating `--command` for each check. Run each command there, then record each
76
+ actual result with `{{ computed.spindle_package_manager }} spindle sdd checks record --spec <original-spec> --scope final --merge <merge-sha> --snapshot <snapshot> --command <command> --result <result> --author <controller>`.
77
+ Failed or unavailable results require `--details` and block cleanup until the
78
+ latest result for each command passes. The list is frozen once declared.
79
+
80
+ Run `{{ computed.spindle_package_manager }} spindle sdd finish --spec <original-spec> --author <controller>`
81
+ again to preflight and clean up the recorded worktrees and branches. The final
82
+ merge is the checked commit; the subsequent ledger-only relocation commit is
83
+ reported separately and is not itself checked. Preserve any dirty or unexpected
84
+ work and follow the reported journal for recovery rather than forcing cleanup.
85
+ Ignored files in worktrees slated for removal also block cleanup; do not discard
86
+ them without authorization. After a crash, remove a reported finalization lock
87
+ only after verifying its recorded owner has stopped.
68
88
 
69
89
  Use `{{ computed.spindle_package_manager }} spindle sdd status`, `{{ computed.spindle_package_manager }} spindle sdd next`, and
70
90
  `{{ computed.spindle_package_manager }} spindle sdd resume --scope delivery` to inspect blockers and
@@ -6,18 +6,18 @@ Read when preparing or accepting a review assignment. The controller supplies th
6
6
 
7
7
  `REVIEW_INPUTS` names an absolute, read-required package/manifest path. Read it and its required sources before inspecting the checkout or reviewing. Equivalent structured inputs inline remain valid; preserve supplied values rather than inferring missing revisions from Git.
8
8
 
9
- | Input | Required meaning |
10
- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
- | Requirements | Canonical ticket/spec/comments pointers, applicable instructions, criteria, and constraints. Identify inapplicable sources explicitly. |
12
- | Workspace and snapshot | Absolute shared checkout; exact reviewed identity, comparison base and head revisions, and included dirty/untracked changes or `NONE`. SHAs are provenance metadata and may live in the package rather than repeated prompt fields. |
13
- | Complete change | Complete assigned diff with file inventory, stat, and enough context, or approved read-only retrieval using supplied revisions. Include dirty/untracked additions and binary changes, or identify unavailable material as a coverage gap. |
14
- | Verification | Commands, results, test summary, exact snapshot covered, and unavailable required checks. Evidence pointers are valid; read them before judging coverage. |
9
+ | Input | Required meaning |
10
+ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | Requirements | Canonical ticket/spec/comments pointers, applicable instructions, criteria, and constraints. Identify inapplicable sources explicitly. |
12
+ | Workspace and snapshot | Absolute ticket or feature worktree, as appropriate; exact reviewed identity, comparison base and head revisions, and included dirty/untracked changes or `NONE`. SHAs are provenance metadata and may live in the package rather than repeated prompt fields. |
13
+ | Complete change | Complete assigned diff with file inventory, stat, and enough context, or approved read-only retrieval using supplied revisions. Include dirty/untracked additions and binary changes, or identify unavailable material as a coverage gap. |
14
+ | Verification | Commands, results, test summary, exact snapshot covered, and unavailable required checks. Evidence pointers are valid; read them before judging coverage. |
15
15
 
16
16
  Keep every meaning authoritative in one place: reference canonical requirements, reports, and evidence rather than copying full logs or the entire ledger. A pointer must identify the required material, not merely say "see ledger". The role-specific assignment supplies phase, objective, history relevant to that role, and its distinct report destination.
17
17
 
18
18
  ## Snapshot ownership and completeness
19
19
 
20
- The controller owns construction, freezing, and freshness checks. Reuse existing durable complete diffs and evidence; no additional packaging command or hash scheme is required. The identity must distinguish uncommitted/untracked content, not just HEAD. Keep implementation frozen throughout the review batch, allowing assigned report writes without changing the reviewed code identity.
20
+ The controller owns construction, freezing, and freshness checks. Reuse existing durable complete diffs and evidence; no additional packaging command or hash scheme is required. Ticket reviews must cover the exact committed ticket revision and its complete change against the assigned base. Keep that worktree clean and frozen throughout the review batch; reports are written to the canonical feature workspace.
21
21
 
22
22
  Corrections produce a new reviewed identity with fresh covering checks. Preserve the previous package and evidence as history rather than relabeling them as verification of changed code.
23
23
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: asd-ste100
2
+ name: ref-asd-ste100
3
3
  description: "Rewrites ambiguous English into ASD-STE100 style — one meaning per word, active voice, simple tense, short sentences. Use when agent output is hard to parse; triggers: simplify this, STE100 rewrite."
4
4
  user-invocable: false
5
5
  metadata:
@@ -16,9 +16,9 @@ Help the user clarify what they want before turning an idea into a design. A des
16
16
 
17
17
  Before drafting or editing, read:
18
18
 
19
- - **REQUIRED:** `asd-ste100`
19
+ - **REQUIRED:** `ref-asd-ste100`
20
20
 
21
- Apply the clarity rules from the `asd-ste100` skill. Include a before/after table only when the user requests one.
21
+ Apply the clarity rules from the `ref-asd-ste100` skill. Include a before/after table only when the user requests one.
22
22
 
23
23
  ## Process
24
24
 
@@ -4,13 +4,11 @@ description: "Implement the result of /sdd-to-spec and /sdd-to-tickets in code."
4
4
  disable-model-invocation: true
5
5
  metadata:
6
6
  spindle:
7
- version: 1.0.0
7
+ version: 1.2.0
8
8
  ---
9
9
 
10
10
  # Implement a Spec
11
11
 
12
- Deliver the supplied spec and all associated tickets in the existing checkout. Require configured tracker guidance; if absent, request `/spindle-project-setup`.
13
-
14
12
  ## Required Skills
15
13
 
16
14
  Before acting, read and follow each required skill:
@@ -19,15 +17,15 @@ Before acting, read and follow each required skill:
19
17
 
20
18
  ## Steps
21
19
 
22
- 1. **Bind the whole-spec assignment.** Locate the full spec, every ticket and its comments, and tracker guidance. Supply accessible context pointers rather than duplicating their contents. Record the existing checkout, starting revision, existing work and permissions.
20
+ 1. **Bind the whole-spec assignment.** Locate the full spec, every ticket and its comments, and tracker guidance. Supply accessible context pointers rather than duplicating their contents. Record the original branch, existing work, permissions, and the allowed feature worktree location; obtain an allowed location for each ticket at dispatch.
23
21
 
24
22
  **Complete when:** the complete graph and delivery inputs are available to one controller, or missing requirements are reported for triage.
25
23
 
26
- 2. **Execute the complete graph.** Follow [int-subagent-driven-dev](../int-subagent-driven-dev/SKILL.md) once with the entire graph and explicit ownership of frontier selection, sequential ticket delivery, aggregate review, and retrospective. Do not call it as a separate standalone delivery for every ticket. Its dependency validation, shared-checkout workflow, resume handling, review budgets, and completion criteria are authoritative. Accepted work does not unblock dependents until integrated and verified in the existing checkout.
24
+ 2. **Execute the complete graph.** Follow the `int-subagent-driven-dev` skill once with the entire graph and explicit ownership of frontier selection, ticket delivery, aggregate review, and retrospective. Accepted work does not unblock dependents until integrated and verified in the feature worktree.
27
25
 
28
26
  If the tracker calls for a PR, or the user requests one, open an authorized draft during execution after the first authorized commit is available; retain it as draft while delivery is incomplete.
29
27
 
30
- **Complete when:** its final report reconciles every ticket and requirement, one aggregate review, fresh verification and one retrospective for the spec, or explicitly identifies unfinished work and blockers.
28
+ **Complete when:** its final report reconciles every ticket and requirement, one aggregate review, fresh verification, and any retrospective required by policy or requested by the user, or explicitly identifies unfinished work and blockers.
31
29
 
32
30
  3. **Apply authorized publication transitions.** Mark an authorized draft ready only after the full delivery's review and checks pass. Apply closing references and ticket closure only with the user's authorization.
33
31
 
@@ -26,8 +26,16 @@ The command returns the new ticket ID and path. Complete its template, then set
26
26
  {{ computed.spindle_package_manager }} spindle sdd ready --spec <absolute-spec-path>
27
27
  ```
28
28
 
29
- Use `--clear-blocked-by` to remove dependencies. Use `ticket update --status` to change status. Ticket Markdown remains editable; attributed comments are appended under `## Comments`. Do not add an execution field to the ticket file: execution transitions are recorded in `sdd.json`.
29
+ Use `--clear-blocked-by` to remove dependencies. Ticket Markdown remains editable; attributed comments are appended under `## Comments`. Do not add an execution field to the ticket file: execution transitions are recorded in `sdd.json`.
30
30
 
31
31
  ## Delivery
32
32
 
33
- Use `{{ computed.spindle_package_manager }} spindle sdd status` and `{{ computed.spindle_package_manager }} spindle sdd ready` to inspect work. Claim and dispatch ready tickets with `{{ computed.spindle_package_manager }} spindle sdd claim` and `{{ computed.spindle_package_manager }} spindle sdd implement`, submit the assigned report with `{{ computed.spindle_package_manager }} spindle sdd submit`, and close completed tickets with `{{ computed.spindle_package_manager }} spindle sdd ticket update --status closed`. Follow the `int-subagent-driven-dev` skill for review, correction, and feature completion.
33
+ Use `{{ computed.spindle_package_manager }} spindle sdd status` and `{{ computed.spindle_package_manager }} spindle sdd ready` to inspect work. Follow the `int-subagent-driven-dev` skill for dispatch, review, correction, integration, and feature completion.
34
+
35
+ Inspect feature records for sensitive content, then start a feature worktree in an existing external directory with `{{ computed.spindle_package_manager }} spindle sdd start --spec <absolute-spec-path> --workspace <absolute-directory> --confirm-records`. Use its returned spec path for subsequent commands.
36
+
37
+ Dispatch each ready ticket to a separate worktree with `{{ computed.spindle_package_manager }} spindle sdd implement --spec <feature-spec-path> --ticket <id> --author <name> --workspace <absolute-directory>`. Inspect changed canonical records and pass `--confirm-records` before automatic record commits. Submit the implementation report and review the committed ticket before merging it with `{{ computed.spindle_package_manager }} spindle sdd integrate`.
38
+
39
+ Declare the complete post-merge check list with `checks require --scope post-merge --ticket <id>`, run the checks, and record each result with `checks record --scope post-merge --ticket <id>`. Passing results close the ticket automatically unless a blocker or dependency prevents closure. Resolve it, then repeat `checks require` with the same complete list; rerun any stale checks. Failed checks block other merges until a reviewed correction passes. Resolve conflicts in the ticket worktree, adopt the rebased baseline with `checks require --rebase-baseline`, and obtain fresh checks and review.
40
+
41
+ After aggregate checks and review pass, inspect records and run `{{ computed.spindle_package_manager }} spindle sdd finish --spec <feature-spec-path> --author <name> --confirm-records` from the feature worktree. Include `--report <absolute-report-path>` when a retrospective is required. In the original checkout, declare the complete list with `checks require --scope final`, run the checks, and record each result with `checks record --scope final --merge <merge-sha> --snapshot <snapshot>`. Repeat `finish` there to preflight and clean up. Final checks cover the merge; a separate ledger-only relocation commit follows. Preserve work and inspect the journal if recovery or cleanup is blocked.
@@ -2,6 +2,7 @@ import { Command } from "../../Commands/Command.js";
2
2
  import { CommandOptions } from "../../Commands/CommandOptions.js";
3
3
  import { group } from "./groups.js";
4
4
  import { ChecksService } from "../Services/ChecksService.js";
5
+ import { FeatureFinalizationService } from "../Services/FeatureFinalizationService.js";
5
6
  export class ChecksRecordCommand extends Command {
6
7
  static register(root, createApp) {
7
8
  group(root, "checks")
@@ -9,7 +10,8 @@ export class ChecksRecordCommand extends Command {
9
10
  .description("Record an externally executed check against a current snapshot.")
10
11
  .requiredOption("--spec <path>", "Feature spec path", CommandOptions.once("--spec"))
11
12
  .option("--ticket <id>", "Ticket ID", CommandOptions.once("--ticket"))
12
- .option("--scope <scope>", "Workflow scope: delivery")
13
+ .option("--scope <scope>", "Workflow scope: delivery, post-merge or final")
14
+ .option("--merge <sha>", "Exact feature merge commit; required for scope final", CommandOptions.once("--merge"))
13
15
  .requiredOption("--snapshot <snapshot>", "CLI-returned content snapshot identity", CommandOptions.once("--snapshot"))
14
16
  .requiredOption("--command <command>", "Exact required command", CommandOptions.once("--command"))
15
17
  .requiredOption("--result <result>", "Check result: passed, failed, unavailable", CommandOptions.once("--result"))
@@ -18,11 +20,12 @@ export class ChecksRecordCommand extends Command {
18
20
  .requiredOption("--author <author>", "Acting controller", CommandOptions.once("--author"))
19
21
  .allowExcessArguments(false)
20
22
  .action(async (options) => {
21
- if (options.scope !== undefined && options.scope !== "delivery") {
22
- throw new Error("--scope must be 'delivery'.");
23
+ if (options.scope !== undefined &&
24
+ !["delivery", "post-merge", "final"].includes(options.scope)) {
25
+ throw new Error("--scope must be 'delivery', 'post-merge' or 'final'.");
23
26
  }
24
- if (Boolean(options.ticket) === (options.scope === "delivery")) {
25
- throw new Error("checks record needs exactly one of --ticket or --scope delivery.");
27
+ if ((options.scope === "delivery" || options.scope === "final") === Boolean(options.ticket)) {
28
+ throw new Error("checks record needs --ticket or --scope delivery/final; scope post-merge also needs --ticket.");
26
29
  }
27
30
  const command = await (await createApp()).make(ChecksRecordCommand);
28
31
  console.log(JSON.stringify(await command.run(options), null, 2));
@@ -30,6 +33,25 @@ export class ChecksRecordCommand extends Command {
30
33
  }
31
34
  async run(options) {
32
35
  this.assertApplicationBooted();
36
+ if (options.scope === "final") {
37
+ if (options.ticket || options.paths || !options.merge)
38
+ throw new Error("Final records require --merge and do not accept ticket/path coverage.");
39
+ const finalization = await this.app.make(FeatureFinalizationService);
40
+ const feature = finalization.recordedFeature(options.spec);
41
+ if (!feature)
42
+ throw new Error("Final records require a recorded feature merge.");
43
+ return finalization.record({
44
+ feature: feature.feature,
45
+ merge: options.merge,
46
+ snapshot: options.snapshot,
47
+ command: options.command,
48
+ result: options.result,
49
+ author: options.author,
50
+ ...(options.details ? { details: options.details } : {}),
51
+ });
52
+ }
53
+ if (options.merge)
54
+ throw new Error("--merge is only valid with --scope final.");
33
55
  return (await this.app.make(ChecksService)).checksRecord(options);
34
56
  }
35
57
  }
@@ -2,6 +2,7 @@ import { Command } from "../../Commands/Command.js";
2
2
  import { CommandOptions } from "../../Commands/CommandOptions.js";
3
3
  import { group } from "./groups.js";
4
4
  import { ChecksService } from "../Services/ChecksService.js";
5
+ import { FeatureFinalizationService } from "../Services/FeatureFinalizationService.js";
5
6
  export class ChecksRequireCommand extends Command {
6
7
  static register(root, createApp) {
7
8
  group(root, "checks")
@@ -9,25 +10,48 @@ export class ChecksRequireCommand extends Command {
9
10
  .description("Add or remove a required external check.")
10
11
  .requiredOption("--spec <path>", "Feature spec path", CommandOptions.once("--spec"))
11
12
  .option("--ticket <id>", "Ticket ID", CommandOptions.once("--ticket"))
12
- .option("--scope <scope>", "Workflow scope: delivery")
13
- .requiredOption("--command <command>", "Exact externally executed command", CommandOptions.once("--command"))
13
+ .option("--scope <scope>", "Workflow scope: delivery, post-merge or final")
14
+ .requiredOption("--command <command>", "Exact externally executed command; repeat for post-merge or final lists", (value, previous = []) => [...previous, value], [])
14
15
  .option("--remove", "Remove the requirement; requires --details rationale")
16
+ .option("--rebase-baseline", "Adopt current feature HEAD after manually rebasing the ticket worktree")
15
17
  .option("--details <details>", "Removal rationale")
16
18
  .requiredOption("--author <author>", "Acting controller", CommandOptions.once("--author"))
17
19
  .allowExcessArguments(false)
18
20
  .action(async (options) => {
19
- if (options.scope !== undefined && options.scope !== "delivery") {
20
- throw new Error("--scope must be 'delivery'.");
21
+ if (options.scope !== undefined &&
22
+ options.scope !== "delivery" &&
23
+ options.scope !== "post-merge" &&
24
+ options.scope !== "final") {
25
+ throw new Error("--scope must be 'delivery', 'post-merge' or 'final'.");
21
26
  }
22
- if (Boolean(options.ticket) === (options.scope === "delivery")) {
23
- throw new Error("checks require needs exactly one of --ticket or --scope delivery.");
27
+ if ((options.scope === "delivery" || options.scope === "final") === Boolean(options.ticket)) {
28
+ throw new Error("checks require needs --ticket or --scope delivery/final; scope post-merge also needs --ticket.");
24
29
  }
30
+ if (options.scope !== "post-merge" &&
31
+ options.scope !== "final" &&
32
+ options.command.length !== 1)
33
+ throw new Error("Exactly one --command is required outside scopes post-merge and final.");
25
34
  const command = await (await createApp()).make(ChecksRequireCommand);
26
- console.log(JSON.stringify(await command.run(options), null, 2));
35
+ console.log(JSON.stringify(await command.run({
36
+ ...options,
37
+ command: options.scope === "post-merge" || options.scope === "final"
38
+ ? options.command
39
+ : options.command[0],
40
+ }), null, 2));
27
41
  });
28
42
  }
29
43
  async run(options) {
30
44
  this.assertApplicationBooted();
45
+ if (options.scope === "final") {
46
+ if (options.ticket || options.remove || options.details || options.rebaseBaseline) {
47
+ throw new Error("Final declarations do not accept ticket, removal, rebase or coverage options.");
48
+ }
49
+ return (await this.app.make(FeatureFinalizationService)).declare({
50
+ spec: options.spec,
51
+ command: Array.isArray(options.command) ? options.command : [options.command],
52
+ author: options.author,
53
+ });
54
+ }
31
55
  return (await this.app.make(ChecksService)).checksRequire(options);
32
56
  }
33
57
  }
@@ -15,7 +15,6 @@ export class CorrectCommand extends Command {
15
15
  .requiredOption("--details <details>", "Correction objective or adjudication rationale", CommandOptions.once("--details"))
16
16
  .option("--decision <decision>", "Continuation decision: continue or pause")
17
17
  .option("--assessment <assessment>", "Recorded progress assessment for the prior attempt")
18
- .option("--assessment-result <result>", "Progress result: productive")
19
18
  .option("--reason <reason>", "Pause reason: no-progress, repeated-failure, recurring-blocker, requirements-disagreement, worker-blocked")
20
19
  .requiredOption("--author <author>", "Controller author", CommandOptions.once("--author"))
21
20
  .allowExcessArguments(false)
@@ -6,10 +6,11 @@ export class FinishCommand extends Command {
6
6
  static register(root, createApp) {
7
7
  group(root)
8
8
  .command("finish")
9
- .description("Complete feature delivery after all tickets are closed and required checks and reviews pass.")
9
+ .description("Merge approved feature delivery, then clean up only after exact final-merge checks pass.")
10
10
  .requiredOption("--spec <path>", "Feature spec path", CommandOptions.once("--spec"))
11
11
  .option("--report <path>", "Optional or policy-required Markdown report inside feature reports/", CommandOptions.once("--report"))
12
12
  .requiredOption("--author <author>", "Controller author", CommandOptions.once("--author"))
13
+ .option("--confirm-records", "Confirm inspected canonical records may be committed")
13
14
  .allowExcessArguments(false)
14
15
  .action(async (options) => {
15
16
  const command = await (await createApp()).make(FinishCommand);
@@ -10,6 +10,8 @@ export class ImplementCommand extends Command {
10
10
  .requiredOption("--spec <path>", "Feature spec path", CommandOptions.once("--spec"))
11
11
  .requiredOption("--ticket <id>", "Ticket ID", CommandOptions.once("--ticket"))
12
12
  .requiredOption("--author <author>", "Controller author", CommandOptions.once("--author"))
13
+ .requiredOption("--workspace <directory>", "Existing absolute external directory for the ticket worktree", CommandOptions.once("--workspace"))
14
+ .option("--confirm-records", "Confirm that current canonical feature records were inspected before batching")
13
15
  .allowExcessArguments(false)
14
16
  .action(async (options) => {
15
17
  const command = await (await createApp()).make(ImplementCommand);