* fix(#2402): honor response_language across orchestrator output + UAT checkpoint renderer Replays the in-flight bot branch fix/2402-response-language-orchestrator-coverage (seven commits, never pushed) onto current origin/next as a single squashed commit. The original work was substantial and correct; this commit preserves its full scope, trimmed where rebase conflicts + workflow size budgets required it. Three independent layers where response_language was being dropped are closed: Layer 1 — orchestrator-facing directives across workflows. Adds the strong "All user-facing output in this workflow MUST be presented in {response_language}; technical terms, code, paths, and subagent prompts stay in English" directive to ~40 workflows that previously either lacked it entirely (verify-work, new-project, new-milestone, quick, manager, and ~35 more) or carried only the weak subagent-prompt-only form (plan-phase, execute-phase). The directive covers narration between tool calls and banner output, not just the AskUserQuestion prompts. Layer 2 — UAT checkpoint renderer (src/uat.cts). buildCheckpoint now accepts an optional responseLanguage parameter and renders the frame strings ("CHECKPOINT: Verification Required", "Type `pass` or describe what's wrong.") in any of 9 languages (English/Spanish/French/German/Portuguese/Japanese/ Chinese/Korean/Italian) with an alias table covering ~30 input variants (en, es, español, ja, 日本語, etc.). cmdRenderCheckpoint reads config.response_language via loadConfig(cwd) and passes it through, so the byte-for-byte block verify-work.md reprints verbatim is already localized when written — preserving the anti-injection hygiene rule at verify-work.md (the model is forbidden to translate after the fact). CJK display width is computed by East Asian Width property ranges (W/F) so the right ║ border of the banner stays aligned for full-width characters. English fallback is byte-identical to the pre-fix behavior when response_language is unset or unrecognized. Layer 3 — literal English report templates in execute-phase. The top-of- workflow directive covers all template sites (templates are a structural source, not literal output). Inline render-language notes that previously sat at each template site were removed during the squash because they pushed execute-phase.md over its frozen pre-phase-6 byte ceiling (93600 — ADR-857 Phase 6 capstone). The single top directive covers the same surface with fewer bytes. Also extends src/docs.cts and src/init.cts to propagate response_language into the init JSON bundle of the additional workflows so the directive can read it. Tests added: - tests/uat.test.cjs: buildCheckpoint with unset/unrecognized language falls back to English default; recognized language swaps only the two frame strings while structural lines stay untouched; CJK display-width regression (independent recomputation of East Asian Width W/F ranges). - tests/workspace.test.cjs, tests/docs-update.test.cjs: response_language wiring through docs.cts/init.cts. References: #2402; reporter's three-layer triage + Layer-4 follow-up; the byte-for-byte anti-injection hygiene rule at verify-work.md (the reason Layer 2 must be renderer-side, not model-translated). This is a squash of the in-flight bot branch — seven commits representing the original implementation plus its subsequent fix/CJK-padding/test/ changeset/regen cycles, none of which were ever pushed or PR'd. The squash captures the final coherent state. * chore(#2402): backfill pr:2457 in .changeset/2402-response-language-orchestrator-coverage.md * chore(#2402): regen golden + size baseline after rebase against #2315 (PR #2451) Rebase conflicts were entirely in generated artifacts (golden-install-parity fixtures + workflow-size-baseline.json). After taking theirs during rebase, regenerated cleanly against the merged source tree.
13 KiB
Called from plan-phase.md's mandatory_discovery step with a depth parameter.
NOTE: For comprehensive ecosystem research ("how do experts build this"), use /gsd:plan-phase --research-phase instead, which produces RESEARCH.md.
_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 "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$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
RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
If response_language is set: All user-facing questions, prompts, and explanations in this workflow MUST be presented in {response_language}. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
<depth_levels> This workflow supports three depth levels:
| Level | Name | Time | Output | When |
|---|---|---|---|---|
| 1 | Quick Verify | 2-5 min | No file, proceed with verified knowledge | Single library, confirming current syntax |
| 2 | Standard | 15-30 min | DISCOVERY.md | Choosing between options, new integration |
| 3 | Deep Dive | 1+ hour | Detailed DISCOVERY.md with validation gates | Architectural decisions, novel problems |
Depth is determined by plan-phase.md before routing here. </depth_levels>
<source_hierarchy> MANDATORY: Context7 BEFORE WebSearch
Claude's training data is 6-18 months stale. Always verify.
- Context7 MCP FIRST - Current docs, no hallucination
- Official docs - When Context7 lacks coverage
- WebSearch LAST - For comparisons and trends only
See ~/.claude/gsd-core/templates/discovery.md <discovery_protocol> for full protocol.
</source_hierarchy>
Route to appropriate level workflow below.
**Level 1: Quick Verification (2-5 minutes)**For: Single known library, confirming syntax/version still correct.
Process:
-
Resolve library in Context7:
mcp__context7__resolve-library-id with libraryName: "[library]" -
Fetch relevant docs:
mcp__context7__get-library-docs with: - context7CompatibleLibraryID: [from step 1] - topic: [specific concern] -
Verify:
- Current version matches expectations
- API syntax unchanged
- No breaking changes in recent versions
-
If verified: Return to plan-phase.md with confirmation. No DISCOVERY.md needed.
-
If concerns found: Escalate to Level 2.
Output: Verbal confirmation to proceed, or escalation to Level 2.
**Level 2: Standard Discovery (15-30 minutes)**For: Choosing between options, new external integration.
Process:
-
Identify what to discover:
- What options exist?
- What are the key comparison criteria?
- What's our specific use case?
-
Context7 for each option:
For each library/framework: - mcp__context7__resolve-library-id - mcp__context7__get-library-docs (mode: "code" for API, "info" for concepts) -
Official docs for anything Context7 lacks.
-
WebSearch for comparisons:
- "[option A] vs [option B] {current_year}"
- "[option] known issues"
- "[option] with [our stack]"
-
Cross-verify: Any WebSearch finding → confirm with Context7/official docs.
-
Create DISCOVERY.md using ~/.claude/gsd-core/templates/discovery.md structure:
- Summary with recommendation
- Key findings per option
- Code examples from Context7
- Confidence level (should be MEDIUM-HIGH for Level 2)
-
Return to plan-phase.md.
Output: .planning/phases/XX-name/DISCOVERY.md
For: Architectural decisions, novel problems, high-risk choices.
Process:
-
Scope the discovery using ~/.claude/gsd-core/templates/discovery.md:
- Define clear scope
- Define include/exclude boundaries
- List specific questions to answer
-
Exhaustive Context7 research:
- All relevant libraries
- Related patterns and concepts
- Multiple topics per library if needed
-
Official documentation deep read:
- Architecture guides
- Best practices sections
- Migration/upgrade guides
- Known limitations
-
WebSearch for ecosystem context:
- How others solved similar problems
- Production experiences
- Gotchas and anti-patterns
- Recent changes/announcements
-
Cross-verify ALL findings:
- Every WebSearch claim → verify with authoritative source
- Mark what's verified vs assumed
- Flag contradictions
-
Create comprehensive DISCOVERY.md:
- Full structure from ~/.claude/gsd-core/templates/discovery.md
- Quality report with source attribution
- Confidence by finding
- If LOW confidence on any critical finding → add validation checkpoints
-
Confidence gate: If overall confidence is LOW, present options before proceeding.
-
Return to plan-phase.md.
Output: .planning/phases/XX-name/DISCOVERY.md (comprehensive)
Ask: What do we need to learn before we can plan this phase?
- Technology choices?
- Best practices?
- API patterns?
- Architecture approach?
Include:
- Clear discovery objective
- Scoped include/exclude lists
- Source preferences (official docs, Context7, current year)
- Output structure for DISCOVERY.md
If confidence is LOW:
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.
Use AskUserQuestion:
- header: "Low Conf."
- question: "Discovery confidence is LOW: [reason]. How would you like to proceed?"
- options:
- "Dig deeper" - Do more research before planning
- "Proceed anyway" - Accept uncertainty, plan with caveats
- "Pause" - I need to think about this
If confidence is MEDIUM: Inline: "Discovery complete (medium confidence). [brief reason]. Proceed to planning?"
If confidence is HIGH: Proceed directly, just note: "Discovery complete (high confidence)."
If DISCOVERY.md has open_questions:Present them inline: "Open questions from discovery:
- [Question 1]
- [Question 2]
These may affect implementation. Acknowledge and proceed? (yes / address first)"
If "address first": Gather user input on questions, update discovery.
``` Discovery complete: .planning/phases/XX-name/DISCOVERY.md Recommendation: [one-liner] Confidence: [level]What's next?
- Discuss phase context (/gsd:discuss-phase [current-phase])
- Create phase plan (/gsd:plan-phase [current-phase])
- Refine discovery (dig deeper)
- Review discovery
NOTE: DISCOVERY.md is NOT committed separately. It will be committed with phase completion.
</step>
</process>
<success_criteria>
**Level 1 (Quick Verify):**
- Context7 consulted for library/topic
- Current state verified or concerns escalated
- Verbal confirmation to proceed (no files)
**Level 2 (Standard):**
- Context7 consulted for all options
- WebSearch findings cross-verified
- DISCOVERY.md created with recommendation
- Confidence level MEDIUM or higher
- Ready to inform PLAN.md creation
**Level 3 (Deep Dive):**
- Discovery scope defined
- Context7 exhaustively consulted
- All WebSearch findings verified against authoritative sources
- DISCOVERY.md created with comprehensive analysis
- Quality report with source attribution
- If LOW confidence findings → validation checkpoints defined
- Confidence gate passed
- Ready to inform PLAN.md creation
</success_criteria>