98e4233ce9f20f827d01ac4e7e53a2f4c5ec3fff
86 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
60e3c4988a |
feat(#2182): scaffold community capability + EoS registry (tests + stubbed core)
Adds the discoverability-registry surface for issue #2182: JSON-sourced capability/eos catalogs, a pure schema/vocab module (registry-schema.cjs) with the ADR-857 loop points + ADR-1239 axes, thin validate/gen CLIs, the registry-entry PR template, README spec, and CONTEXT.md glossary terms. The three pure functions (isValidGsdRange/validateEntries/renderMarkdown) are stubbed here so the comprehensive test suite fails first (red), per the feature-implementation red-first directive; the next commit implements them. Refs #2182 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a3cca0704d | no-mistakes(document): Sync onboard documentation | ||
|
|
8f2ebbe9bf |
feat(#1928): remove sunset Gemini CLI runtime, redirect to Antigravity (#1996)
* feat(#1928): remove sunset gemini cli runtime, redirect to antigravity Google sunset Gemini CLI on 2026-06-18; Antigravity CLI is its official successor (already a first-class GSD runtime). Remove the gemini runtime from the enum (16->15), aliases, labels, config-home fragment, install path, converters (convertClaudeToGemini{Markdown,Toml,Agent}, convertSlashCommandsToGeminiMentions), capability descriptor, gemini-extension.json, RULESET.GEMINI.*, and the interactive menu (renumbered, no gap). --gemini now prints an explicit deprecation notice citing the 2026-06-18 sunset and redirects to --antigravity (no silent alias, per the issue's Hyrum's-Law rejection). Antigravity is preserved throughout: its GEMINI.md contextFileName, .gemini/antigravity config home, the shared convertGeminiToolName/claudeToGeminiTools tool vocabulary, and the 'gemini' hookEvents dialect it declares. GEMINI.md retargeted as Antigravity's context file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(#1928): backfill changeset PR number (#1996) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(#1928): drop Gemini CLI from issue templates (review nit) Removes the sunset Gemini CLI runtime from the two GitHub issue-template runtime lists that the removal PR missed, per @davesienkowski's review nit: - feature_request.yml: 'Applicable runtimes' checkbox (a user could otherwise request a feature for a runtime GSD no longer supports) - bug_report.yml: 'Runtime' dropdown + the stale ~/.gemini/settings.json retrieval-help line Leaves the post-removal templates fully consistent with the Antigravity redirect. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
e32eac56a6 | docs(#1618): correct Claude skill layout from nested to flat | ||
|
|
08dfcad5f1 | docs(#1617): correct Antigravity skill layout from nested to flat | ||
|
|
ba96c70b14 |
feat(#1602): deterministic coverage-metadata UAT routing for verify-work
Add an optional structured `coverage:` block to SUMMARY.md frontmatter and a deterministic classifier that `verify-work` consumes to route deliverables to auto-pass vs human-UAT — replacing the rejected #1598/#1599 post-hoc heuristic. - New `src/coverage.cts` (→ bin/lib/coverage.cjs) parses the nested coverage block (extractFrontmatter can't — its `-` items are scalars-only; this is a focused parser, sibling of parseMustHavesBlock), validates each entry, and classifies into auto_passed vs present. Frozen MODE/PRESENT_REASON/ERROR_CODE typed-IR surface. Exposed via `uat classify-coverage --summary <f>`. - Auto-pass is the narrow proven case only: strict-boolean human_judgment:false AND non-empty all-`pass` verification AND zero validation errors. Everything else — judgment, empty/failing verification, malformed entry — routes to the human (fail-safe). A malformed block falls back to legacy prose extraction and surfaces an error; an absent block is byte-identical to pre-#1602. - execute-plan create_summary populates the block (fail-safe default human_judgment:true); verify-work extract_tests consumes it; create_uat_file marks auto-passed entries `source: automated`. - Templates (summary + 3 variants), CONTEXT.md predicate + glossary, INVENTORY, eslint/gitignore registration, and Diataxis docs (COMMANDS reference + USER-GUIDE explanation) updated. - Behavioral tests via the CLI (no source-grep); parser-robustness regressions for the null-entry/comment-header/mis-indent cases found in adversarial review. Closes #1602 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
e12a2abfd8 |
feat(#441): add /gsd-capture --list-seeds for seed listing and audit (#722)
* feat(#441): add /gsd-capture --list-seeds for seed listing and audit Seeds (.planning/seeds/SEED-NNN-slug.md) could only be created (--seed), enriched (--enrich), or auto-surfaced at /gsd-new-milestone. There was no way to browse or audit parked seeds on demand. This adds a read-only listing, following the established --list → workflow pattern (per the approved scope on - gsd-tools `list-seeds [status]` (cmdListSeeds in src/commands.cts): scans the seeds dir, returns { count, seeds[], summary } JSON with each seed's id, slug, status, scope, trigger_when, planted, title. Optional case-insensitive status filter. User-controlled content is sanitized (sanitizeForDisplay) and every path validated (requireSafePath); read-only. Independent of audit.scanSeeds, which only returns unimplemented seeds for the milestone surface. - /gsd-capture --list-seeds routes to a new read-only list-seeds workflow that renders the seed table. Closes #441 * chore(#441): point changeset fragment at PR #722 * test(#441): allowlist list-seeds test in prompt-injection scan The test asserts that list-seeds neutralizes injection payloads (<system>, [INST]) embedded in seed content, so the fixtures legitimately contain those patterns — same as the sibling security tests already on the allowlist. * fix(#441): use canonical /gsd:capture colon form in list-seeds workflow Claude-facing source (commands/, agents/, gsd-core/workflows/, ...) must use the /gsd:<cmd> colon form per ADR/CONTEXT.md; the hyphen /gsd-<cmd> form is retired there (enforced by bug-2543-gsd-slash-namespace.test.cjs). The new list-seeds workflow used the hyphen form. * docs(#441): sync help full.md + INVENTORY for --list-seeds Adds the --list-seeds entry to the help reference (help/modes/full.md, per bug-2954 argument-hint↔help parity) and registers the new list-seeds workflow in docs/INVENTORY.md (88→89) and the generated INVENTORY-MANIFEST.json. * docs(#441): add --list-seeds how-to + drop phantom statuses Addresses CHANGES_REQUESTED on PR #722 (two documentation blockers): - USER-GUIDE.md Seeds section (how-to): extend the task to cover auditing parked seeds on demand via --list-seeds, including the status filter — kept task-oriented per Diataxis how-to mode. - CLI-TOOLS.md (reference): drop phantom statuses implemented|rejected from the list-seeds filter vocabulary; the system only produces dormant|active|triggered (src/audit.cts scanSeeds). Reference must be factually accurate and complete. * fix(#441): guard non-scalar status frontmatter in cmdListSeeds A seed with a bare `status:` line (extractFrontmatter yields {}) or a `status: [a, b]` value (yields an array) crashed the whole audit list: `(fm.status || 'dormant').toLowerCase()` throws a TypeError on a non-string. Coerce every frontmatter read through a `fmStr` helper (mirrors the existing `typeof fm.id === 'string'` guard), so a non-scalar status falls back to dormant and non-scalar scope/trigger_when/title can no longer leak a raw array/object into the JSON contract. Title is now capped symmetrically. Adds regression coverage for empty and array `status:` and non-scalar fields. Refs #441 * docs(#441): align list-seeds workflow status vocabulary The load_seeds step listed `implemented` as an example status filter, but the real seed vocabulary is dormant|active|triggered (src/audit.cts scanSeeds); `implemented` has no producer. Matches the earlier CLI-TOOLS.md correction. Refs #441 * refactor(#441): extract pure deriveSeedIdentity; match raw status in list-seeds Pull the seed_id/slug derivation out of cmdListSeeds into a pure, exported deriveSeedIdentity(stem, rawFmId) so the parsing contract can be property-tested in-process (review minor #1). No behavior change. Filter comparison now matches the raw lowercased status (both sides already normalized) instead of sanitizeForDisplay(status); sanitization is for output, not matching (review nit #3). * test(#441): add fast-check property coverage and count=1 boundary for list-seeds Adds tests/list-seeds.property.test.cjs with four fast-check properties over deriveSeedIdentity (never-throws, string-only contract, canonical id->seed_id/slug invariant, filename-prefix fallback) per RULESET.TESTS.property-based-testing (review minor #1). Adds an N==1 status-filter boundary case to list-seeds.test.cjs (review minor #2). * chore(#441): sync runtime launcher snippet into list-seeds workflow Propagate the current _runtime-launcher.snippet.sh (with non-Claude runtime home probes) into the new list-seeds.md workflow via scripts/sync-runtime-launcher.cjs, satisfying bug-891 (E) propagation. * test(#441): record list-seeds.md in workflow size baseline (#1074) --------- Co-authored-by: Tom Boucher <trekkie@nomorestars.com> |
||
|
|
f3c06f59df |
fix(#1326): stop emitting Codex agents/openai.yaml sidecars; clean up stale ones (#1360)
* fix(#1326): stop emitting Codex agents/openai.yaml sidecars; clean up stale ones Codex installs wrote an agents/openai.yaml sidecar under every managed gsd-* skill dir. Recent Codex builds index both SKILL.md and the sidecar, so each GSD skill appeared twice in autocomplete (canonical gsd-* name + humanized display_name). - Replace writeCodexSkillMetadataFiles / generateCodexSkillMetadataYaml with cleanupCodexSkillMetadataSidecars: Codex-only (if isCodex), removes stale managed gsd-*/agents/openai.yaml and prunes the now-empty agents/ dir. - Preserve user-owned dirs (gsd-dev-preferences), non-empty agents/ dirs, and non-gsd dirs; lstat-guard against symlinked agents/ so a delete can never escape the skills tree; fail-open per directory. - Codex relies on SKILL.md alone for /skills discovery. - Update USER-GUIDE/FEATURES docs and rewrite the #774 emission tests into cleanup tests. Scope: the sidecar duplicate only. The separate multi-root (~/.agents/skills shared-skills) duplicate facet is a distinct concern, not addressed here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#1326): add changeset for Codex sidecar cleanup Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
14e0709eed |
refactor(#1307): gate intel on isCapabilityActive + loop-resolver honors capability active (#1315)
* refactor(#1307): gate intel on isCapabilityActive + loop-resolver honors capability active Part A: intel's command gate moves from config-only isIntelEnabled to the shared isCapabilityActive('intel', cwd) — a consistency cutover (intel has skills:[] so its tri-state collapses to the intel.enabled config leg; the gate now flows through the resolver's precedence + runtime-aware resolution). Part B: loop-resolver hook rendering now gates on capability state.active (=== true, fail-closed) instead of state.enabled, so the capability config gate is honored by the hook consumer, not just per-hook 'when'. active is now required in the loop-resolver input types. Regression test proves a config- disabled (active=false) capability's unconditional hook is not rendered. Part of #1302. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(#1307): add changeset for intel + loop-resolver active gate Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
e3b829e765 |
refactor(#1306): gate graphify on isCapabilityActive (tri-state, runtime-aware) (#1313)
* refactor(#1306): gate graphify on isCapabilityActive (tri-state), not config-only graphify's command gate moves from the config-only isGraphifyEnabled to the shared isCapabilityActive('graphify', cwd) — so graphify is off unless installed AND surfaced AND graphify.enabled. Fixes a latent claude-hardcoding in the resolver: resolveCapabilityRuntimeState now detects the active runtime via resolveRuntime(cwd) (GSD_RUNTIME -> config.runtime -> 'claude') so non-Claude runtimes (Codex/Cursor) read their own surface, not ~/.claude. Hermetic regression test proves config-on+unsurfaced -> disabled; cross-runtime test proves GSD_RUNTIME=codex honors CODEX_HOME. Gate fails closed on every error path. Part of #1302. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(#1306): add changeset for graphify tri-state gate Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
91bd82f9a6 |
enhance(execute): isolated-executor rejected/over-reaching run fails safe — never default recovery to main (#1292) (#1303)
* enhance(execute): isolated-executor rejected/over-reaching run fails safe (#1292) When an isolated (worktree) executor run is rejected — the user declines to merge it, the orchestrator surfaces recovery for a blocked/halted plan, or the run over-reached the requested scope — the orchestrator must no longer default/propose recovery by editing the primary checkout (`main`). Absent an explicit guardrail, the LLM orchestrator could improvise "continue on main", inverting the isolation contract at the moment it matters most. Added an ISOLATED-RUN RECOVERY — FAIL SAFE policy: default to a safe halt that offers a fresh, narrowly-scoped worktree or inspect/discard; editing the primary checkout requires explicit, clearly-labeled confirmation and is never the default/proposed option. To respect the ADR-857 phase-6 host-loop size cap on execute-phase.md (it sits just under the pre-phase-6 baseline), the policy is delivered as an extracted reference fragment rather than inline: - New `execute-phase/steps/worktree-recovery-policy.md` holds the recovery policy (the existing FAIL-CLOSED rule #48 for base/HEAD mismatches + the #1292 fail-safe guardrail). No #48 behavior change — moved verbatim. - execute-phase.md references the fragment at the worktree-spawn recovery point, the step-5.5 merge decision, and the stalled-agent "switch to inline execution" menu (which for an isolated run now follows the fail-safe policy). Net effect: execute-phase.md shrinks below its cap. - quick.md carries the fail-safe guardrail inline at its post-return merge/discard decision (quick.md is not size-capped). Scoped to the recovery offer only — no automatic scope-overreach detection (explicitly out of scope per the issue) and no new config key. Adds content regression tests, a USER-GUIDE note, and a workflow size-baseline update. Closes #1292 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(changeset): Changed fragment for #1292 isolated-executor fail-safe recovery Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
93c5ecd645 |
feat(#792): add devin-desktop runtime alias for windsurf (#1086)
windsurf now also answers to devin-desktop (CLI --devin-desktop) for the Windsurf→Devin Desktop rebrand; all paths unchanged. The .devin/skills/ workspace migration is split to #1085. Closes #792. |
||
|
|
cd5db1f8db |
test(suites): seed security/slow/integration suites via measured retags
Renames (git mv) with all references updated (ci-test-scope RULES, windows-parity allowlist, test-file-count allowlist, docs in 6 locales): - 5 scanner tests -> *.security.test.cjs — the 'Run security tests' CI step ran zero files since the suite taxonomy landed; it is now honest. - graphify-auto-update -> *.slow.test.cjs (36s, slowest file in the suite; e2e gsd-tools spawns) — runs on full-matrix lanes and push to next. - installer-migration-install-integration -> *.integration.test.cjs (13s; an integration test by its own name). Coverage gate measured after retags: 88.55% lines (gate 70%). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
0a11d361ca |
feat(#69): nest concrete skills under namespace routers at install (#883)
Emit the 6 gsd-ns-* routers as the only top-level skill bundles and nest the ~61 concrete skills under <router>/skills/<name>/SKILL.md on runtimes with confirmed non-recursive skill loaders (claude global, cline, qwen, hermes, augment, trae, antigravity). Router bodies rewrite their routing tables from Skill-tool dispatch to a Read skills/<name>/SKILL.md pattern. Recursive/unconfirmed loaders (cursor, codex, copilot, windsurf, codebuddy, opencode, kilo) keep the flat layout. Completes the v1.40 namespace architecture (#2792) so the eager skill listing drops to ~6 entries. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
40d48c0508 |
feat(#815): add /gsd-update --next to install the @next RC channel (#839)
Adds an opt-in --next (alias --rc) flag to /gsd-update targeting the @next RC dist-tag (ADR #660), with a {latest,next} allowlist enforced at three layers, channel-aware version check + banner, and byte-for-byte unchanged default @latest behavior. Closes #815 |
||
|
|
cb284962bf |
feat(#789): elevate CodeBuddy — slash commands (#830)
* feat(#789): elevate CodeBuddy — emit slash commands (+ document subagent/MCP scope) Emit a CodeBuddy slash-command surface so GSD workflows appear in the '/' menu, reaching parity with other elevated runtimes. - Add convertClaudeCommandToCodebuddyCommand and register a commands/ artifact kind for the codebuddy runtime (commands/gsd-<name>.md), consistent with the Cursor (#785) and Augment (#790) commands surfaces. - Mark emitted skills user-invocable:false so the commands surface is the sole '/' entry point (no duplicate /gsd-* entries); skills stay model-invocable. CodeBuddy's SKILL.md supports this field. - Normalize $HOME/.codebuddy (bare + slash) path forms in runtime rewrites so --config-dir/local installs don't leak the default home. - Report installed commands/ count on install; uninstall prunes gsd-* commands while preserving user-owned commands. Scope: subagents (~/.codebuddy/agents/) are already emitted by the generic agents block (unchanged); no mcp.json is written (gsd ships no MCP server, and CodeBuddy's mcp.json registers only external servers). Closes #789 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#789): set changeset pr number to 830 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
28c8d524fe |
feat(#778): cross-runtime command enrichment (Gemini {{args}}/!{}, Qwen priority) (#825)
* feat(#778): cross-runtime command enrichment (Gemini {{args}}/!{}, Qwen priority) Enrich the installer's per-runtime command/skill generators with native, verified, additive fields: - Gemini CLI: map Claude's $ARGUMENTS -> Gemini's {{args}} in generated TOML commands so typed arguments interpolate; inject live .planning/STATE.md into /gsd:progress via a fixed, injection-safe !{cat .planning/STATE.md 2>/dev/null} shell block (no interpolated input). - Qwen Code: emit the optional numeric `priority` field on main-loop skills so the most-used workflows sort first in the /skills list (higher = earlier per the Qwen skills spec; the issue's inverse numbering was corrected). OpenCode per-command model/agent/subtask/variant enrichment was evaluated and intentionally not implemented: `model` reintroduces the #1156 ProviderModelNotFoundError regression for non-Anthropic providers (the converter deliberately strips model:), `subtask`/`agent` change execution semantics for GSD's interactive commands, and `variant` is not in the OpenCode command schema. Schemas verified against primary docs (Gemini custom-commands, Qwen skills, OpenCode commands/skills). Adds tests/enh-778-* and how-to + USER-GUIDE docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#778): set changeset PR number to 825 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
19280510fe |
feat(#774): emit service_tier/model_verbosity in Codex agent TOML + agents/openai.yaml skill chip (#828)
* feat(#774): emit service_tier/model_verbosity in Codex agent TOML + agents/openai.yaml skill chip - Add service_tier = "flex" and model_verbosity = "low" to the Codex ConfigProfile TOML for light-tier agents (gsd-research-synthesizer, gsd-codebase-mapper, gsd-plan-checker, and 8 others identified via AGENT_DEFAULT_TIERS). Field names/values verified against Codex schema (profile_toml.rs / config_types.rs Verbosity enum). Non-light agents are unaffected. - Add generateCodexSkillMetadataYaml() and writeCodexSkillMetadataFiles(): after installRuntimeArtifacts, iterate every gsd-* skill directory, read the short-description already emitted in the SKILL.md frontmatter by convertClaudeCommandToCodexSkill, and write agents/openai.yaml with interface.display_name and interface.short_description for the Codex TUI skill picker chip. - yamlQuote (JSON.stringify) handles all YAML-unsafe chars. - User-owned gsd-dev-preferences dir is never overwritten. - Errors per-skill are swallowed so a bad SKILL.md can't abort install. - agents/openai.yaml is covered by the snapshot/rollback system and manifest hash (writeManifest hashes skill dirs recursively). - Uninstall symmetry: _removeGsdEntries removes whole gsd-* dirs. - 21 new tests in codex-config.test.cjs covering service_tier/verbosity TOML emission, YAML generation (round-trip via js-yaml), and writeCodexSkillMetadataFiles including an e2e integration test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#774): correct docs-lint coverage — proper changeset format + USER-GUIDE entry Rewrite the changeset fragment from old @opengsd/gsd-core:patch format to the required type:/pr: schema so the docs-lint parser can consume it. Add a new "Codex skill picker and agent scheduling (#774)" section to docs/USER-GUIDE.md describing the flex-tier scheduling and /skills TUI chip enrichments — both are user-visible and belong in docs rather than behind a docs-exempt marker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
dc7f1557c6 |
feat(#768): pre-populate settings.json permissions.allow/deny for Claude Code (#819)
* feat(#768): pre-populate settings.json permissions.allow/deny for Claude Code Adds mergeClaudePermissions() to bin/install.js which non-destructively appends GSD's known-safe tool-call patterns to permissions.allow and defense-in-depth credential-file patterns to permissions.deny during Claude Code installs. Merge is idempotent (no duplicates on reinstall) and additive (existing user entries preserved). Uninstall removes only the exact GSD-owned entries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: update changeset pr number to 819 --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a3aa0ae142 |
feat(#775): ship a gemini-extension.json extension package (#818)
Add a Gemini CLI extension package so users can install, update, and remove GSD through Gemini's own extension lifecycle and have it appear in `gemini extensions list`: gemini extensions install https://github.com/open-gsd/gsd-core gemini extensions update gsd-core gemini extensions uninstall gsd-core gemini extensions link /path/to/gsd-core # dev This mirrors the additive Claude Code plugin manifest (#766): a thin, version-stamped manifest enforced by an in-repo drift test. The extension ships the context-file payload (GEMINI.md), loaded into every Gemini session; slash-command/agent/hook TOML projection into the extension is a documented follow-up. The manual `npx gsd-core --gemini` installer (which provides the /gsd:* commands) is unchanged — purely additive, no breaking change. - gemini-extension.json: name=binName, version tracks package.json, description, contextFileName=GEMINI.md (minimal; no mcpServers — gsd ships no MCP server) - GEMINI.md: Gemini-session context payload - package.json: add both artifacts to files[] so they publish - CONTEXT.md: add "Gemini Extension Package" glossary entry - docs: USER-GUIDE + install-on-your-runtime how-to - tests/issue-775-gemini-extension.test.cjs: manifest validity, version parity with package.json, contextFileName existence, files[] publication Closes #775 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3025a6846e |
fix(#812): honor COPILOT_HOME in Copilot global config-dir resolution (#814)
* fix(#812): honor COPILOT_HOME in Copilot global config-dir resolution getGlobalConfigDir('copilot') resolved the global config directory using only --config-dir > COPILOT_CONFIG_DIR > ~/.copilot, ignoring the COPILOT_HOME env var. Per GitHub's Copilot CLI docs, COPILOT_HOME overrides the default ~/.copilot location (and user-level hooks are read from $COPILOT_HOME/hooks/), so a global --copilot install wrote all artifacts (skills, agents, copilot-instructions.md, the gsd-session.json hook) to ~/.copilot even when the user relocated their Copilot home, making them undiscoverable by Copilot CLI. Mirror the codex/CODEX_HOME branch: precedence is now --config-dir > COPILOT_CONFIG_DIR > COPILOT_HOME > ~/.copilot. Uninstall uses the same resolver, so it stays symmetric. Also: document COPILOT_HOME in the installer --help notes, the USER-GUIDE env-var table, and the installer-migrations Copilot row; and clear COPILOT_HOME in the two default-path test suites so they stay hermetic now that the resolver honors it. Closes #812 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#812): add changeset for PR #814 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
463cffd894 |
chore(#604): rename get-shit-done/ runtime directory to gsd-core/ (#615)
* chore(#604): rename get-shit-done/ runtime directory to gsd-core/ Renames the installed runtime directory `get-shit-done/` to `gsd-core/` so the on-disk name matches the package (`@opengsd/gsd-core`), repo, and binary (`gsd-tools`). The npm package name and binary are unchanged; npx/npm consumers are unaffected. Mechanical (bulk, ~90% of the diff): - `git mv get-shit-done gsd-core` - Swept path/identifier references across the repo via `perl -pe 's/get-shit-done(?!-\w)/gsd-core/g'`. The negative lookahead preserves the five legitimate slug variants that are NOT the directory: get-shit-done-{OLD,cc,classic,cli,redux} (old package/repo names). - Build/manifest wiring: package.json (bin, files, coverage globs), tsconfig.build.json (outDir), ~86 .gitignore build-output entries, stryker.config.mjs, scan-ignore files, install.js path strings. - Frozen (not rewritten): CHANGELOG.md history; translated docs (README.<locale>.md and docs/{ja-JP,ko-KR,pt-BR,zh-CN}/). New logic (review here): - src/installer-migrations/003-rename-get-shit-done-to-gsd-core.cts: a proper ADR-0008 installer migration. On upgrade it walks the legacy `~/.claude/get-shit-done/` tree, classifies each file via the prior install manifest, and emits remove-managed / backup-and-remove for managed files while PRESERVING unknown user-added files. Symlink-safe (skips a symlinked root and symlinked entries; bounds-checks every path under configDir). The framework rolls back on install failure. Emptied dirs may remain (framework has no recursive dir-removal primitive) — documented. - scripts/lint-legacy-dir-name.cjs: CI regression guard forbidding the bare `get-shit-done` directory token (split token to avoid self-match; case- insensitive; `(?!-\w)` lookahead allows the slug variants; allowlists CHANGELOG, translated docs, and `gsd-allow-legacy-name` marker lines). Wired into the lint-tests CI job. - Restored scripts/lint-package-identity-drift.cjs detection regexes (the mechanical sweep had wrongly rewritten the old-name patterns it exists to detect) and marked them as intentional legacy references. - TDD tests for the migration and the guard; do.md slash-command guard regex tightened so a `/gsd-core/bin` path segment is not mistaken for a command; changeset + docs/installer-migrations.md row added. Breaking: the installed runtime path moves `~/.claude/get-shit-done/` -> `~/.claude/gsd-core/`. Migration 003 removes the stale legacy dir's managed files (preserving user files) on upgrade. Users with custom hooks/configs hardcoding the old path must update them. Closes #604 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): unsweep pending changesets + allowlist injection-example docs CI fixes for the rename PR: - Do not sweep pending .changeset/*.md (ephemeral release-note fragments, like CHANGELOG); reverted those body edits so 5 pre-existing malformed fragments (missing type/pr) no longer enter the PR diff and trip docs-lint. Allowlisted .changeset/ in the legacy-name guard accordingly. - Allowlisted TEST-EXAMPLES.md and docs/explanation/security-model.md in prompt-injection-scan.sh: they contain intentional injection examples / security-model prose; the path-reference rewrites are kept. CodeQL alerts on this PR are pre-existing (alert lines unchanged by this PR; none in the new migration/guard) and are out of scope for the rename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): resolve CodeQL alerts surfaced on this PR The rename diff touched files carrying pre-existing CodeQL findings; per the no-pre-existing-dismissal rule, fixing every surfaced alert rather than waving them off. All behavior-preserving: - scripts/ci-test-scope.cjs: build the config-path match from string .includes() instead of a RegExp over an arg-derived value (js/regex-injection). - src/profile-output.cts: escape backslashes before pipe-escaping desc/safeName so the table-cell escape is complete (js/incomplete-sanitization). - tests/{bug-2643,bug-2808,docs-parity-live-registry}: two-pass HTML-comment strip so a bare/unclosed `<!--` cannot survive (js/incomplete-multi-character-sanitization). - tests/inline-plan-threshold: drop the no-op `\s`->`\s` identity replace, keep the meaningful POSIX-class conversion (js/identity-replacement). Verified: build:lib green; the touched test files + ci-test-scope + profile-output suites pass; lint:legacy-name clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): correctly resolve remaining CodeQL alerts (regex-injection + sanitization) The prior commit's fixes for two alerts were ineffective: - ci-test-scope.cjs js/regex-injection: the alert is the CLI-arg-derived `file` reaching static regex `.test(file)` calls (not the config rule). Removed ALL regex over file/t — startsWith/includes/=== string checks + an isWindowsHint helper — so there is no regex sink for the tainted value. - js/incomplete-multi-character-sanitization (3 test files): a single `.replace(/<!--...-->/g,'')` can let `<!--` re-form. Replaced with a fixpoint loop (replace until stable) plus a final bare-opener strip. Verified: no regex over file/t remains; ci-test-scope + the 3 test suites pass; lint:legacy-name clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): make ci-test-scope + comment-strippers regex-free to clear CodeQL CodeQL flags the regex PATTERNS syntactically (regex-injection on the --files arg split; incomplete-multi-character-sanitization on the <!--...--> replace), so loop fixes do not satisfy it. Made these paths regex-free: - ci-test-scope.cjs splitFiles: char-by-char separator tokenizer (no /[,\\s]+/). - 3 test files: indexOf/slice HTML-comment stripper (no .replace(/<!--/)). Behavior preserved; ci-test-scope + the 3 suites pass; guard clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): unblock security base64 scan on the large rename diff The security job hit its 10m timeout: base64-scan.sh choked on the binary test fixture tests/feat-3594-parser-property-style.test.cjs (embedded NUL/ non-UTF8 bytes -> thousands of bogus blobs + "ignored null byte" warnings), and the ~800-file rename diff is slow to scan regardless. - scripts/base64-scan.sh: skip binary-by-content files (grep -Iq .) — they can't carry base64-obfuscated *text* and feeding NUL bytes through the per-line scanner is pathologically slow. collect_files already filtered binary *extensions*; this catches binary *content* in text extensions. - .github/workflows/security-scan.yml: raise the security job timeout 10m->30m to accommodate very large diffs (the scan itself is unchanged). Verified locally: scan skips the fixture, 0 "ignored null byte" warnings, 0 findings, exit 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): sweep get-shit-done refs introduced by merging next The branch was updated with next (#614/#384/#618 etc.), which reference the get-shit-done/ dir (still named that on next). Swept the stale references in the merged files to gsd-core so the rename stays consistent and lint:legacy-name passes: - commands/gsd/discuss-phase.md (runtime-launcher shim paths) - src/core.cts (getAgentsDir layout comments) - tests/bug-384-agents-runtime-aware.test.cjs (require path to runtime lib) Verified: guard 0 violations; build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): exclude gsd-core/ path segments from bug-3683 command cross-ref invariant The #614 runtime-launcher shim added to discuss-phase.md references `${_GSD_RUNTIME_ROOT}/gsd-core/bin/...`. bug-3683's REF_PATTERN excluded path-y refs only via lookbehind, but `}` precedes `/gsd-core/` in the shim, so it mis-read the directory path as a dangling `/gsd-core` command ref (same class as the #604 bug-2954 fix). Added a trailing `(?![\w-]*\/)` so `/gsd-<x>/...` path segments are not treated as slash-command references. Verified locally on BOTH platforms before pushing: - mac (node 26) full suite: 0 failures - gsd-test-runner (linux, node22 image) full suite: 0 failures - bug-3683 + bug-2954 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): lazily resolve findProjectRoot in gsd-tools (harden flaky CI) CI intermittently failed state.test's gsd-tools subprocess with "findProjectRoot is not a function" (flip-flopping across legs; not reproducible on mac full suite, gsd-test linux full suite, test:unit, or state.test x8). findProjectRoot is a re-export from core.cjs (sourced from project-root.cjs); binding it via destructure at module-load can be undefined under a load-ordering edge. Resolve it lazily at call time via a small wrapper so the lookup happens after core.cjs is fully initialized. Verified green on BOTH platforms before pushing: - mac (node 26) full suite: 0 failures - gsd-test-runner (linux, node22) full suite: 0 failures - state.test.cjs: 106/106; gsd-tools loads cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#604): allowlist verification-patterns.md placeholder examples in secret scan The rename git-mv'd references/verification-patterns.md into gsd-core/, pulling it into the secret-scan diff. It documents stub/placeholder RED-FLAG env-var examples (illustrative Stripe test-key / database-URL / API-key placeholders) — not real credentials. Added it to .secretscanignore with the strict annotation, mirroring the existing gsd-core/workflows/plan-phase.md exception. Verified locally: secret-scan-lint --strict OK; secret-scan --diff origin/next exits 0 with 0 findings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3bb2f8f1c5 |
docs: rebrand to GSD Core and restructure docs with Diataxis (#605)
* chore: wire docs/agents config into AGENTS.md Agent skills section
Add the `## Agent skills` discovery block pointing the engineering
skills at the existing docs/agents/{issue-tracker,triage-labels,domain}.md
files (issue tracker, triage label mapping, single-context domain docs).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs: rebrand to GSD Core and restructure docs with Diataxis
Reorganise the root README and docs/ around the Diataxis framework
(tutorials, how-to guides, reference, explanation), add new how-to
guides and schema references (STATE.md / CONTEXT.md / PLAN.md /
planning artifacts), and cross-link the whole set. Update the lone
legacy gsd-build reference to open-gsd; keep internal get-shit-done/
filesystem paths unchanged (directory rename tracked separately in
open-gsd/gsd-core#604). Regenerate the ja-JP, ko-KR, pt-BR and zh-CN
localised trees to mirror the new structure.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs: backfill changeset PR number (#605)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
e3bc53f835 |
enhancement(#558): add liveness hints to all GSD spawn announcements (#566)
* enhancement(#558): add liveness hints to all GSD spawn announcements Append '(runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)' inline to every ◆ Spawning… banner and subagent dispatch instruction across 26 workflows. Silent subagents look identical to frozen sessions — this note sets the expectation so users wait instead of killing healthy in-progress work. Changes: - references/ui-brand.md: document liveness convention under Spawning Indicators - 10 banner workflows: append liveness note to ◆ Spawning… lines in-place - 18 subagent-only workflows: add print instruction with liveness phrase - tests/spawn-liveness-banner.test.cjs: new test; fails if any workflow with subagent_type omits 'runs in a subagent' - docs/USER-GUIDE.md: troubleshooting entry for frozen-looking spawns - .changeset/558-spawn-liveness-banner.md: changeset fragment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#558): add missing pr field to changeset fragment The changeset lint requires pr: <NNN> in frontmatter; the fragment was written without it, causing parse.cjs to reject it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#558): address codex review — missed spawns and tighten test - plan-phase.md: add liveness note to chunked outline planner and per-plan chunked planner banners (two missed ◆ Spawning… lines) - quick.md: add liveness note to research banner and add missing display line before planner spawn in Step 5 - plan-review-convergence.md: add liveness note to initial planning and review-agent spawn Display lines - docs-update.md: add Print instructions with liveness note before gsd-doc-verifier spawns in Phase 1 and Phase 2 - autonomous.md: add Print instruction with liveness note before background plan-phase agent dispatch in step 3b - tests/spawn-liveness-banner.test.cjs: replace single file-level check with two assertions: (1) every ◆ Spawning… banner line carries the phrase on that line (2) every file with subagent_type contains the phrase somewhere The tighter test would have caught all five missed spawns. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#558): tighten spawn-liveness test regex to catch spawn-word-anywhere variants Previous SPAWN_BANNER_RE only matched ◆ immediately followed by Spawning|spawning. Replace with /◆[^\n]*\bspawning?\b/i which matches the spawn word anywhere on the ◆ line — catching "◆ Chunked mode: spawning outline planner..." and similar. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#558): rename changeset to PR number 566 and correct pr field Changeset was filed as 558-spawn-liveness-banner.md (issue#) but the convention is the PR number. Renamed to 566-spawn-liveness-banner.md and updated pr: 558 → pr: 566 so release notes link to the right PR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
0fbe1d899e |
chore(#191): retire the gsd-sdk shim — route everything at gsd-tools (#522)
* chore(#191): migrate gsd-sdk query call sites to gsd-tools query Retiring the gsd-sdk shim. gsd-tools.cjs already accepts `query` as a meta-prefix (gsd-tools query <command>), so this is a behavior-preserving 1:1 swap across the runtime reference prompts, the graphify hook's commit-detection gate, and two bin/lib comment/message references. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#191): remove vestigial gsd-sdk shim code from installer + projection The gsd-sdk shim was already not wired up (no gsd-sdk bin in package.json; buildWindowsShimTriple had zero call sites). Remove the dead code: - shell-command-projection.cjs: buildWindowsShimTriple + formatSdkPathDiagnostic (+ their now-unused PACKAGE_NAME import) and exports - install.js: the re-export wrappers + imports, the #3406 stale-standalone-sdk detection (detectStaleStandaloneSdk/formatStaleStandaloneSdkWarning + its global-install call site), and the exports Preserved (retained, not gsd-sdk): buildCodexHookWindowsShimIR (#3426) — only its comments referenced the gsd-sdk pattern; reworded. Also kept the homePathCoveredByRc 'reopen your shell' branch in maybeSuggestPathExport — its logic is bin-dir-agnostic, only the message mentioned gsd-sdk; reworded to use the actual bin dir. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(#191): update tests for retired gsd-sdk shim - bug-3441/bug-3442: drop the formatSdkPathDiagnostic / buildWindowsShimTriple assertions (functions removed); retained PATH-action + drift-guard tests stay - bug-505: remove the 'still exported' assertions for detectStaleStandaloneSdk / formatStaleStandaloneSdkWarning / the shim contract surface (#505 kept them; #191 removes them) - graphify-auto-update: migrate the hook-dispatch inputs gsd-sdk query commit -> gsd-tools query commit to match the migrated commit hook Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(#191): point active docs at gsd-tools query (gsd-sdk shim retired) Update the user/agent-facing docs (AGENTS, COMMANDS, CONFIGURATION, USER-GUIDE, ship-pr-body-sections) that presented gsd-sdk query as a current command to gsd-tools query. Historical docs (ADRs, PRDs, release notes) left untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(#191): correct state.load vs state.json description for gsd-tools query Adversarial-review (codex) finding: the migrated USER-GUIDE line claimed both 'gsd-tools query state.json' and 'state.load' resolve to the frontmatter-rebuild handler. Verified they don't — state.load returns the CJS load shape (config + state_raw + flags), state.json returns the frontmatter shape. Both are available via gsd-tools query; corrected the text to say so. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#191): add changeset for gsd-sdk shim retirement Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
79002a00cb |
chore(#518): rename npm package + bin to @opengsd/gsd-core (#519)
* chore: rename npm package + bin to @opengsd/gsd-core (functional) - package.json: name @opengsd/get-shit-done-redux → @opengsd/gsd-core, bin key get-shit-done-redux → gsd-core, repository/homepage/bugs URLs - package-lock.json: regenerated (npm install --package-lock-only) - tests/**, scripts/**, bin/**, .github/**, agents/**, commands/**, get-shit-done/bin/**, get-shit-done/workflows/**: applied the 4-rule replacement (scoped npm ref, GitHub repo path, bin/clone invocations) per #505 single-source refactor Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: sweep live references to @opengsd/gsd-core Update all live documentation (README.md + translations, docs/**, CONTRIBUTING.md, VERSIONING.md, SECURITY.md, CONTEXT.md, docs/CANARY.md) to reflect the renamed package and repository. Rules applied: - @opengsd/get-shit-done-redux → @opengsd/gsd-core (scoped npm name) - open-gsd/get-shit-done-redux → open-gsd/gsd-core (GitHub repo) - GSD-redux/get-shit-done-redux → open-gsd/gsd-core (stale badge org) - bare bin/clone refs → gsd-core CHANGELOG.md, docs/adr/**, docs/RELEASE-*.md, docs/research/**, and .changeset/** are preserved byte-identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: add negative lookbehind to slash-command regex in bug-2954 test The extractSlashReferences regex matched /gsd-core inside npm package URLs (@opengsd/gsd-core), producing a false /gsd:core command reference. Adding a negative lookbehind (?<![a-z]) excludes matches preceded by a letter, so only standalone /gsd-<cmd> and /gsd:<cmd> tokens are found. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#518): add changeset for package rename Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(#518): update package-identity expectations to the renamed coordinates The rebase regenerated the seam to @opengsd/gsd-core (bin gsd-core, repo open-gsd/gsd-core). The #498 seam tests assert deriveIdentity against the REAL package.json, so their expected literals must follow the rename. The drift-lint unit test is left as-is — its SEAM is a self-consistent fixture and its stale-literal detection cases would shift if altered; the live-repo scan in it already passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
05cdec5f47 |
feat(#22): plan-vs-codebase drift guard (source-grounded reviewer + intel surface) (#487)
* feat(#22): add plan_review.source_grounding + _authority config keys Two additive opt-out keys for the drift guard: source_grounding (bool, default true) gates the source-grounded reviewer pass; _authority (enum grep|intel|treesitter|lsp|scip, default grep) selects the resolver rung. No existing default changed. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(#22): add intel api-surface renderer + CLI subcommand Renders .planning/intel/api-map.json into a human-readable API-SURFACE.md for planner injection. Empty/missing map still writes a surface that announces itself incomplete (absence = unknown, not 'does not exist'). Gated on intel.enabled like all intel functions. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(#22): add source-grounding pass to plan-review-convergence Default-on reviewer pass (plan_review.source_grounding) that enumerates every symbol a plan cites, excludes declared new artifacts, resolves each against source via the configured authority adapter, and records three-valued verdicts. rung-0/1 MISSING is needs-acknowledgement, not a hard block; UNCHECKABLE is logged in a REVIEWS.md coverage section. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(#22): inject API-SURFACE.md into planner + require Artifacts section When intel.enabled, plan-phase regenerates API-SURFACE.md and injects it as a HINT (prefer, may be incomplete, absence = unknown), never a hard rule. Every plan must now emit an 'Artifacts this phase produces' section so the source-grounding reviewer can separate new symbols from references to existing code. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(#22): surface drift-guard in setup + settings, add docs /gsd:new-project asks to enable plan_review.source_grounding (default Y); /gsd:settings exposes the toggle and authority knob. Documents both config keys in CONFIGURATION.md, the intel api-surface command in COMMANDS.md, the drift guard in USER-GUIDE.md, and links ADR 22 from ARCHITECTURE.md. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(#22): respect AskUserQuestion 4-option cap and plan-phase XL line budget settings drift-guard toggle moved to its own 2-option question; #22 plan-phase additions condensed to bring the file back under the 1810-line XL budget without dropping the intel gate, the incomplete-surface hint, or the Artifacts-section requirement. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(#22): use live slash-command forms in drift-guard docs Doc-parity gate requires every slash-command token in docs/*.md to resolve to a registered command. Corrected the command form(s) referenced in the #22 drift-guard / api-surface documentation. The unresolved token was /gsd-core, matched from the GitHub repo reference "open-gsd/gsd-core#22" in docs/adr/22-plan-drift-guard.md. This is the same pattern as the existing 'test-runner' exemption (open-gsd/gsd-test-runner). Added 'core' to INTERNAL_COMPONENT_SLUGS with a matching explanatory comment. Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(#22): add changeset fragment for drift guard (PR #487) Refs #22 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: CI Rebase Check <ci@gsd-redux> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
5b3646d6c8 |
fix(#213): support antigravity 2.x config directory split (#217)
* fix(#213): support antigravity 2.x config directory split * fix(#213): harden antigravity tests for windows parity |
||
|
|
c439890e26 |
docs(2): clarify installer is required for cross-runtime compatibility (#144)
* docs(readme): add cross-runtime compatibility note for installer requirement Source files in agents/ and commands/ are Claude Code-format frontmatter. The installer (bin/install.js:5208 convertClaudeToOpencodeFrontmatter) is the mandatory conversion layer for non-Claude-Code runtimes. Manually copying source files to ~/.config/opencode/agents (or equivalent) bypasses conversion and produces schema validation errors. README lines 37, 165, 273 all claim OpenCode as a first-class runtime without flagging the installer as mandatory. This adds an explicit note immediately after the Getting Started section (README.md line ~175). Refs #2 * docs(user-guide): add manual install / no-Node.js setup section for non-Claude runtimes Users without Node.js (Windows + OpenCode being the most common case per issue #2) cannot run the installer and may attempt to copy agents/ source files directly. This section documents what manual conversion is required for OpenCode (remove tools:, convert color: to hex), references the installer function at bin/install.js:5208, links to the OpenCode schema docs, and covers the Docker/WSL alternative. USER-GUIDE.md insertion after line 1258 (after the Codex/non-Claude runtime section, before Installing for Cline). Refs #2 * ci: retrigger checks after transient git-auth runner failure The original run for this PR had a single CI job fail with: "fatal: could not read Username for 'https://github.com': terminal prompts disabled" That is a hosted-runner infrastructure flake — no code defect. The run cannot be retried via gh CLI (too old). This empty commit kicks a fresh full CI cycle. |
||
|
|
334a64168e |
chore(npm): rebrand packages to @opengsd scope (#127)
* chore(npm): rebrand packages to @opengsd scope Rename: - get-shit-done-redux → @opengsd/get-shit-done-redux - @gsd-redux/sdk → @opengsd/gsd-sdk Add publishConfig.access=public for first-time scoped publish. CLI binary names (get-shit-done-redux, gsd-sdk, gsd-tools) unchanged. Sweeps install commands, npx invocations, CI publish/version-check workflows, tests, docs, READMEs (all translations), and the PACKAGE_NAME constant in check-latest-version. Bumps qs 6.15.1 → 6.15.2 to clear a moderate advisory surfaced by the audit-clean test (GHSA-q8mj-m7cp-5q26). Closes #126 * chore: pin 2.0.0 release + remove canary workflow - Bump both packages 1.50.0-canary.0 → 2.0.0 for first @opengsd publish - Remove .github/workflows/canary.yml and canary dist-tag handling in release.yml / release-sdk.yml - Drop canary section from VERSIONING.md Refs #126 * chore: address review findings + harden tarball-smoke timeout - .changeset/opengsd-org-rename.md: match project's custom parse.cjs frontmatter (type: Changed / pr: 127); the scoped @changesets/cli keys were silently rejected. - CONTEXT.md: drop two canary-stream policy lines and a dangling DEFECT.CANARY-VERSION-LEAK.cross-ref now that canary.yml is gone. - tests/release-tarball-smoke.install.test.cjs: pass timeout: 600_000 for npm pack + global install; the 3-minute runNpm default was timing out on slower Docker hosts (cartographer). Refs #126 * fix(sdk): add missing type/runtime devDependencies for build prepublishOnly invokes tsc which couldn't resolve @types/node, @types/ws, or synckit. They had been hoisted from root but were not declared in sdk/'s own package.json — first publish from a clean SDK tree failed. Refs #126 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ci): use npm pack stdout instead of glob to find tarball `npm pack --silent` for a scoped package (@opengsd/get-shit-done-redux) produces `opengsd-get-shit-done-redux-*.tgz`, not `get-shit-done-redux-*.tgz`. Capture the filename from stdout instead of a hardcoded glob so the step works regardless of package name format. Fixes smoke (ubuntu-latest, 22, false) CI failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: treat workflow-file changes as test-skip eligible `.github/workflows/install-smoke.yml` (and other workflow files) were in neither `test.yml` paths nor `test-skip.yml` paths-ignore, so neither workflow ran on a workflow-only commit — leaving the required test-skip check perpetually missing. Refs #126 * chore: reset version to 1.0.0 for first @opengsd publish Nothing has been published yet under the @opengsd scope, so the inaugural release uses 1.0.0 rather than 2.0.0. The "major bump" in the changeset reflects the breaking install-command change for users migrating from the prior unscoped `get-shit-done-redux`, not a numeric continuation from a 1.x line under the new identity. Refs #126 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
2a915c1b82 |
chore: migrate references from gsd-build to open-gsd/get-shit-done-redux (#120) (#121)
Security-motivated migration of all stale repository and npm-scope references. Three categories of changes (58 files, 174 substitutions): 1. gsd-build → open-gsd (security-critical): - .github/workflows/release-sdk.yml — npm token comment, tarball filename pattern - .github/workflows/hotfix.yml — same - .changeset/fix-3406-detect-stale-sdk-shadow.md — @gsd-build/sdk → @open-gsd/sdk - .changeset/sharp-quails-leap.md — same - get-shit-done/workflows/update.md — CHANGELOG raw GitHub URL 2. GSD-redux org slug → open-gsd (canonical rename): - package.json + sdk/package.json — repository/homepage/bugs metadata - All README.*.md — live badge and link sections - CONTRIBUTING.md, CONTEXT.md, QUICK-WINS-CONFIRMED-BUGS.md - .coderabbit.yaml, .release-monitor.sh, scripts/sync-rulesets.sh - docs/** — all live agent/ADR/user-facing documentation - tests/** — repo slug assertions and test fixtures - scripts/changeset/cli.cjs + github-release-notes.cjs - .github/ISSUE_TEMPLATE/*, .github/pull_request_template.md - bin/install.js, get-shit-done/bin/lib/model-catalog.cjs - sdk/HANDOVER-*.md, sdk/src/*.test.ts 3. CLAUDE.md (gitignored local file — not in this commit): Updated separately outside git: --repo gsd-build/get-shit-done → --repo open-gsd/get-shit-done-redux with security warning. Intentionally unchanged: CHANGELOG.md, docs/RELEASE-*.md, .changeset/README.md, .changeset/build-hooks-atomic-write.md, README.md migration table (historical fork record), tests/changeset-serialize.test.cjs line 78 (serialization fixture). The gsd-build/get-shit-done repo is compromised (rug-pull documented in README.md). Do not push to or interact with that repo. Closes #120 |
||
|
|
dff176bfd2 |
chore: rebrand to GSD-redux/get-shit-done-redux
Mirror of code, issues, and PRs from the upstream gsd-build/get-shit-done, which appears compromised or abandoned (maintainer unreachable since 2026-04-01; $GSD token linked to rug-pull). - Adds rebrand notice block at top of English README - Removes $GSD token badge and @gsd_foundation X badge (keeps Discord) - Renames npm packages: get-shit-done-cc -> get-shit-done-redux, @gsd-build/sdk -> @gsd-redux/sdk - Updates all repo URLs across docs, workflows, package.json, bin/ - Updates ci@gsd-build -> ci@gsd-redux in workflow git identities - Leaves CHANGELOG and .changeset/* alone (historical, time-stamped) |
||
|
|
08848df839 |
docs(3562): pin minimum Codex CLI version (0.130.0) and explain the seam
Rationale for the version pin (the timeline that produced the oscillation):
2026-05-08 Codex CLI 0.130.0 ships, dropping extra-skills-roots
discovery via openai/codex#21485 (scans only ~/.codex/skills,
cwd .codex/skills, and registered plugin roots).
2026-05-14 GSD PR #3512 lands, removing ~/.codex/skills/gsd-* under the
assumption Codex would auto-discover from extra roots.
That assumption was already obsolete in shipped Codex.
2026-05-15 #3562 filed — Codex CLI 0.130.0 users have zero $gsd-*
commands after install.
The previous fix (#3427) was for Codex Desktop's official-skills surface,
which is a different product; that surface still exists on Desktop and
remains harmless duplication when both root scans see the gsd-* dirs.
Documents the supported version inline at the Codex sections of both
USER-GUIDE.md and CONFIGURATION.md, plus a one-line note in README's
Troubleshooting block. No runtime version-detection added — out of scope
and brittle against future Codex changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
5c202372ed | docs: update v1.42.1 release documentation | ||
|
|
e79c472d7b |
Feat(ship): add configurable PR body sections (#3391)
* feat: add configurable ship PR body sections * chore: add changeset for ship PR sections * docs: avoid prompt scanner trigger in PR body guide * docs: escape pr body source separator |
||
|
|
3aaed8f5d7 |
test: replace deny-list parity tests with polarity-inverted live-registry (#3049) (#3284)
* test: reproduce Windows SDK not found after fresh npx install (#3211) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: red — docs-parity live-registry tests fail against stub helper (#3049) Adds: - tests/helpers/live-command-registry.cjs (stub: returns empty Set) - tests/docs-parity-live-registry.test.cjs (new polarity-inverted test) - tests/fixtures/live-command-registry/ (fixture .md files) All parity and helper-contract tests fail because the stub returns an empty registry. This is the intentional RED state before GREEN implementation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(test-helpers): live-command-registry derives canonical tokens from commands/gsd/*.md (#3049) Implements GREEN phase: - tests/helpers/live-command-registry.cjs: walks commands/gsd/*.md, parses YAML frontmatter name: field, emits /gsd-slug, /gsd:slug, $gsd-slug per command. Memoized per process. Fails loud on malformed frontmatter (k302). - tests/docs-parity-live-registry.test.cjs: updated with INTERNAL_COMPONENT_SLUGS exemption for path-component and placeholder tokens (gsd-build from GitHub org URLs, gsd-workspaces from ~/gsd-workspaces/ paths, gsd-tools from bin/gsd-tools.cjs paths, etc.) Docs drift caught and fixed: - ns-* rename: /gsd-ns-workflow→/gsd-workflow etc. in COMMANDS, FEATURES, INVENTORY, USER-GUIDE (6 commands across 4 English files) - /gsd-scan → /gsd-map-codebase --fast (FEATURES, INVENTORY, USER-GUIDE) - /gsd-note → /gsd-capture (FEATURES, issue-driven-orchestration, ja-JP, ko-KR) - /gsd-do → /gsd-fast (FEATURES, ja-JP, ko-KR) - /gsd-from-gsd2 → /gsd-import --from-gsd2 (CLI-TOOLS, FEATURES, INVENTORY) - /gsd-verify-phase → /gsd-validate-phase (STATE-MD-LIFECYCLE) - /gsd-settings-integrations → /gsd-settings or /gsd-config --integrations (CLI-TOOLS) - /gsd-dev-preferences removed from profile-user artifact lists (AGENTS, COMMANDS, FEATURES in English, ja-JP, ko-KR) - /gsd-select-framework removed from gsd-framework-selector spawner list (AGENTS, INVENTORY) All 28 new tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(test): replace deny-list parity tests with polarity-inverted live-registry approach (#3049) - Delete bug-3010-reapply-patches-references.test.cjs (hardcoded deny-list) - Delete bug-3029-3034-stale-command-routes.test.cjs (hardcoded deny-list) - Delete bug-3042-3044-research-flag-and-stale-refs.test.cjs (deny-list + frontmatter checks) - Add tests/skill-frontmatter-contract.test.cjs (frontmatter structural checks extracted from deleted file) - Update tests/commands-doc-parity.test.cjs to derive slug from name: frontmatter field instead of filename, so ns-* commands resolve to their actual deployed tokens Closes #3049 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: annotate commands-doc-parity with source-text-is-the-product exemption (#3049 lint fix) The readFileSync on commands/gsd/*.md reads product markdown whose deployed text IS what the user sees — content.startsWith('---') detects YAML frontmatter in those files, not source-code structure. Add the allow-test-rule exemption matching the same rationale used in docs-parity-live-registry.test.cjs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: walk docs/** recursively to cover nested locale trees (CR finding 7) Replaced the non-recursive listMdFiles() with a hand-rolled DFS walker compatible with Node 20+. Surfaces unreadable-directory errors as stderr warnings (PRED.k302) rather than silently skipping. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: annotate live-command-registry helper and commands-doc-parity with source-text exemptions (CR findings 6, 8) Adds allow-test-rule comments to suppress lint-no-source-grep false positives on YAML frontmatter structure checks in both files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: anchor --research-phase assertions to arg-parsing section and verify combined refresh (CR findings 9, 10) Finding 9: scopes --research-phase check to within 1200 chars of the flag description section header, preventing false positives from prose mentions. Finding 10: tightens the force-refresh assertion to require BOTH --research and force/refresh semantics within the --research-phase description section, verifying the combined-mode contract rather than standalone --research presence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: fix execSync mock to accept opts parameter, forward to saved implementation (CR finding 5) The mock at line 212 dropped the options parameter when delegating to savedExecSync. Updated to (cmd, opts) signature and pass opts through. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: correct routing entrypoint, --fast default, /gsd-review collision, verifying-stage mapping (CR findings 1-4) Finding 1: Change Freeform Routing command from /gsd-fast to /gsd-progress --do. /gsd-fast is the inline trivial-task executor, not the routing entrypoint. Finding 2: Clarify that /gsd-map-codebase --fast REQ-SCAN-02 default (tech+arch) runs as a single combined-focus agent, resolving the contradiction with REQ-SCAN-01. Finding 3: Rename the namespace router /gsd-review to /gsd-quality across all docs, command file, and help.md to eliminate the naming collision with the concrete cross-AI peer-review command (review.md, name: gsd:review). Finding 4: Replace /gsd-validate-phase with /gsd-verify-work in the STATE-MD-LIFECYCLE.md verifying-stage table. /gsd-validate-phase is the retroactive Nyquist-validation flow, not the normal phase-verification step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs+test: fix locale doc drift surfaced by recursive walker (CR finding 7 follow-up) The recursive listMdFiles() walker newly covered docs/**/*.md subdirs. Stale command references in locale docs are now caught and fixed: - docs/zh-CN/references/model-profiles.md: remove /gsd-set-profile (deleted command); config.json is the current mechanism - docs/zh-CN/references/ui-brand.md: remove /gsd-alternative-1/2 template placeholders - docs/{ja-JP,ko-KR,pt-BR}/superpowers/specs/2026-03-20-*: replace /gsd-new-workspace, /gsd-list-workspaces, /gsd-remove-workspace with /gsd-workspace --new / --list / --remove (consolidated in #2790) Also adds smoke- and alternative-{1,2} to INTERNAL_COMPONENT_SLUGS (filesystem path and template placeholder patterns, not slash commands) and introduces listEnglishMdFiles() to scope the English parity check to docs/ excluding locale subdirectories (which have their own per-locale describe blocks). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add bash language tag to fenced code blocks in ja-JP and ko-KR workspace specs (CR round 2) Satisfies MD040 fenced-code-language requirement. These blocks contain shell commands and were missing the language specifier. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
b37c487325 |
feat(security): package legitimacy gate against slopsquatting (#3215)
* feat(security): package legitimacy gate against slopsquatting (#2827) GSD's research → plan → execute pipeline had no install-time legitimacy gate: a hallucinated package name that passes `npm view` could flow all the way to `gsd-executor` running `npm install <malicious-pkg>` with no human checkpoint. This PR closes that gap. Changes: - gsd-phase-researcher: runs slopcheck on every recommended package; emits `## Package Legitimacy Audit` table; strips [SLOP] packages; ecosystem-specific verification (pip/npm/cargo); WebSearch-sourced packages tagged [ASSUMED]; ctx7 fallback uses `command -v` guard instead of `npx --yes` - gsd-planner: injects `checkpoint:human-verify` before [ASSUMED]/[SUS] installs; adds T-{phase}-SC STRIDE row to <threat_model> template; ctx7 fallback also uses `command -v` guard - gsd-executor: RULE 3 excludes package installs from auto-fix; failed installs surface as checkpoints, never silent substitutions - tests/package-legitimacy-gate.test.cjs: 24 structural assertions covering the full gate (node:test + node:assert, no raw .includes()) - docs: USER-GUIDE, COMMANDS, ARCHITECTURE updated with gate description - .changeset: Security fragment for v1.51 release notes Closes #2827 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: expand Package Legitimacy Gate documentation Add full user-facing depth to the gate docs across USER-GUIDE, COMMANDS, and ARCHITECTURE: - USER-GUIDE: rewrite gate section with concrete RESEARCH.md/PLAN.md examples, slopcheck verdict table, [ASSUMED] WebSearch tagging explanation, slopcheck-unavailable troubleshooting, and graceful degradation behavior - COMMANDS.md: expand /gsd-plan-phase gate note with verdict bullets; add install-failure checkpoint behavior to /gsd-execute-phase - ARCHITECTURE.md: expand gate section with threat model rationale, layer table, claim provenance integration, ecosystem coverage, and graceful degradation semantics Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(security): harden package legitimacy checkpoint semantics * fix(planner): satisfy size gates and tighten package gate wording --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
924c697097 |
docs: replace retired /gsd-intel with /gsd-map-codebase --query (#3258) (#3260)
* test: forbid stale /gsd-intel references in workflow/reference docs (#3258) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: replace retired /gsd-intel with /gsd-map-codebase --query (#3258) Fixes 5 stale references across the two primary source files called out in the issue. PR #2790 folded /gsd-intel into /gsd-map-codebase --query; these prose surfaces were not updated at that time. Fixes #3258 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: fix additional stale /gsd-intel references found in adversarial sweep (#3258) Sweep found 7 more occurrences in docs/INVENTORY.md (x2), docs/USER-GUIDE.md (x4), docs/FEATURES.md (x2), and agents/gsd-intel-updater.md (x2). All replaced with /gsd-map-codebase --query. The gsd-intel-updater agent name itself (without leading slash) is intentionally preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * changeset: pr=3260 for #3258 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: fail loudly on unreadable files in bug-3258 regression scan (CR finding) Replace silent early-return on readFileSync failure with an explicit throw so unreadable files surface as test failures rather than skipped coverage gaps. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
94f835af40 |
docs: add Prerelease editions install guidance (Next/Nightly/Insiders/Preview) (#3173)
* docs: add Prerelease editions install guidance (Next/Nightly/Insiders/Preview) Documents the existing <RUNTIME>_CONFIG_DIR override pattern for users on prerelease runtime editions (Windsurf Next, Cursor Nightly, VS Code Insiders, Codex preview, JetBrains EAP, etc.) and explicitly states they are best-effort and not separately tested under release CI — consistent with the free-string runtime policy in #2517. Resolves the discoverability gap behind issue #3161 without enumerating each prerelease channel as a named runtime. Future "add <runtime>-next/-nightly" requests can be redirected to the new section. Closes #3172 * chore(changeset): set PR number for prerelease docs fragment |
||
|
|
858c821829 |
docs: sweep stale /gsd-* command references across all user-facing docs
Replace 30 absorbed/deleted standalone command forms with their consolidated flag-based equivalents across 25 files (English + 4 locales + AGENTS/CLI-TOOLS/CONFIGURATION): /gsd-session-report → /gsd-pause-work --report /gsd-list-phase-assumptions → /gsd-discuss-phase --assumptions /gsd-analyze-dependencies → /gsd-manager --analyze-deps /gsd-research-phase → /gsd-plan-phase --research-phase /gsd-plan-milestone-gaps → /gsd-audit-milestone /gsd-code-review-fix → /gsd-code-review --fix /gsd-spike-wrap-up → /gsd-spike --wrap-up /gsd-sketch-wrap-up → /gsd-sketch --wrap-up /gsd-set-profile → /gsd-config --profile /gsd-check-todos → /gsd-capture --list /gsd-add-todo → /gsd-capture /gsd-add-backlog → /gsd-capture --backlog /gsd-plant-seed → /gsd-capture --seed /gsd-note → /gsd-capture --note /gsd-add-phase → /gsd-phase /gsd-insert-phase → /gsd-phase --insert /gsd-edit-phase → /gsd-phase --edit /gsd-remove-phase → /gsd-phase --remove /gsd-new-workspace → /gsd-workspace --new /gsd-list-workspaces → /gsd-workspace --list /gsd-remove-workspace → /gsd-workspace --remove /gsd-sync-skills → /gsd-update --sync /gsd-reapply-patches → /gsd-update --reapply /gsd-scan → /gsd-map-codebase --fast /gsd-intel → /gsd-map-codebase --query /gsd-next → /gsd-progress --next /gsd-do → /gsd-progress --do /gsd-status → /gsd-progress /gsd-join-discord → /gsd-help Skipped: CHANGELOG, RELEASE notes, superpowers/specs (historical) Suite: 6971/6971 pass |
||
|
|
d978ad6b2f | merge: sync main into PR #3114 and keep canonical next/profile commands | ||
|
|
72f4c3b362 | fix(docs): replace stale /gsd-next references with /gsd-progress --next | ||
|
|
eb365f7336 |
docs: audit and update docs/ for v1.40.0 release (#3048)
* docs(en): update FEATURES/USER-GUIDE/COMMANDS for v1.40.0 surface - FEATURES.md: append v1.40.0 section (#122 skill consolidation, #123 namespace meta-skills, #124 context-window guard, #125 phase-lifecycle status-line read-side); add to TOC. - USER-GUIDE.md: add slash-command form (hyphen vs colon) primer and namespace routing primer; replace deleted slash forms in walkthroughs (`/gsd-add-backlog`, `/gsd-plant-seed`, `/gsd-add-phase`, `/gsd-set-profile`, `/gsd-list-workspaces`, etc.) with consolidated forms (`/gsd-capture --backlog`, `/gsd-phase --insert`, `/gsd-config --profile`, `/gsd-workspace --list`, etc.); fix `/gsd-spike-wrap-up` and `/gsd-sketch-wrap-up` to flag form. - COMMANDS.md: clarify Command Syntax (Gemini = colon form, others = hyphen form); add Namespace Meta-Skills section with all six routers; add `--context` to /gsd-health flag table. Refs #3047 * docs(en): refresh INVENTORY/CLI-TOOLS/STATE-MD-LIFECYCLE for v1.40.0 - INVENTORY.md: workflow-row "Invoked by" column updated to point at consolidated commands (`/gsd-phase` family, `/gsd-workspace --list`, `/gsd-config --advanced/--integrations/--profile`, `/gsd-sketch --wrap-up`, `/gsd-spike --wrap-up`); CLI-modules row for `secrets.cjs` updated to `/gsd-config --integrations`. Command count and namespace meta-skills section already reflect 65 shipped (= 59 consolidated sub-skills + 6 ns-* routers). - CLI-TOOLS.md: add `validate context` row under Validation Commands with the 60 %/70 % threshold envelope used by `/gsd-health --context`. - STATE-MD-LIFECYCLE.md: flip status header from "proposed" to "shipped in v1.40.0" since `parseStateMd()` and `formatGsdState()` now read and render `active_phase`, `next_action`, `next_phases`, and `progress`. `docs/AGENTS.md` audited and verified clean — `gsd-code-fixer` row already lists the correct `/gsd-code-review --fix` spawner; no deleted-skill references found. `docs/INVENTORY-MANIFEST.json` audited and verified clean — already enumerates the 65 commands (including six ns-* routers) and contains no deleted slash forms. Refs #3047 * docs(en): cleanup ARCHITECTURE/CONFIGURATION for v1.40.0 - ARCHITECTURE.md: split Commands install-target list to call out the Gemini colon form (`/gsd:command-name`) vs hyphen form for every other runtime. Add a new subsection covering two-stage hierarchical routing via the six namespace meta-skills (#2792) and a paired note on the MCP token-budget interaction so readers see the two big per-turn cost levers in one place. - CONFIGURATION.md: rewrite three references to the deleted `/gsd-settings-advanced` and `/gsd-settings-integrations` slash forms to use the consolidated `/gsd-config --advanced` / `/gsd-config --integrations` invocations. Add a new "STATE.md Frontmatter (Phase Lifecycle)" section documenting the four optional fields (`active_phase`, `next_action`, `next_phases`, `progress`) read by the v1.40 status-line, with a pointer to STATE-MD-LIFECYCLE.md for the full reference. `docs/manual-update.md` audited and verified clean — already documents `/gsd-update --reapply` (the consolidated form), no reference to the deleted `/gsd-reapply-patches`. Refs #3047 * docs(i18n): mirror v1.40.0 slash-command rename into ja-JP/ko-KR/zh-CN/pt-BR Mechanical token-level renames only — every reference to a deleted micro-skill slash form is rewritten to the consolidated form on the matching parent skill. No prose was machine-translated; new prose sections (slash-form primer, namespace routing primer, v1.40 feature entries, STATE.md frontmatter) were left for human translator follow-up. Renames applied uniformly across all four trees: /gsd-add-todo, /gsd-add-note, /gsd-add-backlog, /gsd-plant-seed, /gsd-check-todos → /gsd-capture[ --note| --backlog|--seed|--list] /gsd-add-phase, /gsd-insert-phase, /gsd-remove-phase, /gsd-edit-phase → /gsd-phase[ --insert| --remove|--edit] /gsd-new-workspace, /gsd-list-workspaces, /gsd-remove-workspace → /gsd-workspace[ --new| --list|--remove] /gsd-settings-advanced, /gsd-settings-integrations, /gsd-set-profile → /gsd-config[ --advanced| --integrations|--profile] /gsd-sketch-wrap-up → /gsd-sketch --wrap-up /gsd-spike-wrap-up → /gsd-spike --wrap-up /gsd-reapply-patches → /gsd-update --reapply /gsd-code-review-fix → /gsd-code-review --fix /gsd-plan-milestone-gaps → /gsd-audit-milestone Refs #3047 * docs(changelog): regroup [Unreleased] under Feature/Enhancement/Fix Replace the existing Keep-a-Changelog \`Added\` / \`Changed\` / \`Performance\` / \`Removed\` / \`Fixed\` sub-headers in the [Unreleased] block with the issue/PR template taxonomy: Added → Feature Changed / Performance → Enhancement Removed → Enhancement Fixed → Fix Order within the release: Feature → Enhancement → Fix. Every bullet preserved verbatim — only headers and grouping changed; the awkward inline-versioned headers (\`### Added — 1.40.0-rc.1\`, \`### Changed — 1.40.0-rc.1\`, \`### Fixed — 1.40.0-rc.1\`) folded into the same buckets with the \`— 1.40.0-rc.1\` suffix dropped, since the [Unreleased] block IS 1.40.0-rc.1. The [1.39.2] hotfix block called out in #3047's spec does not yet exist in CHANGELOG.md (the previously released hotfix is [1.39.1]), so this commit only regroups [Unreleased]. Older release blocks ([1.39.1] and earlier) are frozen and untouched. Refs #3047 * docs(changeset): add fragment for v1.40.0 doc audit Refs #3047 * docs(en): strip leading / from deleted slash-command tokens in FEATURES REQ-CONSOLIDATE-03 and REQ-CONSOLIDATE-04 listed deleted commands by their `/gsd-foo` form for the historical record. The docs-parity tests in bug-3010, bug-3029-3034, and bug-3042-3044 use the regex `/\/gsd-[a-z0-9][a-z0-9-]*/g` to scan user-facing surfaces for any remaining mention of removed slash forms — they cannot tell prose about a deleted command from a live recommendation. Strip the leading slash from the bare-name references (preserve the historical text otherwise). Tests now require a `/` prefix to match, so `gsd-add-todo` reads identically to a human but no longer trips the parser. Verified locally: 65/65 tests pass across the three docs-parity suites that were red on CI run 25270072600. Refs #3047 * docs(en): fix CR feedback + drop literal /gsd:plan-phase from USER-GUIDE CI: tests/bug-2543-gsd-slash-namespace.test.cjs flagged docs/USER-GUIDE.md:35 for embedding the literal `/gsd:plan-phase` token in the parenthetical Gemini-form example. The test scans every .md under docs/ for `/gsd:<live-cmd>` because non-Gemini surfaces must not advertise the colon form. Replaced the literal example with a prose substitution rule. CR: docs/ARCHITECTURE.md:125 — the namespace meta-skills were listed by file-prefix (`gsd-ns-workflow`) but the invocable frontmatter `name:` is the bare form (`gsd-workflow`). Verified against the six `commands/gsd/ns-*.md` files. Replaced with the canonical names and noted the file/name disagreement in-line. CR: docs/COMMANDS.md:723 — `v1.40` aligned to canonical `v1.40.0`. CR: docs/FEATURES.md:2679 — REQ-CTX-GUARD-02 advertised the wrong invocation (`gsd-tools validate context`). The shipped handler is exposed via `gsd-sdk query validate.context` and requires explicit `--tokens-used <int>` + `--context-window <int>` flags (verified against sdk/src/query/validate.ts:849-882 and get-shit-done/bin/lib/validate-command-router.cjs:19-36). CR: docs/zh-CN/README.md:533 — added `inherit` to the profile-options parenthetical to match the canonical set (verified against model-profiles.cjs:29 `VALID_PROFILES = […MODEL_PROFILES['gsd-planner'], 'inherit']`). Verified locally: 74/74 tests pass across the four docs-parity suites that were red on CI runs 25270072600 and 25270182903. Refs #3047 |
||
|
|
1e6737cd8e |
feat(plan-phase): --research-phase flag + scrub stale slash-command refs (#3042, #3044) (#3045)
* feat(plan-phase): --research-phase flag absorbs deleted /gsd-research-phase + scrub stale refs (#3042, #3044) #3042 (orphaned research-phase): /gsd-research-phase had a workflow file but no slash-command stub. Rather than restore the orphan, the research- only capability is now a flag on /gsd-plan-phase: /gsd-plan-phase --research-phase <N> When set, the workflow scopes to phase N, runs the research step (Section 5 of the existing plan-phase workflow), then early-exits before the planner/plan-checker/verifier chain. Per RCA against the deleted standalone, the flag adds two modifiers to fully cover the original surface (Option B from the RCA discussion): - --view : print existing RESEARCH.md to stdout, no spawn. Cheapest mode for the correction-without-replanning loop the issue reporter explicitly called out. Errors with a clear hint if RESEARCH.md is missing. - --research : reuse the existing "force re-research" semantics. In research-only mode this skips the existing-RESEARCH.md prompt and re-spawns unconditionally. - Neither flag, RESEARCH.md exists : prompt update/view/skip. Mirrors the deleted standalone's existing-artifact menu (#3042 RCA). #3044 (stale slash-command refs): scrubbed five deleted commands from all user-facing surfaces, including English docs, 4 localized doc sets (ja-JP, ko-KR, zh-CN, pt-BR), workflows, templates, and references. /gsd-check-todos → /gsd-capture --list /gsd-new-workspace → /gsd-workspace --new /gsd-status → /gsd-progress /gsd-plan-milestone-gaps → table rows / orphan sections removed (PR #3038 only scrubbed workflows/agent; missed the docs surfaces this PR covers) /gsd-research-phase → /gsd-plan-phase --research-phase Includes a fix to docs/issue-driven-orchestration.md (PR #3036) which itself referenced /gsd-new-workspace 4 times — self-correction. Removed: - get-shit-done/workflows/research-phase.md (orphan, capability absorbed into --research-phase flag) Tests: - tests/bug-3042-3044-research-flag-and-stale-refs.test.cjs — 46 structural-IR tests across both bugs: - argument-hint advertises --research-phase + --view - workflow parses --research-phase, sets RESEARCH_ONLY, early-exits before planner - --view prints RESEARCH.md without spawning - --research forces refresh in research-only mode - existing-RESEARCH.md prompt path with update/view/skip - workflows/research-phase.md is removed - 5 deleted slash-commands absent from 17 English user-facing surfaces + 16 localized doc surfaces (4 locales × 4 docs each) - replacement command tokens present where deleted ones lived 6950/6950 full suite pass. Lints clean. Closes #3042 Closes #3044 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: address all 8 CR findings on PR #3045 Major (3): - get-shit-done/workflows/plan-phase.md:344 — added explicit early-exit guard at Section 5.1: "Skip if RESEARCH_ONLY=true". Without it, an LLM could fall through "use existing, skip to step 6" → planner spawn, violating the research-only contract. The guard makes the early-exit unreachable from any non-research-only branch. - get-shit-done/references/continuation-format.md (3 examples) + zh-CN/.../continuation-format.md (3 examples) — pointed to `/gsd-plan-phase --research-phase` but docs/COMMANDS.md didn't document the flag. Added a full --research-phase + --view + --research modifier section to the /gsd-plan-phase flag table in COMMANDS.md so the canonical reference matches the continuation examples. Minor (5): - docs/FEATURES.md:1632 — `/gsd-plan-phase --research-phase` → `/gsd-plan-phase --research-phase <N>` (include required arg). - get-shit-done/templates/README.md:46 — NN-VALIDATION.md producer reverted from `/gsd-plan-phase --research-phase` (Nyquist) to plain `/gsd-plan-phase` (Nyquist). VALIDATION.md is created during normal Nyquist flow, not research-only mode — the bulk replacement was wrong for that line. - get-shit-done/workflows/help.md:89 — signature line was missing `--research`; added it alongside `--research-phase` and `--view`. - tests/bug-3042-3044-...:197 — promptHasView/promptHasSkip were tautological (matched anywhere in 1700-line workflow). Tightened to a proximity check anchored on "RESEARCH.md already exists" prompt header within a 600-char window. Updated workflow to emit that literal phrase. - tests/feat-2840-...:95 — workspace assertion used `/gsd-workspace` but the documented replacement is `/gsd-workspace --new`. Tightened to require both tokens (in 3 places: requiredCommands list, regex in conceptPairs, error message). 6950/6950 full suite pass. Lint clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
7714b5244b |
fix(workflows,docs): scrub stale /gsd-code-review-fix and /gsd-plan-milestone-gaps refs (#3029, #3034) (#3038)
* fix(workflows,docs): scrub stale /gsd-code-review-fix and /gsd-plan-milestone-gaps refs (#3029, #3034) #2790 consolidated /gsd-code-review-fix into /gsd-code-review --fix and deleted /gsd-plan-milestone-gaps in favor of inline gap planning as part of /gsd-audit-milestone's output. The deletion was propagated through some surfaces (#2950 covered help/do/settings/discuss-phase/etc.) but several user-facing surfaces still emitted the old forms: #3029 — /gsd-code-review-fix references in: - agents/gsd-code-fixer.md (description, "Spawned by", recovery prose) - get-shit-done/workflows/code-review.md (offer text) - get-shit-done/workflows/execute-phase.md (offer text) - get-shit-done/workflows/code-review-fix.md (internal retry hints) - docs/INVENTORY.md (agent + workflow rows) - docs/CONFIGURATION.md (workflow.code_review row) - docs/USER-GUIDE.md (3 occurrences in walkthrough) - docs/AGENTS.md (gsd-code-fixer agent stub) - docs/FEATURES.md (commands list + REQ-REVIEW-04) All replaced with /gsd-code-review --fix. Internal retry hints in the workflow file itself updated to point at the new form. Release notes (docs/RELEASE-*.md) and gsd-ns-review's "absorbed by" deletion note left unchanged — historical/explanatory content. #3034 — /gsd-plan-milestone-gaps references in: - get-shit-done/workflows/audit-milestone.md (<offer_next> blocks for gaps_found and tech_debt: lines 281, 323) - commands/gsd/complete-milestone.md (gaps_found pre-flight: lines 46, 57) Replaced with inline closure path: /gsd-phase --insert <N> "Close gap: <REQ-ID> ..." /gsd-discuss-phase <N> /gsd-plan-phase <N> /gsd-execute-phase <N> Plus a Nyquist-coverage hint pointing at /gsd-validate-phase / /gsd-secure-phase for retroactive audit-chain hygiene gaps. The gsd-ns-project SKILL.md "deleted by #2790" note is preserved (it's the canonical pointer for future readers asking what happened to the command). Tests: - tests/bug-3029-3034-stale-command-routes.test.cjs — parser-based assertions per fixed surface, plus a structural cross-check that gsd-ns-project keeps the deletion note. 15 tests, all green. - 6905/6905 full suite passes. Closes #3029 Closes #3034 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: address CR feedback on PR #3038 — argument order, structural tests, agent count CR findings on PR #3038: 1. **docs/USER-GUIDE.md (Major)** — `--fix` examples used flag-first form (`/gsd-code-review --fix 3`), but the supported CLI grammar is phase-first (`/gsd-code-review 3 --fix`). The original sed-based replacement preserved the position of the `gsd-code-review-fix` token, producing the wrong order. Fixed in USER-GUIDE.md (3 occurrences) and the same drift in the workflow surfaces: - get-shit-done/workflows/code-review-fix.md (2 retry hints) - get-shit-done/workflows/code-review.md (offer text) - get-shit-done/workflows/execute-phase.md (offer text) 2. **docs/AGENTS.md (Minor)** — internal count drift: line 483 said "Ten additional agents" but line 725 said "12 advanced/specialized". Filesystem reality: 33 agents total, 21 primary, 12 specialized (count of `### ` stubs in the Advanced and Specialized section). Updated lines 3, 13, 483 to use 12/33 and added the two missing names (doc-classifier, doc-synthesizer) to the inline list at line 13. 3. **tests:94 (Major refactor suggestion)** — `.includes()` token checks were source-grep style. Refactored to a typed-IR pattern: extract the SET of slash-command tokens via regex, assert membership on the parsed Set instead of substring scanning the raw file text. Added the `allow-test-rule` comment explaining the IR-build vs IR-assertion split per scripts/lint-no-source-grep.cjs convention. 4. **tests:130 (Major)** — replacement-path assertion was file-wide and could false-pass on generic mentions of "inline" elsewhere in the file. Refactored: `extractOfferBlocks(content)` returns the typed list of `<offer_next>` and "Pre-flight" blocks where the deleted command previously lived, and the assertion runs against those blocks specifically. Now requires `/gsd-phase --insert` or inline-audit prose to appear in the same offer block, not just somewhere in the file. 15/15 targeted tests pass. 6905/6905 full suite pass. Lints clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
117b3ec009 |
docs: add issue-driven orchestration guide (#2840) (#3036)
* docs: add issue-driven orchestration guide (#2840) Adds docs/issue-driven-orchestration.md — a recipe for driving GSD from a GitHub / Linear / Jira issue using existing primitives. Maps Symphony-style orchestration concepts onto GSD commands without vendoring code, adding a daemon, or introducing tracker integration. Concept mapping covers: - WORKFLOW.md → ROADMAP.md / STATE.md / phase CONTEXT.md / phase PLAN.md - isolated agent workspace → /gsd-new-workspace --strategy worktree - agent dispatch → /gsd-manager (interactive), /gsd-autonomous (unattended) - per-phase steps → /gsd-discuss-phase → /gsd-plan-phase → /gsd-execute-phase - proof-of-work → /gsd-verify-work (UAT.md persists across /clear) - adversarial review → /gsd-review (cross-AI peer review) - human merge gate → /gsd-ship - follow-up capture → /gsd-note, /gsd-plant-seed, /gsd-new-milestone End-to-end flow walks through 7 numbered steps from picking the tracker issue to capturing follow-ups. Safety boundaries (isolated worktrees, explicit human review, no automatic public posting, verification before ship) and non-goals (no vendoring, no daemon, no mandatory tracker, no gate bypass, no command-surface expansion) are spelled out explicitly so the doc cannot drift into "let's just add one more flag". Cross-linked from docs/README.md (Documentation Index) and docs/USER-GUIDE.md (Table of Contents preamble). Tests: tests/feat-2840-issue-driven-orchestration-guide.test.cjs — 9 structural-IR tests parse the guide into a typed record and assert on flags (commandsPresent, conceptPairs, nonGoalFlags, safetyFlags, numberedSteps). Fence-language MD040 check enforced. Cross-link presence enforced. No raw-text assertions on prose. 6890/6890 tests pass. Lint:tests clean (allow-test-rule comment justifies the doc-shape parser per scripts/lint-no-source-grep.cjs escape hatch). Lint:changeset clean. Closes #2840 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(test): guard USER-GUIDE.md existsSync before read (CR #3036) CR Minor: cross-linked-from-USER-GUIDE.md test called fs.readFileSync directly without first asserting fs.existsSync, asymmetric with the README.md test above. A missing USER-GUIDE.md would throw ENOENT instead of producing a meaningful assertion message. Mirror the null-guard pattern. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
95d2bc20f8 |
feat(hooks): opt-in SessionStart update banner for non-statusline users (#2795) (#3035)
* feat(hooks): opt-in SessionStart update banner for non-statusline users (#2795) When a user declines (or keeps a non-GSD) statusline at install time, the installer now offers an opt-in SessionStart banner that surfaces GSD update availability. The banner reads the existing ~/.cache/gsd/gsd-update-check.json cache (written by gsd-check-update-worker.js) and emits a single systemMessage line only when update_available is true: GSD update available: <installed> → <latest>. Run /gsd-update. It is silent when up-to-date and rate-limits "check failed" diagnostics to once per 24h via a sentinel file so a corrupt cache doesn't nag every session. Removed cleanly by `npx get-shit-done-cc --uninstall` which strips both the script and the SessionStart entry. The banner is never offered when GSD's statusline is being installed (statusline already surfaces update info, so re-prompting would be noise). Implementation: - hooks/gsd-update-banner.js — pure functions buildBannerOutput, shouldSuppressFailureWarning, readCache; thin main() wires them. - bin/install.js — handleUpdateBanner() prompt, parseUpdateBannerInput(), buildUpdateBannerHookEntry(), buildUpdateBannerPromptText(); chained into installAllRuntimes() so finalize() receives both flags. updateBannerCommand computed alongside the other JS-hook commands; finishInstall() registers the SessionStart entry only when shouldInstallBanner === true and the hook file is present at the target. - Hook ships in scripts/build-hooks.js HOOKS_TO_COPY, listed in MANAGED_HOOKS for stale-detection in gsd-check-update-worker.js, in the uninstall hook-removal lists in install.js, and in the rewriteLegacyManagedNodeHookCommands allowlist. Tests: - tests/feat-2795-update-banner.test.cjs — 22 tests, structural-IR assertions on parsed JSON envelopes (no raw-text matching). Covers pure-function branches (cache present/absent, parseError, rate-limit suppression, missing version fields), end-to-end hook invocation against fixture cache states, and install.js wiring (prompt text, input parsing, hook entry shape). - tests/trae-install.test.cjs — updated install() return-shape assertion to include updateBannerCommand: null for the no-settings runtime. - 6881/6881 tests pass. Docs (bundled in same commit per the bundle-docs-with-code skill): - docs/USER-GUIDE.md — new "Surface GSD Update Notifications Without GSD's Statusline" task section with opt-in/opt-out instructions. - docs/FEATURES.md — REQ-HOOK-08 added; "Update Banner" subsection under the Hook System feature with cache flow + removal path. - docs/INVENTORY.md — hook count 11 → 12, new row for gsd-update-banner.js. - docs/INVENTORY-MANIFEST.json — regenerated. Closes #2795 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(install): gate banner prompt on actual installability (CR #3035) CodeRabbit findings on PR #3035: - bin/install.js (Major): continueAfterStatusline gated banner prompt on the raw `shouldInstallStatusline` flag from handleStatusline. But finishInstall later silently skips the statusline write on local installs unless --force-statusline is set (#2248). Two consequences: 1. Interactive local Claude/Gemini installs got neither a statusline nor a banner offer. 2. Codex/Cursor/Copilot/Windsurf/Trae/Cline-only installs (where every result.updateBannerCommand is null) still got prompted even though the choice was silently ignored. Fix: derive willInstallStatusline = shouldInstallStatusline && (isGlobal || forceStatusline), and gate the banner prompt on a canInstallBanner precondition computed from results[].updateBannerCommand. Pass the raw shouldInstallStatusline through to finalize unchanged so per-runtime statusline gating in finishInstall is unaffected. - tests/feat-2795-update-banner.test.cjs (Minor): rate-limit suppression test parsed r1.stdout without first asserting r1.status === 0. Other e2e tests in this file (lines 210, 241) do this. A non-zero exit would surface as a cryptic SyntaxError instead of a status assertion failure. Fix applied verbatim. 6881/6881 tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
8c43ba7301 |
docs(#3025): MCP tool schema as a context-budget concern (#3032)
* docs(#3025): MCP tool schema as a context-budget concern Adds documentation covering the largest GSD cost lever that GSD itself does not own: MCP tool schema injection. Every enabled MCP server adds its schema to every turn (often 20k+ tokens for heavyweight servers like browser/playwright, mac-tools, etc.), which can dwarf whatever `model_profile` tuning saves. Two doc surfaces (per the bundle-docs-with-code skill depth gradient): 1. get-shit-done/references/context-budget.md - New "MCP Tool Schema Cost (Harness Concern)" section. - Explains schemas-per-turn cost framing. - Names enabledMcpjsonServers / disabledMcpjsonServers and .claude/settings.json explicitly. - Pre-phase audit checklist: browser/playwright, platform-specific, cross-project/stale, duplicate/shadow. - Explicit "GSD does not manage MCP enablement — harness concern" statement so users don't hunt for a GSD setting. - Links to Anthropic Claude Code MCP docs as canonical reference. - Notes compounding interaction with model_profile (additive levers). 2. docs/USER-GUIDE.md - New task-oriented "Trim MCP servers to reduce per-turn cost" section above "Using Non-Claude Runtimes". - Same checklist condensed. - Cross-link to context-budget.md for the full reference. Tests: - tests/feat-3025-mcp-token-budget-docs.test.cjs (12 cases) parses both docs into typed semantic-flag records and asserts behavioral invariants (mentions key, includes audit, names harness, etc.) rather than substring-matching prose. Adheres to CONTRIBUTING.md no-source-grep — section can be reworded freely as long as the required semantics survive. - Markdownlint pre-flight tests (MD040 fence language, MD056 table column count) per the bundle-docs-with-code skill so CR can't ratchet on prose nitpicks across multiple review rounds. Verification: - 12/12 pass on regression test - 6857/6857 full suite (12 net new) - lint-no-source-grep clean (377 test files) Companion to #3023 (per-phase-type model map) and #3024 (dynamic routing). Together they cover the three biggest cost levers users ask about; this issue covers the one GSD does not own. Closes #3025 * docs(#3025): batch 3 CR fixes — pr id, relative link, named flag CodeRabbit on PR #3032 (3 minor — 2 inline + 1 nitpick), all in one push per the bundle-docs-with-code skill (avoid per-round nitpick ratchet): 1. Inline (Minor) — .changeset/mcp-token-budget-docs.md:3 `pr: TBD` → `pr: 3032` so changeset tooling can link the entry. 2. Inline (Minor) — docs/USER-GUIDE.md:1101 Used a hardcoded `https://github.com/.../blob/main/...` URL for the cross-link to `context-budget.md`. Rest of USER-GUIDE.md uses relative links. Switched to `../get-shit-done/references/context- budget.md#mcp-tool-schema-cost-harness-concern` so feature-branch work shows the right content and rename-resilience is preserved. 3. Nitpick — tests/feat-3025-mcp-token-budget-docs.test.cjs:234 The cross-link assertion used an inline `/context-budget/i.test(...)` while every other invariant in the file lived as a named flag in `parseMcpBudgetSection`. Per CONTRIBUTING.md no-source-grep, added `crossLinksContextBudget` to the parser and asserted on `parsed.crossLinksContextBudget` so the cross-link rule sits next to its siblings. Verification: - 12/12 pass on regression test (no count change; refactor only) - No source code changes, only docs + tests * test(#3025): strip inline markdown before phrase-match (CR nitpick) CodeRabbit caught that the `explainsHarnessNotGsd` primary regex branch couldn't match "GSD does **not** manage" in context-budget.md because the markdown bold markers (`**`) sit between contiguous words. The test passed today only via the fallback `harness (concern|setting|controlled)` branch — the primary branch was effectively dead code. Fix: strip inline markdown emphasis (`**`, `*`, `~~`) and inline- code backticks before any phrase-matching in `parseMcpBudgetSection`. All seven flag computations now run against the stripped text so markdown formatting can't silently invalidate any invariant. Underscores are intentionally NOT stripped — `model_profile` and other snake_case identifiers must survive intact for the mentionsModelProfileInteraction check to find them. Verification: 12/12 still pass; primary branches now fire on real markdown content rather than relying on fallbacks. * test(#3025): guard markdownlint tests against null section (CR nitpick) CodeRabbit caught that the MD040 and MD056 markdownlint pre-flight tests called `section.match(...)` and `section.split('\n')` directly on the value returned by `extractSection`, which returns null when no matching header is found. If the MCP section is ever removed (regression), both tests would throw `TypeError: Cannot read properties of null` instead of producing a clean assertion failure naming the actual problem. The semantic tests above are protected because parseMcpBudgetSection short-circuits to a typed-falsy record on null input. The markdownlint tests bypassed that guard since they need raw section text, not parsed flags. Added `assert.ok(section, ...)` preconditions to both so a missing section produces a meaningful failure message. No content changes; defensive programming only. Verification: 12/12 still pass. |
||
|
|
e1d661ece0 |
feat(#3024): dynamic routing with failure-tier escalation (#3031)
* feat(#3024): dynamic routing with failure-tier escalation Adds a `dynamic_routing` block to .planning/config.json that lets the resolver start agents on a cheap tier and escalate one tier up when the orchestrator detects a soft failure (verification inconclusive, plan-check FLAG, etc.). Solves the "pay Opus rates as insurance" anti-pattern by making escalation observed-quality-driven. Architecture: - AGENT_DEFAULT_TIERS map (light/standard/heavy) — every agent in MODEL_PROFILES declares a default tier; tests assert coverage so adding a new agent without updating the map fails CI. - nextTier(currentTier) helper — light → standard → heavy → heavy (heavy stays at heavy; can't go further). - resolveModelForTier(cwd, agentType, attempt) — new resolver. The orchestrator tracks the attempt counter and passes 0 for the first spawn, 1+ on escalation. The resolver caps internally at max_escalations so the orchestrator can blindly bump the counter. - Schema validation: dynamic_routing.enabled / escalate_on_failure / max_escalations / tier_models.<light|standard|heavy>. Unknown tiers and unknown sub-keys rejected at config-set time. - SDK schema mirror updated to keep CJS/SDK in lockstep (#2653). Resolution precedence (highest → lowest): 1. model_overrides[<agent>] (full IDs accepted) 2. dynamic_routing.tier_models[<tier>] (NEW; escalation-aware) 3. models[<phase_type>] (#3023 phase-type map) 4. model_profile (per-agent column) 5. Runtime default Backward compatibility: dynamic_routing is disabled by default (enabled: false or block omitted). resolveModelForTier short- circuits to resolveModelInternal in that case, so callers can adopt unconditionally without breaking existing behavior. This PR delivers the JS-layer infrastructure: schema + tier map + resolver. Orchestrator adoption (workflow markdown updates that detect soft failures and call resolveModelForTier with attempt+1) is incremental follow-up — verifier / plan-checker / integration- checker each adopt the protocol when ready. Tests (23 cases, all structural-IR — no stdout grep): - Schema invariants: AGENT_DEFAULT_TIERS coverage, VALID_AGENT_TIERS exact match, every assignment uses a valid tier - nextTier helper: light→standard→heavy→heavy, null on invalid input - Disabled mode: no block + enabled:false both no-op (back-compat) - Enabled mode: attempt=0 returns default tier model, attempt=1 escalates, beyond max_escalations caps, heavy agents stay heavy, default max_escalations=1 when omitted - Precedence: per-agent override beats dynamic_routing, dynamic_routing beats phase-type models - Validation: every settings key accepted, unknown tiers/sub-keys rejected, bare `dynamic_routing` rejected as config-set target Documentation: - get-shit-done/references/model-profiles.md — full reference section - docs/CONFIGURATION.md — full settings table + escalation flow - docs/USER-GUIDE.md — task-oriented "Cheap-by-default" section - docs/FEATURES.md — config row cross-link Verification: - 23/23 pass on regression test - 6843/6843 full suite (23 net new from 6820) - lint-no-source-grep clean (376 test files) - SDK schema mirror keeps CJS/SDK in sync per #2653 parity test Closes #3024 * fix(#3024): honor escalate_on_failure:false + 3 CR follow-ups CodeRabbit on PR #3031 (4 findings — 1 Major + 2 Minor + 1 Nitpick): 1. **Major (inline)** — get-shit-done/bin/lib/core.cjs:1668 resolveModelForTier ignored dynamic_routing.escalate_on_failure. When the user set it to false, escalation should be disabled, but the resolver only checked attempt/max_escalations. An orchestrator that always passes attempt+1 on retry would silently escalate despite the user opting out. Fix: gate effectiveAttempt on `dr.escalate_on_failure !== false` so false short-circuits every attempt back to the default tier. 2. **Minor (inline)** — docs/CONFIGURATION.md:123-126 The dynamic_routing rows in the Core Settings table had 4 cells instead of 5 (missing the Options column), breaking the table structure. Added explicit Options values for enabled / escalate_on_failure / max_escalations rows. 3. **Minor (outside-diff)** — references/model-profiles.md:179-195 "Resolution Logic" sketch was pre-#3024 and didn't include dynamic_routing in the precedence ladder. Updated to a 6-step block with dynamic_routing at step 3 (between override and phase-type). 4. **Nitpick** — tests/feat-3024-dynamic-routing.test.cjs:189+ Tests used `if (lightAgent) { ... }` guards that silent-pass when AGENT_DEFAULT_TIERS drifts. Replaced all 5 conditional skips with `assert.ok(lightAgent, '...')` preconditions so a tier-mapping change surfaces as a test failure. Plus: 2 new regression tests for the Major fix: - escalate_on_failure:false caps every attempt at default tier - escalate_on_failure:true (explicit) still escalates normally Verification: - 25/25 pass on regression test (23 prior + 2 escalate_on_failure) - 6845/6845 full suite (2 net new) - lint-no-source-grep clean * docs(#3024): align precedence + add fence language tags (CR follow-up) CodeRabbit (3 minor): 1. docs/CONFIGURATION.md:691 — "Per-Phase-Type Models → Resolution precedence" was a 4-step block written pre-#3024; readers got contradictory rules between the per-phase-type section and the later dynamic_routing section. Updated to the same 5-step ladder with dynamic_routing at step 2, and noted that dynamic_routing is disabled by default so this section's behavior is unchanged when the kill-switch is off. 2. docs/CONFIGURATION.md:770 — escalation-flow code fence missing language tag (MD040). Added `text`. 3. references/model-profiles.md:184 — resolution-ladder code fence missing language tag (MD040). Added `text`. No code changes; docs only. Verification: regression test still 25/25. * docs(#3024): clarify precedence prose — five layers, not four (CR nitpick) CodeRabbit nitpick: the "Per-Phase-Type Models → Resolution precedence" prose said "The four layers compose..." but the ladder above lists five (including Runtime default). Also "dynamic_routing escalates per-attempt above all of them" misreads as suggesting dynamic_routing wins over model_overrides — actually overrides still win at step 1. Reworded top-down so the precedence direction is unambiguous: - model_profile = base - models = phase-level override - dynamic_routing = per-attempt escalation - model_overrides = per-agent exception (top) - runtime default = fallback No code changes; docs only. * docs(#3024): note escalate_on_failure:false in escalation-flow diagram (CR) CodeRabbit nitpick: the escalation-flow diagram in docs/CONFIGURATION.md described the soft-failure → respawn → tier_models[next_tier_up] path, but didn't surface the `dynamic_routing.escalate_on_failure: false` kill-switch right next to it. Users reading the flow diagram (which is the canonical place to understand attempt behavior) wouldn't see that the kill-switch overrides the soft-failure branch. Added a one-paragraph note immediately after the flow listing, before the tier-sequence example, so the kill-switch is visible exactly where users decide whether escalation will happen. No code changes; docs only. |
||
|
|
d812c66020 |
feat(#3023): per-phase-type model map in .planning/config.json (#3030)
* feat(#3023): per-phase-type model map in .planning/config.json Adds a new `models` block to .planning/config.json with six phase-type slots (planning / discuss / research / execution / verification / completion). Lets users express coarse tuning ("Opus for planning, Sonnet for the rest") without learning the agent taxonomy. Resolution precedence (highest → lowest): 1. Per-agent `model_overrides[agent]` (full IDs; targeted exception) 2. Phase-type `models[phase_type]` (NEW; tier alias) 3. Profile table (`model_profile`) (per-agent column) 4. Runtime default The three layers compose: `models` defaults a phase, `model_overrides` carves an exception. Phase-type values are tier aliases (opus/sonnet/ haiku/inherit) so the runtime-resolution chain (#2517) stays correct end-to-end without further branching. Implementation: - model-profiles.cjs: new AGENT_TO_PHASE_TYPE map + VALID_PHASE_TYPES set. Each agent in MODEL_PROFILES gets one phase-type assignment; tests assert coverage so adding a new agent without updating the table fails CI. - core.cjs (resolveModelInternal): inserts phase-type tier lookup between per-agent override and profile-derived tier. Skips runtime resolution when the resolved tier is 'inherit' (was previously gated only on profile === 'inherit'; phase-type can now produce inherit independently). - core.cjs (loadConfig): pass `parsed.models` through both code paths so resolveModelInternal can read it. - config-schema.cjs + sdk/src/query/config-schema.ts: dynamic-pattern validator accepts only the six known phase-types; unknown slots rejected at config-set time. Backward compat: configs without `models` behave exactly as today. Tests (15 cases, all structural-IR — no stdout grep): - Schema: AGENT_TO_PHASE_TYPE coverage, VALID_PHASE_TYPES exact match - Resolver: phase-type alone; per-agent override beats phase-type; phase-type beats profile; issue's full example; "inherit"; empty block is no-op; no block is no-op - Validation: each of the 6 slots accepted; unknown slot rejected; bare `models` (no slot) rejected Verification: - 15/15 pass on new regression test - 6808/6808 full suite (5 net new), 0 fail - lint-no-source-grep clean across 375 test files Closes #3023 * docs(#3023): document `models` per-phase-type config in user-facing docs Adds `models` block coverage to the three user-facing docs that ship with each release: 1. docs/CONFIGURATION.md - New "Per-Phase-Type Models" section between "Per-Agent Overrides" and "Non-Claude Runtimes" with: * full example mixing models + model_overrides * phase-type → agent mapping table * resolution-precedence pseudocode * accepted values (tier alias only) * "When to use which" decision matrix * validation behavior + example error - Added `"models": {}` to the Full Schema snippet - Added a row for `models.<phase_type>` to the config keys table (next to model_profile_overrides for adjacency) 2. docs/FEATURES.md - Added a row for models.<phase_type> in the Configurable Settings table (right under model_profile) - Cross-link to CONFIGURATION.md for the full surface 3. docs/USER-GUIDE.md - New task-oriented "Tuning model cost by phase" section above "Using Non-Claude Runtimes" — leads with the concrete config and shows the override pattern (one-shot phase + targeted exception) - Cross-link to CONFIGURATION.md Verification: - 29/29 pass on config-schema-docs-parity + docs-update + new feature test (parity-check passes, so the config-schema entry I added in the feature commit is now matched by a docs row) - 6808/6808 full suite pass - lint-no-source-grep clean Doc style follows the same pattern used by the existing model_profile, model_overrides, and model_profile_overrides sections — example-led, table-backed, cross-referenced. Each doc surfaces the feature at the right depth (reference / settings table / task guide). * fix(#3023): mirror phase-type tier in resolveReasoningEffortInternal (CR Major) CodeRabbit caught a real Codex correctness bug + 3 minor docs/test issues: 1. **Major (outside-diff)** — resolveReasoningEffortInternal in core.cjs derived its tier exclusively from the profile table, ignoring the models.<phase_type> override added in #3023. Failure mode on Codex: Config: model_profile=balanced, models.execution=opus, agent=gsd-executor resolveModelInternal: tier=opus → gpt-5.4 resolveReasoningEffortInternal: tier=sonnet → reasoning_effort=medium ↑ WRONG — should be xhigh (opus tier on Codex) The runtime received a mismatched (model, effort) pair. Mirrored the phase-type lookup from resolveModelInternal so both functions derive from the same tier source. 'inherit' phase-type returns null effort (no runtime entry maps to 'inherit'; let runtime decide). 2. Minor — .changeset/per-phase-type-models.md `pr: TBD` → `pr: 3030`. 3. Minor (outside-diff) — model-profiles.md "Resolution Logic" section omitted the new phase-type tier. Updated the 4-step block to a 5-step block including `models[phase_type]` between override and profile, plus a paragraph noting that `model` and `reasoning_effort` derive from the same tier source. 4. Nitpick — added 2 typo-safety tests: - models.research = "haiku3" (typo) → falls through to profile - models.research = "openai/gpt-5" (full ID) → falls through to profile Plus 5 new reasoning_effort tests covering the Major fix: - exported correctly - phase-type override flips both model AND effort to same tier - inherit phase-type returns null effort - per-agent override still bypasses phase-type for effort - claude runtime ignores models.* (no effort propagation) Verification: - 24/24 pass on regression test (15 original + 2 typo-safety + 5 effort + 2 outside-diff related) - 6815/6815 full suite (7 net new from 6808) - lint-no-source-grep clean The reasoning_effort tests are written semantically (phase-type override must produce the SAME effort as a profile-only opus config) rather than hard-coding tier-specific effort strings, so changes to the runtime tier map don't break them. * fix(#3023): phase-type override beats profile=inherit (CR Major round 2) CodeRabbit caught another precedence inversion: when { model_profile: 'inherit', models: { execution: 'opus' } } both resolvers short-circuited on `profile === 'inherit'` BEFORE the phase-type override could be honored. Result: model returned 'inherit' and reasoning_effort returned null — both contradicting the documented precedence where models[phase_type] wins over model_profile. Fix in resolveModelInternal: - Compute tier from phase-type FIRST. If phase-type is a valid alias, it wins. Otherwise, fall back to profile-derived tier OR 'inherit' (when profile === 'inherit'). - Gate the runtime-resolution branch on `tier !== 'inherit'` (was `profile !== 'inherit'`) so phase-type=opus can flip runtime mapping on even when profile=inherit. - Gate the inherit-return on `tier === 'inherit'` (was `profile === 'inherit'`). Fix in resolveReasoningEffortInternal: - Remove the `if (profile === 'inherit') return null;` early-return. - Compute tier from phase-type first, fall back to profile. If phase-type is explicitly 'inherit' OR the resolved tier is 'inherit', return null (no runtime entry maps to inherit). Tests added (5 new): - model: phase-type wins over profile=inherit (with explicit opus, with haiku for one phase + planner-without-slot still inheriting) - model: profile=inherit + no models block → all agents inherit (no regression on existing inherit semantics) - model: profile=inherit + models block but agent has no slot → that agent inherits, agents with slots get phase-type tier - effort: phase-type opus + profile=inherit → produces opus-tier effort, NOT null (the original bug) Verification: - 27/27 pass on regression test (24 prior + 3 model + 1 effort) - 6820/6820 full suite (5 net new) - lint-no-source-grep clean The effort test reads the expected value by running a profile-only opus config and comparing — semantic check, not hard-coded effort string. So runtime tier map changes don't break the test. |