Skip to content

fix(sdd): gate CodeGraph guidance for subagents#998

Merged
Alan-TheGentleman merged 1 commit into
mainfrom
fix/codegraph-sdd-subagents
Jun 30, 2026
Merged

fix(sdd): gate CodeGraph guidance for subagents#998
Alan-TheGentleman merged 1 commit into
mainfrom
fix/codegraph-sdd-subagents

Conversation

@Alan-TheGentleman

@Alan-TheGentleman Alan-TheGentleman commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Closes #997

PR Type

  • Bug fix
  • New feature
  • Documentation only
  • Code refactoring
  • Maintenance/tooling
  • Breaking change

Summary

  • Propagates CodeGraph guidance into generated SDD/JD/review sub-agent prompts only when CodeGraph is selected or configured.
  • Keeps normal SDD installs default-off when only the CodeGraph CLI is present.
  • Preserves Kimi YAML control files and injects guidance into referenced Markdown prompts instead.

Changes

File Change
internal/cli/run.go Adds gated CodeGraph guidance selection for SDD install paths.
internal/cli/sync.go Adds same-run sync wiring and clarifies CodeGraph guidance handling.
internal/components/sdd/inject.go Passes gated guidance into OpenCode/native/profile generated sub-agents.
internal/components/sdd/profiles.go Propagates guidance through generated OpenCode profile overlays.
internal/components/sdd/prompts.go Adds shared prompt injection helpers while avoiding YAML mutation.
internal/cli/*_test.go, internal/components/sdd/prompts_test.go Adds gating, behavior-level, and Kimi YAML regression coverage.

Test Plan

  • go test ./internal/cli -run 'CodeGraphGuidance|Component.*CodeGraph|Sync.*CodeGraph|Apply.*CodeGraph|InstallRuntimeStagePlanAddsCommunityToolStepsInSelectionOrder|CommunityToolInstallStepUsesInjectableInstaller'
  • go test ./internal/components/sdd -run 'CodeGraph|Subagent|Kimi'
  • go test ./internal/components/sdd ./internal/components/communitytool

Contributor Checklist

  • Linked an approved issue
  • Added exactly one type:* label
  • Ran shellcheck on modified scripts (not applicable: no shell scripts changed)
  • Skills tested in at least one agent
  • Docs updated if behavior changed (not applicable: generated prompt behavior covered by tests)
  • Conventional commit format
  • No Co-Authored-By trailers

Summary by CodeRabbit

  • New Features

    • SDD-generated prompts can now include CodeGraph guidance when the tool is selected or already configured.
    • Guidance is carried through shared prompts, profile overlays, and sub-agent prompts across supported modes.
  • Bug Fixes

    • Prevents CodeGraph guidance from appearing when only the CLI is installed and no guidance is configured.
    • Sync now preserves and restores guidance content more consistently, including legacy setups.

Copilot AI review requested due to automatic review settings June 30, 2026 16:25
@Alan-TheGentleman Alan-TheGentleman added the type:bug Bug fix label Jun 30, 2026
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds CodeGraphGuidanceMarkdown to sdd.InjectOptions and threads it through WriteSharedPromptFiles, GenerateProfileOverlay, inlineOpenCodeSDDPrompts, and native sub-agent file installation. Introduces codeGraphGuidanceMarkdownForSDD in the CLI to compute guidance from selected/configured/legacy CodeGraph state, and renames shouldRefreshCodeGraphGuidance to shouldHandleCodeGraphGuidance in sync.

Changes

CodeGraph Guidance Propagation to SDD Sub-agents

Layer / File(s) Summary
InjectOptions field and prompt injection helpers
internal/components/sdd/inject.go, internal/components/sdd/prompts.go, internal/components/sdd/profiles.go
Adds CodeGraphGuidanceMarkdown string field to InjectOptions; extends WriteSharedPromptFiles and GenerateProfileOverlay with variadic guidance parameter; adds injectCodeGraphGuidanceIntoPrompt, isMarkdownSubAgentPromptFile, and injectCodeGraphGuidanceIntoOpenCodeSubagentPrompts helpers.
Threading guidance through inject.go call sites
internal/components/sdd/inject.go
Wires CodeGraphGuidanceMarkdown into multi-mode WriteSharedPromptFiles, inlineOpenCodeSDDPrompts, GenerateProfileOverlay, and native sub-agent markdown file copying. Extends inlineOpenCodeSDDPrompts signature and adds single-mode guidance inlining.
CLI helpers and sync gating
internal/cli/run.go, internal/cli/sync.go
Adds codeGraphGuidanceMarkdownForSDD/shouldInjectCodeGraphGuidanceForSDD helpers and wires guidance into componentApplyStep and sync SDD injection. Renames shouldRefreshCodeGraphGuidance to shouldHandleCodeGraphGuidance and updates all three call sites in sync.
Tests
internal/components/sdd/prompts_test.go, internal/cli/run_community_tool_test.go, internal/cli/sync_test.go
Adds table-driven and integration tests for guidance omission/inclusion across WriteSharedPromptFiles, Inject (single/multi-mode, native, Kimi YAML), componentApplyStep, componentSyncStep, and sync predicate rename.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Gentleman-Programming/gentle-ai#883: Extends InjectOptions and inlineOpenCodeSDDPrompts with an additional injected prompt section (trigger-rules), the same structural pattern used here for codegraph guidance.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the main change: gating CodeGraph guidance for subagents.
Linked Issues check ✅ Passed The PR matches #997 by gating guidance to selected/configured CodeGraph and propagating it to generated subagents across install and sync flows.
Out of Scope Changes check ✅ Passed The changes stay focused on CodeGraph guidance propagation and add only supporting tests and plumbing.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/codegraph-sdd-subagents

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Alan-TheGentleman Alan-TheGentleman added the size:exception Maintainer-approved exception for PRs above the 400 changed-line review budget label Jun 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes inconsistent propagation of CodeGraph “search-order” guidance into generated SDD/JD/review sub-agent prompts by injecting the guidance only when CodeGraph is explicitly selected or is already configured, while avoiding unwanted default-on behavior when only the CodeGraph CLI is present.

Changes:

  • Adds CodeGraph guidance injection helpers for Markdown prompts and OpenCode inline sub-agent prompts, gated on an explicit guidance string.
  • Plumbs gated guidance through SDD inject + OpenCode profile overlay generation, and adds extensive regression coverage (including Kimi YAML control-file behavior).
  • Wires CLI install/sync paths to compute CodeGraph guidance only when CodeGraph is selected/configured (plus legacy handling).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
internal/components/sdd/prompts.go Adds shared helpers to inject CodeGraph guidance into Markdown prompts and OpenCode inline sub-agent prompts.
internal/components/sdd/prompts_test.go Adds behavior-level tests ensuring guidance is injected only when enabled and remains idempotent; includes Kimi YAML control-file regression tests.
internal/components/sdd/profiles.go Propagates gated guidance into generated OpenCode profile overlays (for inline sub-agent prompts).
internal/components/sdd/inject.go Plumbs guidance through shared prompt generation, OpenCode inline prompt inlining, and Markdown sub-agent prompt writes.
internal/cli/sync.go Updates sync-stage planning/gating for CodeGraph guidance handling and passes CodeGraph guidance into SDD injection options.
internal/cli/sync_test.go Updates sync tests for the renamed guidance gating helper.
internal/cli/run.go Adds gated guidance selection helpers for SDD install/apply flows based on selection/config/legacy state.
internal/cli/run_community_tool_test.go Adds coverage for “selected or configured” gating and apply/sync behavior around SDD prompt guidance injection.
Comments suppressed due to low confidence (1)

internal/cli/sync.go:447

  • shouldHandleCodeGraphGuidance(r.homeDir) only considers existing configuration/legacy markers. If the sync flow allows selecting CodeGraph for the current run via Selection.CommunityTools, this step will not be planned, so same-run enablement would not refresh/inject managed CodeGraph guidance (only previously-configured installations would). Consider incorporating r.selection.CommunityTools into the gating and ensuring the sync step injects guidance when CodeGraph is selected (not just when already configured).
	if shouldHandleCodeGraphGuidance(r.homeDir) {
		apply = append(apply, codeGraphGuidanceSyncStep{
			id:           "sync:community-tool:codegraph-guidance",
			homeDir:      r.homeDir,
			changedFiles: &r.changedFiles,
		})
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/cli/sync.go
StrictTDD: s.selection.StrictTDD,
PreserveOpenCodeOrchestratorPrompt: profileStrategy == model.SDDProfileStrategyExternalSingleActive,
Profiles: profiles,
CodeGraphGuidanceMarkdown: codeGraphGuidanceMarkdownForSDD(s.homeDir, nil),

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/cli/sync.go`:
- Line 698: The SDD guidance is being built with a nil tool selection, so the
first prompt can miss a community CodeGraph tool selected in the same sync run.
Update the `componentSDD` setup in `sync.go` to use `s.selection.CommunityTools`
when calling `codeGraphGuidanceMarkdownForSDD`, or refresh the guidance before
`codeGraphGuidanceSyncStep` runs, so `componentSDD` reflects same-run
selections.

In `@internal/components/sdd/prompts_test.go`:
- Around line 344-571: The new CodeGraph guidance tests only verify first-run
behavior; add an idempotency check that re-runs the same write/install path and
confirms the guidance is not duplicated and no extra changes are reported.
Update the relevant tests around WriteSharedPromptFiles and Inject to call them
twice for the enabled case, then assert each prompt file or agent prompt still
contains exactly one codegraph guidance block and the second run remains
unchanged. Use the existing symbols WriteSharedPromptFiles, Inject,
InjectOptions{CodeGraphGuidanceMarkdown: ...}, and the shared/native prompt
helpers to locate the assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: aa1d76ec-206c-478a-a669-4e4723e867d4

📥 Commits

Reviewing files that changed from the base of the PR and between 72fa2e9 and 4c2a1ec.

📒 Files selected for processing (8)
  • internal/cli/run.go
  • internal/cli/run_community_tool_test.go
  • internal/cli/sync.go
  • internal/cli/sync_test.go
  • internal/components/sdd/inject.go
  • internal/components/sdd/profiles.go
  • internal/components/sdd/prompts.go
  • internal/components/sdd/prompts_test.go

Comment thread internal/cli/sync.go
StrictTDD: s.selection.StrictTDD,
PreserveOpenCodeOrchestratorPrompt: profileStrategy == model.SDDProfileStrategyExternalSingleActive,
Profiles: profiles,
CodeGraphGuidanceMarkdown: codeGraphGuidanceMarkdownForSDD(s.homeDir, nil),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect sync selection wiring and step ordering for CodeGraph guidance.
rg -nP 'codeGraphGuidanceMarkdownForSDD|CommunityTools|codeGraphGuidanceSyncStep|shouldHandleCodeGraphGuidance' internal/cli/sync.go

Repository: Gentleman-Programming/gentle-ai

Length of output: 712


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== sync.go around guidance and step ordering ==\n'
sed -n '420,760p' internal/cli/sync.go

printf '\n== run.go around comparable call site ==\n'
sed -n '860,950p' internal/cli/run.go

printf '\n== definition/usages of codeGraphGuidanceMarkdownForSDD ==\n'
rg -n "func codeGraphGuidanceMarkdownForSDD|codeGraphGuidanceMarkdownForSDD\(" internal/cli

Repository: Gentleman-Programming/gentle-ai

Length of output: 16805


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== codeGraphGuidanceMarkdownForSDD implementation ==\n'
sed -n '1360,1425p' internal/cli/run.go

printf '\n== CommunityTools references in sync/selection plumbing ==\n'
rg -n "CommunityTools|CommunityTool" internal/cli internal/model

Repository: Gentleman-Programming/gentle-ai

Length of output: 5024


Pass selected community tools into SDD guidance in sync

componentSDD in sync reads guidance before codeGraphGuidanceSyncStep runs, so passing nil here ignores a just-selected CodeGraph tool and can omit guidance from the first SDD prompt. Use s.selection.CommunityTools (or move the guidance refresh earlier) so same-run selections are reflected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/cli/sync.go` at line 698, The SDD guidance is being built with a nil
tool selection, so the first prompt can miss a community CodeGraph tool selected
in the same sync run. Update the `componentSDD` setup in `sync.go` to use
`s.selection.CommunityTools` when calling `codeGraphGuidanceMarkdownForSDD`, or
refresh the guidance before `codeGraphGuidanceSyncStep` runs, so `componentSDD`
reflects same-run selections.

Comment on lines +344 to +571
func TestWriteSharedPromptFilesOmitCodeGraphGuidanceByDefault(t *testing.T) {
home := t.TempDir()

if _, err := WriteSharedPromptFiles(home, nil); err != nil {
t.Fatalf("WriteSharedPromptFiles() error = %v", err)
}

for _, phase := range SharedPromptPhases() {
path := filepath.Join(SharedPromptDir(home), phase+".md")
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", path, err)
}
text := string(content)
if strings.Contains(text, "<!-- gentle-ai:codegraph-guidance -->") || strings.Contains(text, "codegraph init <project-root>") {
t.Fatalf("%s unexpectedly contains CodeGraph guidance by default", phase)
}
}
}

func TestWriteSharedPromptFilesIncludeCodeGraphGuidanceWhenEnabled(t *testing.T) {
home := t.TempDir()
guidance := communitytool.CodeGraphGuidanceMarkdown()

if _, err := WriteSharedPromptFiles(home, nil, guidance); err != nil {
t.Fatalf("WriteSharedPromptFiles() error = %v", err)
}

for _, phase := range SharedPromptPhases() {
path := filepath.Join(SharedPromptDir(home), phase+".md")
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", path, err)
}
text := string(content)
if !strings.Contains(text, "<!-- gentle-ai:codegraph-guidance -->") || !strings.Contains(text, "codegraph init <project-root>") {
t.Fatalf("%s missing CodeGraph guidance when enabled", phase)
}
if count := strings.Count(text, "<!-- gentle-ai:codegraph-guidance -->"); count != 1 {
t.Fatalf("%s has %d CodeGraph guidance sections, want 1", phase, count)
}
}
}

func TestInjectOpenCodeSingleModeSubagentPromptsOmitCodeGraphGuidanceByDefault(t *testing.T) {
home := t.TempDir()
mockNoPackageManager(t)

if _, err := Inject(home, opencodeAdapter(), model.SDDModeSingle); err != nil {
t.Fatalf("Inject(single) error = %v", err)
}

agentsMap := readOpenCodeAgents(t, filepath.Join(home, ".config", "opencode", "opencode.json"))
for _, agentName := range sddInstalledSubAgentsForCodeGraphTest() {
prompt := agentPrompt(t, agentsMap, agentName)
if strings.Contains(prompt, "<!-- gentle-ai:codegraph-guidance -->") || strings.Contains(prompt, "codegraph init <project-root>") {
t.Fatalf("%s unexpectedly contains CodeGraph guidance by default", agentName)
}
}
}

func TestInjectOpenCodeSingleModeSubagentPromptsIncludeCodeGraphGuidanceWhenEnabled(t *testing.T) {
home := t.TempDir()
mockNoPackageManager(t)

if _, err := Inject(home, opencodeAdapter(), model.SDDModeSingle, InjectOptions{CodeGraphGuidanceMarkdown: communitytool.CodeGraphGuidanceMarkdown()}); err != nil {
t.Fatalf("Inject(single) error = %v", err)
}

agentsMap := readOpenCodeAgents(t, filepath.Join(home, ".config", "opencode", "opencode.json"))
for _, agentName := range sddInstalledSubAgentsForCodeGraphTest() {
prompt := agentPrompt(t, agentsMap, agentName)
if !strings.Contains(prompt, "<!-- gentle-ai:codegraph-guidance -->") || !strings.Contains(prompt, "codegraph init <project-root>") {
t.Fatalf("%s missing CodeGraph guidance when enabled", agentName)
}
if count := strings.Count(prompt, "<!-- gentle-ai:codegraph-guidance -->"); count != 1 {
t.Fatalf("%s has %d CodeGraph guidance sections, want 1", agentName, count)
}
}
}

func TestInjectOpenCodeMultiModeSubagentPromptFilesIncludeCodeGraphGuidanceWhenEnabled(t *testing.T) {
home := t.TempDir()
mockNoPackageManager(t)

if _, err := Inject(home, opencodeAdapter(), model.SDDModeMulti, InjectOptions{CodeGraphGuidanceMarkdown: communitytool.CodeGraphGuidanceMarkdown()}); err != nil {
t.Fatalf("Inject(multi) error = %v", err)
}

for _, phase := range SharedPromptPhases() {
path := filepath.Join(SharedPromptDir(home), phase+".md")
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", path, err)
}
text := string(content)
if !strings.Contains(text, "<!-- gentle-ai:codegraph-guidance -->") || !strings.Contains(text, "codegraph init <project-root>") {
t.Fatalf("%s missing CodeGraph guidance when enabled", phase)
}
}

agentsMap := readOpenCodeAgents(t, filepath.Join(home, ".config", "opencode", "opencode.json"))
inlineSubagents := append(sddJudgmentDaySubAgentsForCodeGraphTest(), sddReviewSubAgentsForCodeGraphTest()...)
for _, agentName := range inlineSubagents {
prompt := agentPrompt(t, agentsMap, agentName)
if !strings.Contains(prompt, "<!-- gentle-ai:codegraph-guidance -->") || !strings.Contains(prompt, "codegraph init <project-root>") {
t.Fatalf("%s missing CodeGraph guidance in multi-mode inline prompt when enabled", agentName)
}
}
}

func TestInjectNativeSDDSubagentsIncludeCodeGraphGuidanceWhenEnabled(t *testing.T) {
tests := []struct {
name string
agentID model.AgentID
}{
{name: "claude", agentID: model.AgentClaudeCode},
{name: "cursor", agentID: model.AgentCursor},
{name: "kiro", agentID: model.AgentKiroIDE},
{name: "kimi", agentID: model.AgentKimi},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
home := t.TempDir()
adapter := mustAdapter(t, tc.agentID)

if _, err := Inject(home, adapter, model.SDDModeSingle, InjectOptions{CodeGraphGuidanceMarkdown: communitytool.CodeGraphGuidanceMarkdown()}); err != nil {
t.Fatalf("Inject(%s) error = %v", tc.name, err)
}

for _, agentName := range nativeMarkdownSubAgentsForCodeGraphTest(tc.agentID) {
path := filepath.Join(adapter.SubAgentsDir(home), agentName+".md")
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", path, err)
}
text := string(content)
if !strings.Contains(text, "<!-- gentle-ai:codegraph-guidance -->") || !strings.Contains(text, "codegraph init <project-root>") {
t.Fatalf("%s native subagent missing CodeGraph guidance when enabled", agentName)
}
}
})
}

for _, agentName := range []string{"jd-judge-a", "review-risk"} {
if !containsString(nativeMarkdownSubAgentsForCodeGraphTest(model.AgentClaudeCode), agentName) {
t.Fatalf("native coverage helper missing %s", agentName)
}
}
}

func TestInjectNativeSDDSubagentsOmitCodeGraphGuidanceByDefault(t *testing.T) {
home := t.TempDir()

if _, err := Inject(home, claudeAdapter(), model.SDDModeSingle); err != nil {
t.Fatalf("Inject(claude) error = %v", err)
}

for _, agentName := range nativeMarkdownSubAgentsForCodeGraphTest(model.AgentClaudeCode) {
path := filepath.Join(home, ".claude", "agents", agentName+".md")
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", path, err)
}
text := string(content)
if strings.Contains(text, "<!-- gentle-ai:codegraph-guidance -->") || strings.Contains(text, "codegraph init <project-root>") {
t.Fatalf("%s native subagent unexpectedly contains CodeGraph guidance by default", agentName)
}
}
}

func TestInjectKimiYAMLSubagentsOmitCodeGraphGuidanceByDefault(t *testing.T) {
home := t.TempDir()

if _, err := Inject(home, kimiAdapter(), model.SDDModeSingle); err != nil {
t.Fatalf("Inject(kimi) error = %v", err)
}

for _, fileName := range kimiYAMLSubagentFilesForCodeGraphTest() {
path := filepath.Join(home, ".kimi", "agents", fileName)
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", path, err)
}
text := string(content)
if strings.Contains(text, " instructions: |-") || strings.Contains(text, "codegraph init <project-root>") {
t.Fatalf("%s YAML unexpectedly contains CodeGraph guidance by default", fileName)
}
}
}

func TestInjectKimiYAMLSubagentsRemainControlFilesWhenCodeGraphEnabled(t *testing.T) {
home := t.TempDir()

if _, err := Inject(home, kimiAdapter(), model.SDDModeSingle, InjectOptions{CodeGraphGuidanceMarkdown: communitytool.CodeGraphGuidanceMarkdown()}); err != nil {
t.Fatalf("Inject(kimi) error = %v", err)
}

for _, fileName := range kimiYAMLSubagentFilesForCodeGraphTest() {
path := filepath.Join(home, ".kimi", "agents", fileName)
content, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", path, err)
}
text := string(content)
for _, want := range []string{" system_prompt_path: ./", " exclude_tools:"} {
if !strings.Contains(text, want) {
t.Fatalf("%s YAML missing %q:\n%s", fileName, want, text)
}
}
for _, forbidden := range []string{" instructions: |-", "<!-- gentle-ai:codegraph-guidance -->", "codegraph init <project-root>"} {
if strings.Contains(text, forbidden) {
t.Fatalf("%s YAML unexpectedly contains %q:\n%s", fileName, forbidden, text)
}
}

markdownPath := strings.TrimSuffix(path, ".yaml") + ".md"
markdownContent, err := os.ReadFile(markdownPath)
if err != nil {
t.Fatalf("ReadFile(%q) error = %v", markdownPath, err)
}
markdownText := string(markdownContent)
if !strings.Contains(markdownText, "<!-- gentle-ai:codegraph-guidance -->") || !strings.Contains(markdownText, "codegraph init <project-root>") {
t.Fatalf("%s referenced Markdown prompt missing CodeGraph guidance when enabled", markdownPath)
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding an idempotency assertion for the enabled path.

The new tests cover default-off vs enabled-on, but none re-run Inject/WriteSharedPromptFiles to confirm guidance is injected exactly once on a second run (no duplicate codegraph-guidance sections, no spurious Changed). Given the install/sync idempotency requirement, a double-run case for guidance injection would close a meaningful gap.

As per path instructions: "Install/sync operations must be idempotent (running twice equals running once)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/components/sdd/prompts_test.go` around lines 344 - 571, The new
CodeGraph guidance tests only verify first-run behavior; add an idempotency
check that re-runs the same write/install path and confirms the guidance is not
duplicated and no extra changes are reported. Update the relevant tests around
WriteSharedPromptFiles and Inject to call them twice for the enabled case, then
assert each prompt file or agent prompt still contains exactly one codegraph
guidance block and the second run remains unchanged. Use the existing symbols
WriteSharedPromptFiles, Inject, InjectOptions{CodeGraphGuidanceMarkdown: ...},
and the shared/native prompt helpers to locate the assertions.

Source: Path instructions

@Alan-TheGentleman Alan-TheGentleman merged commit 87f7fab into main Jun 30, 2026
20 of 22 checks passed
@Alan-TheGentleman Alan-TheGentleman deleted the fix/codegraph-sdd-subagents branch June 30, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:exception Maintainer-approved exception for PRs above the 400 changed-line review budget type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(sdd): propagate CodeGraph guidance to generated subagents

2 participants