@opengsd/gsd-core 1.6.0-rc.2 → 1.6.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/.claude-plugin/plugin.json +2 -1
- package/agents/gsd-advisor-researcher.md +2 -0
- package/agents/gsd-ai-researcher.md +2 -0
- package/agents/gsd-assumptions-analyzer.md +2 -0
- package/agents/gsd-doc-classifier.md +2 -0
- package/agents/gsd-doc-synthesizer.md +2 -0
- package/agents/gsd-domain-researcher.md +2 -0
- package/agents/gsd-eval-auditor.md +6 -9
- package/agents/gsd-phase-researcher.md +2 -0
- package/agents/gsd-planner.md +8 -57
- package/agents/gsd-project-researcher.md +2 -0
- package/agents/gsd-research-synthesizer.md +2 -0
- package/agents/gsd-security-auditor.md +37 -18
- package/agents/gsd-ui-researcher.md +2 -0
- package/bin/install.js +370 -18
- package/gemini-extension.json +1 -1
- package/gsd-core/bin/gsd-tools.cjs +46 -4
- package/gsd-core/bin/lib/audit-command-router.cjs +52 -14
- package/gsd-core/bin/lib/capability-lifecycle.cjs +30 -7
- package/gsd-core/bin/lib/capability-registry.cjs +96 -83
- package/gsd-core/bin/lib/capability-validator.cjs +22 -0
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +40 -2
- package/gsd-core/bin/lib/command-aliases.cjs +10 -1
- package/gsd-core/bin/lib/command-routing-hub.cjs +10 -3
- package/gsd-core/bin/lib/config-schema.cjs +1 -0
- package/gsd-core/bin/lib/config.cjs +67 -24
- package/gsd-core/bin/lib/coverage.cjs +464 -0
- package/gsd-core/bin/lib/decisions.cjs +27 -0
- package/gsd-core/bin/lib/eval-command-router.cjs +21 -0
- package/gsd-core/bin/lib/eval.cjs +60 -0
- package/gsd-core/bin/lib/frontmatter.cjs +132 -13
- package/gsd-core/bin/lib/graphify-command-router.cjs +53 -36
- package/gsd-core/bin/lib/init.cjs +139 -30
- package/gsd-core/bin/lib/install-profiles.cjs +6 -3
- package/gsd-core/bin/lib/intel-command-router.cjs +79 -60
- package/gsd-core/bin/lib/io.cjs +1 -0
- package/gsd-core/bin/lib/phase.cjs +16 -2
- package/gsd-core/bin/lib/plan-scan.cjs +2 -2
- package/gsd-core/bin/lib/planning-workspace.cjs +157 -13
- package/gsd-core/bin/lib/profile-output.cjs +18 -6
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +53 -16
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +21 -3
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +15 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +47 -2
- package/gsd-core/bin/lib/shell-command-projection.cjs +10 -0
- package/gsd-core/bin/lib/state.cjs +398 -60
- package/gsd-core/bin/lib/surface.cjs +42 -10
- package/gsd-core/bin/lib/uat-predicate.cjs +13 -6
- package/gsd-core/bin/lib/update-context.cjs +2 -2
- package/gsd-core/bin/lib/verification.cjs +67 -6
- package/gsd-core/bin/lib/verify.cjs +8 -1
- package/gsd-core/bin/shared/config-defaults.manifest.json +3 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +2 -1
- package/gsd-core/references/planner-guidance.md +66 -0
- package/gsd-core/references/planning-config.md +2 -2
- package/gsd-core/references/security-asvs-levels.md +27 -0
- package/gsd-core/references/untrusted-input-boundary.md +13 -0
- package/gsd-core/templates/SECURITY.md +6 -4
- package/gsd-core/templates/summary-complex.md +4 -0
- package/gsd-core/templates/summary-minimal.md +3 -0
- package/gsd-core/templates/summary-standard.md +4 -0
- package/gsd-core/templates/summary.md +41 -0
- package/gsd-core/workflows/autonomous.md +53 -46
- package/gsd-core/workflows/complete-milestone.md +27 -8
- package/gsd-core/workflows/execute-phase.md +1 -1
- package/gsd-core/workflows/execute-plan.md +5 -0
- package/gsd-core/workflows/manager.md +17 -7
- package/gsd-core/workflows/new-project.md +82 -16
- package/gsd-core/workflows/plan-phase.md +15 -0
- package/gsd-core/workflows/profile-user.md +6 -2
- package/gsd-core/workflows/progress.md +37 -4
- package/gsd-core/workflows/quick.md +3 -1
- package/gsd-core/workflows/secure-phase.md +13 -7
- package/gsd-core/workflows/ship.md +3 -1
- package/gsd-core/workflows/spec-phase.md +3 -1
- package/gsd-core/workflows/transition.md +14 -12
- package/gsd-core/workflows/ui-review.md +2 -6
- package/gsd-core/workflows/verify-work.md +74 -1
- package/hooks/dist/gsd-read-injection-scanner.js +49 -25
- package/hooks/gsd-read-injection-scanner.js +49 -25
- package/hooks/hooks.json +1 -1
- package/package.json +4 -2
- package/scripts/check-alias-drift.cjs +5 -0
- package/scripts/gen-plugin-skills.cjs +117 -0
- package/scripts/lint-test-file-count.allowlist.json +2 -1
- package/scripts/prompt-injection-scan.sh +9 -0
- package/scripts/release-notes/conventional-title.cjs +88 -0
- package/scripts/release-notes/format-github-release-notes.cjs +4 -3
- package/skills/gsd-add-tests/SKILL.md +38 -0
- package/skills/gsd-ai-integration-phase/SKILL.md +37 -0
- package/skills/gsd-audit-fix/SKILL.md +33 -0
- package/skills/gsd-audit-milestone/SKILL.md +37 -0
- package/skills/gsd-audit-uat/SKILL.md +25 -0
- package/skills/gsd-autonomous/SKILL.md +51 -0
- package/skills/gsd-capture/SKILL.md +67 -0
- package/skills/gsd-cleanup/SKILL.md +24 -0
- package/skills/gsd-code-review/SKILL.md +59 -0
- package/skills/gsd-complete-milestone/SKILL.md +142 -0
- package/skills/gsd-config/SKILL.md +56 -0
- package/skills/gsd-debug/SKILL.md +53 -0
- package/skills/gsd-discuss-phase/SKILL.md +77 -0
- package/skills/gsd-docs-update/SKILL.md +49 -0
- package/skills/gsd-eval-review/SKILL.md +33 -0
- package/skills/gsd-execute-phase/SKILL.md +65 -0
- package/skills/gsd-explore/SKILL.md +28 -0
- package/skills/gsd-extract-learnings/SKILL.md +22 -0
- package/skills/gsd-fast/SKILL.md +31 -0
- package/skills/gsd-forensics/SKILL.md +56 -0
- package/skills/gsd-graphify/SKILL.md +204 -0
- package/skills/gsd-health/SKILL.md +31 -0
- package/skills/gsd-help/SKILL.md +29 -0
- package/skills/gsd-import/SKILL.md +46 -0
- package/skills/gsd-inbox/SKILL.md +39 -0
- package/skills/gsd-ingest-docs/SKILL.md +43 -0
- package/skills/gsd-manager/SKILL.md +45 -0
- package/skills/gsd-map-codebase/SKILL.md +83 -0
- package/skills/gsd-mempalace-capture/SKILL.md +71 -0
- package/skills/gsd-mempalace-recall/SKILL.md +102 -0
- package/skills/gsd-milestone-summary/SKILL.md +51 -0
- package/skills/gsd-mvp-phase/SKILL.md +45 -0
- package/skills/gsd-new-milestone/SKILL.md +45 -0
- package/skills/gsd-new-project/SKILL.md +47 -0
- package/skills/gsd-ns-context/SKILL.md +24 -0
- package/skills/gsd-ns-ideate/SKILL.md +23 -0
- package/skills/gsd-ns-manage/SKILL.md +35 -0
- package/skills/gsd-ns-project/SKILL.md +26 -0
- package/skills/gsd-ns-review/SKILL.md +28 -0
- package/skills/gsd-ns-workflow/SKILL.md +33 -0
- package/skills/gsd-pause-work/SKILL.md +43 -0
- package/skills/gsd-phase/SKILL.md +57 -0
- package/skills/gsd-plan-phase/SKILL.md +63 -0
- package/skills/gsd-plan-review-convergence/SKILL.md +60 -0
- package/skills/gsd-pr-branch/SKILL.md +26 -0
- package/skills/gsd-profile-user/SKILL.md +47 -0
- package/skills/gsd-progress/SKILL.md +49 -0
- package/skills/gsd-quick/SKILL.md +174 -0
- package/skills/gsd-resume-work/SKILL.md +31 -0
- package/skills/gsd-review/SKILL.md +42 -0
- package/skills/gsd-review-backlog/SKILL.md +63 -0
- package/skills/gsd-secure-phase/SKILL.md +36 -0
- package/skills/gsd-settings/SKILL.md +29 -0
- package/skills/gsd-ship/SKILL.md +24 -0
- package/skills/gsd-sketch/SKILL.md +60 -0
- package/skills/gsd-spec-phase/SKILL.md +63 -0
- package/skills/gsd-spike/SKILL.md +57 -0
- package/skills/gsd-stats/SKILL.md +20 -0
- package/skills/gsd-surface/SKILL.md +162 -0
- package/skills/gsd-thread/SKILL.md +24 -0
- package/skills/gsd-ui-phase/SKILL.md +35 -0
- package/skills/gsd-ui-review/SKILL.md +33 -0
- package/skills/gsd-ultraplan-phase/SKILL.md +34 -0
- package/skills/gsd-undo/SKILL.md +35 -0
- package/skills/gsd-update/SKILL.md +50 -0
- package/skills/gsd-validate-phase/SKILL.md +36 -0
- package/skills/gsd-verify-work/SKILL.md +39 -0
- package/skills/gsd-workspace/SKILL.md +53 -0
- package/skills/gsd-workstreams/SKILL.md +70 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsd-core",
|
|
3
3
|
"displayName": "GSD Core",
|
|
4
|
-
"version": "1.6.0
|
|
4
|
+
"version": "1.6.0",
|
|
5
5
|
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "open-gsd",
|
|
@@ -19,5 +19,6 @@
|
|
|
19
19
|
"gsd"
|
|
20
20
|
],
|
|
21
21
|
"commands": "./commands/gsd/",
|
|
22
|
+
"skills": "./skills/",
|
|
22
23
|
"hooks": "./hooks/hooks.json"
|
|
23
24
|
}
|
|
@@ -17,6 +17,8 @@ Spawned by `discuss-phase` via `Task()`. You do NOT present output directly to t
|
|
|
17
17
|
- Return structured markdown output for the main agent to synthesize
|
|
18
18
|
</role>
|
|
19
19
|
|
|
20
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
21
|
+
|
|
20
22
|
<documentation_lookup>
|
|
21
23
|
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
|
22
24
|
</documentation_lookup>
|
|
@@ -16,6 +16,8 @@ You are a GSD AI researcher. Answer: "How do I correctly implement this AI syste
|
|
|
16
16
|
Write Sections 3–4b of AI-SPEC.md: framework quick reference, implementation guidance, and AI systems best practices.
|
|
17
17
|
</role>
|
|
18
18
|
|
|
19
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
20
|
+
|
|
19
21
|
<documentation_lookup>
|
|
20
22
|
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
|
21
23
|
</documentation_lookup>
|
|
@@ -18,6 +18,8 @@ Spawned by `discuss-phase-assumptions` via `Task()`. You do NOT present output d
|
|
|
18
18
|
- Flag topics where codebase analysis alone is insufficient (needs external research)
|
|
19
19
|
</role>
|
|
20
20
|
|
|
21
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
22
|
+
|
|
21
23
|
<input>
|
|
22
24
|
Agent receives via prompt:
|
|
23
25
|
|
|
@@ -18,6 +18,8 @@ You are a GSD doc classifier. You read ONE document and write a structured class
|
|
|
18
18
|
If the prompt contains a `<required_reading>` block, use the `Read` tool to load every file listed there before doing anything else. That is your primary context.
|
|
19
19
|
</role>
|
|
20
20
|
|
|
21
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
22
|
+
|
|
21
23
|
<why_this_matters>
|
|
22
24
|
Your classification drives extraction. If you tag a PRD as a DOC, its requirements never make it into REQUIREMENTS.md. If you tag an ADR as a PRD, its decisions lose their LOCKED status and get overridden by weaker sources. Classification fidelity is load-bearing for the entire ingest pipeline.
|
|
23
25
|
</why_this_matters>
|
|
@@ -20,6 +20,8 @@ You do NOT prompt the user. You do NOT write PROJECT.md, REQUIREMENTS.md, or ROA
|
|
|
20
20
|
If the prompt contains a `<required_reading>` block, load every file listed there first — especially `references/doc-conflict-engine.md` which defines your conflict report format.
|
|
21
21
|
</role>
|
|
22
22
|
|
|
23
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
24
|
+
|
|
23
25
|
<why_this_matters>
|
|
24
26
|
You are the precedence-enforcing layer. Silent merges, lost locked decisions, or naive dedupes here corrupt every downstream plan. When in doubt, surface the conflict rather than pick.
|
|
25
27
|
</why_this_matters>
|
|
@@ -16,6 +16,8 @@ You are a GSD domain researcher. Answer: "What do domain experts actually care a
|
|
|
16
16
|
Research the business domain — not the technical framework. Write Section 1b of AI-SPEC.md.
|
|
17
17
|
</role>
|
|
18
18
|
|
|
19
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
20
|
+
|
|
19
21
|
<documentation_lookup>
|
|
20
22
|
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
|
21
23
|
</documentation_lookup>
|
|
@@ -109,17 +109,14 @@ Score 5 components (ok / partial / missing):
|
|
|
109
109
|
</step>
|
|
110
110
|
|
|
111
111
|
<step name="calculate_scores">
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
Do NOT compute scores by hand. Call the deterministic verb with your audited inputs:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
116
|
+
gsd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
|
|
116
117
|
```
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
- 80-100: **PRODUCTION READY** — deploy with monitoring
|
|
120
|
-
- 60-79: **NEEDS WORK** — address CRITICAL gaps before production
|
|
121
|
-
- 40-59: **SIGNIFICANT GAPS** — do not deploy
|
|
122
|
-
- 0-39: **NOT IMPLEMENTED** — review AI-SPEC.md and implement
|
|
119
|
+
where each infra component is `ok`, `partial`, or `missing` (from the audit_infrastructure step). Parse the JSON result — it returns `coverage_score`, `infra_score`, `overall_score`, and `verdict` (PRODUCTION READY / NEEDS WORK / SIGNIFICANT GAPS / NOT IMPLEMENTED). Use those values verbatim in EVAL-REVIEW.md; never recompute or override them.
|
|
123
120
|
</step>
|
|
124
121
|
|
|
125
122
|
<step name="write_eval_review">
|
|
@@ -35,6 +35,8 @@ Spawned by `/gsd:plan-phase` (integrated) or `/gsd:plan-phase --research-phase <
|
|
|
35
35
|
Claims tagged `[ASSUMED]` signal to the planner and discuss-phase that the information needs user confirmation before becoming a locked decision. Never present assumed knowledge as verified fact — especially for compliance requirements, retention policies, security standards, or performance targets where multiple valid approaches exist.
|
|
36
36
|
</role>
|
|
37
37
|
|
|
38
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
39
|
+
|
|
38
40
|
<documentation_lookup>
|
|
39
41
|
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
|
40
42
|
</documentation_lookup>
|
package/agents/gsd-planner.md
CHANGED
|
@@ -380,11 +380,11 @@ Output: [Artifacts created]
|
|
|
380
380
|
|
|
381
381
|
## STRIDE Threat Register
|
|
382
382
|
|
|
383
|
-
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
|
384
|
-
|
|
385
|
-
| T-{phase}-01 | {S/T/R/I/D/E} | {function/endpoint/file} | mitigate | {specific
|
|
386
|
-
| T-{phase}-02 | {category} | {component} | accept | {rationale
|
|
387
|
-
| T-{phase}-SC | Tampering | npm/pip/cargo installs | mitigate | slopcheck + blocking human checkpoint for [ASSUMED]/[SUS] |
|
|
383
|
+
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
|
384
|
+
|-----------|----------|-----------|----------|-------------|-----------------|
|
|
385
|
+
| T-{phase}-01 | {S/T/R/I/D/E} | {function/endpoint/file} | {critical\|high\|medium\|low} | mitigate | {specific mitigation action} |
|
|
386
|
+
| T-{phase}-02 | {category} | {component} | low | accept | {rationale for acceptance} |
|
|
387
|
+
| T-{phase}-SC | Tampering | npm/pip/cargo installs | high | mitigate | slopcheck + blocking human checkpoint for [ASSUMED]/[SUS] |
|
|
388
388
|
</threat_model>
|
|
389
389
|
|
|
390
390
|
<verification>
|
|
@@ -459,7 +459,7 @@ Only include what Claude literally cannot do.
|
|
|
459
459
|
**Step 0: Extract Requirement IDs**
|
|
460
460
|
Read ROADMAP.md `**Requirements:**` line for this phase. Strip brackets if present (e.g., `[AUTH-01, AUTH-02]` → `AUTH-01, AUTH-02`). Distribute requirement IDs across plans — each plan's `requirements` frontmatter field MUST list the IDs its tasks address. **CRITICAL:** Every requirement ID MUST appear in at least one plan. Plans with an empty `requirements` field are invalid.
|
|
461
461
|
|
|
462
|
-
**Security (when `security_enforcement` enabled — absent = enabled):** Identify trust boundaries in this phase's scope. Map STRIDE categories to applicable tech stack from RESEARCH.md security domain. For each threat: assign
|
|
462
|
+
**Security (when `security_enforcement` enabled — absent = enabled):** Identify trust boundaries in this phase's scope. Map STRIDE categories to applicable tech stack from RESEARCH.md security domain. For each threat: assign a **severity** (critical|high|medium|low) based on impact × likelihood, and a disposition (`mitigate`/`accept`/`transfer`) per the configured OWASP ASVS level — see @~/.claude/gsd-core/references/security-asvs-levels.md. Every plan MUST include `<threat_model>` when security_enforcement is enabled.
|
|
463
463
|
|
|
464
464
|
**Package legitimacy gate (npm/pip/cargo only):**
|
|
465
465
|
- Require RESEARCH.md `## Package Legitimacy Audit` before package-manager install tasks.
|
|
@@ -477,66 +477,16 @@ Take phase goal from ROADMAP.md. Must be outcome-shaped, not task-shaped.
|
|
|
477
477
|
**Step 2: Derive Observable Truths**
|
|
478
478
|
"What must be TRUE for this goal to be achieved?" List 3-7 truths from USER's perspective.
|
|
479
479
|
|
|
480
|
-
For "working chat interface":
|
|
481
|
-
- User can see existing messages
|
|
482
|
-
- User can type a new message
|
|
483
|
-
- User can send the message
|
|
484
|
-
- Sent message appears in the list
|
|
485
|
-
- Messages persist across page refresh
|
|
486
|
-
|
|
487
|
-
**Test:** Each truth verifiable by a human using the application.
|
|
488
|
-
|
|
489
480
|
**Step 3: Derive Required Artifacts**
|
|
490
481
|
For each truth: "What must EXIST for this to be true?"
|
|
491
482
|
|
|
492
|
-
"User can see existing messages" requires:
|
|
493
|
-
- Message list component (renders Message[])
|
|
494
|
-
- Messages state (loaded from somewhere)
|
|
495
|
-
- API route or data source (provides messages)
|
|
496
|
-
- Message type definition (shapes the data)
|
|
497
|
-
|
|
498
|
-
**Test:** Each artifact = a specific file or database object.
|
|
499
|
-
|
|
500
483
|
**Step 4: Derive Required Wiring**
|
|
501
484
|
For each artifact: "What must be CONNECTED for this to function?"
|
|
502
485
|
|
|
503
|
-
Message list component wiring:
|
|
504
|
-
- Imports Message type (not using `any`)
|
|
505
|
-
- Receives messages prop or fetches from API
|
|
506
|
-
- Maps over messages to render (not hardcoded)
|
|
507
|
-
- Handles empty state (not just crashes)
|
|
508
|
-
|
|
509
486
|
**Step 5: Identify Key Links**
|
|
510
487
|
"Where is this most likely to break?" Key links = critical connections where breakage causes cascading failures.
|
|
511
488
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
```yaml
|
|
515
|
-
must_haves:
|
|
516
|
-
truths:
|
|
517
|
-
- "User can see existing messages"
|
|
518
|
-
- "User can send a message"
|
|
519
|
-
- "Messages persist across refresh"
|
|
520
|
-
artifacts:
|
|
521
|
-
- path: "src/components/Chat.tsx"
|
|
522
|
-
provides: "Message list rendering"
|
|
523
|
-
min_lines: 30
|
|
524
|
-
- path: "src/app/api/chat/route.ts"
|
|
525
|
-
provides: "Message CRUD operations"
|
|
526
|
-
exports: ["GET", "POST"]
|
|
527
|
-
- path: "prisma/schema.prisma"
|
|
528
|
-
provides: "Message model"
|
|
529
|
-
contains: "model Message"
|
|
530
|
-
key_links:
|
|
531
|
-
- from: "src/components/Chat.tsx"
|
|
532
|
-
to: "src/app/api/chat/route.ts"
|
|
533
|
-
via: "fetch in useEffect — calls /api/chat endpoint"
|
|
534
|
-
pattern: "fetch.*api/chat"
|
|
535
|
-
- from: "src/app/api/chat/route.ts"
|
|
536
|
-
to: "prisma/schema.prisma"
|
|
537
|
-
via: "database query via prisma.message"
|
|
538
|
-
pattern: "prisma\\.message\\.(find|create)"
|
|
539
|
-
```
|
|
489
|
+
See @~/.claude/gsd-core/references/planner-guidance.md for a worked example and the `must_haves` YAML format.
|
|
540
490
|
|
|
541
491
|
</goal_backward>
|
|
542
492
|
|
|
@@ -1037,6 +987,7 @@ Phase planning complete when:
|
|
|
1037
987
|
- [ ] User knows next steps and wave structure
|
|
1038
988
|
- [ ] `<threat_model>` present with STRIDE register (when `security_enforcement` enabled)
|
|
1039
989
|
- [ ] Every threat has a disposition (mitigate / accept / transfer)
|
|
990
|
+
- [ ] Every threat has a Severity (critical|high|medium|low)
|
|
1040
991
|
- [ ] Mitigations reference specific implementation (not generic advice)
|
|
1041
992
|
|
|
1042
993
|
## Gap Closure Mode
|
|
@@ -32,6 +32,8 @@ Your files feed the roadmap:
|
|
|
32
32
|
**Be comprehensive but opinionated.** "Use X because Y" not "Options are X, Y, Z."
|
|
33
33
|
</role>
|
|
34
34
|
|
|
35
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
36
|
+
|
|
35
37
|
<documentation_lookup>
|
|
36
38
|
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
|
37
39
|
</documentation_lookup>
|
|
@@ -32,6 +32,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
|
|
|
32
32
|
- Commit ALL research files (researchers write but don't commit — you commit everything)
|
|
33
33
|
</role>
|
|
34
34
|
|
|
35
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
36
|
+
|
|
35
37
|
<downstream_consumer>
|
|
36
38
|
Your SUMMARY.md is consumed by the gsd-roadmapper agent which uses it to:
|
|
37
39
|
|
|
@@ -33,18 +33,19 @@ Does NOT scan blindly for new vulnerabilities. Verifies each threat in `<threat_
|
|
|
33
33
|
- Marking CLOSED based on code structure ("looks like it validates input") without finding the actual validation call
|
|
34
34
|
|
|
35
35
|
**Required finding classification:**
|
|
36
|
-
- **BLOCKER** — `OPEN_THREATS`: a declared mitigation is absent in implemented code; phase must not ship
|
|
36
|
+
- **BLOCKER** — `OPEN_THREATS`: a declared mitigation is absent in implemented code AND the threat's severity ≥ `block_on` threshold; phase must not ship until resolved
|
|
37
|
+
- **OPEN — non-blocking** — mitigation absent BUT the threat's severity is below the `block_on` threshold; tracked in SECURITY.md, does NOT count toward `threats_open`, does not block ship
|
|
37
38
|
- **WARNING** — `unregistered_flag`: new attack surface appeared during implementation with no threat mapping
|
|
38
|
-
Every threat must resolve to CLOSED, OPEN (
|
|
39
|
+
Every threat must resolve to CLOSED, OPEN-blocking (severity ≥ block_on), OPEN-non-blocking (severity below block_on), or documented accepted risk.
|
|
39
40
|
</adversarial_stance>
|
|
40
41
|
|
|
41
42
|
<execution_flow>
|
|
42
43
|
|
|
43
44
|
<step name="load_context">
|
|
44
45
|
Read ALL files from `<required_reading>`. Extract:
|
|
45
|
-
- PLAN.md `<threat_model>` block: full threat register with IDs, categories, dispositions, mitigation plans
|
|
46
|
+
- PLAN.md `<threat_model>` block: full threat register with IDs, categories, severities, dispositions, mitigation plans
|
|
46
47
|
- SUMMARY.md `## Threat Flags` section: new attack surface detected by executor during implementation
|
|
47
|
-
- `<config>` block: `asvs_level` (1/2/3), `block_on` (
|
|
48
|
+
- `<config>` block: `asvs_level` (1/2/3), `block_on` (critical | high | medium | low | none) — severity ordering: critical > high > medium > low; none = never block
|
|
48
49
|
- Implementation files: exports, auth patterns, input handling, data flows
|
|
49
50
|
|
|
50
51
|
**Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
|
|
@@ -60,7 +61,7 @@ This ensures project-specific patterns, conventions, and best practices are appl
|
|
|
60
61
|
</step>
|
|
61
62
|
|
|
62
63
|
<step name="analyze_threats">
|
|
63
|
-
For each threat in `<threat_model>`,
|
|
64
|
+
For each threat in `<threat_model>`, read its `severity` field (critical|high|medium|low). If building the register retroactively (no `<threat_model>` in PLAN.md), assign a severity to each threat you construct based on impact × likelihood. Determine verification method by disposition:
|
|
64
65
|
|
|
65
66
|
| Disposition | Verification Method |
|
|
66
67
|
|-------------|---------------------|
|
|
@@ -69,16 +70,27 @@ For each threat in `<threat_model>`, determine verification method by dispositio
|
|
|
69
70
|
| `transfer` | Verify transfer documentation present (insurance, vendor SLA, etc.) |
|
|
70
71
|
|
|
71
72
|
Classify each threat before verification. Record classification for every threat — no threat skipped.
|
|
73
|
+
|
|
74
|
+
**Verification depth scales with `asvs_level`** (see @~/.claude/gsd-core/references/security-asvs-levels.md for full definitions):
|
|
75
|
+
- L1: verify mitigation is PRESENT in the cited file (grep-level — pattern exists).
|
|
76
|
+
- L2: verify the mitigation ADDRESSES the threat vector and is placed at the correct boundary (a check in the wrong layer does not close the threat).
|
|
77
|
+
- L3: deep trace — follow the data flow end-to-end, check edge cases and ordering, confirm no bypass path exists.
|
|
72
78
|
</step>
|
|
73
79
|
|
|
74
80
|
<step name="verify_and_write">
|
|
75
|
-
For each `mitigate` threat: grep for declared mitigation pattern in cited files → found = `CLOSED`, not found = `OPEN`.
|
|
81
|
+
For each `mitigate` threat: grep for declared mitigation pattern in cited files → found = `CLOSED`, not found = `OPEN`. Apply depth per `asvs_level` (see analyze_threats step).
|
|
76
82
|
For `accept` threats: check SECURITY.md accepted risks log → entry present = `CLOSED`, absent = `OPEN`.
|
|
77
83
|
For `transfer` threats: check for transfer documentation → present = `CLOSED`, absent = `OPEN`.
|
|
78
84
|
|
|
79
85
|
For each `threat_flag` in SUMMARY.md `## Threat Flags`: if maps to existing threat ID → informational. If no mapping → log as `unregistered_flag` in SECURITY.md (not a blocker).
|
|
80
86
|
|
|
81
|
-
|
|
87
|
+
**Severity-aware `threats_open` computation (severity order: critical > high > medium > low):**
|
|
88
|
+
`threats_open` (the SECURITY.md frontmatter gate field) = the count of threats whose status is OPEN AND whose severity rank ≥ the `block_on` rank. `block_on: none` ⇒ 0 (nothing ever blocks). `block_on: low` ⇒ all open threats block. `block_on: high` (default) ⇒ only high and critical open threats block.
|
|
89
|
+
Open threats BELOW the block threshold are recorded in SECURITY.md as **open — below {block_on} threshold (non-blocking)** and MUST NOT be counted in `threats_open`.
|
|
90
|
+
|
|
91
|
+
**Fail-closed for missing severity:** if an OPEN threat has no severity or an unparseable severity (e.g. a legacy register predating the Severity column), treat it as `critical` for this computation — it COUNTS toward `threats_open` (blocking). Never silently drop an unranked open threat.
|
|
92
|
+
|
|
93
|
+
Write SECURITY.md. Set `threats_open` to the severity-filtered count. Return structured result.
|
|
82
94
|
</step>
|
|
83
95
|
|
|
84
96
|
</execution_flow>
|
|
@@ -95,9 +107,9 @@ Write SECURITY.md. Set `threats_open` count. Return structured result.
|
|
|
95
107
|
**ASVS Level:** {1/2/3}
|
|
96
108
|
|
|
97
109
|
### Threat Verification
|
|
98
|
-
| Threat ID | Category | Disposition | Evidence |
|
|
99
|
-
|
|
100
|
-
| {id} | {category} | {mitigate/accept/transfer} | {file:line or doc reference} |
|
|
110
|
+
| Threat ID | Category | Severity | Disposition | Evidence |
|
|
111
|
+
|-----------|----------|----------|-------------|----------|
|
|
112
|
+
| {id} | {category} | {critical\|high\|medium\|low} | {mitigate/accept/transfer} | {file:line or doc reference} |
|
|
101
113
|
|
|
102
114
|
### Unregistered Flags
|
|
103
115
|
{none / list from SUMMARY.md ## Threat Flags with no threat mapping}
|
|
@@ -115,14 +127,21 @@ SECURITY.md: {path}
|
|
|
115
127
|
**ASVS Level:** {1/2/3}
|
|
116
128
|
|
|
117
129
|
### Closed
|
|
118
|
-
| Threat ID | Category | Disposition | Evidence |
|
|
119
|
-
|
|
120
|
-
| {id} | {category} | {disposition} | {evidence} |
|
|
121
|
-
|
|
122
|
-
### Open
|
|
123
|
-
| Threat ID | Category | Mitigation Expected | Files Searched |
|
|
124
|
-
|
|
125
|
-
| {id} | {category} | {pattern not found} | {file paths} |
|
|
130
|
+
| Threat ID | Category | Severity | Disposition | Evidence |
|
|
131
|
+
|-----------|----------|----------|-------------|----------|
|
|
132
|
+
| {id} | {category} | {critical\|high\|medium\|low} | {disposition} | {evidence} |
|
|
133
|
+
|
|
134
|
+
### Open (blocking — severity ≥ block_on threshold)
|
|
135
|
+
| Threat ID | Category | Severity | Mitigation Expected | Files Searched |
|
|
136
|
+
|-----------|----------|----------|---------------------|----------------|
|
|
137
|
+
| {id} | {category} | {critical\|high\|medium\|low} | {pattern not found} | {file paths} |
|
|
138
|
+
|
|
139
|
+
### Open (non-blocking — severity below block_on threshold)
|
|
140
|
+
| Threat ID | Category | Severity | Mitigation Expected | Files Searched |
|
|
141
|
+
|-----------|----------|----------|---------------------|----------------|
|
|
142
|
+
| {id} | {category} | {critical\|high\|medium\|low} | {pattern not found} | {file paths} |
|
|
143
|
+
|
|
144
|
+
*Only blocking-open threats count toward `threats_open` in SECURITY.md frontmatter.*
|
|
126
145
|
|
|
127
146
|
Next: Implement mitigations or document as accepted in SECURITY.md accepted risks log, then re-run /gsd:secure-phase.
|
|
128
147
|
|
|
@@ -27,6 +27,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
|
|
|
27
27
|
- Return structured result to orchestrator
|
|
28
28
|
</role>
|
|
29
29
|
|
|
30
|
+
@~/.claude/gsd-core/references/untrusted-input-boundary.md
|
|
31
|
+
|
|
30
32
|
<documentation_lookup>
|
|
31
33
|
@~/.claude/gsd-core/references/research-documentation-lookup.md
|
|
32
34
|
</documentation_lookup>
|