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