opensddrag 0.1.2 → 0.2.2

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.
@@ -3,6 +3,11 @@
3
3
  * Installed to .opencode/commands/opsr/ when OpenCode is selected.
4
4
  * Uses a compact openCodeHeader() (project_slug only) instead of the Claude Code
5
5
  * IMPORTANT/tool-list/STOP block — MCP tools are auto-available in OpenCode.
6
+ *
7
+ * Per the command-skill-separation-contract, every command is a pure pointer:
8
+ * Purpose + Input + a single "Load the skill" step. The complete workflow
9
+ * (MCP calls, templates, examples, edge cases) lives in the matching
10
+ * opensddrag-<name> skill. Do NOT add workflow steps here.
6
11
  */
7
12
 
8
13
  export function getOpenCodeCommands(slug, _serverUrl) {
@@ -10,6 +15,17 @@ export function getOpenCodeCommands(slug, _serverUrl) {
10
15
 
11
16
  const openCodeHeader = () => `> **project_slug for every call:** \`${slug}\`\n\n---\n\n\n`;
12
17
 
18
+ /**
19
+ * Standard pointer tail for OpenCode commands. Tells the agent to load the
20
+ * corresponding skill (the single source of truth for the workflow) via the
21
+ * `skill` tool and follow it. No workflow detail is duplicated here.
22
+ */
23
+ const pointerTail = (skillName) => `
24
+ ## Step 1 — Load the skill
25
+ Invoke the \`${skillName}\` skill (OpenCode loads it from \`.opencode/skills/${skillName}/SKILL.md\` via the \`skill\` tool).
26
+ The skill contains the complete workflow — MCP calls, templates, examples, edge cases. Follow it verbatim and do not duplicate its steps here.
27
+ `;
28
+
13
29
  return [
14
30
  // ── /opsr:propose ──────────────────────────────────────────────────────────
15
31
  {
@@ -22,115 +38,7 @@ After this command, /opsr:spec and /opsr:design become available.
22
38
 
23
39
  ## Input
24
40
  $ARGUMENTS = change name (kebab-case) or plain description. If plain description, derive a kebab-case name.
25
-
26
- ## Step 1 — Derive change name
27
- If $ARGUMENTS is a plain description (contains spaces), convert to kebab-case.
28
- Example: "add user authentication" → "add-user-authentication"
29
-
30
- ## Step 2 — Search for existing work (avoid duplication)
31
- Call MCP tool:
32
- \`search_semantic(query="$ARGUMENTS", project_slug="${slug}", limit=5)\`
33
- If relevant artifacts are found, show them and ask the user to confirm this is new work.
34
-
35
- ## Step 3 — Write the proposal content
36
- Compose the following structure (do NOT skip any section):
37
-
38
- \`\`\`markdown
39
- # <change-name>
40
-
41
- ## Why
42
- [1-2 sentences on the problem or opportunity being addressed]
43
-
44
- ## What Changes
45
- - [Specific change 1]
46
- - [Specific change 2]
47
- - **BREAKING** [Breaking change if any]
48
-
49
- ## Capabilities
50
- ### New Capabilities
51
- - [capability-name] — brief description
52
-
53
- ### Modified Capabilities
54
- - [existing-capability] — what changes
55
-
56
- ## Impact
57
- [Affected code, APIs, dependencies, systems]
58
- \`\`\`
59
-
60
- ## Step 4 — Save proposal to database
61
- Call MCP tool:
62
- \`create_artifact(name="<change-name>-proposal", type="proposal", content="<full proposal markdown>", metadata={"change_name": "<change-name>", "status_phase": "planning"}, project_slug="${slug}")\`
63
- Note the returned artifact ID.
64
-
65
- ## Step 5 — Create spec drafts for each capability
66
- Parse the "## Capabilities" section. For each capability listed in "New Capabilities" or "Modified Capabilities":
67
- 1. Check if a spec for this capability already exists:
68
- \`read_artifact(name="<change-name>-<capability-name>-spec", project_slug="${slug}")\`
69
- If it exists and is not empty, skip creating a draft.
70
-
71
- 2. If no spec exists, create a draft spec:
72
- \`create_artifact(name="<change-name>-<capability-name>-spec", type="spec", status="draft", content="# <capability-name> Specification
73
-
74
- [TODO: Define purpose, requirements, and scenarios for this capability]
75
-
76
- ## Purpose
77
- [TODO: Describe what this capability enables]
78
-
79
- ## Requirements
80
- [TODO: List requirements with REQ-NNN format]
81
-
82
- ### Requirement: <REQ-001>
83
- [TODO: Describe requirement using SHALL/MUST language]
84
-
85
- #### Scenario: <Name>
86
- - **WHEN** [condition]
87
- - **THEN** [expected outcome]", metadata={"change_name": "<change-name>", "capability": "<capability-name>", "is_delta": true}, project_slug="${slug}")\`
88
-
89
- ## Step 6 — Create design skeleton
90
- Create a draft design document:
91
- \`create_artifact(name="<change-name>-design", type="design", status="draft", content="# Design: <change-name>
92
-
93
- [TODO: Document technical decisions, architecture, trade-offs]
94
-
95
- ## Context
96
- [TODO: Background and constraints]
97
-
98
- ## Goals / Non-Goals
99
- **Goals:**
100
- - [Goal 1]
101
-
102
- **Non-Goals:**
103
- - [Non-goal 1]
104
-
105
- ## Decisions
106
- ### Decision: <Title>
107
- **Chosen:** [What was chosen]
108
- **Alternatives:**
109
- - [Alternative 1] — rejected because [reason]
110
-
111
- ## Architecture
112
- [TODO: Components and data flow]
113
-
114
- ## Risks / Trade-offs
115
- | Risk | Mitigation |
116
- |------|------------|
117
- | [Risk] | [Mitigation] |
118
-
119
- ## Open Questions
120
- - [ ] [Question]
121
- ", metadata={"change_name": "<change-name>"}, project_slug="${slug}")\`
122
-
123
- ## Step 7 — Record the action
124
- Call MCP tool:
125
- \`record_trace(action="propose", result_summary="Created proposal: <change-name>-proposal", project_slug="${slug}")\`
126
-
127
- ## Step 8 — Show what is now available
128
- Tell the user:
129
- - "Proposal saved with full scaffolding. The following commands are now available:"
130
- - \`/opsr:spec <change-name>\` — formalize requirements (draft specs already created for each capability)
131
- - \`/opsr:design <change-name>\` — document technical approach (draft design already created)
132
- - Or run \`/opsr:flow <change-name>\` to continue the full flow automatically.
133
- `,
41
+ ${pointerTail("opensddrag-propose")}`,
134
42
  },
135
43
 
136
44
  // ── /opsr:spec ─────────────────────────────────────────────────────────────
@@ -144,94 +52,7 @@ Specs use SHALL/MUST language and must have Scenarios with WHEN/THEN format.
144
52
 
145
53
  ## Input
146
54
  $ARGUMENTS = change name. If not provided, list proposals and ask.
147
-
148
- ## Step 1 — Read the proposal from the database
149
- Call MCP tool:
150
- \`list_artifacts(type="proposal", project_slug="${slug}")\`
151
- Then read the selected proposal:
152
- \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
153
-
154
- ## Step 2 — Identify capabilities from the proposal
155
- Parse the "## Capabilities" section. Each capability in "New Capabilities" and "Modified Capabilities" needs a spec.
156
-
157
- **New capability** → create a full spec (Purpose + Requirements + Scenarios)
158
- **Modified capability** → check if a main spec exists first:
159
- \`search_semantic(query="<capability-name> spec", project_slug="${slug}", limit=3)\`
160
- If main spec exists → create a DELTA spec with ADDED/MODIFIED/REMOVED/RENAMED sections.
161
- If no main spec → create BOTH:
162
- 1. The main spec with metadata={"capability": "<capability-name>", "is_delta": false}
163
- 2. The delta spec with metadata={"change_name": "<change-name>", "capability": "<capability-name>", "is_delta": true}
164
-
165
- ## Step 3 — Write spec content for EACH capability
166
-
167
- ### Full spec structure (new capabilities):
168
- \`\`\`markdown
169
- # <capability-name> Specification
170
-
171
- ## Purpose
172
- [High-level description of this capability]
173
-
174
- ## Requirements
175
-
176
- ### Requirement: <REQ-001 Name>
177
- [Description using SHALL/MUST language]
178
-
179
- #### Scenario: <Happy path name>
180
- - **WHEN** [condition]
181
- - **THEN** [expected outcome]
182
-
183
- #### Scenario: <Edge case name>
184
- - **WHEN** [edge condition]
185
- - **THEN** [expected outcome]
186
-
187
- ### Requirement: <REQ-002 Name>
188
- [Description]
189
-
190
- #### Scenario: <Name>
191
- - **WHEN** [condition]
192
- - **THEN** [outcome]
193
- \`\`\`
194
-
195
- ### Delta spec structure (modified capabilities):
196
- \`\`\`markdown
197
- # <capability-name> Specification — Delta
198
-
199
- ## ADDED Requirements
200
- ### Requirement: <New requirement name>
201
- [Full requirement with scenarios]
202
-
203
- ## MODIFIED Requirements
204
- ### Requirement: <Existing requirement name>
205
- [Updated requirement — include FULL updated text with all scenarios]
206
-
207
- ## REMOVED Requirements
208
- ### Requirement: <Removed requirement name>
209
- **Reason:** [Why this is being removed]
210
- **Migration:** [How consumers should migrate]
211
-
212
- ## RENAMED Requirements
213
- - FROM: \`### Requirement: Old Name\`
214
- - TO: \`### Requirement: New Name\`
215
- \`\`\`
216
-
217
- ## Step 4 — Save each spec to the database
218
- For each capability spec:
219
- \`create_artifact(name="<change-name>-<capability-name>-spec", type="spec", content="<full spec markdown>", metadata={"change_name": "<change-name>", "capability": "<capability-name>", "is_delta": true/false}, project_slug="${slug}")\`
220
-
221
- ## Step 5 — Link each spec to the proposal
222
- \`link_artifacts(source_name="<spec-name>", target_name="<change-name>-proposal", relationship_type="implements", project_slug="${slug}")\`
223
-
224
- ## Step 6 — Validate each spec
225
- \`validate_artifact(name="<spec-name>", project_slug="${slug}")\`
226
- Fix any validation errors before continuing.
227
-
228
- ## Step 7 — Record the action
229
- \`record_trace(action="spec", result_summary="Created specs for: <capability-list>", project_slug="${slug}")\`
230
-
231
- ## Step 8 — Show what is now available
232
- - "Specs saved. You can now run:"
233
- - \`/opsr:design <change-name>\` — document technical decisions
234
- `,
55
+ ${pointerTail("opensddrag-spec")}`,
235
56
  },
236
57
 
237
58
  // ── /opsr:design ───────────────────────────────────────────────────────────
@@ -244,67 +65,7 @@ The design must be based on the proposal and spec artifacts already in the datab
244
65
 
245
66
  ## Input
246
67
  $ARGUMENTS = change name.
247
-
248
- ## Step 1 — Read proposal and all specs from the database
249
- \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
250
- \`list_artifacts(type="spec", project_slug="${slug}")\`
251
- Read each spec linked to this change:
252
- \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
253
-
254
- ## Step 2 — Search for related prior designs
255
- \`search_semantic(query="<change topic> design decisions", project_slug="${slug}", limit=3)\`
256
- Use findings as context — don't duplicate prior work.
257
-
258
- ## Step 3 — Write the design content
259
- \`\`\`markdown
260
- # Design: <change-name>
261
-
262
- ## Context
263
- [Background, current state, constraints that shaped this design]
264
-
265
- ## Goals / Non-Goals
266
- **Goals:**
267
- - [What this design achieves]
268
-
269
- **Non-Goals:**
270
- - [What this design deliberately does NOT address]
271
-
272
- ## Decisions
273
-
274
- ### Decision: <Title>
275
- **Chosen:** [What was chosen and why]
276
- **Alternatives considered:**
277
- - [Alternative 1] — rejected because [reason]
278
- - [Alternative 2] — rejected because [reason]
279
-
280
- ### Decision: <Title>
281
- ...
282
-
283
- ## Architecture
284
- [Components, data flow, integration points — use ASCII diagrams if helpful]
285
-
286
- ## Risks / Trade-offs
287
- | Risk | Mitigation |
288
- |------|------------|
289
- | [Risk] | [Mitigation] |
290
-
291
- ## Migration Plan
292
- [Deployment steps, backward compatibility, rollback plan]
293
-
294
- ## Open Questions
295
- - [ ] [Question that still needs resolution]
296
- \`\`\`
297
-
298
- ## Step 4 — Save design to database
299
- \`create_artifact(name="<change-name>-design", type="design", content="<full design markdown>", metadata={"change_name": "<change-name>"}, project_slug="${slug}")\`
300
-
301
- ## Step 5 — Link design to proposal
302
- \`link_artifacts(source_name="<change-name>-design", target_name="<change-name>-proposal", relationship_type="depends_on", project_slug="${slug}")\`
303
-
304
- ## Step 6 — Record and show next steps
305
- \`record_trace(action="design", result_summary="Created design: <change-name>-design", project_slug="${slug}")\`
306
- Tell the user: "Design saved. Run \`/opsr:tasks <change-name>\` to decompose into tasks."
307
- `,
68
+ ${pointerTail("opensddrag-design")}`,
308
69
  },
309
70
 
310
71
  // ── /opsr:tasks ────────────────────────────────────────────────────────────
@@ -318,36 +79,7 @@ Tasks depend on BOTH specs AND design being in the database.
318
79
 
319
80
  ## Input
320
81
  $ARGUMENTS = change name.
321
-
322
- ## Step 1 — Read all planning artifacts from the database
323
- \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
324
- \`read_artifact(name="<change-name>-design", project_slug="${slug}")\`
325
- Get all specs for this change:
326
- \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
327
- Read each linked spec artifact.
328
-
329
- ## Step 2 — Plan task groups from the design and specs
330
- Group tasks by logical phase. Each task must have:
331
- - A clear **Goal** (what it accomplishes)
332
- - **Acceptance criteria** referencing spec REQ-NNN items (not vague)
333
- - **Dependencies** on other tasks (if any)
334
- - Estimated effort: < 4 hours
335
-
336
- ## Step 3 — Create each task artifact in the database
337
- For each task (name as \`<change-name>-task-<group>-<N>\`):
338
- \`create_artifact(name="<change-name>-task-<group>-<N>", type="task", content="## Goal\\n<what this task accomplishes>\\n\\n## Acceptance Criteria\\n- [ ] REQ-NNN: <criterion>\\n- [ ] <criterion>\\n\\n## Dependencies\\n- <other task name or 'none'>", metadata={"change_name": "<change-name>", "group": "<group-name>", "order": <N>}, project_slug="${slug}")\`
339
-
340
- ## Step 4 — Link each task to its spec(s)
341
- \`link_artifacts(source_name="<task-name>", target_name="<spec-name>", relationship_type="implements", project_slug="${slug}")\`
342
-
343
- ## Step 5 — Update working context with the task list
344
- \`update_working_context(context={"change_name": "<change-name>", "tasks": ["<task-1>", "<task-2>", "..."], "current_task": null}, project_slug="${slug}")\`
345
-
346
- ## Step 6 — Record and show next steps
347
- \`record_trace(action="tasks", result_summary="Created <N> tasks for <change-name>", project_slug="${slug}")\`
348
- Show the full task list with names and goals.
349
- Tell the user: "Tasks saved. Run \`/opsr:apply <change-name>\` to start implementing."
350
- `,
82
+ ${pointerTail("opensddrag-tasks")}`,
351
83
  },
352
84
 
353
85
  // ── /opsr:apply ────────────────────────────────────────────────────────────
@@ -360,52 +92,7 @@ Read ALL planning artifacts (proposal, specs, design) as context before implemen
360
92
 
361
93
  ## Input
362
94
  $ARGUMENTS = change name, or specific task name.
363
-
364
- ## Step 1 — Load full planning context from the database
365
- \`get_working_context(project_slug="${slug}")\`
366
- \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
367
- \`read_artifact(name="<change-name>-design", project_slug="${slug}")\`
368
- Get and read all specs linked to this change.
369
-
370
- ## Step 2 — List pending tasks in order
371
- \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
372
- AND
373
- \`list_artifacts(type="task", status="active", project_slug="${slug}")\`
374
- Combine both results. Prioritize tasks with status="active" (resuming interrupted session), then status="draft" in dependency order. Filter tasks for this change using metadata.change_name.
375
-
376
- ## Step 3 — Select next task
377
- If $ARGUMENTS specifies a task name, use it.
378
- Otherwise:
379
- 1. First, check for tasks with status="active" (resuming interrupted session)
380
- 2. If no active tasks, pick the first draft task whose dependencies are all archived (done)
381
-
382
- Read the task:
383
- \`read_artifact(name="<task-name>", project_slug="${slug}")\`
384
-
385
- ## Step 4 — Mark task as active in database
386
- \`update_artifact(name="<task-name>", status="active", project_slug="${slug}")\`
387
- Update working context:
388
- \`update_working_context(context={"current_task": "<task-name>"}, project_slug="${slug}")\`
389
-
390
- ## Step 5 — Implement the task
391
- Implement the code changes required by the task.
392
- The implementation MUST satisfy all acceptance criteria from the task's "## Acceptance Criteria" section.
393
- Pause and ask the user if any requirement is unclear — do not guess.
394
-
395
- ## Step 6 — Validate against spec requirements
396
- For each acceptance criterion (REQ-NNN) in the task:
397
- - Confirm the implementation satisfies the requirement
398
- - Verify no spec scenarios are broken
399
-
400
- ## Step 7 — Mark task as done in database
401
- \`update_artifact(name="<task-name>", status="archived", project_slug="${slug}")\`
402
-
403
- ## Step 8 — Record and check remaining tasks
404
- \`record_trace(action="apply_task", result_summary="Completed task: <task-name>", artifact_id="<artifact-id>", project_slug="${slug}")\`
405
- \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
406
- - If tasks remain: "Task complete. Run \`/opsr:apply <change-name>\` for the next task."
407
- - If all done: "All tasks complete. Run \`/opsr:verify <change-name>\` to validate, then \`/opsr:archive <change-name>\`."
408
- `,
95
+ ${pointerTail("opensddrag-apply")}`,
409
96
  },
410
97
 
411
98
  // ── /opsr:verify ────────────────────────────────────────────────────────────
@@ -419,63 +106,7 @@ Does NOT modify any artifacts — read-only operation.
419
106
 
420
107
  ## Input
421
108
  $ARGUMENTS = change name.
422
-
423
- ## Step 1 — Load all artifacts from the database
424
- \`read_artifact(name="<change-name>-proposal", project_slug="${slug}")\`
425
- \`read_artifact(name="<change-name>-design", project_slug="${slug}")\`
426
- Get all specs and tasks for this change:
427
- \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
428
- Read each linked spec and task artifact.
429
-
430
- ## Step 2 — Verify COMPLETENESS
431
- Check task completion:
432
- \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
433
- - If pending tasks exist → **CRITICAL: Tasks not complete**
434
-
435
- Extract all requirements (REQ-NNN) from specs.
436
- For each requirement, search the codebase for implementation evidence.
437
- - If requirement has no implementation evidence → **CRITICAL: Requirement not implemented**
438
-
439
- ## Step 3 — Verify CORRECTNESS
440
- For each spec scenario (WHEN/THEN blocks):
441
- - Search the codebase for test coverage or implementation of the scenario condition
442
- - If scenario has no coverage → **WARNING: Scenario not covered**
443
-
444
- ## Step 4 — Verify COHERENCE
445
- Extract decisions from the "## Decisions" section of the design.
446
- For each decision:
447
- - Check if the implementation follows the chosen approach
448
- - If implementation deviates from a decision → **SUGGESTION: Possible deviation from design**
449
-
450
- ## Step 5 — Generate report
451
- Output a structured report:
452
-
453
- \`\`\`
454
- ## Verification Report: <change-name>
455
-
456
- ### Summary
457
- | Dimension | Status |
458
- |--------------|--------|
459
- | Completeness | ✓/✗ |
460
- | Correctness | ✓/✗ |
461
- | Coherence | ✓/✗ |
462
-
463
- ### CRITICAL Issues
464
- - [Issue description]
465
-
466
- ### WARNING Issues
467
- - [Issue description]
468
-
469
- ### SUGGESTIONS
470
- - [Issue description]
471
-
472
- ### Assessment
473
- [READY TO ARCHIVE | ISSUES MUST BE FIXED BEFORE ARCHIVING]
474
- \`\`\`
475
-
476
- ## Step 6 — Record the verification
477
- \`record_trace(action="verify", result_summary="Verification: <PASS/FAIL> — <N> critical, <N> warnings", project_slug="${slug}")\`
478
- `,
109
+ ${pointerTail("opensddrag-verify")}`,
479
110
  },
480
111
 
481
112
  // ── /opsr:sync ──────────────────────────────────────────────────────────────
@@ -489,52 +120,7 @@ After sync, the main spec reflects all changes. This is called automatically dur
489
120
 
490
121
  ## Input
491
122
  $ARGUMENTS = change name.
492
-
493
- ## Step 1 — Find delta specs for this change
494
- \`list_artifacts(type="spec", project_slug="${slug}")\`
495
- Filter specs where metadata.change_name = "<change-name>" AND metadata.is_delta = true.
496
-
497
- ## Step 2 — For each delta spec, find the main spec
498
- Search for the main (non-delta) spec for the same capability:
499
- \`search_semantic(query="<capability-name> spec", project_slug="${slug}", limit=5)\`
500
- Find the spec where metadata.is_delta = false (or not set) for the same capability.
501
-
502
- ## Step 3 — Apply delta operations to the main spec
503
- Read both delta and main spec:
504
- \`read_artifact(name="<delta-spec-name>", project_slug="${slug}")\`
505
- \`read_artifact(name="<main-spec-name>", project_slug="${slug}")\`
506
-
507
- Apply each section from the delta:
508
-
509
- **## ADDED Requirements:**
510
- - Find or confirm the requirement does NOT exist in main spec
511
- - Append the new requirement (with all scenarios) to the main spec
512
-
513
- **## MODIFIED Requirements:**
514
- - Find the requirement in main spec by name
515
- - Apply ONLY the changed parts (add new scenarios, update descriptions)
516
- - Do NOT wholesale replace — apply partial updates intelligently
517
-
518
- **## REMOVED Requirements:**
519
- - Find the requirement in main spec by name
520
- - Remove the entire requirement block
521
- - The Reason and Migration from delta should be noted in a comment
522
-
523
- **## RENAMED Requirements:**
524
- - Find FROM name in main spec
525
- - Change the heading to TO name
526
-
527
- ## Step 4 — Save the updated main spec to database
528
- \`update_artifact(name="<main-spec-name>", content="<merged spec content>", project_slug="${slug}")\`
529
-
530
- ## Step 5 — Mark delta spec as archived
531
- After merging the delta, mark the delta spec as archived:
532
- \`update_artifact(name="<delta-spec-name>", status="archived", metadata={"synced_at": "<ISO timestamp>", "merged_into": "<main-spec-name>"}, project_slug="${slug}")\`
533
-
534
- ## Step 6 — Record the sync
535
- \`record_trace(action="sync", result_summary="Synced delta for capability: <capability> into main spec", project_slug="${slug}")\`
536
- Tell the user which capabilities were updated.
537
- `,
123
+ ${pointerTail("opensddrag-sync")}`,
538
124
  },
539
125
 
540
126
  // ── /opsr:archive ───────────────────────────────────────────────────────────
@@ -547,42 +133,7 @@ Runs verification checks, syncs delta specs to main specs, then archives everyth
547
133
 
548
134
  ## Input
549
135
  $ARGUMENTS = change name. If not provided, list active changes and ask.
550
-
551
- ## Step 1 — Get full status of the change
552
- \`list_artifacts(type="proposal", project_slug="${slug}")\`
553
- Select the change to archive (or use $ARGUMENTS).
554
- \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
555
- Get all linked artifacts (specs, design, tasks).
556
-
557
- ## Step 2 — Validate artifact completion
558
- Check each artifact status:
559
- \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
560
- If pending tasks exist → warn the user and ask for confirmation to archive anyway.
561
-
562
- ## Step 3 — Validate task completion
563
- Count draft vs archived tasks. If any draft tasks remain → warn and confirm.
564
-
565
- ## Step 4 — Check for delta specs that need syncing
566
- \`list_artifacts(type="spec", project_slug="${slug}")\`
567
- Filter for specs where metadata.change_name = "<change-name>" AND metadata.is_delta = true.
568
-
569
- If delta specs exist:
570
- - Show which capabilities have deltas
571
- - Ask: "Sync delta specs to main specs now? (recommended)"
572
- - If yes → execute /opsr:sync logic for each delta spec
573
- - If no → archive without syncing
574
-
575
- ## Step 5 — Archive all change artifacts
576
- For each artifact in this change (proposal, all specs, design, all tasks):
577
- \`update_artifact(name="<artifact-name>", status="archived", metadata={"archived_at": "<ISO timestamp>", "change_name": "<change-name>"}, project_slug="${slug}")\`
578
-
579
- ## Step 6 — Record and show summary
580
- \`record_trace(action="archive", result_summary="Archived change: <change-name> (<N> artifacts)", project_slug="${slug}")\`
581
- Show summary:
582
- - Artifacts archived: list
583
- - Specs synced: list (if any)
584
- - "Change <change-name> is complete."
585
- `,
136
+ ${pointerTail("opensddrag-archive")}`,
586
137
  },
587
138
 
588
139
  // ── /opsr:explore ───────────────────────────────────────────────────────────
@@ -596,41 +147,7 @@ You may create OpenSddRag artifacts to capture insights, but NEVER write applica
596
147
 
597
148
  ## Input
598
149
  $ARGUMENTS = topic, question, or idea to explore.
599
-
600
- ## Stance
601
- You are in THINKING MODE. Your role is to:
602
- - Ask clarifying questions
603
- - Surface multiple options with trade-offs
604
- - Investigate the codebase (read-only)
605
- - Create ASCII diagrams to illustrate ideas
606
- - Challenge assumptions
607
- - Reference existing specs for context
608
-
609
- You MUST NOT:
610
- - Write application code
611
- - Create implementation files
612
- - Make changes to the codebase
613
-
614
- ## Step 1 — Check for existing related work
615
- \`search_semantic(query="$ARGUMENTS", project_slug="${slug}", limit=5)\`
616
- \`recall_episodes(query="$ARGUMENTS", project_slug="${slug}", limit=3)\`
617
- Share any existing specs or past decisions that are relevant.
618
-
619
- ## Step 2 — Investigate and think
620
- - Read relevant codebase files (read-only)
621
- - Identify constraints and dependencies
622
- - Surface at least 2 different approaches
623
- - For each approach, list trade-offs
624
-
625
- ## Step 3 — Capture insights (if user asks)
626
- If the user wants to capture a finding or decision, create an artifact:
627
- \`create_artifact(name="explore-<topic>-<date>", type="proposal", content="<exploration notes, options, trade-offs>", metadata={"explore": true}, project_slug="${slug}")\`
628
-
629
- ## Step 4 — Transition when ready
630
- When the user has enough insight to decide:
631
- - Summarize key findings and recommendation
632
- - Ask: "Ready to create a formal proposal? Run \`/opsr:propose <name>\`"
633
- `,
150
+ ${pointerTail("opensddrag-explore")}`,
634
151
  },
635
152
 
636
153
  // ── /opsr:continue ─────────────────────────────────────────────────────────
@@ -644,34 +161,7 @@ Dependency order: proposal → specs → design → tasks.
644
161
 
645
162
  ## Input
646
163
  $ARGUMENTS = change name.
647
-
648
- ## Step 1 — Get current status from database
649
- \`list_artifacts(type="proposal", project_slug="${slug}")\`
650
- Identify the change to continue.
651
- \`get_relationships(name="<change-name>-proposal", project_slug="${slug}")\`
652
- Get all existing artifacts for this change.
653
-
654
- ## Step 2 — Find the next artifact to create
655
- Check which artifacts exist and which are missing, in dependency order:
656
- 1. proposal → if missing, stop (must run /opsr:propose first)
657
- 2. specs → if any capability has no spec → create ONE spec and stop
658
- 3. design → if missing and all specs exist → create design and stop
659
- 4. tasks → if missing and design exists → create tasks and stop
660
-
661
- If all artifacts exist → tell the user "All planning artifacts complete. Run /opsr:apply."
662
-
663
- ## Step 3 — Create the NEXT artifact only
664
- Follow the logic from the corresponding command:
665
- - For spec: follow /opsr:spec steps for ONE capability
666
- - For design: follow /opsr:design steps
667
- - For tasks: follow /opsr:tasks steps
668
-
669
- ## Step 4 — Show progress
670
- After creating the artifact:
671
- - Show what was created
672
- - Show what is now unlocked (next in dependency chain)
673
- - Suggest: "Run \`/opsr:continue <change-name>\` to create the next artifact."
674
- `,
164
+ ${pointerTail("opensddrag-continue")}`,
675
165
  },
676
166
 
677
167
  // ── /opsr:status ────────────────────────────────────────────────────────────
@@ -684,41 +174,7 @@ Reads from the MCP server — no local files involved.
684
174
 
685
175
  ## Input
686
176
  $ARGUMENTS = optional change name to show details for one change. If not provided, show all.
687
-
688
- ## Step 1 — Load working context
689
- \`get_working_context(project_slug="${slug}")\`
690
-
691
- ## Step 2 — List all artifacts by type and status
692
- \`list_artifacts(type="proposal", status="draft", project_slug="${slug}")\`
693
- \`list_artifacts(type="proposal", status="active", project_slug="${slug}")\`
694
- \`list_artifacts(type="spec", status="draft", project_slug="${slug}")\`
695
- \`list_artifacts(type="design", status="draft", project_slug="${slug}")\`
696
- \`list_artifacts(type="task", status="draft", project_slug="${slug}")\`
697
- \`list_artifacts(type="task", status="active", project_slug="${slug}")\`
698
-
699
- ## Step 3 — Recall recent activity
700
- \`recall_episodes(query="recent actions in this project", project_slug="${slug}", limit=5)\`
701
-
702
- ## Step 4 — Present structured status
703
-
704
- For each active change, show:
705
- \`\`\`
706
- ## Change: <change-name>
707
- | Artifact | Status |
708
- |----------|--------|
709
- | Proposal | ✓ done |
710
- | Specs | ✓ 2/2 |
711
- | Design | ✓ done |
712
- | Tasks | 3/5 done |
713
-
714
- Current task: <task-name>
715
- Next step: /opsr:apply <change-name>
716
- \`\`\`
717
-
718
- Then show:
719
- - Recent activity (last 5 actions from episodic memory)
720
- - Suggested next command based on current state
721
- `,
177
+ ${pointerTail("opensddrag-status")}`,
722
178
  },
723
179
 
724
180
  // ── /opsr:flow ──────────────────────────────────────────────────────────────
@@ -727,51 +183,11 @@ Then show:
727
183
  name: "flow",
728
184
  content: `${fm("Run the complete SDD flow end-to-end")}${openCodeHeader()}## Purpose
729
185
  Run the complete SDD flow end-to-end in a single session.
730
- ALL artifacts are saved to the database via MCP tools no local files.
186
+ ALL planning artifacts are saved to the database via MCP tools; implementation code is written locally.
731
187
 
732
188
  ## Input
733
189
  $ARGUMENTS = feature description or change name.
734
-
735
- ## PHASE 1 — Propose
736
- Follow /opsr:propose steps:
737
- 1. \`search_semantic(query="$ARGUMENTS", project_slug="${slug}")\` — check for duplicates
738
- 2. Compose proposal content (Why / What Changes / Capabilities / Impact)
739
- 3. \`create_artifact(name="<change-name>-proposal", type="proposal", content="...", project_slug="${slug}")\`
740
-
741
- ## PHASE 2 — Spec
742
- Follow /opsr:spec steps for each capability in the proposal:
743
- 4. For each capability: compose spec (Purpose / Requirements with SHALL / Scenarios with WHEN-THEN)
744
- 5. \`create_artifact(name="<change-name>-<capability>-spec", type="spec", content="...", project_slug="${slug}")\`
745
- 6. \`link_artifacts(source_name="<spec>", target_name="<proposal>", relationship_type="implements", project_slug="${slug}")\`
746
- 7. \`validate_artifact(name="<spec>", project_slug="${slug}")\` — fix errors before continuing
747
-
748
- ## PHASE 3 — Design
749
- Follow /opsr:design steps:
750
- 8. Read all specs just created
751
- 9. Compose design (Context / Goals / Decisions / Architecture / Risks / Migration)
752
- 10. \`create_artifact(name="<change-name>-design", type="design", content="...", project_slug="${slug}")\`
753
- 11. \`link_artifacts(source_name="<design>", target_name="<proposal>", relationship_type="depends_on", project_slug="${slug}")\`
754
-
755
- ## PHASE 4 — Tasks
756
- Follow /opsr:tasks steps:
757
- 12. Read proposal, all specs, and design from database
758
- 13. For each task: \`create_artifact(name="<change-name>-task-<N>", type="task", content="...", project_slug="${slug}")\`
759
- 14. \`link_artifacts(source_name="<task>", target_name="<spec>", relationship_type="implements", project_slug="${slug}")\`
760
-
761
- ## PHASE 5 — Apply (repeat for each task in order)
762
- Follow /opsr:apply steps:
763
- 15. Read ALL planning artifacts as context (proposal + specs + design)
764
- 16. \`update_artifact(name="<task>", status="active", project_slug="${slug}")\`
765
- 17. Implement the task against its acceptance criteria
766
- 18. \`update_artifact(name="<task>", status="archived", project_slug="${slug}")\`
767
- 19. \`record_trace(action="apply_task", result_summary="Completed: <task>", project_slug="${slug}")\`
768
-
769
- ## PHASE 6 — Archive
770
- Follow /opsr:archive steps:
771
- 20. Sync delta specs if any
772
- 21. \`update_artifact(name="<all artifacts>", status="archived", project_slug="${slug}")\`
773
- 22. \`record_trace(action="complete_flow", result_summary="Completed: $ARGUMENTS", project_slug="${slug}")\`
774
- `,
190
+ ${pointerTail("opensddrag-flow")}`,
775
191
  },
776
192
 
777
193
  // ── /opsr:search ────────────────────────────────────────────────────────────
@@ -784,23 +200,7 @@ Use this BEFORE starting any new work to find existing specs, decisions, and pas
784
200
 
785
201
  ## Input
786
202
  $ARGUMENTS = natural language search query.
787
-
788
- ## Step 1 — Search this project
789
- \`search_semantic(query="$ARGUMENTS", project_slug="${slug}", limit=5)\`
790
-
791
- ## Step 2 — If no relevant results, search all projects
792
- \`search_semantic(query="$ARGUMENTS", project_slug="*", limit=5)\`
793
-
794
- ## Step 3 — Recall past actions related to the query
795
- \`recall_episodes(query="$ARGUMENTS", project_slug="${slug}", limit=3)\`
796
-
797
- ## Step 4 — Present results clearly
798
- For each result: name, type, status, and a content excerpt (first 200 chars).
799
- Group by: this project / other projects / past actions.
800
-
801
- ## Step 5 — Offer to read the full artifact
802
- \`read_artifact(name="<artifact-name>", project_slug="${slug}")\`
803
- `,
203
+ ${pointerTail("opensddrag-search")}`,
804
204
  },
805
205
 
806
206
  // ── /opsr:harness ───────────────────────────────────────────────────────────
@@ -809,118 +209,11 @@ Group by: this project / other projects / past actions.
809
209
  name: "harness",
810
210
  content: `${fm("Manage persistent project rules (add, list, disable)")}${openCodeHeader()}## Purpose
811
211
  Manage project harness rules: add new rules, list existing rules, and disable rules that are no longer needed.
812
- Harness rules are persistent behavioral constraints injected into every agent session via \`get_working_context\` (for \`trigger="always"\` rules) and surfaced as phase-gate checklists via \`get_harness_checklist\`.
212
+ Harness rules are persistent behavioral constraints injected into every agent session and surfaced as phase-gate checklists at spec/apply/verify/archive.
813
213
 
814
214
  ## Input
815
- $ARGUMENTS = one of:
816
- - \`add\` — followed by rule fields or a natural-language description
817
- - \`list\` — show all rules for this project
818
- - \`disable <rule-name>\` — soft-delete a rule by name
819
-
820
- If $ARGUMENTS is empty, show the current rules list and ask what the user wants to do.
821
-
822
- ## Supported rule fields
823
-
824
- | Field | Values |
825
- |-------|--------|
826
- | \`name\` | kebab-case slug, unique per project |
827
- | \`trigger\` | \`always\` (every session) / \`on_apply\` / \`on_verify\` / \`on_archive\` / \`on_spec\` |
828
- | \`category\` | \`architecture\` / \`naming\` / \`forbidden\` / \`doc-sync\` / \`verification\` |
829
- | \`severity\` | \`error\` (MUST satisfy) / \`warning\` (SHOULD satisfy) / \`info\` (advisory) |
830
- | \`instruction\` | free-text rule the agent must follow |
831
- | \`metadata\` | optional JSON |
832
- | \`enabled\` | \`true\` (default) / \`false\` (soft-delete) |
833
-
834
- ## Step 1 — Parse the operation
835
-
836
- If $ARGUMENTS starts with \`add\`:
837
- → Go to **Step 2A — Add**
838
-
839
- If $ARGUMENTS starts with \`list\`:
840
- → Go to **Step 2B — List**
841
-
842
- If $ARGUMENTS starts with \`disable <name>\`:
843
- → Go to **Step 2C — Disable**
844
-
845
- If $ARGUMENTS is empty:
846
- → Call \`list_rules(project_slug="${slug}")\` and show the current state. Ask the user what they want to do.
847
-
848
- ## Step 2A — Add a rule
849
-
850
- If the user provided explicit fields after \`add\`, use them as-is.
851
-
852
- Otherwise, ask the user for each field. **You can infer sensible defaults from natural language:**
853
- - "always update CHANGELOG when applying" → trigger=\`on_apply\`, category=\`doc-sync\`, severity=\`warning\`
854
- - "never do X" → trigger=\`always\`, category=\`forbidden\`, severity=\`error\`
855
- - "use Y pattern" → trigger=\`always\`, category=\`architecture\`, severity=\`warning\`
856
-
857
- **Show the inferred values and ask for confirmation** before calling \`add_rule\`.
858
-
859
- Then call:
860
- \`\`\`
861
- add_rule(
862
- name: "<kebab-case>",
863
- trigger: "<always|on_apply|on_verify|on_archive|on_spec>",
864
- category: "<architecture|naming|forbidden|doc-sync|verification>",
865
- severity: "<error|warning|info>",
866
- instruction: "<text>",
867
- project_slug:"${slug}",
868
- enabled: true
869
- )
870
- \`\`\`
871
-
872
- Confirm to the user:
873
- "Rule '<name>' added. It will [be injected into every working context | be checked during /opsr:<trigger> when the phase completes]."
874
-
875
- Then record:
876
- \`record_trace(action="add_rule", result_summary="Added harness rule: <name>", project_slug="${slug}")\`
877
-
878
- ## Step 2B — List rules
879
-
880
- Call:
881
- \`list_rules(project_slug="${slug}", enabled_only=true)\`
882
-
883
- Present the results **grouped by trigger**, in this order:
884
-
885
- \`\`\`
886
- ### Always (loaded at session start)
887
- - [<category>:<severity>] <name> — <instruction (max 80 chars)>
888
-
889
- ### On Apply (checked during /opsr:apply)
890
- - ...
891
-
892
- ### On Verify (checked during /opsr:verify)
893
- - ...
894
-
895
- ### On Archive (checked during /opsr:archive)
896
- - ...
897
-
898
- ### On Spec (checked during /opsr:spec)
899
- - ...
900
- \`\`\`
901
-
902
- If the result list is empty, respond:
903
- "No harness rules defined for this project. Run \`/opsr:harness add\` to create the first rule."
904
-
905
- ## Step 2C — Disable a rule
906
-
907
- Extract the rule name from $ARGUMENTS (the token after \`disable\`).
908
-
909
- Call:
910
- \`add_rule(name: "<name>", enabled: false, project_slug: "${slug}")\`
911
-
912
- Confirm:
913
- "Rule '<name>' disabled. It will no longer appear in checklists or session context. Re-add with the same name to re-enable."
914
-
915
- Then record:
916
- \`record_trace(action="disable_rule", result_summary="Disabled harness rule: <name>", project_slug="${slug}")\`
917
-
918
- ## Notes
919
-
920
- - The same \`add_rule\` MCP call is used for create, update, and soft-delete — it is idempotent on \`(project_id, name)\`.
921
- - Disabled rules are preserved in the database and can be re-enabled by calling \`add_rule\` with the same \`name\` and \`enabled=true\`.
922
- - Rules are project-scoped — they never leak across projects.
923
- `,
215
+ $ARGUMENTS = one of: \`add\` (followed by rule fields or a natural-language description), \`list\` (show all rules), or \`disable <rule-name>\` (soft-delete by name). If empty, show the current rules list and ask.
216
+ ${pointerTail("opensddrag-harness")}`,
924
217
  },
925
218
  ];
926
- }
219
+ }