Commit Graph

313 Commits

Author SHA1 Message Date
Tom Boucher
fbfa4e30f3 chore(changeset): add fragment for #3561 2026-05-15 12:48:45 -04:00
Tom Boucher
1a4e6df6b3 Merge pull request #3557 from gsd-build/feat/3347-auto-update-knowledge-graph-after-main-h
feat(3347): opt-in auto-update of knowledge graph after main HEAD advances
2026-05-15 12:06:41 -04:00
Tom Boucher
72bc456662 chore(3347): backfill PR number in changeset
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:59:43 -04:00
Tom Boucher
dacc23137a feat(3347): opt-in auto-update of knowledge graph after main HEAD advances
Closes #3347

Config:
- Add graphify.auto_update (default false) to manifests:
  sdk/shared/config-defaults.manifest.json, config-schema.manifest.json

Hook:
- hooks/gsd-graphify-update.sh — PostToolUse Bash matcher
  - Gates: tool_name=Bash, HEAD-advancing git op, CI=unset, in git repo,
    current branch == default branch (git.base_branch override or main/
    master/trunk fallback), graphify.enabled && graphify.auto_update both
    true, graphify on PATH, no live PID lock
  - Writes .planning/graphs/.last-build-status.json with status=running
    synchronously, then detaches hooks/lib/gsd-graphify-rebuild.sh
- hooks/lib/gsd-graphify-rebuild.sh — detached rebuild runner
  - PID-lock acquire + trap-on-exit cleanup
  - graphify update . then cp graphify-out/* → .planning/graphs/
  - Status file rewritten to status=ok|failed with exit_code, duration_ms,
    head_at_build
- Portable detach (subshell + disown, no setsid dependency)

Installer:
- bin/install.js: register hook as PostToolUse Bash matcher (5s timeout)
- Add to gsdHooks uninstall list and expectedShHooks warning list

Planner / researcher status surface (issue #3347 reviewer must-have AC):
- agents/gsd-planner.md and agents/gsd-phase-researcher.md
  load_graph_context steps now read .last-build-status.json and surface:
  running → "rebuild in flight"; failed → "auto-rebuild FAILED at {ts},
  context is from prior build"; ok with stale head_at_build → "HEAD has
  advanced since last build"

Settings:
- get-shit-done/workflows/settings.md adds "Graph auto-update" question
  with No-Recommended default; bullets and update_config block updated

Inventory:
- docs/INVENTORY.md hook count 12 → 13 with new row
- docs/INVENTORY-MANIFEST.json regenerated

Tests:
- tests/feat-3347-graphify-auto-update-config.test.cjs (8 tests):
  isValidConfigKey accepts graphify.auto_update, CANONICAL_CONFIG_DEFAULTS
  default false, config-set round-trip, sibling key preservation
- tests/feat-3347-graphify-auto-update-hook.test.cjs (18 tests):
  all bail paths (non-Bash, non-HEAD-advancing, enabled=false,
  auto_update=false, CI=true, non-default-branch, missing graphify bin,
  live-PID lock), dispatch path with mock graphify bin (sync running
  status + detached transition to ok/failed), stale-PID lock, all five
  HEAD-advancing command matchers, git.base_branch override

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:59:43 -04:00
Tom Boucher
697c94c782 chore(3558): add changeset fragment for Phase 5.0 2026-05-15 11:11:13 -04:00
Tom Boucher
13ff4a625b fix: address coderabbit doc and ordering feedback 2026-05-15 10:14:37 -04:00
Tom Boucher
0a2787d00b chore(3554): add changeset fragment for Phase 4 2026-05-15 10:07:10 -04:00
Tom Boucher
6d65a1f52f chore: add changeset for workstream inventory builder 2026-05-15 09:36:47 -04:00
Tom Boucher
fa862c77ee Merge pull request #3540 from gsd-build/feat/3536-configuration-module
feat(3536): Configuration Module via shared manifests + generator (Phase 2 of #3524)
2026-05-15 09:33:22 -04:00
Tom Boucher
a31d45eedd Merge pull request #3547 from gsd-build/fix/3541-first-time-baseline-migration-prompt-use
fix(3541): resolve prompt-user migration actions in non-TTY runs; improve error grouping
2026-05-15 09:24:40 -04:00
Tom Boucher
544037e132 fix: honor installer migration resolution env override 2026-05-15 09:16:41 -04:00
Tom Boucher
db76cc8dd5 chore(3541): backfill PR number in changeset
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:36:39 -04:00
Tom Boucher
0d9a800e56 chore(3542): backfill PR number in changeset
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:31:19 -04:00
Tom Boucher
24a992a05c chore(3536): add changeset fragment for user-facing surfaces
PR #3540 was originally labeled `no-changelog` on the premise that it
was a pure internal-module refactor. On second look, two surfaces are
actually user-facing and warrant a changelog entry:

  1. New `gsd-tools migrate-config` CLI subcommand — explicit, opt-in
     on-disk migration of legacy-key shapes. Idempotent.
  2. `mergeDefaults` semantic change — recursive deep-merge instead of
     spread-per-section. Preserves sibling keys under partial overlays.
     Strict improvement, but a behavior change.

Adds `.changeset/patient-lemurs-sing.md` (`type: Changed`). The
`no-changelog` label should be removed in tandem with this commit.
2026-05-15 08:25:06 -04:00
Tom Boucher
c39a7e1f6f fix(3541): resolve prompt-user migration actions in non-TTY runs; improve error grouping
Closes #3541

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:16:28 -04:00
Tom Boucher
85d7a8b4b1 fix(3542): prohibit git stash in executor agents — shared stash storage violates worktree isolation
Closes #3542

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:16:26 -04:00
Tom Boucher
a7f0af2ce9 fix(3537): route every phase-number ROADMAP regex through phaseMarkdownRegexSource (#3538)
* fix(3537): route every phase-number ROADMAP regex through phaseMarkdownRegexSource

v1.42.1 added the padding-tolerant `phaseMarkdownRegexSource()` helper but
wired it into only 1 of 8 call sites that build phase-number regexes against
ROADMAP/STATE prose. The other 7 used raw `escapeRegex(phaseNum)` or partial
`0*${escapeRegex(...)}` (tolerated extra padding, not missing), so when
skills passed the resolved padded form (`02.7`) against un-padded ROADMAP
prose (`### Phase 2.7:`, `- [ ] **Phase 2.7:**`), the verbs silently no-op'd
while reporting success.

This consolidates every phase-number ROADMAP/STATE regex through the
canonical helper:

- Promote `phaseMarkdownRegexSource` from `roadmap.cjs` to `core.cjs` so
  `phase.cjs` and `core.cjs` itself can consume it (no circular dep —
  both already import `core.cjs`).
- Wire the helper into the 7 remaining sites:
  - `core.cjs:getRoadmapPhaseInternal` (replaces hand-rolled `isNumeric`
    branch that only padded integers, not decimals).
  - `roadmap.cjs:cmdRoadmapGetPhase` (searchPhaseInContent escapedPhase).
  - `roadmap.cjs:cmdRoadmapAnalyze` checkbox lookup.
  - `roadmap.cjs:cmdRoadmapAnnotateDependencies` phase header lookup.
  - `phase.cjs:cmdPhaseNextDecimal` ROADMAP prose scan.
  - `phase.cjs:cmdPhaseInsert` target anchor + decimal scan + header.
  - `phase.cjs:cmdPhaseComplete` (3 regexes: checkbox, plan-count,
    REQUIREMENTS extraction).

Adds `tests/bug-3537-padded-id-against-unpadded-roadmap.test.cjs` — a
parity-style regression matching CONTEXT.md DEFECT.GENERATIVE-FIX: for
each user-facing verb, asserts that the padded form (`02.7`) and the
un-padded form (`2.7`) produce identical ROADMAP.md against an identical
fixture. Includes one control case (`update-plan-progress`, already wired
in 1.42.1) to prove the parity assertion is non-vacuous.

Closes #3537

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(3537): add changeset fragment (pr: placeholder, amended post-create)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(3537): pin changeset pr: field to #3538

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 23:17:38 -04:00
Tom Boucher
d4d4178603 Merge pull request #3483 from radioflyer28/feat/agent-launch-reasoning-transport-3474
feat: transport resolved reasoning effort to agent launches
2026-05-14 20:01:32 -04:00
Tom Boucher
9ccd97a9e0 Merge pull request #3528 from gsd-build/fix/3522-gsd-sdk-query-commit-files-silently-over
feat(sdk): add --respect-staged opt-in to commit --files
2026-05-14 19:58:36 -04:00
Tom Boucher
e6790238aa Merge pull request #3527 from gsd-build/fix/3523-bug-cjs-loadconfig-warns-top-level-branc
fix(3523): stop false 'branching_strategy will be ignored' warning in CJS loadConfig
2026-05-14 19:58:08 -04:00
Tom Boucher
cda6cd3e06 Merge pull request #3526 from gsd-build/fix/3521-workflows-quick-md-two-bugs-in-post-merg
fix(quick): pin cleanup-loop CWD to project root before bare git commands (#3521)
2026-05-14 19:57:45 -04:00
Tom Boucher
75dffc8069 fix: address branching strategy review findings 2026-05-14 19:44:01 -04:00
Tom Boucher
085154ace7 docs: clarify gsd-update reapply changeset 2026-05-14 19:43:59 -04:00
Tom Boucher
017abd9236 feat(sdk): add --respect-staged opt-in to gsd-sdk query commit --files (#3522)
Closes #3522. When --respect-staged is passed the git add loop is skipped
entirely so per-hunk staging from git add -p is preserved. Default behavior
(full re-stage) is unchanged. The #3061 pathspec invariant holds under both
modes. Nothing-staged within scope returns { committed: false, reason:
'nothing staged' } without error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 19:08:08 -04:00
Tom Boucher
0f7b018d4d chore: changeset for fix/3523 (branching_strategy false warning)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 19:03:42 -04:00
Tom Boucher
c974d9de74 chore: pin changeset pr field to #3526
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 19:02:53 -04:00
Tom Boucher
04c1296aed chore: add changeset fragment for #3516 filter fix 2026-05-14 19:00:41 -04:00
Tom Boucher
16eee9606a chore: pin changeset pr field to #3520 2026-05-14 17:22:34 -04:00
Tom Boucher
200c012f84 fix(sdk): derive completed_phases from ROADMAP and refresh all STATE.md fields after phase.complete
Fixes two root causes behind bug #3517:

1. Idempotency: completed_phases was blindly incremented (parseInt + 1),
   causing phase.complete N run twice to double-count (4 → 5 → 6).
   Now derives from ROADMAP progress table Complete-row count, making
   the operation idempotent.

2. Field coverage: eight STATE.md fields were left stale after phase
   completion. Now updates in the same atomic lock section:
   - frontmatter: stopped_at, last_updated, total_plans, completed_plans
   - body: Current focus, Status line, By Phase table row

   completed_plans = count of *-SUMMARY.md files across all phase dirs
   total_plans = sum of M/N plan counts from ROADMAP progress table
   percent = recomputed from fresh derived counts

Closes #3517

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:56:18 -04:00
Tom Boucher
b40bc6bf3d chore: pin changeset pr field to #3515
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 15:46:35 -04:00
Tom Boucher
e0adba7e08 feat(statusline): add opt-in context_position config for narrow terminals (#2937)
Extract composeStatusline() helper from duplicated inline template logic in
runStatusline() and renderStatusline(). Both call sites now route through the
helper, which accepts a position param ('end' | 'front', default 'end').

- 'end' (default) preserves byte-identical output to v1.38.x and earlier
- 'front' renders ctx immediately after model name, before the first │
- Invalid values silently coerce to 'end' at runtime (belt-and-suspenders;
  config-set rejects invalid values upfront via enum validator)

Adds statusline.context_position to VALID_CONFIG_KEYS in both CJS and TS
schemas, enum validator in config.cjs, docs row in CONFIGURATION.md,
and a changeset. Closes #2937.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 15:45:41 -04:00
Tom Boucher
3f054b4a96 Merge pull request #3505 from gsd-build/fix/3346-codex-aot-toml-event-key
fix(install): emit event-name leaf key for Codex AoT hooks migration (#3346)
2026-05-14 14:03:54 -04:00
Tom Boucher
0e1de9627a Merge pull request #3508 from gsd-build/feat/3086-allow-disabling-or-customizing-the-miles
feat(workflow): add git.create_tag config to disable milestone tagging
2026-05-14 14:03:18 -04:00
Tom Boucher
79425989e7 chore: pin changeset pr field to #3510
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:44:25 -04:00
Tom Boucher
c21bbf116e fix(tests): use array form for space-containing paths in CLI invocations
On machines where os.tmpdir() returns a path with a space (e.g.
/Volumes/Mini Me/tmp), runGsdTools() string args were whitespace-split by
the helper tokeniser, truncating paths at the first space.  Switch all
calls that embed a dynamic path into the argument list to the array form
of runGsdTools() so execFileSync receives each path as a single argv slot.

Fixes #3509

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:43:48 -04:00
Tom Boucher
e1f742788e chore: pin changeset pr field to #3508
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 12:09:55 -04:00
Tom Boucher
da21edfb59 feat(workflow): add git.create_tag config to disable milestone tagging
Adds boolean config key `git.create_tag` (default: true, fully backcompat)
so projects with their own release flow can disable GSD's automatic
`git tag -a v[X.Y]` on milestone completion. Also adds tag-collision
pre-check to prevent silent failure on re-run. Closes #3086

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 12:06:36 -04:00
Tom Boucher
619915de96 fix(install): emit event-name leaf key for Codex AoT hooks migration (#3346)
migrateCodexHooksMapFormat re-emitted the raw `[hooks.<X>]` path segment as
the leaf TOML key of the new `[[hooks.<EVENT>]]` block. When the legacy
table key was a `<file>:<event>:<line>:<col>` location identifier and the
real event lived in an `event = "..."` body field, the migration emitted a
header like `[[hooks."C:\\Users\\helen\\.codex\\config.toml:session_start:0:0"]]`
that Codex 0.124.0+ refuses to load — causing `npx get-shit-done-cc@latest`
to abort the Codex runtime install on Windows configs that pre-date AoT.

Mirror the flat-AoT branch in the map-format and stale-namespaced-AoT
branches: when the section body declares `event = "..."`, that name wins
as the leaf key and `event` is excluded from the re-emitted handler body.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 10:43:09 -04:00
Tom Boucher
12accdbd02 Merge pull request #3499 from gsd-build/fix/3489-state-complete-phase-idempotent
fix(sdk): make state.complete-phase idempotent (#3489)
2026-05-14 10:08:49 -04:00
Tom Boucher
62c64a757c Merge pull request #3500 from gsd-build/fix/3493-extract-milestone-generic-phase-details
fix(sdk): extractCurrentMilestone preserves generic Phase Details heading (#3493)
2026-05-14 10:08:44 -04:00
Tom Boucher
bb02b16698 Merge pull request #3501 from gsd-build/fix/3488-decimal-phase-short-form-depends-on
fix(sdk): expand short-form depends_on for decimal-phase plans (#3488)
2026-05-14 10:08:40 -04:00
Tom Boucher
5a8495adb7 fix(init): preserve inside=true on root lookup failures 2026-05-14 09:56:36 -04:00
Tom Boucher
fb6633ceda fix(workflow): detect nested git worktree in new-project bootstrap (#3491)
The `has_git` boolean returned by `init new-project` and `init ingest-docs`
was derived from a shallow `pathExists(cwd, '.git')` check, so a subdirectory
of an existing repo reported `has_git: false`. The workflow then ran
`git init`, creating a nested `.git` inside the outer worktree and silently
diverting subsequent `gsd-sdk commit` calls into the nested repo.

Replace the shallow check with `git rev-parse --is-inside-work-tree`
semantics in both CJS (`get-shit-done/bin/lib/init.cjs`) and TS
(`sdk/src/query/init.ts`, `sdk/src/query/init-complex.ts`) handlers via a new
shared `gitWorktreeInfoInternal` helper, and expose `git_worktree_root` +
`in_nested_subdir` so the workflows can refuse `git init` inside an existing
worktree and warn that planning files will track to the outer repo.

Regression test: `tests/bug-3491-nested-git-worktree.test.cjs`.

Fixes #3491

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 09:11:59 -04:00
Tom Boucher
809c2bee39 fix(sdk): expand short-form depends_on for decimal-phase plans (#3488)
The DAG resolver in phase-plan-index only matched full-stem
('03-01-auth-hardening') and canonical-prefix ('03-01') forms when
resolving `depends_on` references, so plans in decimal phases
(e.g. `99.9-test`, `02.2-cross-repo`) declaring short-form
`depends_on: [01]` had their edges silently dropped. Dependents
collapsed into wave 1 and the SDK emitted a misleading
"declared wave: N but depends_on DAG places it in wave 1" warning
that pointed at the wave declaration rather than the broken reference.

Add a tertiary short-form index keyed on the trailing `-NN` of each
plan's canonical ID — derived per plan via `lastIndexOf('-')` so it
handles integer, letter-suffixed, and decimal phase IDs uniformly.
Emit a dedicated `Plan X: unresolved depends_on reference 'NN' — no
matching plan in phase` warning whenever a dep fails all three lookup
forms, so a dropped edge can no longer hide behind the wave-mismatch
warning.

Regression coverage added in `sdk/src/query/phase.test.ts` for the
decimal-phase short-form case, the integer-phase short-form case, and
the unresolved-reference warning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 08:28:11 -04:00
Tom Boucher
15e9c86ead fix(sdk): extractCurrentMilestone preserves generic Phase Details heading (#3493)
When a roadmap places shared phase-detail bodies under a non-version-prefixed
`## Phase Details` heading AFTER a `### 📋 vX.Y+ (Planned)` sibling in document
order, the entire Phase Details section fell outside the slice returned by
`extractCurrentMilestone`. `gsd-sdk query phase.insert N` then reported
"Phase N not found in ROADMAP.md" even though `### Phase N:` was unambiguously
present.

PR #2455 (closing #2422) added a same-version `continue` branch that already
handles the version-prefixed variant (e.g. `## v2.0 Phase Details`). This fix
extends the same intent to the generic-label variant: after the initial
boundary scan, look for a literal `^#{1,3}\s+Phase\s+Details\b` heading past
`sectionEnd` and, if found, append the Phase Details block (up to the next
real milestone boundary — version-bearing or milestone-emoji-bearing heading —
or EOF) to the returned slice. The intervening planned-milestone content is
skipped so it does not leak into the active-milestone view.

Bounded to a single append so a malformed roadmap can't loop. Only matches the
literal `Phase Details` label (canonical per GSD ROADMAP template); anything
else continues to terminate the slice. Does not regress the v2.0/v2.1+
version-prefixed handling shipped by #2455 (existing `bug-2422` test still
passes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 07:52:51 -04:00
Tom Boucher
beca07cf3a fix(sdk): make state.complete-phase idempotent (#3489)
Re-invoking `state complete-phase --phase <N>` on a phase that was
already marked complete in STATE.md silently rolled STATE.md back to
that phase's moment-of-completion — clobbering Status, Last Activity,
Last Activity Description, and the ## Current Position body. The bug
fired whenever a follow-up phase had been inserted (or the next phase
had begun) and a downstream workflow re-ran complete-phase on the
already-closed phase. Damage was silent: handler reported
{"updated":["Status","Last Activity","Current Position"]} and no error.

Root cause: cmdStateCompletePhase wrote unconditionally — it never
consulted STATE.md to detect that the requested phase had been
superseded. The handler is a legacy-bridge fallback (no native SDK
registration), so the SDK CLI fell through to gsd-tools.cjs.

Fix: add an idempotency guard at the top of cmdStateCompletePhase.
If STATE.md's canonical Current Phase field already names a phase
distinct from the one we are being asked to mark complete, return a
no-op payload ({updated:[], phase:"<N>", idempotent:true, note:"phase
already superseded; no-op"}) without writing to STATE.md.

The guard is conservative — it only fires when Current Phase is set
and differs from the resolved target. First-time completion (Current
Phase == target, or Current Phase absent) is unaffected, so the four
existing complete-phase test cases (#2761, #3063) continue to pass.

Regression test: tests/bug-3489-complete-phase-idempotent.test.cjs
- re-running complete-phase --phase 02.2 with Current Phase=02.2.1
  in STATE.md leaves the file byte-identical and reports idempotent:true
- normal first-time completion is NOT flagged idempotent

Scope: handler-level idempotency only. Does not address the related
stopped_at filename-sort ordering issue called out in the bug report
(filed under suggested fix #2) or porting to the native registry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 07:47:18 -04:00
Tom Boucher
49e7c48007 feat(execute-phase): classify quota/rate-limit failures across runtimes (#3095) (#3490)
* feat(execute-phase): classify quota/rate-limit failures across runtimes (#3095)

Dispatched executor subagents that die from provider quota or rate-limit
errors currently look identical to a crashed agent to the orchestrator —
so step 7's recovery prompt offers "retry now" when the right action is
"wait for reset and resume". This adds a runtime-agnostic classifier and
wires execute-phase step 7 to it.

- `agent.classify-failure` SDK query returns
  `{class: 'quota-exceeded' | 'classify-handoff-bug' | 'unknown-failure',
    sentinel?, retryAfterSeconds?}`. Sentinels cover Claude Code
  (`usage limit`, `429`), Copilot CLI (`rate_limit`,
  `user_weekly_rate_limited`), Codex (`usage_limit_reached`,
  `too many requests`), and Gemini (`RESOURCE_EXHAUSTED`,
  `exceeded your`).
- `execute-phase.md` step 7 now branches on the class. Quota-exceeded
  presents a wait-for-reset prompt and points at the safe-resume gate
  landing in #3212 instead of re-dispatching a fresh executor.
- `docs/research/provider-rate-limit-signals.md` records the proactive
  (header / SDK event) signals each provider exposes and the upstream
  Claude Code / Copilot / Codex issues blocking hook-side detection —
  the forward path once host runtimes surface them.

Resume-from-partial-worktree and context-load metrics from the original
report are deliberately out of scope; they overlap #3212's
`state.verify-against-disk` work already in flight.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(execute): render quota retry hint and refresh alias artifacts

* fix(workflow): restore slash namespace and execute-phase size budget

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 07:46:56 -04:00
radioflyer28
810778e137 fix(sdk): gate reasoning effort by runtime allowlist 2026-05-13 22:27:15 -04:00
Tom Boucher
8b679959cc docs: adopt issue#-prefix naming for ADRs/PRDs to eliminate parallel-developer collisions (#3487)
* docs: adopt issue#-prefix naming for ADRs/PRDs (#3485)

The repo's sequential ADR/PRD numbering convention has produced
recurring collisions when developers compute "next number" locally
and ship in parallel — currently visible on disk as duplicate
docs/adr/0010-*.md and triplicate docs/adr/0011-*.md, plus a stack
of "resolve ADR conflict" commits in git history.

Replace the local-compute convention with issue#-prefix slug naming:

  docs/adr/<issue#>-<slug>.md     (new ADRs)
  docs/prd/<issue#>-<slug>.md     (new PRDs — directory introduced)

GitHub issue numbers are server-assigned and atomic, so the
reservation step the CONTRIBUTING.md issue-first rule already enforces
also produces the artifact ID. One issue = one ADR-or-PRD = one PR.
Same shape as the existing changeset random-name pattern (#2975) for
CHANGELOG.md fragments, applied to a different artifact class.

Migration policy: legacy ADRs 0001-* through 0011-* are preserved
as immutable historical record. The new convention applies only to
ADRs/PRDs created on or after this merge.

Files updated:
- docs/adr/README.md        — naming convention + legacy note + link
- docs/prd/README.md (new)  — seeds the new directory + same convention
- CONTRIBUTING.md           — new "Proposing an ADR or PRD" section
- docs/contributor-standards.md — formalize as contributor requirement

No code surface — docs-only.

Closes #3485

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(changeset): add Changed fragment for ADR/PRD naming convention (#3487)

Per CONTRIBUTING.md "When unsure whether a change is user-facing, add
the fragment" — the contributor process IS user-facing for the
contributor user class. Drop the no-changelog opt-out, surface the
naming-convention change in the next CHANGELOG so contributors see
it before they hit it as a PR rejection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: address CodeRabbit findings on #3487

- CONTRIBUTING.md: rename heading to "Proposing an ADR or PRD" so its
  GitHub-anchor slug matches the #proposing-an-adr-or-prd link target
  used from docs/adr/README.md, docs/prd/README.md, and
  docs/contributor-standards.md (broken anchors)
- docs/adr/README.md, docs/prd/README.md, docs/contributor-standards.md:
  add `text` language tag to the new naming-convention fenced blocks
  to satisfy markdownlint MD040

Pre-existing untyped fences elsewhere in the touched files are left
alone per CONTRIBUTING.md "no drive-by formatting".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:20:08 -04:00
Tom Boucher
75d5ca5875 feat(code-review): integrate fallow structural pre-pass for /gsd-code-review (#3424)
* feat(code-review): add optional fallow structural pre-pass

* fix(ci): sync lockfile for fallow optional binaries

* fix(test): make fallow integration tests cross-platform

* fix(review): require executable fallow binary paths

* docs(review): clarify structural findings usage and size guard

* fix(fallow): preserve line:0, prefer node_modules/.bin, sync SDK twin (H1, M2, N1 from #3424 review)

* fix(workflow): harden fallow pre-pass — exit check, timeout, atomic write, size-guard order (B1, H2-H4, M1, M3 from #3424 review)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(deps): pin fallow floor to ^2.70.0 matching lockfile (H7 from #3424 review)

* fix(config): enum-validate fallow.scope/profile + group code_quality.* contiguously (H5, N3 from #3424 review)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(fallow): label mcp gate reserved, version-pin install, expand context schema (B3, H8, M4, M8, L1 from #3424 review)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test(fallow): replace source-grep with behavioral tests, expand fixtures, fail-loud tmpdir (B4, H6, L2, L3, M5, M6, N2 from #3424 review)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(workflow): escape closing structural_findings tag in JSON payload (CR #3424 inline finding)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:19:47 -04:00