@bhargavvc/sdd-cc 1.30.1 → 1.35.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.
- package/README.ja-JP.md +144 -110
- package/README.ko-KR.md +143 -107
- package/README.md +183 -112
- package/README.pt-BR.md +90 -52
- package/README.zh-CN.md +141 -101
- package/agents/sdd-advisor-researcher.md +23 -0
- package/agents/sdd-ai-researcher.md +133 -0
- package/agents/sdd-code-fixer.md +516 -0
- package/agents/sdd-code-reviewer.md +355 -0
- package/agents/sdd-codebase-mapper.md +3 -3
- package/agents/sdd-debugger.md +17 -5
- package/agents/sdd-doc-verifier.md +201 -0
- package/agents/sdd-doc-writer.md +602 -0
- package/agents/sdd-domain-researcher.md +153 -0
- package/agents/sdd-eval-auditor.md +164 -0
- package/agents/sdd-eval-planner.md +154 -0
- package/agents/sdd-executor.md +87 -4
- package/agents/sdd-framework-selector.md +160 -0
- package/agents/sdd-intel-updater.md +314 -0
- package/agents/sdd-nyquist-auditor.md +1 -1
- package/agents/sdd-phase-researcher.md +71 -4
- package/agents/sdd-plan-checker.md +100 -6
- package/agents/sdd-planner.md +145 -206
- package/agents/sdd-project-researcher.md +25 -2
- package/agents/sdd-research-synthesizer.md +3 -3
- package/agents/sdd-roadmapper.md +6 -6
- package/agents/sdd-security-auditor.md +128 -0
- package/agents/sdd-ui-auditor.md +43 -3
- package/agents/sdd-ui-checker.md +5 -5
- package/agents/sdd-ui-researcher.md +27 -4
- package/agents/sdd-user-profiler.md +2 -2
- package/agents/sdd-verifier.md +142 -22
- package/bin/install.js +2145 -545
- package/commands/sdd/add-backlog.md +5 -5
- package/commands/sdd/add-tests.md +2 -2
- package/commands/sdd/ai-integration-phase.md +36 -0
- package/commands/sdd/analyze-dependencies.md +34 -0
- package/commands/sdd/audit-fix.md +33 -0
- package/commands/sdd/autonomous.md +7 -2
- package/commands/sdd/cleanup.md +5 -0
- package/commands/sdd/code-review-fix.md +52 -0
- package/commands/sdd/code-review.md +55 -0
- package/commands/sdd/complete-milestone.md +6 -6
- package/commands/sdd/debug.md +22 -9
- package/commands/sdd/discuss-phase.md +7 -2
- package/commands/sdd/do.md +1 -1
- package/commands/sdd/docs-update.md +48 -0
- package/commands/sdd/eval-review.md +32 -0
- package/commands/sdd/execute-phase.md +4 -0
- package/commands/sdd/explore.md +27 -0
- package/commands/sdd/fast.md +2 -2
- package/commands/sdd/from-sdd2.md +45 -0
- package/commands/sdd/help.md +2 -0
- package/commands/sdd/import.md +36 -0
- package/commands/sdd/intel.md +179 -0
- package/commands/sdd/join-discord.md +2 -1
- package/commands/sdd/manager.md +1 -0
- package/commands/sdd/map-codebase.md +3 -3
- package/commands/sdd/new-milestone.md +1 -1
- package/commands/sdd/new-project.md +5 -1
- package/commands/sdd/new-workspace.md +1 -1
- package/commands/sdd/next.md +2 -0
- package/commands/sdd/plan-milestone-gaps.md +2 -2
- package/commands/sdd/plan-phase.md +6 -1
- package/commands/sdd/plant-seed.md +1 -1
- package/commands/sdd/profile-user.md +1 -1
- package/commands/sdd/quick.md +5 -3
- package/commands/sdd/reapply-patches.md +230 -42
- package/commands/sdd/research-phase.md +3 -3
- package/commands/sdd/review-backlog.md +1 -0
- package/commands/sdd/review.md +6 -3
- package/commands/sdd/scan.md +26 -0
- package/commands/sdd/secure-phase.md +35 -0
- package/commands/sdd/ship.md +1 -1
- package/commands/sdd/thread.md +5 -5
- package/commands/sdd/undo.md +34 -0
- package/commands/sdd/verify-work.md +1 -1
- package/commands/sdd/workstreams.md +17 -11
- package/hooks/dist/sdd-check-update.js +33 -8
- package/hooks/dist/sdd-context-monitor.js +17 -8
- package/hooks/dist/sdd-phase-boundary.sh +27 -0
- package/hooks/dist/sdd-prompt-guard.js +1 -0
- package/hooks/dist/sdd-read-guard.js +82 -0
- package/hooks/dist/sdd-session-state.sh +33 -0
- package/hooks/dist/sdd-statusline.js +137 -15
- package/hooks/dist/sdd-validate-commit.sh +47 -0
- package/hooks/dist/sdd-workflow-guard.js +4 -4
- package/hooks/sdd-check-update.js +139 -0
- package/hooks/sdd-context-monitor.js +165 -0
- package/hooks/sdd-phase-boundary.sh +27 -0
- package/hooks/sdd-prompt-guard.js +97 -0
- package/hooks/sdd-read-guard.js +82 -0
- package/hooks/sdd-session-state.sh +33 -0
- package/hooks/sdd-statusline.js +241 -0
- package/hooks/sdd-validate-commit.sh +47 -0
- package/hooks/sdd-workflow-guard.js +94 -0
- package/package.json +3 -3
- package/scripts/build-hooks.js +18 -7
- package/scripts/prompt-injection-scan.sh +1 -0
- package/scripts/rebrand-gsd-to-sdd.sh +221 -220
- package/scripts/run-tests.cjs +5 -1
- package/scripts/sync-upstream.sh +1 -1
- package/sdd/bin/lib/commands.cjs +79 -17
- package/sdd/bin/lib/config.cjs +90 -48
- package/sdd/bin/lib/core.cjs +452 -87
- package/sdd/bin/lib/docs.cjs +267 -0
- package/sdd/bin/lib/frontmatter.cjs +381 -336
- package/sdd/bin/lib/init.cjs +110 -16
- package/sdd/bin/lib/intel.cjs +660 -0
- package/sdd/bin/lib/learnings.cjs +378 -0
- package/sdd/bin/lib/milestone.cjs +42 -11
- package/sdd/bin/lib/model-profiles.cjs +17 -15
- package/sdd/bin/lib/phase.cjs +367 -288
- package/sdd/bin/lib/profile-output.cjs +106 -10
- package/sdd/bin/lib/roadmap.cjs +146 -115
- package/sdd/bin/lib/schema-detect.cjs +238 -0
- package/sdd/bin/lib/sdd2-import.cjs +511 -0
- package/sdd/bin/lib/security.cjs +124 -3
- package/sdd/bin/lib/state.cjs +648 -264
- package/sdd/bin/lib/template.cjs +8 -4
- package/sdd/bin/lib/verify.cjs +209 -28
- package/sdd/bin/lib/workstream.cjs +7 -3
- package/sdd/bin/sdd-tools.cjs +184 -12
- package/sdd/contexts/dev.md +21 -0
- package/sdd/contexts/research.md +22 -0
- package/sdd/contexts/review.md +22 -0
- package/sdd/references/agent-contracts.md +79 -0
- package/sdd/references/ai-evals.md +156 -0
- package/sdd/references/ai-frameworks.md +186 -0
- package/sdd/references/artifact-types.md +113 -0
- package/sdd/references/common-bug-patterns.md +114 -0
- package/sdd/references/context-budget.md +49 -0
- package/sdd/references/continuation-format.md +25 -25
- package/sdd/references/domain-probes.md +125 -0
- package/sdd/references/few-shot-examples/plan-checker.md +73 -0
- package/sdd/references/few-shot-examples/verifier.md +109 -0
- package/sdd/references/gate-prompts.md +100 -0
- package/sdd/references/gates.md +70 -0
- package/sdd/references/git-integration.md +1 -1
- package/sdd/references/ios-scaffold.md +123 -0
- package/sdd/references/model-profile-resolution.md +2 -0
- package/sdd/references/model-profiles.md +24 -18
- package/sdd/references/planner-gap-closure.md +62 -0
- package/sdd/references/planner-reviews.md +39 -0
- package/sdd/references/planner-revision.md +87 -0
- package/sdd/references/planning-config.md +252 -0
- package/sdd/references/revision-loop.md +97 -0
- package/sdd/references/thinking-models-debug.md +44 -0
- package/sdd/references/thinking-models-execution.md +50 -0
- package/sdd/references/thinking-models-planning.md +62 -0
- package/sdd/references/thinking-models-research.md +50 -0
- package/sdd/references/thinking-models-verification.md +55 -0
- package/sdd/references/thinking-partner.md +96 -0
- package/sdd/references/ui-brand.md +4 -4
- package/sdd/references/universal-anti-patterns.md +63 -0
- package/sdd/references/verification-overrides.md +227 -0
- package/sdd/references/workstream-flag.md +56 -3
- package/sdd/templates/AI-SPEC.md +246 -0
- package/sdd/templates/DEBUG.md +1 -1
- package/sdd/templates/SECURITY.md +61 -0
- package/sdd/templates/UAT.md +4 -4
- package/sdd/templates/VALIDATION.md +4 -4
- package/sdd/templates/claude-md.md +32 -9
- package/sdd/templates/config.json +4 -0
- package/sdd/templates/debug-subagent-prompt.md +1 -1
- package/sdd/templates/dev-preferences.md +1 -1
- package/sdd/templates/discovery.md +2 -2
- package/sdd/templates/phase-prompt.md +1 -1
- package/sdd/templates/planner-subagent-prompt.md +3 -3
- package/sdd/templates/project.md +1 -1
- package/sdd/templates/research.md +1 -1
- package/sdd/templates/state.md +2 -2
- package/sdd/workflows/add-phase.md +8 -8
- package/sdd/workflows/add-tests.md +12 -9
- package/sdd/workflows/add-todo.md +5 -3
- package/sdd/workflows/ai-integration-phase.md +284 -0
- package/sdd/workflows/analyze-dependencies.md +96 -0
- package/sdd/workflows/audit-fix.md +157 -0
- package/sdd/workflows/audit-milestone.md +11 -11
- package/sdd/workflows/audit-uat.md +2 -2
- package/sdd/workflows/autonomous.md +195 -27
- package/sdd/workflows/check-todos.md +12 -10
- package/sdd/workflows/cleanup.md +2 -0
- package/sdd/workflows/code-review-fix.md +497 -0
- package/sdd/workflows/code-review.md +515 -0
- package/sdd/workflows/complete-milestone.md +56 -22
- package/sdd/workflows/diagnose-issues.md +10 -3
- package/sdd/workflows/discovery-phase.md +5 -3
- package/sdd/workflows/discuss-phase-assumptions.md +24 -6
- package/sdd/workflows/discuss-phase-power.md +291 -0
- package/sdd/workflows/discuss-phase.md +173 -21
- package/sdd/workflows/do.md +23 -21
- package/sdd/workflows/docs-update.md +1155 -0
- package/sdd/workflows/eval-review.md +155 -0
- package/sdd/workflows/execute-phase.md +594 -38
- package/sdd/workflows/execute-plan.md +67 -96
- package/sdd/workflows/explore.md +139 -0
- package/sdd/workflows/fast.md +5 -5
- package/sdd/workflows/forensics.md +2 -2
- package/sdd/workflows/health.md +4 -4
- package/sdd/workflows/help.md +122 -119
- package/sdd/workflows/import.md +276 -0
- package/sdd/workflows/inbox.md +387 -0
- package/sdd/workflows/insert-phase.md +7 -7
- package/sdd/workflows/list-phase-assumptions.md +4 -4
- package/sdd/workflows/list-workspaces.md +2 -2
- package/sdd/workflows/manager.md +35 -32
- package/sdd/workflows/map-codebase.md +7 -5
- package/sdd/workflows/milestone-summary.md +2 -2
- package/sdd/workflows/new-milestone.md +17 -9
- package/sdd/workflows/new-project.md +50 -25
- package/sdd/workflows/new-workspace.md +7 -5
- package/sdd/workflows/next.md +67 -11
- package/sdd/workflows/note.md +9 -7
- package/sdd/workflows/pause-work.md +75 -12
- package/sdd/workflows/plan-milestone-gaps.md +8 -8
- package/sdd/workflows/plan-phase.md +294 -42
- package/sdd/workflows/plant-seed.md +6 -3
- package/sdd/workflows/pr-branch.md +42 -14
- package/sdd/workflows/profile-user.md +9 -7
- package/sdd/workflows/progress.md +45 -45
- package/sdd/workflows/quick.md +195 -47
- package/sdd/workflows/remove-phase.md +6 -6
- package/sdd/workflows/remove-workspace.md +3 -1
- package/sdd/workflows/research-phase.md +2 -2
- package/sdd/workflows/resume-project.md +12 -12
- package/sdd/workflows/review.md +109 -9
- package/sdd/workflows/scan.md +102 -0
- package/sdd/workflows/secure-phase.md +166 -0
- package/sdd/workflows/session-report.md +2 -2
- package/sdd/workflows/settings.md +38 -12
- package/sdd/workflows/ship.md +21 -9
- package/sdd/workflows/stats.md +1 -1
- package/sdd/workflows/transition.md +23 -23
- package/sdd/workflows/ui-phase.md +15 -7
- package/sdd/workflows/ui-review.md +29 -4
- package/sdd/workflows/undo.md +314 -0
- package/sdd/workflows/update.md +171 -20
- package/sdd/workflows/validate-phase.md +6 -4
- package/sdd/workflows/verify-phase.md +210 -6
- package/sdd/workflows/verify-work.md +83 -9
- package/sdd/commands/sdd/workstreams.md +0 -63
package/sdd/workflows/update.md
CHANGED
|
@@ -11,28 +11,59 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
11
11
|
<step name="get_installed_version">
|
|
12
12
|
Detect whether SDD is installed locally or globally by checking both locations and validating install integrity.
|
|
13
13
|
|
|
14
|
-
First, derive `PREFERRED_RUNTIME` from the invoking prompt's `execution_context` path:
|
|
14
|
+
First, derive `PREFERRED_CONFIG_DIR` and `PREFERRED_RUNTIME` from the invoking prompt's `execution_context` path:
|
|
15
|
+
- If the path contains `/sdd/workflows/update.md`, strip that suffix and store the remainder as `PREFERRED_CONFIG_DIR`
|
|
15
16
|
- Path contains `/.codex/` -> `codex`
|
|
16
17
|
- Path contains `/.gemini/` -> `gemini`
|
|
17
|
-
- Path contains `/.config/
|
|
18
|
+
- Path contains `/.config/kilo/` or `/.kilo/`, or `PREFERRED_CONFIG_DIR` contains `kilo.json` / `kilo.jsonc` -> `kilo`
|
|
19
|
+
- Path contains `/.config/opencode/` or `/.opencode/`, or `PREFERRED_CONFIG_DIR` contains `opencode.json` / `opencode.jsonc` -> `opencode`
|
|
18
20
|
- Otherwise -> `claude`
|
|
19
21
|
|
|
20
|
-
Use `
|
|
22
|
+
Use `PREFERRED_CONFIG_DIR` when available so custom `--config-dir` installs are checked before default locations.
|
|
23
|
+
Use `PREFERRED_RUNTIME` as the first runtime checked so `/sdd-update` targets the runtime that invoked it.
|
|
24
|
+
|
|
25
|
+
Kilo config precedence must match the installer: `KILO_CONFIG_DIR` -> `dirname(KILO_CONFIG)` -> `XDG_CONFIG_HOME/kilo` -> `~/.config/kilo`.
|
|
21
26
|
|
|
22
27
|
```bash
|
|
28
|
+
expand_home() {
|
|
29
|
+
case "$1" in
|
|
30
|
+
"~/"*) printf '%s/%s\n' "$HOME" "${1#~/}" ;;
|
|
31
|
+
*) printf '%s\n' "$1" ;;
|
|
32
|
+
esac
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
# Runtime candidates: "<runtime>:<config-dir>" stored as an array.
|
|
24
36
|
# Using an array instead of a space-separated string ensures correct
|
|
25
37
|
# iteration in both bash and zsh (zsh does not word-split unquoted
|
|
26
38
|
# variables by default). Fixes #1173.
|
|
27
|
-
RUNTIME_DIRS=( "claude:.claude" "opencode:.config/opencode" "opencode:.opencode" "gemini:.gemini" "codex:.codex" )
|
|
39
|
+
RUNTIME_DIRS=( "claude:.claude" "opencode:.config/opencode" "opencode:.opencode" "gemini:.gemini" "kilo:.config/kilo" "kilo:.kilo" "codex:.codex" )
|
|
40
|
+
ENV_RUNTIME_DIRS=()
|
|
41
|
+
|
|
42
|
+
# PREFERRED_CONFIG_DIR / PREFERRED_RUNTIME should be set from execution_context
|
|
43
|
+
# before running this block.
|
|
44
|
+
if [ -n "$PREFERRED_CONFIG_DIR" ]; then
|
|
45
|
+
PREFERRED_CONFIG_DIR="$(expand_home "$PREFERRED_CONFIG_DIR")"
|
|
46
|
+
if [ -z "$PREFERRED_RUNTIME" ]; then
|
|
47
|
+
if [ -f "$PREFERRED_CONFIG_DIR/kilo.json" ] || [ -f "$PREFERRED_CONFIG_DIR/kilo.jsonc" ]; then
|
|
48
|
+
PREFERRED_RUNTIME="kilo"
|
|
49
|
+
elif [ -f "$PREFERRED_CONFIG_DIR/opencode.json" ] || [ -f "$PREFERRED_CONFIG_DIR/opencode.jsonc" ]; then
|
|
50
|
+
PREFERRED_RUNTIME="opencode"
|
|
51
|
+
elif [ -f "$PREFERRED_CONFIG_DIR/config.toml" ]; then
|
|
52
|
+
PREFERRED_RUNTIME="codex"
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
28
56
|
|
|
29
|
-
#
|
|
30
|
-
# If not set, infer from runtime env vars; fallback to claude.
|
|
57
|
+
# If runtime is still unknown, infer from runtime env vars; fallback to claude.
|
|
31
58
|
if [ -z "$PREFERRED_RUNTIME" ]; then
|
|
32
59
|
if [ -n "$CODEX_HOME" ]; then
|
|
33
60
|
PREFERRED_RUNTIME="codex"
|
|
34
61
|
elif [ -n "$GEMINI_CONFIG_DIR" ]; then
|
|
35
62
|
PREFERRED_RUNTIME="gemini"
|
|
63
|
+
elif [ -n "$KILO_CONFIG_DIR" ]; then
|
|
64
|
+
PREFERRED_RUNTIME="kilo"
|
|
65
|
+
elif [ -n "$KILO_CONFIG" ]; then
|
|
66
|
+
PREFERRED_RUNTIME="kilo"
|
|
36
67
|
elif [ -n "$OPENCODE_CONFIG_DIR" ] || [ -n "$OPENCODE_CONFIG" ]; then
|
|
37
68
|
PREFERRED_RUNTIME="opencode"
|
|
38
69
|
elif [ -n "$CLAUDE_CONFIG_DIR" ]; then
|
|
@@ -42,6 +73,56 @@ if [ -z "$PREFERRED_RUNTIME" ]; then
|
|
|
42
73
|
fi
|
|
43
74
|
fi
|
|
44
75
|
|
|
76
|
+
# If execution_context already points at an installed config dir, trust it first.
|
|
77
|
+
# This covers custom --config-dir installs that do not live under the default
|
|
78
|
+
# runtime directories.
|
|
79
|
+
if [ -n "$PREFERRED_CONFIG_DIR" ] && { [ -f "$PREFERRED_CONFIG_DIR/sdd/VERSION" ] || [ -f "$PREFERRED_CONFIG_DIR/sdd/workflows/update.md" ]; }; then
|
|
80
|
+
INSTALL_SCOPE="GLOBAL"
|
|
81
|
+
for dir in .claude .config/opencode .opencode .gemini .config/kilo .kilo .codex; do
|
|
82
|
+
resolved_local="$(cd "./$dir" 2>/dev/null && pwd)"
|
|
83
|
+
if [ -n "$resolved_local" ] && [ "$resolved_local" = "$PREFERRED_CONFIG_DIR" ]; then
|
|
84
|
+
INSTALL_SCOPE="LOCAL"
|
|
85
|
+
break
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
if [ -f "$PREFERRED_CONFIG_DIR/sdd/VERSION" ] && grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' "$PREFERRED_CONFIG_DIR/sdd/VERSION"; then
|
|
90
|
+
INSTALLED_VERSION="$(cat "$PREFERRED_CONFIG_DIR/sdd/VERSION")"
|
|
91
|
+
else
|
|
92
|
+
INSTALLED_VERSION="0.0.0"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
echo "$INSTALLED_VERSION"
|
|
96
|
+
echo "$INSTALL_SCOPE"
|
|
97
|
+
echo "${PREFERRED_RUNTIME:-claude}"
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Absolute global candidates from env overrides (covers custom config dirs).
|
|
102
|
+
if [ -n "$CLAUDE_CONFIG_DIR" ]; then
|
|
103
|
+
ENV_RUNTIME_DIRS+=( "claude:$(expand_home "$CLAUDE_CONFIG_DIR")" )
|
|
104
|
+
fi
|
|
105
|
+
if [ -n "$GEMINI_CONFIG_DIR" ]; then
|
|
106
|
+
ENV_RUNTIME_DIRS+=( "gemini:$(expand_home "$GEMINI_CONFIG_DIR")" )
|
|
107
|
+
fi
|
|
108
|
+
if [ -n "$KILO_CONFIG_DIR" ]; then
|
|
109
|
+
ENV_RUNTIME_DIRS+=( "kilo:$(expand_home "$KILO_CONFIG_DIR")" )
|
|
110
|
+
elif [ -n "$KILO_CONFIG" ]; then
|
|
111
|
+
ENV_RUNTIME_DIRS+=( "kilo:$(dirname "$(expand_home "$KILO_CONFIG")")" )
|
|
112
|
+
elif [ -n "$XDG_CONFIG_HOME" ]; then
|
|
113
|
+
ENV_RUNTIME_DIRS+=( "kilo:$(expand_home "$XDG_CONFIG_HOME")/kilo" )
|
|
114
|
+
fi
|
|
115
|
+
if [ -n "$OPENCODE_CONFIG_DIR" ]; then
|
|
116
|
+
ENV_RUNTIME_DIRS+=( "opencode:$(expand_home "$OPENCODE_CONFIG_DIR")" )
|
|
117
|
+
elif [ -n "$OPENCODE_CONFIG" ]; then
|
|
118
|
+
ENV_RUNTIME_DIRS+=( "opencode:$(dirname "$(expand_home "$OPENCODE_CONFIG")")" )
|
|
119
|
+
elif [ -n "$XDG_CONFIG_HOME" ]; then
|
|
120
|
+
ENV_RUNTIME_DIRS+=( "opencode:$(expand_home "$XDG_CONFIG_HOME")/opencode" )
|
|
121
|
+
fi
|
|
122
|
+
if [ -n "$CODEX_HOME" ]; then
|
|
123
|
+
ENV_RUNTIME_DIRS+=( "codex:$(expand_home "$CODEX_HOME")" )
|
|
124
|
+
fi
|
|
125
|
+
|
|
45
126
|
# Reorder entries so preferred runtime is checked first.
|
|
46
127
|
ORDERED_RUNTIME_DIRS=()
|
|
47
128
|
for entry in "${RUNTIME_DIRS[@]}"; do
|
|
@@ -50,6 +131,19 @@ for entry in "${RUNTIME_DIRS[@]}"; do
|
|
|
50
131
|
ORDERED_RUNTIME_DIRS+=( "$entry" )
|
|
51
132
|
fi
|
|
52
133
|
done
|
|
134
|
+
ORDERED_ENV_RUNTIME_DIRS=()
|
|
135
|
+
for entry in "${ENV_RUNTIME_DIRS[@]}"; do
|
|
136
|
+
runtime="${entry%%:*}"
|
|
137
|
+
if [ "$runtime" = "$PREFERRED_RUNTIME" ]; then
|
|
138
|
+
ORDERED_ENV_RUNTIME_DIRS+=( "$entry" )
|
|
139
|
+
fi
|
|
140
|
+
done
|
|
141
|
+
for entry in "${ENV_RUNTIME_DIRS[@]}"; do
|
|
142
|
+
runtime="${entry%%:*}"
|
|
143
|
+
if [ "$runtime" != "$PREFERRED_RUNTIME" ]; then
|
|
144
|
+
ORDERED_ENV_RUNTIME_DIRS+=( "$entry" )
|
|
145
|
+
fi
|
|
146
|
+
done
|
|
53
147
|
for entry in "${RUNTIME_DIRS[@]}"; do
|
|
54
148
|
runtime="${entry%%:*}"
|
|
55
149
|
if [ "$runtime" != "$PREFERRED_RUNTIME" ]; then
|
|
@@ -72,18 +166,32 @@ for entry in "${ORDERED_RUNTIME_DIRS[@]}"; do
|
|
|
72
166
|
done
|
|
73
167
|
|
|
74
168
|
GLOBAL_VERSION_FILE="" GLOBAL_MARKER_FILE="" GLOBAL_DIR="" GLOBAL_RUNTIME=""
|
|
75
|
-
for entry in "${
|
|
169
|
+
for entry in "${ORDERED_ENV_RUNTIME_DIRS[@]}"; do
|
|
76
170
|
runtime="${entry%%:*}"
|
|
77
171
|
dir="${entry#*:}"
|
|
78
|
-
if [ -f "$
|
|
172
|
+
if [ -f "$dir/sdd/VERSION" ] || [ -f "$dir/sdd/workflows/update.md" ]; then
|
|
79
173
|
GLOBAL_RUNTIME="$runtime"
|
|
80
|
-
GLOBAL_VERSION_FILE="$
|
|
81
|
-
GLOBAL_MARKER_FILE="$
|
|
82
|
-
GLOBAL_DIR="$(cd "$
|
|
174
|
+
GLOBAL_VERSION_FILE="$dir/sdd/VERSION"
|
|
175
|
+
GLOBAL_MARKER_FILE="$dir/sdd/workflows/update.md"
|
|
176
|
+
GLOBAL_DIR="$(cd "$dir" 2>/dev/null && pwd)"
|
|
83
177
|
break
|
|
84
178
|
fi
|
|
85
179
|
done
|
|
86
180
|
|
|
181
|
+
if [ -z "$GLOBAL_RUNTIME" ]; then
|
|
182
|
+
for entry in "${ORDERED_RUNTIME_DIRS[@]}"; do
|
|
183
|
+
runtime="${entry%%:*}"
|
|
184
|
+
dir="${entry#*:}"
|
|
185
|
+
if [ -f "$HOME/$dir/sdd/VERSION" ] || [ -f "$HOME/$dir/sdd/workflows/update.md" ]; then
|
|
186
|
+
GLOBAL_RUNTIME="$runtime"
|
|
187
|
+
GLOBAL_VERSION_FILE="$HOME/$dir/sdd/VERSION"
|
|
188
|
+
GLOBAL_MARKER_FILE="$HOME/$dir/sdd/workflows/update.md"
|
|
189
|
+
GLOBAL_DIR="$(cd "$HOME/$dir" 2>/dev/null && pwd)"
|
|
190
|
+
break
|
|
191
|
+
fi
|
|
192
|
+
done
|
|
193
|
+
fi
|
|
194
|
+
|
|
87
195
|
# Only treat as LOCAL if the resolved paths differ (prevents misdetection when CWD=$HOME)
|
|
88
196
|
IS_LOCAL=false
|
|
89
197
|
if [ -n "$LOCAL_VERSION_FILE" ] && [ -f "$LOCAL_VERSION_FILE" ] && [ -f "$LOCAL_MARKER_FILE" ] && grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' "$LOCAL_VERSION_FILE"; then
|
|
@@ -123,7 +231,7 @@ echo "$TARGET_RUNTIME"
|
|
|
123
231
|
Parse output:
|
|
124
232
|
- Line 1 = installed version (`0.0.0` means unknown version)
|
|
125
233
|
- Line 2 = install scope (`LOCAL`, `GLOBAL`, or `UNKNOWN`)
|
|
126
|
-
- Line 3 = target runtime (`claude`, `opencode`, `gemini`, or `codex`)
|
|
234
|
+
- Line 3 = target runtime (`claude`, `opencode`, `gemini`, `kilo`, or `codex`)
|
|
127
235
|
- If scope is `UNKNOWN`, proceed to install step using `--claude --global` fallback.
|
|
128
236
|
|
|
129
237
|
If multiple runtime installs are detected and the invoking runtime cannot be determined from execution_context, ask the user which runtime to update before running install.
|
|
@@ -221,8 +329,8 @@ Exit.
|
|
|
221
329
|
- `agents/sdd-*` files will be replaced
|
|
222
330
|
|
|
223
331
|
(Paths are relative to detected runtime install location:
|
|
224
|
-
global: `~/.claude/`, `~/.config/opencode/`, `~/.opencode/`, `~/.gemini/`, or `~/.codex/`
|
|
225
|
-
local: `./.claude/`, `./.config/opencode/`, `./.opencode/`, `./.gemini/`, or `./.codex/`)
|
|
332
|
+
global: `~/.claude/`, `~/.config/opencode/`, `~/.opencode/`, `~/.gemini/`, `~/.config/kilo/`, or `~/.codex/`
|
|
333
|
+
local: `./.claude/`, `./.config/opencode/`, `./.opencode/`, `./.gemini/`, `./.kilo/`, or `./.codex/`)
|
|
226
334
|
|
|
227
335
|
Your custom files in other locations are preserved:
|
|
228
336
|
- Custom commands not in `commands/sdd/` ✓
|
|
@@ -230,9 +338,11 @@ Your custom files in other locations are preserved:
|
|
|
230
338
|
- Custom hooks ✓
|
|
231
339
|
- Your CLAUDE.md files ✓
|
|
232
340
|
|
|
233
|
-
If you've modified any SDD files directly, they'll be automatically backed up to `sdd-local-patches/` and can be reapplied with `/sdd
|
|
341
|
+
If you've modified any SDD files directly, they'll be automatically backed up to `sdd-local-patches/` and can be reapplied with `/sdd-reapply-patches` after the update.
|
|
234
342
|
```
|
|
235
343
|
|
|
344
|
+
|
|
345
|
+
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
|
236
346
|
Use AskUserQuestion:
|
|
237
347
|
- Question: "Proceed with update?"
|
|
238
348
|
- Options:
|
|
@@ -270,14 +380,55 @@ Capture output. If install fails, show error and exit.
|
|
|
270
380
|
Clear the update cache so statusline indicator disappears:
|
|
271
381
|
|
|
272
382
|
```bash
|
|
273
|
-
|
|
274
|
-
|
|
383
|
+
expand_home() {
|
|
384
|
+
case "$1" in
|
|
385
|
+
"~/"*) printf '%s/%s\n' "$HOME" "${1#~/}" ;;
|
|
386
|
+
*) printf '%s\n' "$1" ;;
|
|
387
|
+
esac
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
# Clear update cache across preferred, env-derived, and default runtime directories
|
|
391
|
+
CACHE_DIRS=()
|
|
392
|
+
if [ -n "$PREFERRED_CONFIG_DIR" ]; then
|
|
393
|
+
CACHE_DIRS+=( "$(expand_home "$PREFERRED_CONFIG_DIR")" )
|
|
394
|
+
fi
|
|
395
|
+
if [ -n "$CLAUDE_CONFIG_DIR" ]; then
|
|
396
|
+
CACHE_DIRS+=( "$(expand_home "$CLAUDE_CONFIG_DIR")" )
|
|
397
|
+
fi
|
|
398
|
+
if [ -n "$GEMINI_CONFIG_DIR" ]; then
|
|
399
|
+
CACHE_DIRS+=( "$(expand_home "$GEMINI_CONFIG_DIR")" )
|
|
400
|
+
fi
|
|
401
|
+
if [ -n "$KILO_CONFIG_DIR" ]; then
|
|
402
|
+
CACHE_DIRS+=( "$(expand_home "$KILO_CONFIG_DIR")" )
|
|
403
|
+
elif [ -n "$KILO_CONFIG" ]; then
|
|
404
|
+
CACHE_DIRS+=( "$(dirname "$(expand_home "$KILO_CONFIG")")" )
|
|
405
|
+
elif [ -n "$XDG_CONFIG_HOME" ]; then
|
|
406
|
+
CACHE_DIRS+=( "$(expand_home "$XDG_CONFIG_HOME")/kilo" )
|
|
407
|
+
fi
|
|
408
|
+
if [ -n "$OPENCODE_CONFIG_DIR" ]; then
|
|
409
|
+
CACHE_DIRS+=( "$(expand_home "$OPENCODE_CONFIG_DIR")" )
|
|
410
|
+
elif [ -n "$OPENCODE_CONFIG" ]; then
|
|
411
|
+
CACHE_DIRS+=( "$(dirname "$(expand_home "$OPENCODE_CONFIG")")" )
|
|
412
|
+
elif [ -n "$XDG_CONFIG_HOME" ]; then
|
|
413
|
+
CACHE_DIRS+=( "$(expand_home "$XDG_CONFIG_HOME")/opencode" )
|
|
414
|
+
fi
|
|
415
|
+
if [ -n "$CODEX_HOME" ]; then
|
|
416
|
+
CACHE_DIRS+=( "$(expand_home "$CODEX_HOME")" )
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
for dir in "${CACHE_DIRS[@]}"; do
|
|
420
|
+
if [ -n "$dir" ]; then
|
|
421
|
+
rm -f "$dir/cache/sdd-update-check.json"
|
|
422
|
+
fi
|
|
423
|
+
done
|
|
424
|
+
|
|
425
|
+
for dir in .claude .config/opencode .opencode .gemini .config/kilo .kilo .codex; do
|
|
275
426
|
rm -f "./$dir/cache/sdd-update-check.json"
|
|
276
427
|
rm -f "$HOME/$dir/cache/sdd-update-check.json"
|
|
277
428
|
done
|
|
278
429
|
```
|
|
279
430
|
|
|
280
|
-
The SessionStart hook (`sdd-check-update.js`) writes to the detected runtime's cache directory, so
|
|
431
|
+
The SessionStart hook (`sdd-check-update.js`) writes to the detected runtime's cache directory, so preferred/env-derived paths and default paths must all be cleared to prevent stale update indicators.
|
|
281
432
|
</step>
|
|
282
433
|
|
|
283
434
|
<step name="display_result">
|
|
@@ -290,7 +441,7 @@ Format completion message (changelog was already shown in confirmation step):
|
|
|
290
441
|
|
|
291
442
|
⚠️ Restart your runtime to pick up the new commands.
|
|
292
443
|
|
|
293
|
-
[View full changelog](https://github.com/
|
|
444
|
+
[View full changelog](https://github.com/bhargavvc/sdd-cc/blob/main/CHANGELOG.md)
|
|
294
445
|
```
|
|
295
446
|
</step>
|
|
296
447
|
|
|
@@ -304,7 +455,7 @@ Check for sdd-local-patches/backup-meta.json in the config directory.
|
|
|
304
455
|
|
|
305
456
|
```
|
|
306
457
|
Local patches were backed up before the update.
|
|
307
|
-
Run /sdd
|
|
458
|
+
Run /sdd-reapply-patches to merge your modifications into the new version.
|
|
308
459
|
```
|
|
309
460
|
|
|
310
461
|
**If no patches:** Continue normally.
|
|
@@ -28,7 +28,7 @@ AUDITOR_MODEL=$(node "$HOME/.claude/sdd/bin/sdd-tools.cjs" resolve-model sdd-nyq
|
|
|
28
28
|
NYQUIST_CFG=$(node "$HOME/.claude/sdd/bin/sdd-tools.cjs" config-get workflow.nyquist_validation --raw)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
If `NYQUIST_CFG` is `false`: exit with "Nyquist validation is disabled. Enable via /sdd
|
|
31
|
+
If `NYQUIST_CFG` is `false`: exit with "Nyquist validation is disabled. Enable via /sdd-settings."
|
|
32
32
|
|
|
33
33
|
Display banner: `SDD > VALIDATE PHASE {N}: {name}`
|
|
34
34
|
|
|
@@ -41,7 +41,7 @@ SUMMARY_FILES=$(ls "${PHASE_DIR}"/*-SUMMARY.md 2>/dev/null)
|
|
|
41
41
|
|
|
42
42
|
- **State A** (`VALIDATION_FILE` non-empty): Audit existing
|
|
43
43
|
- **State B** (`VALIDATION_FILE` empty, `SUMMARY_FILES` non-empty): Reconstruct from artifacts
|
|
44
|
-
- **State C** (`SUMMARY_FILES` empty): Exit — "Phase {N} not executed. Run /sdd
|
|
44
|
+
- **State C** (`SUMMARY_FILES` empty): Exit — "Phase {N} not executed. Run /sdd-execute-phase {N} ${SDD_WS} first."
|
|
45
45
|
|
|
46
46
|
## 2. Discovery
|
|
47
47
|
|
|
@@ -83,6 +83,8 @@ No gaps → skip to Step 6, set `nyquist_compliant: true`.
|
|
|
83
83
|
|
|
84
84
|
## 4. Present Gap Plan
|
|
85
85
|
|
|
86
|
+
|
|
87
|
+
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
|
86
88
|
Call AskUserQuestion with gap table and options:
|
|
87
89
|
1. "Fix all gaps" → Step 5
|
|
88
90
|
2. "Skip — mark manual-only" → add to Manual-Only, Step 6
|
|
@@ -144,14 +146,14 @@ node "$HOME/.claude/sdd/bin/sdd-tools.cjs" commit "docs(phase-${PHASE}): add/upd
|
|
|
144
146
|
```
|
|
145
147
|
SDD > PHASE {N} IS NYQUIST-COMPLIANT
|
|
146
148
|
All requirements have automated verification.
|
|
147
|
-
▶ Next: /sdd
|
|
149
|
+
▶ Next: /sdd-audit-milestone ${SDD_WS}
|
|
148
150
|
```
|
|
149
151
|
|
|
150
152
|
**Partial:**
|
|
151
153
|
```
|
|
152
154
|
SDD > PHASE {N} VALIDATED (PARTIAL)
|
|
153
155
|
{M} automated, {K} manual-only.
|
|
154
|
-
▶ Retry: /sdd
|
|
156
|
+
▶ Retry: /sdd-validate-phase {N} ${SDD_WS}
|
|
155
157
|
```
|
|
156
158
|
|
|
157
159
|
Display `/clear` reminder.
|
|
@@ -13,6 +13,7 @@ Goal-backward verification:
|
|
|
13
13
|
1. What must be TRUE for the goal to be achieved?
|
|
14
14
|
2. What must EXIST for those truths to hold?
|
|
15
15
|
3. What must be WIRED for those artifacts to function?
|
|
16
|
+
4. What must TESTS PROVE for those truths to be evidenced?
|
|
16
17
|
|
|
17
18
|
Then verify each level against the actual codebase.
|
|
18
19
|
</core_principle>
|
|
@@ -41,7 +42,12 @@ grep -E "^| ${phase_number}" .planning/REQUIREMENTS.md 2>/dev/null || true
|
|
|
41
42
|
ls "$phase_dir"/*-SUMMARY.md "$phase_dir"/*-PLAN.md 2>/dev/null || true
|
|
42
43
|
```
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
Load full milestone phases for deferred-item filtering (Step 9b):
|
|
46
|
+
```bash
|
|
47
|
+
node "$HOME/.claude/sdd/bin/sdd-tools.cjs" roadmap analyze
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Extract **phase goal** from ROADMAP.md (the outcome to verify, not tasks), **requirements** from REQUIREMENTS.md if it exists, and **all milestone phases** from roadmap analyze (for cross-referencing gaps against later phases).
|
|
45
51
|
</step>
|
|
46
52
|
|
|
47
53
|
<step name="establish_must_haves">
|
|
@@ -177,6 +183,89 @@ grep -E "Phase ${PHASE_NUM}" .planning/REQUIREMENTS.md 2>/dev/null || true
|
|
|
177
183
|
For each requirement: parse description → identify supporting truths/artifacts → status: ✓ SATISFIED / ✗ BLOCKED / ? NEEDS HUMAN.
|
|
178
184
|
</step>
|
|
179
185
|
|
|
186
|
+
<step name="behavioral_verification">
|
|
187
|
+
**Run the project's test suite and CLI commands to verify behavior, not just structure.**
|
|
188
|
+
|
|
189
|
+
Static checks (grep, file existence, wiring) catch structural gaps but miss runtime
|
|
190
|
+
failures. This step runs actual tests and project commands to verify the phase goal
|
|
191
|
+
is behaviorally achieved.
|
|
192
|
+
|
|
193
|
+
This follows Anthropic's harness engineering principle: separating generation from
|
|
194
|
+
evaluation, with the evaluator interacting with the running system rather than
|
|
195
|
+
inspecting static artifacts.
|
|
196
|
+
|
|
197
|
+
**Step 1: Run test suite**
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# Detect test runner and run all tests (timeout: 5 minutes)
|
|
201
|
+
TEST_EXIT=0
|
|
202
|
+
timeout 300 bash -c '
|
|
203
|
+
if [ -f "package.json" ]; then
|
|
204
|
+
npm test 2>&1
|
|
205
|
+
elif [ -f "Cargo.toml" ]; then
|
|
206
|
+
cargo test 2>&1
|
|
207
|
+
elif [ -f "go.mod" ]; then
|
|
208
|
+
go test ./... 2>&1
|
|
209
|
+
elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then
|
|
210
|
+
python -m pytest -q --tb=short 2>&1 || uv run python -m pytest -q --tb=short 2>&1
|
|
211
|
+
else
|
|
212
|
+
echo "⚠ No test runner detected — skipping test suite"
|
|
213
|
+
exit 1
|
|
214
|
+
fi
|
|
215
|
+
'
|
|
216
|
+
TEST_EXIT=$?
|
|
217
|
+
if [ "${TEST_EXIT}" -eq 0 ]; then
|
|
218
|
+
echo "✓ Test suite passed"
|
|
219
|
+
elif [ "${TEST_EXIT}" -eq 124 ]; then
|
|
220
|
+
echo "⚠ Test suite timed out after 5 minutes"
|
|
221
|
+
else
|
|
222
|
+
echo "✗ Test suite failed (exit code ${TEST_EXIT})"
|
|
223
|
+
fi
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Record: total tests, passed, failed, coverage (if available).
|
|
227
|
+
|
|
228
|
+
**If any tests fail:** Mark as `behavioral_failures` — these are BLOCKER severity
|
|
229
|
+
regardless of whether static checks passed. A phase cannot be verified if tests fail.
|
|
230
|
+
|
|
231
|
+
**Step 2: Run project CLI/commands from success criteria (if testable)**
|
|
232
|
+
|
|
233
|
+
For each success criterion that describes a user command (e.g., "User can run
|
|
234
|
+
`mixtiq validate`", "User can run `npm start`"):
|
|
235
|
+
|
|
236
|
+
1. Check if the command exists and required inputs are available:
|
|
237
|
+
- Look for example files in `templates/`, `fixtures/`, `test/`, `examples/`, or `testdata/`
|
|
238
|
+
- Check if the CLI binary/script exists on PATH or in the project
|
|
239
|
+
2. **If no suitable inputs or fixtures exist:** Mark as `? NEEDS HUMAN` with reason
|
|
240
|
+
"No test fixtures available — requires manual verification" and move on.
|
|
241
|
+
Do NOT invent example inputs.
|
|
242
|
+
3. If inputs are available: run the command and verify it exits successfully.
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Only run if both command and input exist
|
|
246
|
+
if command -v {project_cli} &>/dev/null && [ -f "{example_input}" ]; then
|
|
247
|
+
{project_cli} {example_input} 2>&1
|
|
248
|
+
fi
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Record: command, exit code, output summary, pass/fail (or SKIPPED if no fixtures).
|
|
252
|
+
|
|
253
|
+
**Step 3: Report**
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
## Behavioral Verification
|
|
257
|
+
|
|
258
|
+
| Check | Result | Detail |
|
|
259
|
+
|-------|--------|--------|
|
|
260
|
+
| Test suite | {N} passed, {M} failed | {first failure if any} |
|
|
261
|
+
| {CLI command 1} | ✓ / ✗ | {output summary} |
|
|
262
|
+
| {CLI command 2} | ✓ / ✗ | {output summary} |
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**If all behavioral checks pass:** Continue to scan_antipatterns.
|
|
266
|
+
**If any fail:** Add to verification gaps with BLOCKER severity.
|
|
267
|
+
</step>
|
|
268
|
+
|
|
180
269
|
<step name="scan_antipatterns">
|
|
181
270
|
Extract files modified in this phase from SUMMARY.md, scan each:
|
|
182
271
|
|
|
@@ -190,6 +279,93 @@ Extract files modified in this phase from SUMMARY.md, scan each:
|
|
|
190
279
|
Categorize: 🛑 Blocker (prevents goal) | ⚠️ Warning (incomplete) | ℹ️ Info (notable).
|
|
191
280
|
</step>
|
|
192
281
|
|
|
282
|
+
<step name="audit_test_quality">
|
|
283
|
+
**Verify that tests PROVE what they claim to prove.**
|
|
284
|
+
|
|
285
|
+
This step catches test-level deceptions that pass all prior checks: files exist, are substantive, are wired, and tests pass — but the tests don't actually validate the requirement.
|
|
286
|
+
|
|
287
|
+
**1. Identify requirement-linked test files**
|
|
288
|
+
|
|
289
|
+
From PLAN and SUMMARY files, map each requirement to the test files that are supposed to prove it.
|
|
290
|
+
|
|
291
|
+
**2. Disabled test scan**
|
|
292
|
+
|
|
293
|
+
For ALL test files linked to requirements, search for disabled/skipped patterns:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
grep -rn -E "it\.skip|describe\.skip|test\.skip|xit\(|xdescribe\(|xtest\(|@pytest\.mark\.skip|@unittest\.skip|#\[ignore\]|\.pending|it\.todo|test\.todo" "$TEST_FILE"
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Rule:** A disabled test linked to a requirement = requirement NOT tested.
|
|
300
|
+
- 🛑 BLOCKER if the disabled test is the only test proving that requirement
|
|
301
|
+
- ⚠️ WARNING if other active tests also cover the requirement
|
|
302
|
+
|
|
303
|
+
**3. Circular test detection**
|
|
304
|
+
|
|
305
|
+
Search for scripts/utilities that generate expected values by running the system under test:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
grep -rn -E "writeFileSync|writeFile|fs\.write|open\(.*w\)" "$TEST_DIRS"
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
For each match, check if it also imports the system/service/module being tested. If a script both imports the system-under-test AND writes expected output values → CIRCULAR.
|
|
312
|
+
|
|
313
|
+
**Circular test indicators:**
|
|
314
|
+
- Script imports a service AND writes to fixture files
|
|
315
|
+
- Expected values have comments like "computed from engine", "captured from baseline"
|
|
316
|
+
- Script filename contains "capture", "baseline", "generate", "snapshot" in test context
|
|
317
|
+
- Expected values were added in the same commit as the test assertions
|
|
318
|
+
|
|
319
|
+
**Rule:** A test comparing system output against values generated by the same system is circular. It proves consistency, not correctness.
|
|
320
|
+
|
|
321
|
+
**4. Expected value provenance** (for comparison/parity/migration requirements)
|
|
322
|
+
|
|
323
|
+
When a requirement demands comparison with an external source ("identical to X", "matches Y", "same output as Z"):
|
|
324
|
+
|
|
325
|
+
- Is the external source actually invoked or referenced in the test pipeline?
|
|
326
|
+
- Do fixture files contain data sourced from the external system?
|
|
327
|
+
- Or do all expected values come from the new system itself or from mathematical formulas?
|
|
328
|
+
|
|
329
|
+
**Provenance classification:**
|
|
330
|
+
- VALID: Expected value from external/legacy system output, manual capture, or independent oracle
|
|
331
|
+
- PARTIAL: Expected value from mathematical derivation (proves formula, not system match)
|
|
332
|
+
- CIRCULAR: Expected value from the system being tested
|
|
333
|
+
- UNKNOWN: No provenance information — treat as SUSPECT
|
|
334
|
+
|
|
335
|
+
**5. Assertion strength**
|
|
336
|
+
|
|
337
|
+
For each test linked to a requirement, classify the strongest assertion:
|
|
338
|
+
|
|
339
|
+
| Level | Examples | Proves |
|
|
340
|
+
|-------|---------|--------|
|
|
341
|
+
| Existence | `toBeDefined()`, `!= null` | Something returned |
|
|
342
|
+
| Type | `typeof x === 'number'` | Correct shape |
|
|
343
|
+
| Status | `code === 200` | No error |
|
|
344
|
+
| Value | `toEqual(expected)`, `toBeCloseTo(x)` | Specific value |
|
|
345
|
+
| Behavioral | Multi-step workflow assertions | End-to-end correctness |
|
|
346
|
+
|
|
347
|
+
If a requirement demands value-level or behavioral-level proof and the test only has existence/type/status assertions → INSUFFICIENT.
|
|
348
|
+
|
|
349
|
+
**6. Coverage quantity**
|
|
350
|
+
|
|
351
|
+
If a requirement specifies a quantity of test cases (e.g., "30 calculations"), check if the actual number of active (non-skipped) test cases meets the requirement.
|
|
352
|
+
|
|
353
|
+
**Reporting — add to VERIFICATION.md:**
|
|
354
|
+
|
|
355
|
+
```markdown
|
|
356
|
+
### Test Quality Audit
|
|
357
|
+
|
|
358
|
+
| Test File | Linked Req | Active | Skipped | Circular | Assertion Level | Verdict |
|
|
359
|
+
|-----------|-----------|--------|---------|----------|----------------|---------|
|
|
360
|
+
|
|
361
|
+
**Disabled tests on requirements:** {N} → {BLOCKER if any req has ONLY disabled tests}
|
|
362
|
+
**Circular patterns detected:** {N} → {BLOCKER if any}
|
|
363
|
+
**Insufficient assertions:** {N} → {WARNING}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Impact on status:** Any BLOCKER from test quality audit ��� overall status = `gaps_found`, regardless of other checks passing.
|
|
367
|
+
</step>
|
|
368
|
+
|
|
193
369
|
<step name="identify_human_verification">
|
|
194
370
|
**Always needs human:** Visual appearance, user flow completion, real-time behavior (WebSocket/SSE), external service integration, performance feel, error message clarity.
|
|
195
371
|
|
|
@@ -199,15 +375,41 @@ Format each as: Test Name → What to do → Expected result → Why can't verif
|
|
|
199
375
|
</step>
|
|
200
376
|
|
|
201
377
|
<step name="determine_status">
|
|
202
|
-
|
|
378
|
+
Classify status using this decision tree IN ORDER (most restrictive first):
|
|
203
379
|
|
|
204
|
-
|
|
380
|
+
1. IF any truth FAILED, artifact MISSING/STUB, key link NOT_WIRED, blocker found, **or test quality audit found blockers (disabled requirement tests, circular tests)**:
|
|
381
|
+
→ **gaps_found**
|
|
205
382
|
|
|
206
|
-
|
|
383
|
+
2. IF the previous step produced ANY human verification items:
|
|
384
|
+
→ **human_needed** (even if all truths VERIFIED and score is N/N)
|
|
385
|
+
|
|
386
|
+
3. IF all checks pass AND no human verification items:
|
|
387
|
+
→ **passed**
|
|
388
|
+
|
|
389
|
+
**passed is ONLY valid when no human verification items exist.**
|
|
207
390
|
|
|
208
391
|
**Score:** `verified_truths / total_truths`
|
|
209
392
|
</step>
|
|
210
393
|
|
|
394
|
+
<step name="filter_deferred_items">
|
|
395
|
+
Before reporting gaps, cross-reference each gap against later phases in the milestone using the full roadmap data loaded in load_context (from `roadmap analyze`).
|
|
396
|
+
|
|
397
|
+
For each potential gap identified in determine_status:
|
|
398
|
+
1. Check if the gap's failed truth or missing item is covered by a later phase's goal or success criteria
|
|
399
|
+
2. **Match criteria:** The gap's concern appears in a later phase's goal text, success criteria text, or the later phase's name clearly suggests it covers this area
|
|
400
|
+
3. If a clear match is found → move the gap to a `deferred` list with the matching phase reference and evidence text
|
|
401
|
+
4. If no match in any later phase → keep as a real `gap`
|
|
402
|
+
|
|
403
|
+
**Important:** Be conservative. Only defer a gap when there is clear, specific evidence in a later phase. Vague or tangential matches should NOT cause deferral — when in doubt, keep it as a real gap.
|
|
404
|
+
|
|
405
|
+
**Deferred items do NOT affect the status determination.** Recalculate after filtering:
|
|
406
|
+
- If gaps list is now empty and no human items exist → `passed`
|
|
407
|
+
- If gaps list is now empty but human items exist → `human_needed`
|
|
408
|
+
- If gaps list still has items → `gaps_found`
|
|
409
|
+
|
|
410
|
+
Include deferred items in VERIFICATION.md frontmatter (`deferred:` section) and body (Deferred Items table) for transparency. If no deferred items exist, omit these sections.
|
|
411
|
+
</step>
|
|
412
|
+
|
|
211
413
|
<step name="generate_fix_plans">
|
|
212
414
|
If gaps_found:
|
|
213
415
|
|
|
@@ -215,7 +417,7 @@ If gaps_found:
|
|
|
215
417
|
|
|
216
418
|
2. **Generate plan per cluster:** Objective, 2-3 tasks (files/action/verify each), re-verify step. Keep focused: single concern per plan.
|
|
217
419
|
|
|
218
|
-
3. **Order by dependency:** Fix missing → fix stubs → fix wiring → verify.
|
|
420
|
+
3. **Order by dependency:** Fix missing → fix stubs → fix wiring → **fix test evidence** → verify.
|
|
219
421
|
</step>
|
|
220
422
|
|
|
221
423
|
<step name="create_report">
|
|
@@ -246,9 +448,11 @@ Orchestrator routes: `passed` → update_roadmap | `gaps_found` → create/execu
|
|
|
246
448
|
- [ ] All key links verified
|
|
247
449
|
- [ ] Requirements coverage assessed (if applicable)
|
|
248
450
|
- [ ] Anti-patterns scanned and categorized
|
|
451
|
+
- [ ] Test quality audited (disabled tests, circular patterns, assertion strength, provenance)
|
|
249
452
|
- [ ] Human verification items identified
|
|
250
453
|
- [ ] Overall status determined
|
|
251
|
-
- [ ]
|
|
454
|
+
- [ ] Deferred items filtered against later milestone phases (if gaps found)
|
|
455
|
+
- [ ] Fix plans generated (if gaps_found after filtering)
|
|
252
456
|
- [ ] VERIFICATION.md created with complete report
|
|
253
457
|
- [ ] Results returned to orchestrator
|
|
254
458
|
</success_criteria>
|