@tudeorangbiasa/sdd-multiagent-opencode 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,25 +22,41 @@ Explore the codebase to discover existing patterns, reusable components, technic
22
22
 
23
23
  ## Tools
24
24
 
25
- - **codebase-memory-mcp**: Use `search_graph` for function/class discovery, `trace_path` for call chains, `get_code_snippet` for reading source, `query_graph` for complex patterns. Prefer these over grep/glob.
25
+ - **codebase-memory-mcp**: Mandatory first-line toolset for project code. You MUST use it before grep/glob/read. Use `search_graph` for function/class discovery, `get_architecture` for structure, `trace_path` for call chains, `get_code_snippet` for source, and `query_graph` for complex patterns.
26
26
  - **exa_web_search_exa**: For external pattern research and documentation lookup.
27
27
  - **webfetch**: For reading specific URLs found during research.
28
28
 
29
+ If codebase-memory-mcp is unavailable, say so in `MCP Status`, then fall back to grep/glob/read. Do not silently skip MCP.
30
+
29
31
  ## Strategy
30
32
 
31
- ### Phase 1: Breadth-First Discovery
32
- 1. Use `search_graph` with natural language queries for similar functionality
33
- 2. Identify relevant directories and modules via `get_architecture`
34
- 3. Map dependency graph via `query_graph` for affected areas
33
+ ### MCP-First Investigation Loop
34
+
35
+ Repeat this loop until evidence saturates, with a minimum of 2 passes and a maximum of 5 passes:
36
+
37
+ 1. **Query** — run 2-4 codebase-memory searches (`search_graph`, `get_architecture`, or `query_graph`) from different terms/angles.
38
+ 2. **Trace** — use `trace_path` for key functions/classes/routes found in Query.
39
+ 3. **Read** — use `get_code_snippet` for the exact symbols that explain behavior.
40
+ 4. **Refine** — derive new search terms from real names discovered in snippets.
41
+ 5. **Stop Check** — stop only when the last pass finds no new relevant symbols, files, routes, constraints, risks, or search terms.
42
+
43
+ Fallback grep/glob/read is allowed only after MCP miss/unavailable, and must cite why MCP was insufficient. If MCP is unavailable, stop after one fallback pass unless user explicitly asks for deeper exploration.
44
+
45
+ ### Interactive Planning Gate
46
+
47
+ If the MCP loop reveals unclear scope, contradictory evidence, multiple plausible change boundaries, or missing domain terms, stop exploration and ask bounded questions before making a recommendation or updating artifacts. Ask at most 3 questions. Each question must include your recommended answer.
35
48
 
36
- ### Phase 2: Depth Investigation
37
- 1. Use `get_code_snippet` to read key files from Phase 1
38
- 2. Understand interfaces and contracts
39
- 3. Document patterns and conventions
49
+ Default `/sdd-explore` is read-only: return a chat report or write a temporary report outside the repo only. Do not create or update `proposal.md`, `spec.md`, `design.md`, `tasks.md`, `progress.md`, or `verification.md` by default.
40
50
 
41
- ### Phase 3: External Context
42
- 1. Check related documentation via `exa_web_search_exa`
43
- 2. Review existing specs in `specs/`
51
+ Artifact writes are allowed if and only if both conditions are true:
52
+ 1. The request provides an existing Change ID.
53
+ 2. After interactive planning, the user explicitly says to `update artifacts`.
54
+
55
+ If allowed to update artifacts, write only exploration findings and open questions. Do not write implementation tasks.
56
+
57
+ ### External Context
58
+
59
+ Use `exa_web_search_exa` only when external facts, libraries, or current docs matter. Review existing specs in `specs/` when request touches active SDD work.
44
60
 
45
61
  ## Output Format
46
62
 
@@ -50,6 +66,11 @@ Explore the codebase to discover existing patterns, reusable components, technic
50
66
  ### Relevant Existing Code
51
67
  - [file path]: [what it does, why relevant]
52
68
 
69
+ ### MCP Status
70
+ - codebase-memory-mcp: used|unavailable|insufficient
71
+ - passes: [number]
72
+ - fallback tools: [none|grep/glob/read with reason]
73
+
53
74
  ### Patterns Discovered
54
75
  - [pattern]: [where used, how it works]
55
76
 
@@ -64,11 +85,25 @@ Explore the codebase to discover existing patterns, reusable components, technic
64
85
 
65
86
  ### Open Questions
66
87
  [Questions needing human input]
88
+
89
+ ### Interactive Planning
90
+ - asked: yes|no
91
+ - questions: [bounded questions asked, if any]
92
+ - recommended answers: [your recommended answers]
93
+
94
+ ### Artifact Writes
95
+ - allowed: yes|no
96
+ - reason: [read-only by default|Change ID + explicit update artifacts]
97
+ - files changed: [none|paths]
67
98
  ```
68
99
 
69
100
  ## Key Behaviors
70
101
 
71
102
  - Run multiple parallel searches for coverage
103
+ - Loop until evidence saturates; do not stop after one search pass
104
+ - Always report MCP usage or explicit fallback reason
105
+ - Ask bounded planning questions when scope is unclear; do not guess
106
+ - Treat artifact writes as opt-in only; read-only is the default
72
107
  - Focus on understanding, not implementation
73
108
  - Flag uncertainties rather than guessing
74
109
  - Use the question tool if critical information is missing
@@ -29,7 +29,16 @@ Execute approved SDD changes by following `tasks.md` in order and tracking progr
29
29
  5. **Use codebase-memory-mcp** — prefer `search_graph` and `get_code_snippet` over grep to understand existing patterns before implementing
30
30
 
31
31
  ### After Completion
32
- Spawn `sdd-verifier` as a child subagent to validate the implementation before reporting done.
32
+ Spawn `sdd-verifier` as a child subagent to validate the implementation before reporting done. Treat verifier output as incomplete unless it includes `verified:` or `unverified:` plus exact commands/evidence.
33
+
34
+ ### Child Subagent Liveness Check
35
+
36
+ If a spawned verifier returns no output, vague output, missing status labels, or no verification evidence:
37
+
38
+ 1. Mark current task `[BLOCKED: verifier stalled or incomplete evidence]` in `tasks.md` or `progress.md`.
39
+ 2. Run the most targeted verification command yourself if safe.
40
+ 3. Retry verifier once with a smaller scope.
41
+ 4. If still incomplete, report `unverified:` with exact missing evidence. Do not claim done.
33
42
 
34
43
  ## Blocker Handling
35
44
 
@@ -39,7 +48,7 @@ Spawn `sdd-verifier` as a child subagent to validate the implementation before r
39
48
  - Needs: [what's required to unblock]
40
49
  ```
41
50
 
42
- Use the question tool for ambiguous requirements or missing information.
51
+ Do not use the question tool for ambiguous requirements during `/sdd-apply`. Mark the task blocked, state the exact missing artifact detail, and recommend `/sdd-explore` or `/sdd-propose` to resolve it.
43
52
 
44
53
  ## Output Format
45
54
 
@@ -69,3 +78,4 @@ Use the question tool for ambiguous requirements or missing information.
69
78
  - Preserve existing patterns in the codebase
70
79
  - Surface blockers early rather than getting stuck
71
80
  - Spawn `sdd-verifier` after completing implementation
81
+ - Verify child subagent completion evidence before reporting success
@@ -37,6 +37,25 @@ Coordinate multiple SDD subagents when one change is too large for a single line
37
37
  4. Collect results and reconcile conflicts.
38
38
  5. Update the change artifacts with status, blockers, and verification evidence.
39
39
 
40
+ ## Subagent Liveness Contract
41
+
42
+ Before spawning a subagent, write down expected outputs: task id, touched files, required status label, required verification command or evidence, and timeout/checkpoint expectation.
43
+
44
+ Treat a subagent as stuck or failed when any of these happen:
45
+
46
+ - No final response or tool activity is visible when the parent regains control.
47
+ - Final response lacks `changed:`, `verified:`, `unverified:`, or `blocked:` label.
48
+ - Claimed completion has no file paths, artifact updates, test output, or verifier evidence.
49
+ - Expected `tasks.md`/`progress.md` checkpoint was not updated.
50
+ - Verification command was skipped without `unverified:` reason.
51
+
52
+ Recovery:
53
+
54
+ 1. Mark the task `[BLOCKED: subagent stalled or returned incomplete evidence]` in `tasks.md` or `progress.md`.
55
+ 2. Run one focused read-only verification pass yourself.
56
+ 3. Retry once with a smaller task payload, or switch to sequential execution.
57
+ 4. Report `blocked:` if retry still lacks evidence.
58
+
40
59
  ## Output
41
60
 
42
61
  Return a concise coordination summary with completed work, blocked work, file conflicts, and recommended next action.
@@ -21,9 +21,11 @@ Transform a focused change request into reviewable SDD artifacts with requiremen
21
21
  ### 1. Understand the Specification
22
22
  - Read existing `proposal.md`, `spec.md`, `design.md`, or exploration findings when present
23
23
  - Identify functional/non-functional requirements and acceptance criteria
24
+ - If scope is ambiguous, ask at most 3 bounded questions before writing artifacts. Each question must include your recommended answer.
24
25
 
25
26
  ### 2. Analyze Context
26
27
  - Review exploration findings from `sdd-explorer` or `/sdd-explore`
28
+ - Treat `/sdd-explore` findings as advisory unless the user explicitly approved `update artifacts` for a Change ID
27
29
  - Use `codebase-memory-mcp` to understand existing architecture constraints via `get_architecture` and `query_graph`
28
30
  - Understand integration points
29
31
 
@@ -22,7 +22,8 @@ Review code for spec compliance, security vulnerabilities, performance bottlenec
22
22
 
23
23
  ### 1. Context
24
24
  - Read `spec.md` for requirements, `plan.md` for intended approach
25
- - Identify files changed in implementation
25
+ - Run `git diff --stat` and `git diff` to identify files changed in implementation
26
+ - Confirm every changed file belongs to the intended scope from `tasks.md` and `design.md`
26
27
 
27
28
  ### 2. Security Review
28
29
  Check: input validation, auth/authz, secrets exposure, injection/XSS/CSRF, secure data handling.
@@ -36,6 +37,9 @@ Check: naming conventions, error handling, duplication, complex functions, test
36
37
  ### 5. Spec Compliance
37
38
  For each requirement: is it implemented, does it meet acceptance criteria, are edge cases handled?
38
39
 
40
+ ### 6. Diff Scope
41
+ Compare the diff against the accepted artifacts. Report any unrelated file, broad rewrite, missing test, weakened assertion, or changed behavior outside scope before writing `verification.md`.
42
+
39
43
  ## Report Format
40
44
 
41
45
  ```markdown
@@ -58,6 +62,9 @@ For each requirement: is it implemented, does it meet acceptance criteria, are e
58
62
  ### Spec Compliance
59
63
  | Requirement | Status | Notes |
60
64
 
65
+ ### Diff Scope
66
+ | File | In Scope? | Evidence |
67
+
61
68
  ### Positive Observations
62
69
  - [good patterns noticed]
63
70
 
@@ -68,6 +75,7 @@ For each requirement: is it implemented, does it meet acceptance criteria, are e
68
75
  ## Key Behaviors
69
76
 
70
77
  - Review objectively without personal preference bias
78
+ - Use `git diff` as mandatory evidence before final readiness decision
71
79
  - Provide specific, actionable feedback with line references
72
80
  - Acknowledge good patterns, not just problems
73
81
  - Prioritize issues by impact
@@ -19,6 +19,7 @@ Verify that claimed work actually works: implementation exists, tests pass, spec
19
19
 
20
20
  - **chrome-devtools**: Use `chrome-devtools_navigate_page`, `chrome-devtools_take_screenshot`, `chrome-devtools_take_snapshot`, `chrome-devtools_list_console_messages` for visual/UI verification.
21
21
  - **codebase-memory-mcp**: Use `search_graph`, `trace_path`, `get_code_snippet` for structural code verification.
22
+ - **git diff**: Mandatory scope check. Run `git diff --stat` and `git diff` before finalizing verification.
22
23
  - **exa_web_search_exa**: For validating external API patterns or library usage.
23
24
 
24
25
  ## Protocol
@@ -30,6 +31,7 @@ Verify that claimed work actually works: implementation exists, tests pass, spec
30
31
  ### 2. Verify Implementation
31
32
  For each claimed completion:
32
33
  - **File existence** — do expected files exist?
34
+ - **Scope diff** — inspect `git diff --stat` and `git diff`; confirm changed files match `tasks.md` and `design.md`
33
35
  - **Code review** — use `codebase-memory-mcp` to verify code structure
34
36
  - **Integration** — is it properly connected?
35
37
  - **Error handling** — are edge cases covered?
@@ -50,6 +52,9 @@ For UI features:
50
52
  ### 5. Compare to Spec
51
53
  For each acceptance criterion, find implementing code and verify it meets the criterion.
52
54
 
55
+ ### 6. Stop Conditions
56
+ Stop verification and report `FAIL` or `PARTIAL` when `git diff` shows unrelated files, tests fail, Test Spec rows are missing, assertions are weakened, mocks differ from the Mock Requirement, or evidence is insufficient.
57
+
53
58
  ## Report Format
54
59
 
55
60
  ```markdown
@@ -63,6 +68,10 @@ For each acceptance criterion, find implementing code and verify it meets the cr
63
68
  ### Verified Items
64
69
  | Task | Status | Evidence |
65
70
 
71
+ ### Diff Scope
72
+ - `git diff --stat`: [summary]
73
+ - Unintended changes: yes|no
74
+
66
75
  ### Spec Compliance
67
76
  | Requirement | Status | Notes |
68
77
 
@@ -83,6 +92,7 @@ For each acceptance criterion, find implementing code and verify it meets the cr
83
92
  ## Key Behaviors
84
93
 
85
94
  - Be skeptical — don't accept claims at face value
95
+ - Always inspect `git diff` before final verdict
86
96
  - Test everything that can be tested
87
97
  - Check edge cases, not just happy paths
88
98
  - Report honestly even if news is bad
@@ -15,7 +15,7 @@ Implement an existing change from `specs/active/<change-id>/`.
15
15
 
16
16
  - `specs/active/<change-id>/tasks.md` must exist.
17
17
  - Read `proposal.md`, `spec.md`, `design.md`, `tasks.md`, and `progress.md` if present before editing.
18
- - If artifacts are missing or contradictory, stop and ask for clarification.
18
+ - If artifacts are missing or contradictory, stop with `blocked:` and state the exact artifact fix needed. Do not ask interactive clarification during `/sdd-apply`.
19
19
 
20
20
  ## Rules
21
21
 
@@ -27,6 +27,7 @@ Implement an existing change from `specs/active/<change-id>/`.
27
27
  - If implementation reveals a design issue, update the relevant artifact and explain the deviation.
28
28
  - Verify with the commands listed in `design.md` when available.
29
29
  - Stop on blockers. Do not silently skip tasks.
30
+ - Remain execution-only. Do not ask planning questions; unresolved ambiguity becomes `blocked:` with a concrete next `/sdd-explore` or `/sdd-propose` recommendation.
30
31
 
31
32
  ## Test Integrity
32
33
 
@@ -51,6 +52,9 @@ Parallelize only when it is safe:
51
52
  - Never run parallel tasks that edit shared config, package files, schemas, generated files, migrations, or the same directory boundary unless the design explicitly marks it safe.
52
53
  - Spawn at most 3 implementer subagents per batch.
53
54
  - Each subagent must receive only its task, relevant artifact paths, expected files, and verification command.
55
+ - Each subagent must return a completion contract: `changed:` or `blocked:`, plus `verified:` or `unverified:`, touched files, artifact updates, and exact test/verifier evidence.
56
+ - After each subagent returns, verify it did not stall: check output labels, touched files, `tasks.md`/`progress.md` checkpoint, and verification evidence before starting the next batch.
57
+ - If a subagent returns no output, vague output, missing labels, no artifact update, or no verification evidence, mark it `[BLOCKED: subagent stalled or incomplete evidence]`, retry once with a smaller payload, then continue sequentially or stop with `blocked:`.
54
58
  - Reconcile results before starting the next batch.
55
59
 
56
60
  If parallel execution is possible, ask once:
@@ -17,7 +17,13 @@ Explore the request safely before committing to a change.
17
17
  - Do not edit source code.
18
18
  - Do not implement fixes.
19
19
  - Do not create a change unless the user explicitly asks.
20
- - Use codebase search first for project-specific questions.
20
+ - Default mode is read-only: return a chat report or a temporary report outside the repo. Do not update SDD artifacts by default.
21
+ - Artifact writes are allowed if and only if a Change ID is provided and, after interactive planning, the user explicitly says to `update artifacts`.
22
+ - Use codebase-memory-mcp first for project-specific questions; fallback to grep/glob/read only if MCP is unavailable or insufficient, and report why.
23
+ - Run MCP investigation as a loop: query → trace → read snippets → refine terms → stop only when a pass finds no new relevant evidence.
24
+ - If the MCP loop exposes unclear scope, contradictory evidence, multiple plausible change boundaries, or missing domain terms, stop and ask at most 3 bounded questions before recommending a plan.
25
+ - Each bounded question must include your recommended answer.
26
+ - If artifact writes are allowed, write only exploration findings and open questions. Do not write implementation tasks.
21
27
  - Use web research only when external facts, libraries, or current docs matter.
22
28
  - If an explicit first token is a slug, treat it as the optional change id. Otherwise derive a short slug only for recommendations.
23
29
  - For project-specific exploration, cite real files, functions, routes, commands, or config paths.
@@ -52,11 +58,24 @@ Return a concise investigation report:
52
58
 
53
59
  [Recommended next step and why]
54
60
 
61
+ ## Interactive Planning
62
+
63
+ - asked: yes|no
64
+ - questions: [bounded questions asked, if any]
65
+ - recommended answers: [your recommended answers]
66
+
55
67
  ## Evidence
56
68
 
69
+ - MCP Status: used|unavailable|insufficient; passes: [number]; fallback: [none|reason]
57
70
  - `[path]`: [what was verified]
58
71
  - [source URL] - reliability: high|medium|low
59
72
 
73
+ ## Artifact Writes
74
+
75
+ - allowed: yes|no
76
+ - reason: [read-only by default|Change ID + explicit update artifacts]
77
+ - files changed: [none|paths]
78
+
60
79
  ## Next Command
61
80
 
62
81
  Run `/sdd-propose <change-id> "<focused change>"` when ready.
@@ -27,6 +27,7 @@ Create a compact, reviewable change plan. Stop before implementation.
27
27
  - Do not write implementation code.
28
28
  - Do not modify application source files.
29
29
  - Ask at most 3 clarifying questions only if the request is too ambiguous to plan safely.
30
+ - Each clarifying question must be bounded and include your recommended answer.
30
31
 
31
32
  ## Sizing
32
33
 
@@ -16,6 +16,7 @@ Verify a completed change before considering it ready.
16
16
 
17
17
  - Read `specs/active/<change-id>/proposal.md`, `spec.md`, `design.md`, and `tasks.md`.
18
18
  - Inspect the implementation against the artifacts.
19
+ - Run `git diff --stat` and `git diff` before writing `verification.md`; use the diff to prove changed files match intended scope.
19
20
  - Run or recommend the project's relevant test, lint, typecheck, build, or browser verification commands.
20
21
  - Create or update `specs/active/<change-id>/verification.md`.
21
22
  - Do not make product code changes unless the user explicitly asks for fixes.
@@ -36,6 +37,7 @@ Perform a strict audit comparing the "Test Spec" tables in `tasks.md` against th
36
37
  - Tasks completed or intentionally deferred
37
38
  - Bugs, regressions, security risks, and missing tests
38
39
  - Verification evidence
40
+ - Diff scope: no unrelated files, broad rewrites, weakened assertions, or hidden side effects
39
41
  - Release readiness
40
42
 
41
43
  ## Finalize Behavior
@@ -51,6 +53,7 @@ When the request includes `finalize`, `complete`, or `archive`:
51
53
  ## Evidence Requirements
52
54
 
53
55
  - Every finding must include a file path, command output, browser evidence, or explicit `assumption:` label.
56
+ - `verification.md` must include `git diff --stat`, test command results, and any unrelated-change finding.
54
57
  - If no findings are found, state `No findings` and list residual risks.
55
58
  - Do not mark ready unless verification evidence exists.
56
59
 
@@ -67,6 +70,7 @@ Findings first, ordered by severity:
67
70
 
68
71
  ## Verification
69
72
 
73
+ - diff: `git diff --stat` [passed|failed] - [scope notes]
70
74
  - passed: `[command]`
71
75
  - failed: `[command]` - [reason]
72
76
  - not run: `[command]` - [reason]
@@ -0,0 +1,21 @@
1
+ import nodeFs from "node:fs";
2
+
3
+ export function checkExploreReadonlyContract({ content }) {
4
+ const hasReadOnly = content.includes("read-only");
5
+ const hasArtifactGate = content.includes("update artifacts");
6
+
7
+ if (hasReadOnly && hasArtifactGate) {
8
+ return { status: "pass", detail: "Read-only contract and update artifacts gate present" };
9
+ }
10
+
11
+ if (hasReadOnly && !hasArtifactGate) {
12
+ return { status: "warn", detail: "Read-only contract present but missing update artifacts gate (see ADR-0001)" };
13
+ }
14
+
15
+ return { status: "fail", detail: "Missing read-only-by-default language in explore command" };
16
+ }
17
+
18
+ export function checkExploreCommandFile(filePath, { fs = nodeFs } = {}) {
19
+ const content = fs.readFileSync(filePath, "utf-8");
20
+ return checkExploreReadonlyContract({ content });
21
+ }
@@ -0,0 +1,82 @@
1
+ import nodeFs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ const SYMLINK_TARGETS = [
5
+ { dir: "commands", prefix: "sdd-" },
6
+ { dir: "agents", prefix: "sdd-" },
7
+ { dir: "rules", prefix: null },
8
+ ];
9
+
10
+ const MIGRATION_MARKER = ".sdd-migrated-v030";
11
+
12
+ function isOwnedTarget(linkTarget) {
13
+ return linkTarget.includes("sdd-multiagent-opencode") || linkTarget.includes("opencode-agent-rules");
14
+ }
15
+
16
+ export function migrateOldSymlinks({ configDir, now = () => new Date().toISOString(), fs = nodeFs }) {
17
+ const removed = [];
18
+ const ignored = [];
19
+ const errors = [];
20
+
21
+ if (fs.existsSync(path.join(configDir, MIGRATION_MARKER))) {
22
+ return {
23
+ skipped: true,
24
+ removed,
25
+ ignored,
26
+ errors: [],
27
+ markerWritten: false,
28
+ };
29
+ }
30
+
31
+ for (const { dir, prefix } of SYMLINK_TARGETS) {
32
+ const dirPath = path.join(configDir, dir);
33
+ if (!fs.existsSync(dirPath)) continue;
34
+
35
+ for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
36
+ const relativePath = path.join(dir, entry.name);
37
+
38
+ if (prefix && !entry.name.startsWith(prefix)) {
39
+ ignored.push(relativePath);
40
+ continue;
41
+ }
42
+
43
+ const fullPath = path.join(dirPath, entry.name);
44
+ try {
45
+ const stat = fs.lstatSync(fullPath);
46
+ if (!stat.isSymbolicLink()) {
47
+ ignored.push(relativePath);
48
+ continue;
49
+ }
50
+
51
+ const linkTarget = fs.readlinkSync(fullPath);
52
+ if (!isOwnedTarget(linkTarget)) {
53
+ ignored.push(relativePath);
54
+ continue;
55
+ }
56
+
57
+ fs.unlinkSync(fullPath);
58
+ removed.push(relativePath);
59
+ } catch (err) {
60
+ errors.push({ path: relativePath, reason: err.message });
61
+ }
62
+ }
63
+ }
64
+
65
+ let markerWritten = false;
66
+ if (removed.length > 0) {
67
+ try {
68
+ fs.writeFileSync(path.join(configDir, MIGRATION_MARKER), now());
69
+ markerWritten = true;
70
+ } catch (err) {
71
+ errors.push({ path: MIGRATION_MARKER, reason: err.message });
72
+ }
73
+ }
74
+
75
+ return {
76
+ skipped: false,
77
+ removed,
78
+ ignored,
79
+ errors,
80
+ markerWritten,
81
+ };
82
+ }
@@ -16,7 +16,7 @@ const DEFAULT_PLUGIN_CONFIG = {
16
16
  "sdd-explorer": { model: "opencode/deepseek-v4-flash-free" },
17
17
  "sdd-implementer": { model: "opencode/deepseek-v4-flash-free" },
18
18
  "sdd-verifier": { model: "opencode/qwen3.6-plus-free" },
19
- "sdd-reviewer": { model: "opencode/minimax-m2.5-free" },
19
+ "sdd-reviewer": { model: "opencode/qwen3.6-plus-free" },
20
20
  "sdd-quick": { model: "opencode/qwen3.6-plus-free" },
21
21
  },
22
22
  reasoning: {
@@ -88,10 +88,7 @@ export default async () => {
88
88
 
89
89
  for (const [agentName, agentConfig] of Object.entries(pluginConfig.agent ?? {})) {
90
90
  if (!agentConfig?.model) continue;
91
-
92
- if (!cfg.agent[agentName]) {
93
- cfg.agent[agentName] = {};
94
- }
91
+ if (!cfg.agent[agentName]) continue;
95
92
 
96
93
  cfg.agent[agentName].model = agentConfig.model;
97
94
  }
@@ -1,8 +1,8 @@
1
- import fs from "node:fs";
2
1
  import path from "node:path";
3
2
  import { fileURLToPath } from "node:url";
4
3
  import sddAutoReasoning from "./sdd-auto-reasoning.js";
5
4
  import sddModelRouter from "./sdd-model-router.js";
5
+ import { migrateOldSymlinks } from "./sdd-migration-symlinks.js";
6
6
 
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = path.dirname(__filename);
@@ -16,64 +16,25 @@ const globalConfigDir = path.join(
16
16
 
17
17
  // ─── Auto-Migration: Remove old symlinks from v0.2.x ────────────────────────
18
18
 
19
- function removeOldSymlinks() {
20
- const MIGRATION_MARKER = ".sdd-migrated-v030";
21
- const markerPath = path.join(globalConfigDir, MIGRATION_MARKER);
22
-
23
- if (fs.existsSync(markerPath)) return;
24
-
25
- const symlinkTargets = [
26
- { dir: "commands", prefix: "sdd-" },
27
- { dir: "agents", prefix: "sdd-" },
28
- { dir: "rules", prefix: null },
29
- ];
30
-
31
- let migrated = false;
32
-
33
- for (const { dir, prefix } of symlinkTargets) {
34
- const dirPath = path.join(globalConfigDir, dir);
35
- if (!fs.existsSync(dirPath)) continue;
36
-
37
- try {
38
- const entries = fs.readdirSync(dirPath, { withFileTypes: true });
39
- for (const entry of entries) {
40
- const fullPath = path.join(dirPath, entry.name);
41
- try {
42
- const stat = fs.lstatSync(fullPath);
43
- if (!stat.isSymbolicLink()) continue;
44
-
45
- if (prefix && !entry.name.startsWith(prefix)) continue;
46
-
47
- const linkTarget = fs.readlinkSync(fullPath);
48
- if (linkTarget.includes("sdd-multiagent-opencode") || linkTarget.includes("opencode-agent-rules")) {
49
- fs.unlinkSync(fullPath);
50
- migrated = true;
51
- }
52
- } catch {
53
- // skip
54
- }
55
- }
56
- } catch {
57
- // skip
58
- }
59
- }
60
-
61
- if (migrated) {
62
- try {
63
- fs.writeFileSync(markerPath, new Date().toISOString());
64
- } catch {
65
- // skip
66
- }
19
+ export function runSilentMigration(configDir = globalConfigDir) {
20
+ try {
21
+ migrateOldSymlinks({ configDir });
22
+ } catch {
23
+ // Plugin boot must stay silent and non-fatal.
67
24
  }
68
25
  }
69
26
 
70
- removeOldSymlinks();
27
+ if (process.env.SDD_REGISTER_SKIP_AUTO_MIGRATION !== "1") {
28
+ runSilentMigration();
29
+ }
71
30
 
72
31
  // ─── Agent Definitions (inlined to avoid sync I/O at boot) ───────────────────
73
32
 
74
33
  const AGENTS = {
75
34
  "sdd-orchestrator": {
35
+ description: "Internal coordination agent for complex SDD changes. Used by SDD commands when work needs multi-agent scheduling.",
76
36
  mode: "subagent",
37
+ hidden: true,
77
38
  temperature: 0.3,
78
39
  permission: {
79
40
  edit: "allow",
@@ -109,13 +70,32 @@ Coordinate multiple SDD subagents when one change is too large for a single line
109
70
  4. Collect results and reconcile conflicts.
110
71
  5. Update the change artifacts with status, blockers, and verification evidence.
111
72
 
73
+ ## Subagent Liveness Contract
74
+
75
+ Before spawning a subagent, write down expected outputs: task id, touched files, required status label, required verification command or evidence, and timeout/checkpoint expectation.
76
+
77
+ Treat a subagent as stuck or failed when any of these happen:
78
+ - No final response or tool activity is visible when the parent regains control.
79
+ - Final response lacks changed:, verified:, unverified:, or blocked: label.
80
+ - Claimed completion has no file paths, artifact updates, test output, or verifier evidence.
81
+ - Expected tasks.md/progress.md checkpoint was not updated.
82
+ - Verification command was skipped without unverified: reason.
83
+
84
+ Recovery:
85
+ 1. Mark the task [BLOCKED: subagent stalled or returned incomplete evidence] in tasks.md or progress.md.
86
+ 2. Run one focused read-only verification pass yourself.
87
+ 3. Retry once with a smaller task payload, or switch to sequential execution.
88
+ 4. Report blocked: if retry still lacks evidence.
89
+
112
90
  ## Output
113
91
 
114
92
  Return a concise coordination summary with completed work, blocked work, file conflicts, and recommended next action.`,
115
93
  },
116
94
 
117
95
  "sdd-planner": {
96
+ description: "Creates compact SDD proposal, spec, design, and task artifacts for /sdd-propose and /sdd-construct.",
118
97
  mode: "subagent",
98
+ hidden: true,
119
99
  temperature: 0.3,
120
100
  permission: {
121
101
  edit: "allow",
@@ -136,9 +116,11 @@ Transform a focused change request into reviewable SDD artifacts with requiremen
136
116
  ### 1. Understand the Specification
137
117
  - Read existing proposal.md, spec.md, design.md, or exploration findings when present
138
118
  - Identify functional/non-functional requirements and acceptance criteria
119
+ - If scope is ambiguous, ask at most 3 bounded questions before writing artifacts. Each question must include your recommended answer.
139
120
 
140
121
  ### 2. Analyze Context
141
122
  - Review exploration findings from sdd-explorer or /sdd-explore
123
+ - Treat /sdd-explore findings as advisory unless the user explicitly approved update artifacts for a Change ID
142
124
  - Use codebase-memory-mcp to understand existing architecture constraints via get_architecture and query_graph
143
125
  - Understand integration points
144
126
 
@@ -173,7 +155,9 @@ For heavy apps (monorepo, microservices, multi-team): Include optional sections:
173
155
  },
174
156
 
175
157
  "sdd-explorer": {
158
+ description: "Readonly codebase exploration for /sdd-explore and uncertain SDD planning requests.",
176
159
  mode: "subagent",
160
+ hidden: true,
177
161
  temperature: 0.1,
178
162
  permission: {
179
163
  edit: "deny",
@@ -195,46 +179,70 @@ Explore the codebase to discover existing patterns, reusable components, technic
195
179
 
196
180
  ## Tools
197
181
 
198
- - codebase-memory-mcp: Use search_graph for function/class discovery, trace_path for call chains, get_code_snippet for reading source, query_graph for complex patterns. Prefer these over grep/glob.
182
+ - codebase-memory-mcp: Mandatory first-line toolset for project code. You MUST use it before grep/glob/read. Use search_graph for function/class discovery, get_architecture for structure, trace_path for call chains, get_code_snippet for source, and query_graph for complex patterns.
199
183
  - exa_web_search_exa: For external pattern research and documentation lookup.
200
184
  - webfetch: For reading specific URLs found during research.
201
185
 
186
+ If codebase-memory-mcp is unavailable, say so in MCP Status, then fall back to grep/glob/read. Do not silently skip MCP.
187
+
202
188
  ## Strategy
203
189
 
204
- ### Phase 1: Breadth-First Discovery
205
- 1. Use search_graph with natural language queries for similar functionality
206
- 2. Identify relevant directories and modules via get_architecture
207
- 3. Map dependency graph via query_graph for affected areas
190
+ ### MCP-First Investigation Loop
191
+
192
+ Repeat this loop until evidence saturates, with a minimum of 2 passes and a maximum of 5 passes:
193
+ 1. Query run 2-4 codebase-memory searches (search_graph, get_architecture, or query_graph) from different terms/angles.
194
+ 2. Trace — use trace_path for key functions/classes/routes found in Query.
195
+ 3. Read — use get_code_snippet for the exact symbols that explain behavior.
196
+ 4. Refine — derive new search terms from real names discovered in snippets.
197
+ 5. Stop Check — stop only when the last pass finds no new relevant symbols, files, routes, constraints, risks, or search terms.
198
+
199
+ Fallback grep/glob/read is allowed only after MCP miss/unavailable, and must cite why MCP was insufficient. If MCP is unavailable, stop after one fallback pass unless user explicitly asks for deeper exploration.
200
+
201
+ ### Interactive Planning Gate
208
202
 
209
- ### Phase 2: Depth Investigation
210
- 1. Use get_code_snippet to read key files from Phase 1
211
- 2. Understand interfaces and contracts
212
- 3. Document patterns and conventions
203
+ If the MCP loop reveals unclear scope, contradictory evidence, multiple plausible change boundaries, or missing domain terms, stop exploration and ask bounded questions before making a recommendation or updating artifacts. Ask at most 3 questions. Each question must include your recommended answer.
213
204
 
214
- ### Phase 3: External Context
215
- 1. Check related documentation via exa_web_search_exa
216
- 2. Review existing specs in specs/
205
+ Default /sdd-explore is read-only: return a chat report or write a temporary report outside the repo only. Do not create or update proposal.md, spec.md, design.md, tasks.md, progress.md, or verification.md by default.
206
+
207
+ Artifact writes are allowed if and only if both conditions are true:
208
+ 1. The request provides an existing Change ID.
209
+ 2. After interactive planning, the user explicitly says to update artifacts.
210
+
211
+ If allowed to update artifacts, write only exploration findings and open questions. Do not write implementation tasks.
212
+
213
+ ### External Context
214
+
215
+ Use exa_web_search_exa only when external facts, libraries, or current docs matter. Review existing specs in specs/ when request touches active SDD work.
217
216
 
218
217
  ## Output Format
219
218
 
220
219
  Return findings as:
221
220
  - Relevant Existing Code: [file path]: [what it does, why relevant]
221
+ - MCP Status: codebase-memory-mcp used|unavailable|insufficient; passes: [number]; fallback tools: [none|grep/glob/read with reason]
222
222
  - Patterns Discovered: [pattern]: [where used, how it works]
223
223
  - Reusable Components: [component]: [how to leverage]
224
224
  - Technical Constraints: [constraint]: [impact on approach]
225
225
  - Recommended Approach: [Technical direction based on findings]
226
226
  - Open Questions: [Questions needing human input]
227
+ - Interactive Planning: asked yes|no; questions; recommended answers
228
+ - Artifact Writes: allowed yes|no; reason; files changed
227
229
 
228
230
  ## Key Behaviors
229
231
 
230
232
  - Run multiple parallel searches for coverage
233
+ - Loop until evidence saturates; do not stop after one search pass
234
+ - Always report MCP usage or explicit fallback reason
235
+ - Ask bounded planning questions when scope is unclear; do not guess
236
+ - Treat artifact writes as opt-in only; read-only is the default
231
237
  - Focus on understanding, not implementation
232
238
  - Flag uncertainties rather than guessing
233
239
  - Use the question tool if critical information is missing`,
234
240
  },
235
241
 
236
242
  "sdd-implementer": {
243
+ description: "Systematic implementation agent for approved /sdd-apply changes and /sdd-quick edits.",
237
244
  mode: "subagent",
245
+ hidden: true,
238
246
  temperature: 0.3,
239
247
  permission: {
240
248
  edit: "allow",
@@ -263,7 +271,15 @@ Execute approved SDD changes by following tasks.md in order and tracking progres
263
271
  5. Use codebase-memory-mcp — prefer search_graph and get_code_snippet over grep to understand existing patterns before implementing
264
272
 
265
273
  ### After Completion
266
- Spawn sdd-verifier as a child subagent to validate the implementation before reporting done.
274
+ Spawn sdd-verifier as a child subagent to validate the implementation before reporting done. Treat verifier output as incomplete unless it includes verified: or unverified: plus exact commands/evidence.
275
+
276
+ ### Child Subagent Liveness Check
277
+
278
+ If a spawned verifier returns no output, vague output, missing status labels, or no verification evidence:
279
+ 1. Mark current task [BLOCKED: verifier stalled or incomplete evidence] in tasks.md or progress.md.
280
+ 2. Run the most targeted verification command yourself if safe.
281
+ 3. Retry verifier once with a smaller scope.
282
+ 4. If still incomplete, report unverified: with exact missing evidence. Do not claim done.
267
283
 
268
284
  ## Blocker Handling
269
285
 
@@ -271,7 +287,7 @@ Spawn sdd-verifier as a child subagent to validate the implementation before rep
271
287
  - Attempted: [what you tried]
272
288
  - Needs: [what's required to unblock]
273
289
 
274
- Use the question tool for ambiguous requirements or missing information.
290
+ Do not use the question tool for ambiguous requirements during /sdd-apply. Mark the task blocked, state the exact missing artifact detail, and recommend /sdd-explore or /sdd-propose to resolve it.
275
291
 
276
292
  ## Key Behaviors
277
293
 
@@ -279,11 +295,14 @@ Use the question tool for ambiguous requirements or missing information.
279
295
  - Always update tasks.md checkboxes immediately
280
296
  - Preserve existing patterns in the codebase
281
297
  - Surface blockers early rather than getting stuck
282
- - Spawn sdd-verifier after completing implementation`,
298
+ - Spawn sdd-verifier after completing implementation
299
+ - Verify child subagent completion evidence before reporting success`,
283
300
  },
284
301
 
285
302
  "sdd-verifier": {
303
+ description: "Independent SDD validation agent for implementation completeness, tests, and UI/browser checks.",
286
304
  mode: "subagent",
305
+ hidden: true,
287
306
  temperature: 0.1,
288
307
  permission: {
289
308
  edit: "deny",
@@ -301,6 +320,7 @@ Verify that claimed work actually works: implementation exists, tests pass, spec
301
320
 
302
321
  - chrome-devtools: Use navigate_page, take_screenshot, take_snapshot, list_console_messages for visual/UI verification.
303
322
  - codebase-memory-mcp: Use search_graph, trace_path, get_code_snippet for structural code verification.
323
+ - git diff: Mandatory scope check. Run git diff --stat and git diff before finalizing verification.
304
324
  - exa_web_search_exa: For validating external API patterns or library usage.
305
325
 
306
326
  ## Protocol
@@ -312,6 +332,7 @@ Verify that claimed work actually works: implementation exists, tests pass, spec
312
332
  ### 2. Verify Implementation
313
333
  For each claimed completion:
314
334
  - File existence — do expected files exist?
335
+ - Scope diff — inspect git diff --stat and git diff; confirm changed files match tasks.md and design.md
315
336
  - Code review — use codebase-memory-mcp to verify code structure
316
337
  - Integration — is it properly connected?
317
338
  - Error handling — are edge cases covered?
@@ -331,9 +352,13 @@ For UI features:
331
352
  ### 5. Compare to Spec
332
353
  For each acceptance criterion, find implementing code and verify it meets the criterion.
333
354
 
355
+ ### 6. Stop Conditions
356
+ Stop verification and report FAIL or PARTIAL when git diff shows unrelated files, tests fail, Test Spec rows are missing, assertions are weakened, mocks differ from the Mock Requirement, or evidence is insufficient.
357
+
334
358
  ## Key Behaviors
335
359
 
336
360
  - Be skeptical — don't accept claims at face value
361
+ - Always inspect git diff before final verdict
337
362
  - Test everything that can be tested
338
363
  - Check edge cases, not just happy paths
339
364
  - Report honestly even if news is bad
@@ -341,7 +366,9 @@ For each acceptance criterion, find implementing code and verify it meets the cr
341
366
  },
342
367
 
343
368
  "sdd-reviewer": {
369
+ description: "Final SDD review agent for /sdd-ship readiness, security, performance, and spec compliance.",
344
370
  mode: "subagent",
371
+ hidden: true,
345
372
  temperature: 0.2,
346
373
  permission: {
347
374
  edit: "deny",
@@ -363,7 +390,8 @@ Review code for spec compliance, security vulnerabilities, performance bottlenec
363
390
 
364
391
  ### 1. Context
365
392
  - Read spec.md for requirements, plan.md for intended approach
366
- - Identify files changed in implementation
393
+ - Run git diff --stat and git diff to identify files changed in implementation
394
+ - Confirm every changed file belongs to the intended scope from tasks.md and design.md
367
395
 
368
396
  ### 2. Security Review
369
397
  Check: input validation, auth/authz, secrets exposure, injection/XSS/CSRF, secure data handling.
@@ -377,9 +405,13 @@ Check: naming conventions, error handling, duplication, complex functions, test
377
405
  ### 5. Spec Compliance
378
406
  For each requirement: is it implemented, does it meet acceptance criteria, are edge cases handled?
379
407
 
408
+ ### 6. Diff Scope
409
+ Compare the diff against the accepted artifacts. Report any unrelated file, broad rewrite, missing test, weakened assertion, or changed behavior outside scope before writing verification.md.
410
+
380
411
  ## Key Behaviors
381
412
 
382
413
  - Review objectively without personal preference bias
414
+ - Use git diff as mandatory evidence before final readiness decision
383
415
  - Provide specific, actionable feedback with line references
384
416
  - Acknowledge good patterns, not just problems
385
417
  - Prioritize issues by impact`,
@@ -537,7 +569,13 @@ Next: run /sdd-propose "<your first feature>" to start building.`,
537
569
  - Do not edit source code.
538
570
  - Do not implement fixes.
539
571
  - Do not create a change unless the user explicitly asks.
540
- - Use codebase search first for project-specific questions.
572
+ - Default mode is read-only: return a chat report or a temporary report outside the repo. Do not update SDD artifacts by default.
573
+ - Artifact writes are allowed if and only if a Change ID is provided and, after interactive planning, the user explicitly says to update artifacts.
574
+ - Use codebase-memory-mcp first for project-specific questions; fallback to grep/glob/read only if MCP is unavailable or insufficient, and report why.
575
+ - Run MCP investigation as a loop: query -> trace -> read snippets -> refine terms -> stop only when a pass finds no new relevant evidence.
576
+ - If the MCP loop exposes unclear scope, contradictory evidence, multiple plausible change boundaries, or missing domain terms, stop and ask at most 3 bounded questions before recommending a plan.
577
+ - Each bounded question must include your recommended answer.
578
+ - If artifact writes are allowed, write only exploration findings and open questions. Do not write implementation tasks.
541
579
  - Use web research only when external facts, libraries, or current docs matter.
542
580
  - If an explicit first token is a slug, treat it as the optional change id.
543
581
  - For project-specific exploration, cite real files, functions, routes, commands, or config paths.
@@ -557,7 +595,9 @@ Return a concise investigation report:
557
595
  - Findings with real file paths
558
596
  - Options with tradeoffs
559
597
  - Recommendation
560
- - Evidence (file paths + source URLs)
598
+ - Interactive Planning status with bounded questions and recommended answers
599
+ - Evidence (MCP Status + file paths + source URLs)
600
+ - Artifact Writes status with reason and changed paths
561
601
  - Next Command: /sdd-propose <change-id> "<focused change>"`,
562
602
  },
563
603
 
@@ -578,7 +618,7 @@ Return a concise investigation report:
578
618
  - Create artifacts in specs/active/<change-id>/.
579
619
  - Generate: proposal.md, spec.md, design.md, tasks.md (and progress.md for large changes).
580
620
  - Do not write implementation code.
581
- - Ask at most 3 clarifying questions only if too ambiguous.
621
+ - Ask at most 3 clarifying questions only if too ambiguous. Each clarifying question must be bounded and include your recommended answer.
582
622
 
583
623
  ## Sizing
584
624
 
@@ -629,7 +669,7 @@ Next: review the artifacts, then run /sdd-apply <change-id>.`,
629
669
 
630
670
  - specs/active/<change-id>/tasks.md must exist.
631
671
  - Read proposal.md, spec.md, design.md, tasks.md, and progress.md if present.
632
- - If artifacts are missing or contradictory, stop and ask.
672
+ - If artifacts are missing or contradictory, stop with blocked: and state the exact artifact fix needed. Do not ask interactive clarification during /sdd-apply.
633
673
 
634
674
  ## Rules
635
675
 
@@ -638,6 +678,7 @@ Next: review the artifacts, then run /sdd-apply <change-id>.`,
638
678
  - Do not broaden scope beyond accepted artifacts.
639
679
  - Update tasks.md checkboxes as work completes.
640
680
  - Stop on blockers. Do not silently skip tasks.
681
+ - Remain execution-only. Do not ask planning questions; unresolved ambiguity becomes blocked: with a concrete next /sdd-explore or /sdd-propose recommendation.
641
682
 
642
683
  ## Test Integrity
643
684
 
@@ -655,6 +696,12 @@ Next: review the artifacts, then run /sdd-apply <change-id>.`,
655
696
 
656
697
  Parallelize only when touched files do not overlap. Spawn at most 3 implementer subagents per batch.
657
698
 
699
+ Each subagent must return a completion contract: changed: or blocked:, plus verified: or unverified:, touched files, artifact updates, and exact test/verifier evidence.
700
+
701
+ After each subagent returns, verify it did not stall: check output labels, touched files, tasks.md/progress.md checkpoint, and verification evidence before starting the next batch.
702
+
703
+ If a subagent returns no output, vague output, missing labels, no artifact update, or no verification evidence, mark it [BLOCKED: subagent stalled or incomplete evidence], retry once with a smaller payload, then continue sequentially or stop with blocked:.
704
+
658
705
  ## Workflow
659
706
 
660
707
  1. Summarize scope in 3-6 bullets.
@@ -687,6 +734,7 @@ Next: run /sdd-ship <change-id> for final review.`,
687
734
 
688
735
  - Read specs/active/<change-id>/ artifacts.
689
736
  - Inspect implementation against artifacts.
737
+ - Run git diff --stat and git diff before writing verification.md; use the diff to prove changed files match intended scope.
690
738
  - Run or recommend relevant test, lint, typecheck, build commands.
691
739
  - Create or update verification.md.
692
740
  - Do not make product code changes unless explicitly asked.
@@ -705,6 +753,7 @@ Strict audit comparing Test Spec tables in tasks.md against actual test files:
705
753
  - Tasks completed or intentionally deferred
706
754
  - Bugs, regressions, security risks, missing tests
707
755
  - Verification evidence
756
+ - Diff scope: no unrelated files, broad rewrites, weakened assertions, or hidden side effects
708
757
  - Release readiness
709
758
 
710
759
  ## Finalize Behavior
@@ -716,10 +765,11 @@ When request includes "finalize", "complete", or "archive":
716
765
  ## Evidence Requirements
717
766
 
718
767
  - Every finding must include file path, command output, browser evidence, or "assumption:" label.
768
+ - verification.md must include git diff --stat, test command results, and any unrelated-change finding.
719
769
 
720
770
  ## Output
721
771
 
722
- Findings first (critical, major, minor), Verification results, Decision (ready: yes|no).`,
772
+ Findings first (critical, major, minor), Verification results including git diff --stat and test commands, Decision (ready: yes|no).`,
723
773
  },
724
774
 
725
775
  "sdd-quick": {
@@ -808,10 +858,18 @@ export default async ({ client, project, directory, $ }) => {
808
858
  const autoReasoningHooks = await sddAutoReasoning({ client, project, directory, $ });
809
859
 
810
860
  return {
811
- agent: AGENTS,
812
861
  ...autoReasoningHooks,
813
862
 
814
863
  config(cfg) {
864
+ // Register SDD agents through config; OpenCode 1.15 ignores top-level plugin `agent` hooks.
865
+ cfg.agent = cfg.agent || {};
866
+ for (const [name, agent] of Object.entries(AGENTS)) {
867
+ cfg.agent[name] = {
868
+ ...(cfg.agent[name] ?? {}),
869
+ ...agent,
870
+ };
871
+ }
872
+
815
873
  // Register SDD skills path
816
874
  const skillsDir = path.join(packageRoot, ".opencode", "skills");
817
875
  if (fs.existsSync(skillsDir)) {
package/README.md CHANGED
@@ -64,7 +64,7 @@ To pin a specific version:
64
64
  ```json
65
65
  {
66
66
  "plugin": [
67
- "@tudeorangbiasa/sdd-multiagent-opencode@0.4.0"
67
+ "@tudeorangbiasa/sdd-multiagent-opencode@0.4.1"
68
68
  ]
69
69
  }
70
70
  ```
@@ -216,9 +216,9 @@ Models available at no cost via OpenCode Zen. Run `opencode models opencode | gr
216
216
  | Model | ID | Best For | Notes |
217
217
  |-------|----|----------|-------|
218
218
  | DeepSeek V4 Flash Free | `opencode/deepseek-v4-flash-free` | Explorer, Implementer | Code generation |
219
- | MiniMax M2.5 Free | `opencode/minimax-m2.5-free` | Reviewer, Compaction | Structured output |
220
- | Nemotron 3 Super Free | `opencode/nemotron-3-super-free` | Explorer | NVIDIA model, 1M context |
221
- | Qwen3.6 Plus Free | `opencode/qwen3.6-plus-free` | Verifier, General, Quick fix | Multimodal support |
219
+ | MiniMax M2.5 Free | `opencode/minimax-m2.5-free` | Fallback only | Currently unavailable in some regions/accounts |
220
+ | Nemotron 3 Super Free | `opencode/nemotron-3-super-free` | Explorer, Compaction | NVIDIA model, 1M context |
221
+ | Qwen3.6 Plus Free | `opencode/qwen3.6-plus-free` | Reviewer, Verifier, General, Quick fix | Multimodal support |
222
222
 
223
223
  ⚠️ Free models are limited-time offers and may be removed or rotated without notice. Not recommended for production SDD workflows. Use `opencode models opencode | grep "free"` to verify what's currently available.
224
224
 
@@ -241,7 +241,7 @@ Recommended starting configuration (orchestrator/planner use OpenAI GPT 5.5, oth
241
241
  "sdd-explorer": { "model": "opencode/deepseek-v4-flash-free" },
242
242
  "sdd-implementer": { "model": "opencode/deepseek-v4-flash-free" },
243
243
  "sdd-verifier": { "model": "opencode/qwen3.6-plus-free" },
244
- "sdd-reviewer": { "model": "opencode/minimax-m2.5-free" },
244
+ "sdd-reviewer": { "model": "opencode/qwen3.6-plus-free" },
245
245
  "sdd-quick": { "model": "opencode/qwen3.6-plus-free" }
246
246
  },
247
247
  "reasoning": {
@@ -280,7 +280,7 @@ Recommended starting configuration (orchestrator/planner use OpenAI GPT 5.5, oth
280
280
  "sdd-explorer": { "model": "opencode/deepseek-v4-flash-free" },
281
281
  "sdd-implementer": { "model": "opencode/deepseek-v4-flash-free" },
282
282
  "sdd-verifier": { "model": "opencode-go/kimi-k2.6" },
283
- "sdd-reviewer": { "model": "opencode/minimax-m2.5-free" },
283
+ "sdd-reviewer": { "model": "opencode/qwen3.6-plus-free" },
284
284
  "sdd-quick": { "model": "opencode-go/qwen3.6-plus" }
285
285
  }
286
286
  }
@@ -292,7 +292,7 @@ Recommended starting configuration (orchestrator/planner use OpenAI GPT 5.5, oth
292
292
  - **Explorer** → DeepSeek free: fast readonly exploration, token-efficient
293
293
  - **Implementer** → DeepSeek free: code generation, handles high token usage
294
294
  - **Verifier** → Qwen3.6 Plus free: multimodal for Chrome DevTools screenshots
295
- - **Reviewer** → MiniMax M2.5 free: structured code review output
295
+ - **Reviewer** → Qwen3.6 Plus free: available free-tier review model
296
296
  - **Quick** → Qwen3.6 Plus free: minimal prompt for small cosmetic/config edits (~200 tokens)
297
297
 
298
298
  `.opencode/plugins/sdd-model-router.js` reads `~/.config/opencode/sdd-multiagent-opencode.json` at OpenCode startup and applies the model settings. **Restart OpenCode after editing it.**
@@ -2,8 +2,10 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
- import { fileURLToPath } from "node:url";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
6
6
  import { execSync } from "node:child_process";
7
+ import { migrateOldSymlinks } from "../.opencode/plugins/sdd-migration-symlinks.js";
8
+ import { checkExploreCommandFile } from "../.opencode/plugins/sdd-doctor-checks.js";
7
9
 
8
10
  const __filename = fileURLToPath(import.meta.url);
9
11
  const __dirname = path.dirname(__filename);
@@ -235,7 +237,7 @@ function parseArgs(argv) {
235
237
  // ─── Usage ───────────────────────────────────────────────────────────────────
236
238
 
237
239
  function usage() {
238
- console.log(`SDD Multi-Agent OpenCode Installer v0.4.0
240
+ console.log(`SDD Multi-Agent OpenCode Installer v0.4.1
239
241
 
240
242
  Usage:
241
243
  sdd-opencode init [flags] Install SDD workflow into current project
@@ -513,7 +515,7 @@ async function runInit(args) {
513
515
  dryRunFiles: [],
514
516
  };
515
517
 
516
- console.log("\nSDD Multi-Agent OpenCode Installer v0.4.0\n");
518
+ console.log("\nSDD Multi-Agent OpenCode Installer v0.4.1\n");
517
519
  console.log(`Target: ${targetRoot}`);
518
520
  if (ctx.dryRun) console.log("Mode: DRY RUN (no files will be written)\n");
519
521
 
@@ -556,7 +558,7 @@ async function runInit(args) {
556
558
 
557
559
  // ─── Doctor Command ──────────────────────────────────────────────────────────
558
560
 
559
- async function runDoctor(args) {
561
+ export async function runDoctor(args, { exploreCommandPath } = {}) {
560
562
  const targetRoot = process.cwd();
561
563
  const results = { pass: 0, warn: 0, fail: 0, checks: [] };
562
564
 
@@ -625,6 +627,16 @@ async function runDoctor(args) {
625
627
 
626
628
  report("L0", "orphaned symlinks", orphanedCount === 0 ? "pass" : "warn", orphanedCount > 0 ? `${orphanedCount} old symlinks found — run "sdd-opencode migrate"` : "clean");
627
629
 
630
+ // L0: SDD Explore read-only contract
631
+ const exploreSourcePath = exploreCommandPath || path.join(packageRoot, ".opencode/commands/sdd-explore.md");
632
+ let exploreResult;
633
+ try {
634
+ exploreResult = checkExploreCommandFile(exploreSourcePath);
635
+ } catch {
636
+ exploreResult = { status: "fail", detail: "Cannot read explore command source" };
637
+ }
638
+ report("L0", "sdd-explore contract", exploreResult.status, exploreResult.detail);
639
+
628
640
  // L1: Plugin registration count
629
641
  console.log("\nL1: Plugin Registration");
630
642
 
@@ -728,79 +740,54 @@ function runWarm() {
728
740
 
729
741
  // ─── Migrate Command ─────────────────────────────────────────────────────────
730
742
 
731
- function runMigrate() {
732
- console.log("\nMigrating from v0.2.x symlink-based installation...\n");
743
+ export function runMigrate({ configDir = globalConfigDir, log = console.log, now } = {}) {
744
+ log("\nMigrating from v0.2.x symlink-based installation...\n");
733
745
 
734
- const MIGRATION_MARKER = ".sdd-migrated-v030";
735
- const markerPath = path.join(globalConfigDir, MIGRATION_MARKER);
746
+ const result = migrateOldSymlinks({ configDir, now });
736
747
 
737
- if (fs.existsSync(markerPath)) {
738
- console.log("Migration already completed. No action needed.");
739
- return;
748
+ if (result.skipped) {
749
+ log("Migration already completed. No action needed.");
750
+ return result;
740
751
  }
741
752
 
742
- const symlinkTargets = [
743
- { dir: "commands", prefix: "sdd-" },
744
- { dir: "agents", prefix: "sdd-" },
745
- { dir: "rules", prefix: null },
746
- ];
747
-
748
- let removed = 0;
749
-
750
- for (const { dir, prefix } of symlinkTargets) {
751
- const dirPath = path.join(globalConfigDir, dir);
752
- if (!fs.existsSync(dirPath)) continue;
753
-
754
- for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
755
- const fullPath = path.join(dirPath, entry.name);
756
- try {
757
- const stat = fs.lstatSync(fullPath);
758
- if (!stat.isSymbolicLink()) continue;
759
- if (prefix && !entry.name.startsWith(prefix)) continue;
760
-
761
- const linkTarget = fs.readlinkSync(fullPath);
762
- if (linkTarget.includes("sdd-multiagent-opencode") || linkTarget.includes("opencode-agent-rules")) {
763
- fs.unlinkSync(fullPath);
764
- console.log(` Removed: ${path.join(dir, entry.name)}`);
765
- removed++;
766
- }
767
- } catch {
768
- // skip
769
- }
770
- }
753
+ for (const removedPath of result.removed) {
754
+ log(` Removed: ${removedPath}`);
771
755
  }
772
756
 
773
- if (removed > 0) {
774
- try {
775
- fs.writeFileSync(markerPath, new Date().toISOString());
776
- } catch {
777
- // skip
778
- }
779
- console.log(`\nMigration complete: ${removed} old symlinks removed.`);
780
- console.log("Plugin-native registration is now active.");
757
+ if (result.removed.length > 0) {
758
+ log(`\nMigration complete: ${result.removed.length} old symlinks removed.`);
759
+ log("Plugin-native registration is now active.");
781
760
  } else {
782
- console.log("No old symlinks found. Nothing to migrate.");
761
+ log("No old symlinks found. Nothing to migrate.");
783
762
  }
763
+
764
+ return result;
784
765
  }
785
766
 
786
767
  // ─── Main ────────────────────────────────────────────────────────────────────
787
768
 
788
- const args = parseArgs(process.argv);
789
-
790
- if (args.command === "help") {
791
- usage();
792
- } else if (args.command === "init") {
793
- runInit(args);
794
- } else if (args.command === "doctor") {
795
- runDoctor(args);
796
- } else if (args.command === "warm") {
797
- runWarm();
798
- } else if (args.command === "migrate") {
799
- runMigrate();
800
- } else if (args.command === "test") {
801
- console.log("Smoke test placeholder plugin loads correctly.");
802
- } else {
803
- console.error(`Unknown command: ${args.command}`);
804
- usage();
805
- process.exit(1);
769
+ function main(argv = process.argv) {
770
+ const args = parseArgs(argv);
771
+
772
+ if (args.command === "help") {
773
+ usage();
774
+ } else if (args.command === "init") {
775
+ runInit(args);
776
+ } else if (args.command === "doctor") {
777
+ runDoctor(args);
778
+ } else if (args.command === "warm") {
779
+ runWarm();
780
+ } else if (args.command === "migrate") {
781
+ runMigrate();
782
+ } else if (args.command === "test") {
783
+ console.log("Smoke test placeholder — plugin loads correctly.");
784
+ } else {
785
+ console.error(`Unknown command: ${args.command}`);
786
+ usage();
787
+ process.exit(1);
788
+ }
789
+ }
790
+
791
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
792
+ main();
806
793
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tudeorangbiasa/sdd-multiagent-opencode",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Spec-Driven Development workflow kit for OpenCode with 5 core commands, multi-agent support, CLI wrappers, and configurable model routing",
5
5
  "type": "module",
6
6
  "main": ".opencode/plugins/sdd-register.js",
@@ -18,7 +18,7 @@
18
18
  "model": "opencode/qwen3.6-plus-free"
19
19
  },
20
20
  "sdd-reviewer": {
21
- "model": "opencode/minimax-m2.5-free"
21
+ "model": "opencode/qwen3.6-plus-free"
22
22
  },
23
23
  "sdd-quick": {
24
24
  "model": "opencode/qwen3.6-plus-free"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "agent": {
3
3
  "compaction": {
4
- "model": "opencode/minimax-m2.5-free",
4
+ "model": "opencode/nemotron-3-super-free",
5
5
  "temperature": 0.1
6
6
  }
7
7
  }