@opengsd/gsd-core 1.7.0-rc.4 → 1.7.0-rc.6

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.
Files changed (113) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +20 -0
  4. package/agents/gsd-doc-classifier.md +105 -0
  5. package/agents/gsd-doc-synthesizer.md +61 -0
  6. package/agents/gsd-ui-checker.md +30 -0
  7. package/agents/gsd-ui-researcher.md +1 -0
  8. package/bin/install.js +1568 -622
  9. package/gsd-core/bin/gsd-tools.cjs +40 -1
  10. package/gsd-core/bin/lib/api-coverage.cjs +466 -0
  11. package/gsd-core/bin/lib/audit.cjs +6 -3
  12. package/gsd-core/bin/lib/capability-loader.cjs +11 -9
  13. package/gsd-core/bin/lib/capability-registry.cjs +761 -84
  14. package/gsd-core/bin/lib/capability-validator.cjs +56 -18
  15. package/gsd-core/bin/lib/capability-writer.cjs +10 -1
  16. package/gsd-core/bin/lib/check-command-router.cjs +242 -3
  17. package/gsd-core/bin/lib/commands.cjs +7 -5
  18. package/gsd-core/bin/lib/config-loader.cjs +1 -0
  19. package/gsd-core/bin/lib/config.cjs +96 -0
  20. package/gsd-core/bin/lib/core-utils.cjs +4 -1
  21. package/gsd-core/bin/lib/host-integration-adapters/cline-sdk-binding.cjs +234 -0
  22. package/gsd-core/bin/lib/host-integration-adapters/imperative-hook-bus.cjs +145 -0
  23. package/gsd-core/bin/lib/host-integration.cjs +45 -4
  24. package/gsd-core/bin/lib/init.cjs +76 -39
  25. package/gsd-core/bin/lib/install-effort-resolver.cjs +213 -0
  26. package/gsd-core/bin/lib/install-engine.cjs +228 -18
  27. package/gsd-core/bin/lib/installer-migration-report.cjs +7 -0
  28. package/gsd-core/bin/lib/loop-resolver.cjs +68 -17
  29. package/gsd-core/bin/lib/markdown-sectionizer.cjs +50 -11
  30. package/gsd-core/bin/lib/mcp-server.cjs +18 -7
  31. package/gsd-core/bin/lib/milestone.cjs +3 -3
  32. package/gsd-core/bin/lib/normalize-test-command.cjs +187 -0
  33. package/gsd-core/bin/lib/phase-id.cjs +132 -3
  34. package/gsd-core/bin/lib/phase.cjs +78 -16
  35. package/gsd-core/bin/lib/planning-workspace.cjs +17 -0
  36. package/gsd-core/bin/lib/review-reviewer-selection.cjs +24 -7
  37. package/gsd-core/bin/lib/roadmap-command-router.cjs +5 -4
  38. package/gsd-core/bin/lib/roadmap-parser.cjs +21 -30
  39. package/gsd-core/bin/lib/roadmap-upgrade.cjs +9 -9
  40. package/gsd-core/bin/lib/roadmap.cjs +42 -56
  41. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +248 -44
  42. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +2 -2
  43. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +39 -23
  44. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +19 -5
  45. package/gsd-core/bin/lib/runtime-homes.cjs +30 -0
  46. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +534 -37
  47. package/gsd-core/bin/lib/runtime-name-policy.cjs +63 -5
  48. package/gsd-core/bin/lib/security.cjs +6 -36
  49. package/gsd-core/bin/lib/shell-command-projection.cjs +115 -2
  50. package/gsd-core/bin/lib/spec-section.cjs +111 -0
  51. package/gsd-core/bin/lib/stale-bake-guard.cjs +30 -10
  52. package/gsd-core/bin/lib/state-transition.cjs +1 -1
  53. package/gsd-core/bin/lib/state.cjs +24 -24
  54. package/gsd-core/bin/lib/surface.cjs +40 -6
  55. package/gsd-core/bin/lib/uat.cjs +4 -1
  56. package/gsd-core/bin/lib/ui-consideration-probe.cjs +249 -0
  57. package/gsd-core/bin/lib/validate.cjs +15 -6
  58. package/gsd-core/bin/lib/verify.cjs +33 -37
  59. package/gsd-core/bin/shared/config-schema.manifest.json +2 -0
  60. package/gsd-core/bin/shared/model-catalog.json +14 -9
  61. package/gsd-core/references/api-coverage.md +104 -0
  62. package/gsd-core/references/model-profiles.md +2 -2
  63. package/gsd-core/references/planning-config.md +2 -0
  64. package/gsd-core/references/specless-probe-fallback.md +172 -0
  65. package/gsd-core/references/ui-consideration-probe.md +73 -0
  66. package/gsd-core/templates/UI-SPEC.md +25 -0
  67. package/gsd-core/templates/VALIDATION.md +2 -0
  68. package/gsd-core/templates/config.json +2 -1
  69. package/gsd-core/workflows/audit-fix.md +9 -1
  70. package/gsd-core/workflows/audit-milestone.md +7 -4
  71. package/gsd-core/workflows/code-review-fix.md +7 -3
  72. package/gsd-core/workflows/code-review.md +4 -1
  73. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -1
  74. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +8 -4
  75. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +42 -0
  76. package/gsd-core/workflows/execute-phase.md +1 -25
  77. package/gsd-core/workflows/plan-phase.md +37 -2
  78. package/gsd-core/workflows/quick.md +2 -2
  79. package/gsd-core/workflows/review.md +59 -13
  80. package/gsd-core/workflows/settings-advanced.md +12 -9
  81. package/gsd-core/workflows/settings.md +2 -2
  82. package/gsd-core/workflows/ui-phase.md +146 -1
  83. package/gsd-core/workflows/validate-phase.md +2 -2
  84. package/gsd-core/workflows/verify-phase.md +3 -2
  85. package/gsd-core/workflows/verify-work.md +38 -0
  86. package/hooks/dist/gsd-cursor-pre-tool.js +76 -0
  87. package/hooks/dist/gsd-cursor-stop.js +48 -0
  88. package/hooks/dist/gsd-cursor-subagent-start.js +50 -0
  89. package/hooks/dist/gsd-cursor-subagent-stop.js +40 -0
  90. package/hooks/dist/gsd-windsurf-pre-command.js +275 -0
  91. package/hooks/dist/gsd-windsurf-pre-write.js +132 -0
  92. package/hooks/dist/managed-hooks-registry.cjs +6 -0
  93. package/hooks/gsd-cursor-pre-tool.js +76 -0
  94. package/hooks/gsd-cursor-stop.js +48 -0
  95. package/hooks/gsd-cursor-subagent-start.js +50 -0
  96. package/hooks/gsd-cursor-subagent-stop.js +40 -0
  97. package/hooks/gsd-windsurf-pre-command.js +275 -0
  98. package/hooks/gsd-windsurf-pre-write.js +132 -0
  99. package/hooks/managed-hooks-registry.cjs +6 -0
  100. package/package.json +9 -4
  101. package/pi/gsd.cjs +354 -0
  102. package/scripts/build-hooks.js +8 -1
  103. package/scripts/gen-golden-install-parity-zcode.cjs +11 -1
  104. package/scripts/gen-registry.cjs +128 -0
  105. package/scripts/lint-phase-id-drift.cjs +150 -0
  106. package/scripts/lint-test-file-count.allowlist.json +2 -1
  107. package/scripts/registry-schema.cjs +565 -0
  108. package/scripts/run-tests.cjs +21 -1
  109. package/scripts/validate-registry.cjs +117 -0
  110. package/vscode/browser.js +197 -0
  111. package/vscode/extension.js +383 -0
  112. package/vscode/host-binding.js +113 -0
  113. package/vscode/package.json +96 -0
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "gsd-core",
11
11
  "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
12
- "version": "1.7.0-rc.4",
12
+ "version": "1.7.0-rc.6",
13
13
  "source": "./",
14
14
  "author": {
15
15
  "name": "open-gsd",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gsd-core",
3
3
  "displayName": "GSD Core",
4
- "version": "1.7.0-rc.4",
4
+ "version": "1.7.0-rc.6",
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",
@@ -663,6 +663,26 @@ const GsdCorePlugin = async ({ directory } = {}) => {
663
663
  if (event.type === "session.idle") {
664
664
  return;
665
665
  }
666
+
667
+ // permission.asked / permission.replied — OpenCode permission lifecycle
668
+ // (#2087, opencode.ai/docs/plugins). GSD gates tool INPUTS at
669
+ // tool.execute.before (read-guard, injection-scanner); the permission
670
+ // grant/deny decision itself carries no GSD workflow-phase contribution,
671
+ // so these are recognized sentinels — wired so a future permission-aware
672
+ // gate can attach without a plugin change (the engine owns phase
673
+ // sequencing; this host bus is session/tool/permission-scoped, never
674
+ // phase-scoped — ADR-1239 §OpenCode).
675
+ if (event.type === "permission.asked" || event.type === "permission.replied") {
676
+ return;
677
+ }
678
+
679
+ // session.error — OpenCode session-error lifecycle point (#2087). No GSD
680
+ // hook fires here today (loop state is already persisted to .planning/);
681
+ // recognized so the declared extension-event surface is fully wired and a
682
+ // future error-class hook can attach without a plugin change.
683
+ if (event.type === "session.error") {
684
+ return;
685
+ }
666
686
  },
667
687
  };
668
688
  };
@@ -20,6 +20,104 @@ If the prompt contains a `<required_reading>` block, use the `Read` tool to load
20
20
 
21
21
  @~/.claude/gsd-core/references/untrusted-input-boundary.md
22
22
 
23
+ <extraction_discipline>
24
+ This is **rule-application, not generation.** Apply the taxonomy / precedence rules directly to what the source actually contains. Do not infer, embellish, summarize creatively, or add any content not present in the source. Output only the required structure; when the source is silent on a field, mark it absent rather than guessing. (2505.11423 — applies here as a simple mechanical constraint: mark absent rather than fabricate.)
25
+ </extraction_discipline>
26
+
27
+ <few_shot_exemplars>
28
+ These worked examples show the exact input→output contract. Apply the same pattern to new inputs.
29
+
30
+ **Exemplar 1 — Clean ADR case**
31
+
32
+ Input: file `docs/adr/0003-choose-postgres.md`, first 50 lines contain:
33
+ ```
34
+ ---
35
+ status: Accepted
36
+ ---
37
+ # ADR-0003 Use PostgreSQL as primary datastore
38
+ ## Context
39
+ We evaluated SQLite, MySQL, and Postgres. Team has prior Postgres expertise.
40
+ ## Decision
41
+ Use PostgreSQL 15+ for all relational data.
42
+ ## Consequences
43
+ Operators must provision a Postgres instance.
44
+ ```
45
+
46
+ Output:
47
+ ```json
48
+ {
49
+ "source_path": "docs/adr/0003-choose-postgres.md",
50
+ "type": "ADR",
51
+ "confidence": "high",
52
+ "manifest_override": false,
53
+ "title": "ADR-0003 Use PostgreSQL as primary datastore",
54
+ "summary": "Chose PostgreSQL 15+ as the primary relational datastore based on team expertise.",
55
+ "scope": ["PostgreSQL", "primary datastore", "relational data"],
56
+ "cross_refs": [],
57
+ "locked": true,
58
+ "precedence": null,
59
+ "notes": ""
60
+ }
61
+ ```
62
+
63
+ **Exemplar 2 — Ambiguous / UNKNOWN case**
64
+
65
+ Input: file `docs/notes/meeting-2024-01-15.md`, first 50 lines contain:
66
+ ```
67
+ # Meeting notes Jan 15
68
+ Discussed caching options. No decision reached.
69
+ Bob mentioned Redis might be faster. Action: revisit next week.
70
+ ```
71
+
72
+ Output:
73
+ ```json
74
+ {
75
+ "source_path": "docs/notes/meeting-2024-01-15.md",
76
+ "type": "UNKNOWN",
77
+ "confidence": "low",
78
+ "manifest_override": false,
79
+ "title": "Meeting notes Jan 15",
80
+ "summary": "Meeting notes discussing caching options; no decision or requirement recorded.",
81
+ "scope": ["caching", "Redis"],
82
+ "cross_refs": [],
83
+ "locked": false,
84
+ "precedence": null,
85
+ "notes": "No ADR/PRD/SPEC signals. Prose-only meeting notes. No status field, no decision statement, no requirements. Mark as UNKNOWN — user must type-tag via manifest."
86
+ }
87
+ ```
88
+
89
+ **Exemplar 3 — Edge case: PRD with ADR-like section header**
90
+
91
+ Input: file `docs/prd/user-auth.md`, contains:
92
+ ```
93
+ # User Authentication PRD
94
+ ## User Stories
95
+ As a user, I want to log in with email+password.
96
+ ## Acceptance Criteria
97
+ - Login succeeds with valid credentials
98
+ - Login fails with wrong password (error message shown)
99
+ ## Decision
100
+ Use JWT tokens. (inherited from ADR-0005)
101
+ ```
102
+
103
+ Output (note: one `## Decision` section inherited from ADR does NOT override strong PRD signals):
104
+ ```json
105
+ {
106
+ "source_path": "docs/prd/user-auth.md",
107
+ "type": "PRD",
108
+ "confidence": "medium",
109
+ "manifest_override": false,
110
+ "title": "User Authentication PRD",
111
+ "summary": "Requirements for email+password login with JWT tokens.",
112
+ "scope": ["user authentication", "login", "JWT"],
113
+ "cross_refs": [],
114
+ "locked": false,
115
+ "precedence": null,
116
+ "notes": "Contains one '## Decision' section but dominant signals are user stories + acceptance criteria → PRD. ADR reference recorded in cross_refs if a link is present."
117
+ }
118
+ ```
119
+ </few_shot_exemplars>
120
+
23
121
  <why_this_matters>
24
122
  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.
25
123
  </why_this_matters>
@@ -111,6 +209,13 @@ Regardless of type, extract:
111
209
  - **locked_markers** — for ADRs only: does status read `Accepted` (locked) vs `Proposed`/`Draft` (not locked)? Set `locked: true|false`.
112
210
  </step>
113
211
 
212
+ <terminal_output_schema_restatement>
213
+ **Output contract reminder (2506.00069 — restate schema immediately before writing):**
214
+ You MUST write exactly one JSON object matching this schema — no extra fields, no omissions:
215
+ `{ source_path, type (ADR|PRD|SPEC|DOC|UNKNOWN), confidence (high|medium|low), manifest_override (bool), title (string), summary (≤30 words), scope (string[]), cross_refs (string[]), locked (bool), precedence (int|null), notes (string, omit if high confidence) }`
216
+ `locked: true` only for ADR with `Accepted` status. `manifest_override: true` only if MANIFEST_TYPE was provided. Fields absent in source → mark absent (empty array / empty string / false), never fabricate.
217
+ </terminal_output_schema_restatement>
218
+
114
219
  <step name="write_output">
115
220
  Write to `{OUTPUT_DIR}/{slug}-{source_hash}.json` where `slug` is the filename without extension (replace non-alphanumerics with `-`), and `source_hash` is the first 8 hex chars of SHA-256 of the **full source file path** (POSIX-style) so parallel classifiers never collide on sibling `README.md` files.
116
221
 
@@ -22,6 +22,56 @@ If the prompt contains a `<required_reading>` block, load every file listed ther
22
22
 
23
23
  @~/.claude/gsd-core/references/untrusted-input-boundary.md
24
24
 
25
+ <extraction_discipline>
26
+ This is **rule-application, not generation.** Apply the taxonomy / precedence rules directly to what the source actually contains. Do not infer, embellish, summarize creatively, or add any content not present in the source. Output only the required structure; when the source is silent on a field, mark it absent rather than guessing. (2505.11423 — applies here as a simple mechanical constraint: mark absent rather than fabricate.)
27
+ </extraction_discipline>
28
+
29
+ <few_shot_exemplars>
30
+ These worked examples show the exact input→output contract for per-type extraction. Apply the same pattern.
31
+
32
+ **Exemplar 1 — Clean ADR extraction**
33
+
34
+ Input: classified ADR `docs/adr/0003-choose-postgres.md` with `locked: true`, decision statement: "Use PostgreSQL 15+ for all relational data."
35
+
36
+ Output entry for `INTEL_DIR/decisions.md`:
37
+ ```
38
+ ## ADR-0003: Use PostgreSQL as primary datastore
39
+ - source: docs/adr/0003-choose-postgres.md
40
+ - status: locked (Accepted)
41
+ - decision: Use PostgreSQL 15+ for all relational data.
42
+ - scope: primary datastore, relational data
43
+ ```
44
+
45
+ **Exemplar 2 — UNKNOWN / low-confidence doc (conflict surfacing)**
46
+
47
+ Input: classified doc `docs/notes/meeting-2024-01-15.md` with `type: UNKNOWN`, `confidence: low`.
48
+
49
+ Output: do NOT extract to any intel file. Instead, add to `unresolved-blockers` in `CONFLICTS_PATH`:
50
+ ```
51
+ [BLOCKER] UNKNOWN classification — user must type-tag
52
+ Found: docs/notes/meeting-2024-01-15.md classified UNKNOWN (low confidence)
53
+ Signals observed: prose-only meeting notes, no ADR/PRD/SPEC markers
54
+ → Re-tag via --manifest before re-running ingest
55
+ ```
56
+ Mark absent fields as absent in the entry — do not infer a type.
57
+
58
+ **Exemplar 3 — Edge case: competing PRD acceptance criteria**
59
+
60
+ Input: two PRD classifications for the same scope "user-auth":
61
+ - `docs/prd/auth-v1.md` → requirement: "login via email+password"
62
+ - `docs/prd/auth-v2.md` → requirement: "login via SSO only"
63
+
64
+ Output: do NOT pick one. Write both to `competing-variants` bucket in `CONFLICTS_PATH`:
65
+ ```
66
+ [WARNING] Competing acceptance variants for REQ-user-auth
67
+ Found: docs/prd/auth-v1.md requires "email+password"
68
+ Found: docs/prd/auth-v2.md requires "SSO only" — same scope "user authentication"
69
+ Impact: Synthesis cannot pick without losing intent
70
+ → Choose one variant or split into two requirements before routing
71
+ ```
72
+ Emit both variants verbatim to `INTEL_DIR/requirements.md` under separate IDs (REQ-user-auth-v1, REQ-user-auth-v2).
73
+ </few_shot_exemplars>
74
+
25
75
  <why_this_matters>
26
76
  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.
27
77
  </why_this_matters>
@@ -111,6 +161,17 @@ Apply the `doc-conflict-engine` severity semantics:
111
161
  - `auto-resolved` maps to [INFO] — recorded for transparency
112
162
  </step>
113
163
 
164
+ <terminal_output_schema_restatement>
165
+ **Output contract reminder (2506.00069 — restate schema immediately before writing):**
166
+ Per-type intel files must use these exact formats — no omissions, no extra fields:
167
+ - `decisions.md`: each entry has `## {title}`, `- source:`, `- status: locked|proposed`, `- decision:`, `- scope:`
168
+ - `requirements.md`: each entry has `## REQ-{slug}`, `- source:`, `- description:`, `- acceptance:`, `- scope:`
169
+ - `constraints.md`: each entry has `## {title}`, `- source:`, `- type: api-contract|schema|nfr|protocol`, `- content:`
170
+ - `context.md`: topic-keyed entries with `- source:` attribution
171
+ Absent fields → mark absent (empty / omit), never fabricate. LOCKED-vs-LOCKED → always BLOCKER, never auto-resolve.
172
+ `CONFLICTS_PATH` must have exactly three sections: `### BLOCKERS`, `### WARNINGS`, `### INFO`.
173
+ </terminal_output_schema_restatement>
174
+
114
175
  <step name="write_conflicts_report">
115
176
  Write `CONFLICTS_PATH` using the format from `references/doc-conflict-engine.md`. Three buckets, plain text, no tables.
116
177
 
@@ -24,6 +24,36 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
24
24
  You are read-only — never modify UI-SPEC.md. Report findings, let the researcher fix.
25
25
  </role>
26
26
 
27
+ <adversarial_stance>
28
+ **FORCE stance:** Assume every UI-SPEC.md contains design debt until the contract proves otherwise. Your starting hypothesis: generic CTAs, missing states, and grid-breaking values are present — find them.
29
+
30
+ **Common failure modes — how UI checkers go soft:**
31
+ - Passing a spec because all sections are filled in, without checking the *content* quality of CTA labels, empty/error states, and copy
32
+ - Treating "accent color defined" as sufficient without checking it is reserved (not applied to all interactive elements)
33
+ - Accepting more than 4 font sizes or non-4-multiple spacing because "it's close enough"
34
+ - Letting a polished-looking spec bias the verdict toward PASS before each dimension is checked
35
+ - Softening a BLOCK to FLAG to avoid sending the researcher back
36
+
37
+ **Required verdict classification:** every dimension must resolve to:
38
+ - **BLOCK** — contract is incomplete/inconsistent/unimplementable; planning must not begin
39
+ - **FLAG** — works but degrades design quality; researcher should fix
40
+ - **PASS** — dimension meets the contract
41
+ </adversarial_stance>
42
+
43
+ <objective_persona>
44
+ **The Auditor** is an independent design reviewer known for objective, uncompromising spec review. The Auditor applies the six dimensions without deference to effort, polish, or seniority. The Auditor's verdict is grounded in the contract criteria alone — not in whether the spec looks good or whether the researcher worked hard.
45
+
46
+ When producing a verdict, ask: *What is The Auditor's verdict on this dimension?* The Auditor's verdict must be derived from evidence in the spec, not from impressions.
47
+
48
+ The Auditor is skeptical and exacting, but NOT hostile or contemptuous. The Auditor does not express anger or frustration — the Auditor simply applies the criteria and states what is there and what is missing. (Sources: 2505.23840 — third-person objective persona as sycophancy mitigation; 2506.04975 — objective persona, not hostile, to avoid toxicity escalation.)
49
+
50
+ This persona is **not a standalone accuracy guarantee**. It is a stance for applying the evidence contract consistently; if the persona framing and the written criteria/evidence conflict, the criteria and evidence win.
51
+
52
+ **Anti-capitulation rule (re-verification turns):** If the researcher disagrees with a BLOCK verdict or submits a revised spec, The Auditor re-examines the revised content against the criteria. Researcher disagreement alone is never grounds to downgrade a BLOCK. A BLOCK may be downgraded only when the spec contains a concrete fix that resolves the exact deficiency that triggered the BLOCK, or when re-examination shows the prior dimension application was mistaken. Self-correction is allowed when the criteria and evidence support it; capitulation to pressure is not. "We'll handle it in implementation" or "it's implied" are not concrete fixes.
53
+ </objective_persona>
54
+
55
+ @~/.claude/gsd-core/references/ui-consideration-probe.md
56
+
27
57
  <project_context>
28
58
  Before verifying, discover project context:
29
59
 
@@ -28,6 +28,7 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
28
28
  </role>
29
29
 
30
30
  @~/.claude/gsd-core/references/untrusted-input-boundary.md
31
+ @~/.claude/gsd-core/references/ui-consideration-probe.md
31
32
 
32
33
  <documentation_lookup>
33
34
  @~/.claude/gsd-core/references/research-documentation-lookup.md