* fix(#2636): surface gsd-sdk query failures and add workflow↔handler parity check Root cause: workflows invoked `gsd-sdk query agent-skills <slug>` with a trailing `2>/dev/null`, swallowing stderr and exit code. When the installed `@gsd-build/sdk` npm was stale (pre-query), the call resolved to an empty string and `agent_skills.<slug>` config was never injected into spawn prompts — silently. The handler exists on main (sdk/src/query/skills.ts), so this is a publish-drift + silent-fallback bug, not a missing handler. Fix: - Remove bare `2>/dev/null` from every `gsd-sdk query agent-skills …` invocation in workflows so SDK failures surface to stderr. - Apply the same rule to other no-fallback calls (audit-open, write-profile, generate-* profile handlers, frontmatter.get in commands). Best-effort cleanup calls (config-set workflow._auto_chain_active false) keep exit-code forgiveness via `|| true` but no longer suppress stderr. Parity tests: - New: tests/bug-2636-gsd-sdk-query-silent-swallow.test.cjs — fails if any `gsd-sdk query agent-skills … 2>/dev/null` is reintroduced. - Existing: tests/gsd-sdk-query-registry-integration.test.cjs already asserts every workflow noun resolves to a registered handler; confirmed passing post-change. Note: npm republish of @gsd-build/sdk is a separate release concern and is not included in this PR. * fix(#2636): address review — restore broken markdown fences and shell syntax The previous commit's mass removal of '2>/dev/null' suffixes also collapsed adjacent closing code fences and 'fi' tokens onto the command line, producing malformed markdown blocks and 'truefi' / 'true fi' shell syntax errors in the workflows. Repaired sites: - commands/gsd/quick.md, thread.md (frontmatter.get fences) - workflows/complete-milestone.md (audit-open fence) - workflows/profile-user.md (write-profile + generate-* fences) - workflows/verify-work.md (audit-open --json fence) - workflows/execute-phase.md (truefi -> true / fi) - workflows/plan-phase.md, discuss-phase-assumptions.md, discuss-phase/modes/chain.md (true fi -> true / fi) All 5450 tests pass.
2.7 KiB
Step: codebase_drift_gate
Post-execution structural drift detection (#2003). Runs after the last wave
commits, before verification. Non-blocking by contract: any internal
error here MUST fall through and continue to verify_phase_goal. The phase
is never failed by this gate.
DRIFT=$(gsd-sdk query verify.codebase-drift 2>/dev/null || echo '{"skipped":true,"reason":"sdk-failed"}')
Parse JSON for: skipped, reason, action_required, directive,
spawn_mapper, affected_paths, elements, threshold, action,
last_mapped_commit, message.
If skipped is true (no STRUCTURE.md, missing git, or any internal error):
Log one line — Codebase drift check skipped: {reason} — and continue to
verify_phase_goal. Do NOT prompt the user. Do NOT block.
If action_required is false: Continue silently to verify_phase_goal.
If action_required is true AND directive is warn:
Print the message field verbatim. The format is:
Codebase drift detected: {N} structural element(s) since last mapping.
New directories:
- {path}
New barrel exports:
- {path}
New migrations:
- {path}
New route modules:
- {path}
Run /gsd:map-codebase --paths {affected_paths} to refresh planning context.
Then continue to verify_phase_goal. Do NOT block. Do NOT spawn anything.
If action_required is true AND directive is auto-remap:
First load the mapper agent's skill bundle (the executor's AGENT_SKILLS
from step init_context is for gsd-executor, not the mapper):
AGENT_SKILLS_MAPPER=$(gsd-sdk query agent-skills gsd-codebase-mapper)
Then spawn gsd-codebase-mapper agents with the --paths hint:
Task(
subagent_type="gsd-codebase-mapper",
description="Incremental codebase remap (drift)",
prompt="Focus: arch
Today's date: {date}
--paths {affected_paths joined by comma}
Refresh STRUCTURE.md and ARCHITECTURE.md scoped to the listed paths only.
Stamp last_mapped_commit in each document's frontmatter.
${AGENT_SKILLS_MAPPER}"
)
If the spawn fails or the agent reports an error: log Codebase drift auto-remap failed: {reason} and continue to verify_phase_goal. The phase
is NOT failed by a remap failure.
If the remap succeeds: log Codebase drift auto-remap completed for paths: {affected_paths} and continue to verify_phase_goal.
The two relevant config keys (continue on error / failure if either is invalid):
workflow.drift_threshold(integer, default 3) — minimum drift elements before actionworkflow.drift_action—warn(default) orauto-remap
This step is fully non-blocking — it never fails the phase, and any
exception path returns control to verify_phase_goal.