Files
g3/analysis/breaker/2025-02-05.md
Dhanji R. Prasanna c3549ce043 refactor: Remove unused functions from skills module
- Remove is_embedded_skill() from discovery.rs (unused)
- Remove get_embedded_skills_map() from embedded.rs (unused)
- Remove associated tests for deleted functions
- Inline path check in test_repo_overrides_embedded test

This eliminates dead code warnings and reduces module surface area
without changing any behavior.

Agent: fowler
2026-02-05 14:17:56 +11:00

4.6 KiB

Breaker Report: 2025-02-05

Focused on changes in commits b6d2582..9443f933 (past 10 commits).

Issue 1: JSON Escaping Bug in g3-research Script

Title

g3-research produces invalid JSON when query contains actual newlines

Repro

# In skills/research/g3-research, the write_status function uses:
escaped_query=$(echo -n "$query" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g')

# Test with actual newlines:
QUERY=$'What is\nthe best\nRust library?'
escaped=$(echo -n "$QUERY" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g')
echo "{\"query\": \"$escaped\"}" | python3 -m json.tool
# Output: Invalid control character at: line 1 column 19 (char 18)

Expected: Valid JSON with \n escape sequences
Actual: Invalid JSON with literal newline characters

Diagnosis

  • File: skills/research/g3-research:66
  • Root cause: The sed pattern s/\n/\\n/g matches the literal two-character string \n, not actual newline characters. Sed processes line-by-line by default and doesn't see newlines in the pattern space.
  • Triggering condition: User query contains actual newline characters (e.g., from multi-line input or programmatic construction)
  • Deterministic: Yes

Impact

  • Severity: Incorrect behavior - status.json becomes unparseable
  • Likelihood: Uncommon but possible - queries are typically single-line, but multi-line queries from programmatic sources or copy-paste could trigger this

Fix

Replace sed with perl which handles newlines correctly:

escaped_query=$(echo -n "$query" | perl -pe 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g')

Issue 2: Embedded Skill Path Not Readable

Title

Embedded skills have non-existent file paths that agents are instructed to read_file

Repro

# When no repo skills/ directory exists, the research skill is loaded from embedded
# The generated prompt contains:
<skill>
  <name>research</name>
  <description>...</description>
  <location><embedded:research>/SKILL.md</location>
</skill>

# The prompt instructs:
"read the full skill file using `read_file` to get detailed instructions"

# Agent attempts:
read_file("<embedded:research>/SKILL.md")
# Result: File not found error

Expected: Agent can read skill documentation
Actual: File path doesn't exist on disk

Diagnosis

  • File: crates/g3-core/src/skills/discovery.rs:97 - sets path to <embedded:name>/SKILL.md
  • File: crates/g3-core/src/skills/prompt.rs:14-15 - instructs agent to use read_file
  • Root cause: Embedded skills use a synthetic path marker, but the prompt doesn't account for this
  • Triggering condition: User has no skills/ directory in their repo (embedded skill not overridden)
  • Deterministic: Yes

Impact

  • Severity: Annoying - agent will fail to read skill docs and may hallucinate or ask for help
  • Likelihood: Common for users outside the g3 repo itself

Possible Fixes

  1. Include the full skill body in the prompt for embedded skills (increases prompt size)
  2. Add special handling in read_file for <embedded:*> paths
  3. Change prompt to say "skill instructions are below" for embedded skills and inline the body

Issue 3: Hardcoded 'main' Branch in SDLC Pipeline

Title

studio sdlc assumes default branch is named 'main'

Repro

# In a repo where default branch is 'master':
studio sdlc run

# has_commits_on_branch runs:
git rev-list --count main..sdlc/session-branch
# Fails silently (returns Ok(false)) because 'main' doesn't exist

# merge_to_main runs:
git checkout main
# Fails with "Failed to checkout main"

Expected: Works with any default branch name
Actual: Fails or behaves incorrectly on repos using 'master' or other branch names

Diagnosis

  • File: crates/studio/src/main.rs:720 - has_commits_on_branch() hardcodes main..{branch}
  • File: crates/studio/src/git.rs - merge_to_main() hardcodes checkout main
  • Root cause: No detection of actual default branch name
  • Triggering condition: Repository uses 'master' or custom default branch
  • Deterministic: Yes

Impact

  • Severity: Incorrect behavior - merge fails or skipped incorrectly
  • Likelihood: Common - many repos still use 'master'

Fix

Detect default branch:

git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'
# or
git config --get init.defaultBranch

Summary

# Issue Severity Likelihood
1 JSON escaping with newlines Incorrect behavior Uncommon
2 Embedded skill path unreadable Annoying Common
3 Hardcoded 'main' branch Incorrect behavior Common

All issues are deterministic and reproducible.