From f18a547e05c4f3ca9ad3df2eb43c0f8ad890269f Mon Sep 17 00:00:00 2001 From: Lex Christopherson Date: Thu, 12 Mar 2026 10:27:34 -0600 Subject: [PATCH] docs(M001): context, requirements, and roadmap --- .gsd/DECISIONS.md | 18 ++ .gsd/PROJECT.md | 33 +++ .gsd/REQUIREMENTS.md | 345 +++++++++++++++++++++++++++ .gsd/STATE.md | 21 ++ .gsd/milestones/M001/M001-CONTEXT.md | 130 ++++++++++ .gsd/milestones/M001/M001-ROADMAP.md | 142 +++++++++++ 6 files changed, 689 insertions(+) create mode 100644 .gsd/DECISIONS.md create mode 100644 .gsd/PROJECT.md create mode 100644 .gsd/REQUIREMENTS.md create mode 100644 .gsd/STATE.md create mode 100644 .gsd/milestones/M001/M001-CONTEXT.md create mode 100644 .gsd/milestones/M001/M001-ROADMAP.md diff --git a/.gsd/DECISIONS.md b/.gsd/DECISIONS.md new file mode 100644 index 000000000..c8c54bda6 --- /dev/null +++ b/.gsd/DECISIONS.md @@ -0,0 +1,18 @@ +# Decisions Register + + + +| # | When | Scope | Decision | Choice | Rationale | Revisable? | +|---|------|-------|----------|--------|-----------|------------| +| D001 | M001 | arch | Smart staging approach | Exclusion filter (not file ownership tracking) | Covers 95% of the problem with minimal complexity. Fallback to git add -A on failure. | Yes — if exclusion filter proves insufficient | +| D002 | M001 | arch | worktree.ts migration strategy | Thin facade (keep exports, delegate to GitService) | Backward compatibility — 6+ existing callers don't need changes | Yes — if full migration desired later | +| D003 | M001 | arch | Merged branch lifecycle | Delete after squash merge (not preserve) | Squash commit is the permanent record. Branch sprawl has near-zero debugging value. | No | +| D004 | M001 | arch | Snapshot refs vs checkpoint commits | Hidden snapshot refs (refs/gsd/snapshots/) | Invisible recovery without cluttering branch history | No | +| D005 | M001 | scope | PR creation workflow | Deferred | Separate concern touching GitHub API, gh CLI, merge queue. Out of scope for trust boundary fix. | Yes — future milestone | +| D006 | M001 | scope | Milestone tags | Deferred | Low value relative to core trust boundary fix | Yes — future milestone | +| D007 | M001 | arch | Git Notes for metadata | Rejected | Fragile, poorly supported by tools, unreliable push/pull semantics | No | +| D008 | M001 | arch | Pre-merge verification timing | Phase 3 (enhanced features) | Core service + bug fixes first. Current workflow hasn't been catastrophic without guards. | No | +| D009 | M001 | arch | Doc fixes timing | Phase 1 (with bug fixes) | Pure text changes, zero risk, related to same git mechanics | No | +| D010 | M001 | arch | Test strategy | Unit tests with temp repos | Same proven pattern as existing worktree.test.ts | No | diff --git a/.gsd/PROJECT.md b/.gsd/PROJECT.md new file mode 100644 index 000000000..5accbb08b --- /dev/null +++ b/.gsd/PROJECT.md @@ -0,0 +1,33 @@ +# Project + +## What This Is + +GSD (Get Shit Done) is a coding agent harness built as a pi extension. It manages structured planning and execution workflows — milestones, slices, tasks — with automated git branching, LLM-driven execution, and mechanical verification. + +This project is the GSD extension itself (`gsd-pi`), a TypeScript package that provides the `/gsd` command, auto-mode orchestration, worktree management, and all planning/execution infrastructure. + +## Core Value + +Deterministic, reliable git operations that keep main clean and working while agents do the coding. The user never touches git — the system handles branching, committing, merging, and recovery. + +## Current State + +GSD is a working, shipped product (v2.3.11). Branch-per-slice workflow works. Squash merge to trunk works. Worktree support works. The git strategy is architecturally sound but has a trust boundary problem: git operations are split between deterministic TypeScript code and probabilistic LLM prompts that run raw `git add -A && git commit`. This causes accidental commits of runtime files, hardcoded commit types, no pre-merge verification, and no recovery mechanism. + +## Architecture / Key Patterns + +- TypeScript, compiled with `tsc`, tested with Node's built-in test runner +- Extension entry: `src/resources/extensions/gsd/index.ts` +- Orchestrator: `auto.ts` (2600+ lines) — dispatches units, manages lifecycle +- Git operations: `worktree.ts` (slice branches), `worktree-manager.ts` (git worktrees), `worktree-command.ts` (CLI commands) +- Prompts: `prompts/*.md` — Handlebars-templated instructions for LLM units +- Preferences: `preferences.ts` — YAML frontmatter in markdown files +- Patterns: `execSync` for git, `runGit()` helper, `SKIP_PATHS` for diff filtering + +## Capability Contract + +See `.gsd/REQUIREMENTS.md` for the explicit capability contract, requirement status, and coverage mapping. + +## Milestone Sequence + +- [ ] M001: Deterministic GitService — Centralize all git mechanics into a single service, fix bugs, remove git from prompts, add merge guards and recovery diff --git a/.gsd/REQUIREMENTS.md b/.gsd/REQUIREMENTS.md new file mode 100644 index 000000000..f667ac40c --- /dev/null +++ b/.gsd/REQUIREMENTS.md @@ -0,0 +1,345 @@ +# Requirements + +This file is the explicit capability and coverage contract for the project. + +## Active + +### R001 — Centralized GitService class +- Class: core-capability +- Status: active +- Description: A single `GitService` class in `git-service.ts` that owns all git mechanics — commit, branch, merge, checkout, staging +- Why it matters: Moves git operations from probabilistic LLM prompts to deterministic code. The foundational trust boundary fix. +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: M001/S02 +- Validation: unmapped +- Notes: Must reuse existing `runGit()` pattern from worktree.ts + +### R002 — Smart staging with exclusion filter +- Class: core-capability +- Status: active +- Description: Replace `git add -A` with filtered staging that excludes known runtime paths (.gsd/runtime/, .gsd/activity/, .gsd/STATE.md, .gsd/auto.lock, .gsd/metrics.json) +- Why it matters: Prevents accidental commits of runtime/bookkeeping files that should never be tracked +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: unmapped +- Notes: Fallback to `git add -A` with warning if filtering fails + +### R003 — Conventional commit type inference +- Class: quality-attribute +- Status: active +- Description: Infer commit type (feat/fix/refactor/docs/test/chore) from slice title keywords instead of hardcoding `feat` +- Why it matters: Accurate git history that can be filtered and parsed by conventional-commits tooling +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: unmapped +- Notes: Default to `feat` when no keywords match + +### R004 — Git preferences schema +- Class: core-capability +- Status: active +- Description: Add `git?: GitPreferences` to GSDPreferences interface with validation, merge logic, and documentation +- Why it matters: Enables all preference-gated git features (auto_push, merge guards, etc.) via existing preferences system +- Source: user +- Primary owning slice: M001/S02 +- Supporting slices: M001/S05 +- Validation: unmapped +- Notes: Fields: auto_push, push_branches, remote, snapshots, pre_merge_check, commit_type + +### R005 — worktree.ts thin facade delegation +- Class: core-capability +- Status: active +- Description: worktree.ts keeps existing exports but delegates internally to GitService. All existing callers continue to work without changes. +- Why it matters: Backward compatibility — existing imports from worktree.ts don't break +- Source: user +- Primary owning slice: M001/S02 +- Supporting slices: none +- Validation: unmapped +- Notes: New code should import from GitService directly + +### R006 — auto.ts wired to GitService +- Class: core-capability +- Status: active +- Description: Replace inline git calls in auto.ts (git init, git add -A, autoCommitCurrentBranch, ensureSliceBranch, switchToMain, mergeSliceToMain) with GitService methods +- Why it matters: The orchestrator is the primary caller of git operations — it must route through the centralized service +- Source: user +- Primary owning slice: M001/S02 +- Supporting slices: none +- Validation: unmapped +- Notes: git status --porcelain for idle detection and git rev-parse --git-dir for init check may remain inline + +### R007 — Bug fix: worktree create ordering +- Class: quality-attribute +- Status: active +- Description: Move autoCommitCurrentBranch() BEFORE createWorktree() in worktree-command.ts so new worktrees fork from committed state +- Why it matters: Currently new worktrees fork from pre-commit HEAD, missing the user's latest saved state +- Source: user +- Primary owning slice: M001/S03 +- Supporting slices: none +- Validation: unmapped +- Notes: worktree-command.ts ~line 352-357 + +### R008 — Bug fix: worktree merge dispatch +- Class: quality-attribute +- Status: active +- Description: Use deterministic mergeWorktreeToMain() helper as default merge path in worktree-command.ts. Keep LLM-mediated path only for complex conflict resolution. +- Why it matters: The deterministic helper already exists but isn't used as the default — merge currently goes through LLM unnecessarily +- Source: user +- Primary owning slice: M001/S03 +- Supporting slices: none +- Validation: unmapped +- Notes: worktree-command.ts ~line 672-696, worktree-manager.ts lines 375-391 + +### R009 — Bug fix: hardcoded feat commit type +- Class: quality-attribute +- Status: active +- Description: Replace hardcoded `feat(...)` in mergeSliceToMain with inferCommitType() from GitService +- Why it matters: Bugfix slices, docs slices, refactor slices are all mislabeled as `feat` +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: M001/S02 +- Validation: unmapped +- Notes: worktree.ts line 258-260 + +### R010 — Doc fixes: branch preservation + checkpoint claims +- Class: quality-attribute +- Status: active +- Description: Fix README.md "preserved" claim to "deleted after merge". Fix GSD-WORKFLOW.md "Branch kept" to "Branch deleted". Replace checkpoint commit documentation with snapshot ref description. +- Why it matters: Docs currently claim behaviors the code doesn't implement — erodes trust +- Source: user +- Primary owning slice: M001/S03 +- Supporting slices: none +- Validation: unmapped +- Notes: README.md lines 258-264, GSD-WORKFLOW.md lines 548-585 + +### R011 — Remove raw git commands from prompts +- Class: core-capability +- Status: active +- Description: Replace `git add -A && git commit` instructions in execute-task.md, complete-slice.md, replan-slice.md, complete-milestone.md with "the system commits automatically" messages +- Why it matters: LLMs should not run git commands — that's the whole point of the GitService trust boundary +- Source: user +- Primary owning slice: M001/S04 +- Supporting slices: none +- Validation: unmapped +- Notes: Keep worktree-merge.md as-is (conflict resolution needs LLM judgment) + +### R012 — Pre-merge verification (merge guards) +- Class: core-capability +- Status: active +- Description: Auto-detect test/typecheck/build commands from package.json, Cargo.toml, Makefile, pyproject.toml. Run before squash merge. Abort on failure. +- Why it matters: Prevents broken code from landing on main +- Source: user +- Primary owning slice: M001/S05 +- Supporting slices: none +- Validation: unmapped +- Notes: Configurable via git.pre_merge_check preference: "auto" (default), false (skip), or custom command + +### R013 — Hidden snapshot refs for rollback +- Class: core-capability +- Status: active +- Description: Create refs/gsd/snapshots// before merges and risky operations. Prunable after 7 days. +- Why it matters: Invisible recovery points without cluttering branch history with checkpoint commits +- Source: user +- Primary owning slice: M001/S05 +- Supporting slices: none +- Validation: unmapped +- Notes: Invisible to normal git log. Visible via git for-each-ref refs/gsd/snapshots/ + +### R014 — Optional auto-push (preference-gated) +- Class: core-capability +- Status: active +- Description: When git.auto_push: true, push main to remote after slice merge. Optionally push slice branches during work. +- Why it matters: Remote backup and team visibility for senior engineers +- Source: user +- Primary owning slice: M001/S05 +- Supporting slices: none +- Validation: unmapped +- Notes: Default: false. Remote name configurable via git.remote (default: "origin") + +### R015 — Rich squash commit messages with task lists +- Class: quality-attribute +- Status: active +- Description: Squash merge commits include task list extracted from branch commit history and branch reference for forensics +- Why it matters: Self-documenting git history that reads like a changelog +- Source: user +- Primary owning slice: M001/S05 +- Supporting slices: none +- Validation: unmapped +- Notes: Format: type(scope): title\n\nTasks:\n- T01: ...\n\nBranch: gsd/M001/S01 + +### R016 — Bug fix: stale branch base with remote fetch +- Class: quality-attribute +- Status: active +- Description: When a remote exists, git fetch --prune before cutting a new slice branch. Warn (don't block) if local main is behind origin. +- Why it matters: Prevents branching from stale trunk HEAD +- Source: user +- Primary owning slice: M001/S05 +- Supporting slices: none +- Validation: unmapped +- Notes: Only when remote exists and auto_push is enabled or remote is configured + +### R017 — GitService unit tests +- Class: quality-attribute +- Status: active +- Description: Unit tests using temp git repos for all GitService methods, following the existing worktree test patterns +- Why it matters: Mechanical verification that git operations work correctly +- Source: inferred +- Primary owning slice: M001/S01 +- Supporting slices: M001/S05 +- Validation: unmapped +- Notes: Same test infrastructure as worktree.test.ts + +### R018 — Archive design input files +- Class: quality-attribute +- Status: active +- Description: Remove or archive CODEX-GIT-SYNTHESIS.md, CLAUDE-GIT-SYNTHESIS.md, GEMINI-GIT-SYNTHESIS.md, and ONBOARDING-PLAN.md +- Why it matters: Design input files are not permanent docs — they clutter the repo after implementation +- Source: user +- Primary owning slice: M001/S06 +- Supporting slices: none +- Validation: unmapped +- Notes: Delete rather than archive — git history preserves them + +## Deferred + +### R019 — PR creation workflow +- Class: core-capability +- Status: deferred +- Description: Auto-create PRs via gh CLI after slice merge when git.auto_pr is enabled +- Why it matters: Team workflow integration for shared repos with protected branches +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: unmapped +- Notes: Deferred — touches GitHub API, gh CLI detection, merge queue awareness. Separate concern from core GitService. + +### R020 — Milestone tags on completion +- Class: quality-attribute +- Status: deferred +- Description: Create annotated git tags on milestone completion (e.g. M001) +- Why it matters: Enables git describe, changelog generation, and clear release markers +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: unmapped +- Notes: Deferred — low value relative to core trust boundary fix + +### R021 — Full file ownership tracking +- Class: core-capability +- Status: deferred +- Description: Track every file the agent creates/modifies per unit. Only stage owned files. +- Why it matters: More precise staging than exclusion filter — prevents unrelated user edits from being committed +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: unmapped +- Notes: Deferred — requires threading ownership through entire execution pipeline. Exclusion filter covers 95% of the problem. + +## Out of Scope + +### R022 — Git Notes for metadata +- Class: anti-feature +- Status: out-of-scope +- Description: Store task plans and verification results in git notes +- Why it matters: Prevents fragile, poorly-supported metadata mechanism from entering the codebase +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: Git Notes are fragile, poorly rendered by most tools, unreliable push/pull semantics + +### R023 — Shadow worktrees as default model +- Class: anti-feature +- Status: out-of-scope +- Description: Make git worktrees the default execution model for all agent work +- Why it matters: Over-engineering for common single-agent case. Worktrees are already available as advanced opt-in. +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: Rejected from Gemini's proposal + +### R024 — AI-driven rebases +- Class: anti-feature +- Status: out-of-scope +- Description: LLM-driven interactive rebase and cross-slice conflict resolution +- Why it matters: Prevents hidden magic that makes senior engineers distrust the system +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: Merge conflicts require deterministic resolution or human intervention + +### R025 — Stacked branches +- Class: anti-feature +- Status: out-of-scope +- Description: Stacked branch/PR workflow as default execution model +- Why it matters: Over-engineering for solo/vibe coder workflows +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: Could be opt-in advanced mode in a future milestone + +### R026 — CI/CD integration +- Class: anti-feature +- Status: out-of-scope +- Description: Deployment pipeline integration from GSD +- Why it matters: GSD manages work orchestration, not infrastructure +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: Merge guards handle "is it broken?" — deployment is the user's concern + +### R027 — Commit signing (GPG) +- Class: anti-feature +- Status: out-of-scope +- Description: GPG commit signing for agent commits +- Why it matters: Adds friction with zero value when the agent is the committer +- Source: research +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: Could be opt-in preference in a future milestone + +## Traceability + +| ID | Class | Status | Primary owner | Supporting | Proof | +|---|---|---|---|---|---| +| R001 | core-capability | active | M001/S01 | M001/S02 | unmapped | +| R002 | core-capability | active | M001/S01 | none | unmapped | +| R003 | quality-attribute | active | M001/S01 | none | unmapped | +| R004 | core-capability | active | M001/S02 | M001/S05 | unmapped | +| R005 | core-capability | active | M001/S02 | none | unmapped | +| R006 | core-capability | active | M001/S02 | none | unmapped | +| R007 | quality-attribute | active | M001/S03 | none | unmapped | +| R008 | quality-attribute | active | M001/S03 | none | unmapped | +| R009 | quality-attribute | active | M001/S01 | M001/S02 | unmapped | +| R010 | quality-attribute | active | M001/S03 | none | unmapped | +| R011 | core-capability | active | M001/S04 | none | unmapped | +| R012 | core-capability | active | M001/S05 | none | unmapped | +| R013 | core-capability | active | M001/S05 | none | unmapped | +| R014 | core-capability | active | M001/S05 | none | unmapped | +| R015 | quality-attribute | active | M001/S05 | none | unmapped | +| R016 | quality-attribute | active | M001/S05 | none | unmapped | +| R017 | quality-attribute | active | M001/S01 | M001/S05 | unmapped | +| R018 | quality-attribute | active | M001/S06 | none | unmapped | +| R019 | core-capability | deferred | none | none | unmapped | +| R020 | quality-attribute | deferred | none | none | unmapped | +| R021 | core-capability | deferred | none | none | unmapped | +| R022 | anti-feature | out-of-scope | none | none | n/a | +| R023 | anti-feature | out-of-scope | none | none | n/a | +| R024 | anti-feature | out-of-scope | none | none | n/a | +| R025 | anti-feature | out-of-scope | none | none | n/a | +| R026 | anti-feature | out-of-scope | none | none | n/a | +| R027 | anti-feature | out-of-scope | none | none | n/a | + +## Coverage Summary + +- Active requirements: 18 +- Mapped to slices: 18 +- Validated: 0 +- Unmapped active requirements: 0 diff --git a/.gsd/STATE.md b/.gsd/STATE.md new file mode 100644 index 000000000..256fcb085 --- /dev/null +++ b/.gsd/STATE.md @@ -0,0 +1,21 @@ +# GSD State + +**Active Milestone:** M001 — Deterministic GitService +**Active Slice:** S01 — GitService core implementation +**Active Task:** none +**Phase:** Planning +**Slice Branch:** none +**Active Workspace:** main +**Next Action:** Plan S01 — decompose into tasks with must-haves +**Last Updated:** 2026-03-12 +**Requirements Status:** 18 active · 0 validated · 3 deferred · 6 out of scope + +## Recent Decisions + +- D001: Smart staging via exclusion filter (not file ownership tracking) +- D002: worktree.ts becomes thin facade (keep exports, delegate internally) +- D003: Delete merged branches (squash commit is the permanent record) + +## Blockers + +- (none) diff --git a/.gsd/milestones/M001/M001-CONTEXT.md b/.gsd/milestones/M001/M001-CONTEXT.md new file mode 100644 index 000000000..d05645554 --- /dev/null +++ b/.gsd/milestones/M001/M001-CONTEXT.md @@ -0,0 +1,130 @@ +# M001: Deterministic GitService — Context + +**Gathered:** 2026-03-12 +**Status:** Ready for planning + +## Project Description + +GSD's git workflow is architecturally sound (trunk-based, branch-per-slice, squash-merge) but has a critical trust boundary problem: git operations are split between deterministic TypeScript code and probabilistic LLM prompts that run raw `git add -A && git commit`. This causes accidental commits of runtime files, hardcoded commit types, no pre-merge verification, and no recovery mechanism. + +The fix is a centralized `GitService` that owns all git mechanics while the LLM focuses on writing code. + +## Why This Milestone + +GSD is already shipping (v2.3.11) and the git strategy mostly works. But the trust boundary problem creates real bugs: runtime files get committed, all commits are labeled `feat`, there's no safety net before merging to main, and docs claim behaviors the code doesn't implement. Fixing this now prevents these issues from compounding as more users adopt GSD. + +## User-Visible Outcome + +### When this milestone is complete, the user can: + +- Run a full GSD auto-mode cycle where all git operations are handled by deterministic code (no LLM-driven git commands) +- See correctly typed commit messages in git log (fix, refactor, docs — not always feat) +- Trust that broken code won't land on main (merge guards auto-detect and run tests) +- Recover from bad merges via hidden snapshot refs +- Optionally enable auto-push to remote via preferences + +### Entry point / environment + +- Entry point: `/gsd auto` CLI command +- Environment: local dev (Node.js, git CLI) +- Live dependencies involved: git CLI, optional remote (origin) + +## Completion Class + +- Contract complete means: `npm run build` passes, `npm run test` passes (existing + new GitService tests), no raw git commands in prompts +- Integration complete means: A full GSD slice lifecycle (branch → execute → commit → merge) routes through GitService +- Operational complete means: none — this is internal infrastructure, not a service + +## Final Integrated Acceptance + +To call this milestone complete, we must prove: + +- `npm run build` and `npm run test` pass +- A slice lifecycle in auto-mode produces commits via GitService (correct types, no accidental runtime file commits) +- Prompts contain no raw git commands (except worktree-merge.md) +- Git preferences are recognized and applied (auto_push, merge guards) +- Existing worktree commands still work (create/merge/remove) + +## Risks and Unknowns + +- **Wiring facade without breaking callers** — worktree.ts is imported by auto.ts, state.ts, worktree-command.ts, workspace-index.ts. The thin facade must preserve all export signatures exactly. +- **auto.ts complexity** — 2600+ lines. Wiring changes need surgical precision to avoid regressions in the orchestrator. +- **Smart staging edge cases** — Exclusion filter might miss patterns or filter too aggressively. Fallback to `git add -A` is the safety net. +- **Test infrastructure compatibility** — Existing worktree tests use temp repos. GitService tests must follow the same pattern without conflicts. + +## Existing Codebase / Prior Art + +- `src/resources/extensions/gsd/worktree.ts` — Current slice branch lifecycle (290 lines). Will become thin facade. +- `src/resources/extensions/gsd/worktree-manager.ts` — Git worktree lifecycle (392 lines). Has `mergeWorktreeToMain()` deterministic helper that should be used by default. +- `src/resources/extensions/gsd/worktree-command.ts` — CLI commands (803 lines). Has bugs #1 and #2. +- `src/resources/extensions/gsd/auto.ts` — Orchestrator (2652 lines). Primary consumer of git operations. +- `src/resources/extensions/gsd/preferences.ts` — Preferences system (616 lines). Will get `git?: GitPreferences`. +- `src/resources/extensions/gsd/gitignore.ts` — Has `BASELINE_PATTERNS` — same set the smart staging exclusion filter should use. +- `src/resources/extensions/gsd/tests/worktree.test.ts` — Existing tests using temp git repos. Pattern to follow for GitService tests. +- `src/resources/extensions/gsd/tests/worktree-integration.test.ts` — Integration tests for worktree lifecycle. + +> See `.gsd/DECISIONS.md` for all architectural and pattern decisions — it is an append-only register; read it during planning, append to it during execution. + +## Relevant Requirements + +- R001–R018 — All active requirements are owned by this milestone's slices +- See `.gsd/REQUIREMENTS.md` for full details + +## Scope + +### In Scope + +- New `git-service.ts` with all git mechanics +- Smart staging (exclusion filter) +- Commit type inference +- Git preferences schema +- Wiring auto.ts and worktree.ts to GitService +- Bug fixes (#1 worktree create ordering, #2 merge dispatch, #4 hardcoded feat, #5 stale branch base) +- Doc fixes (README.md, GSD-WORKFLOW.md) +- Prompt cleanup (remove raw git commands) +- Pre-merge verification (merge guards) +- Hidden snapshot refs +- Optional auto-push +- Rich squash commit messages +- Archive design input files +- Unit tests for GitService + +### Out of Scope / Non-Goals + +- PR creation workflow (R019 — deferred) +- Milestone tags (R020 — deferred) +- Full file ownership tracking (R021 — deferred) +- Git Notes, shadow worktrees, AI rebases, stacked branches, CI/CD, commit signing (R022–R027 — out of scope) + +## Technical Constraints + +- Must preserve all existing exports from worktree.ts (thin facade pattern) +- Must use existing `runGit()` pattern (execSync-based) +- Must use existing test infrastructure (Node built-in test runner, temp git repos) +- Preferences must follow existing YAML-in-markdown frontmatter format +- `git status --porcelain` for idle detection in auto.ts may remain inline (not part of GitService) + +## Integration Points + +- `auto.ts` — Primary consumer. Calls ensureSliceBranch, autoCommit, switchToMain, mergeSliceToMain. +- `worktree-command.ts` — Calls autoCommitCurrentBranch, createWorktree. Has bugs to fix. +- `worktree-manager.ts` — Has mergeWorktreeToMain() that GitService should delegate to or replace. +- `state.ts` — Imports getActiveSliceBranch from worktree.ts. +- `workspace-index.ts` — Imports getSliceBranchName, detectWorktreeName from worktree.ts. +- `preferences.ts` — Will gain git?: GitPreferences field. +- `gitignore.ts` — BASELINE_PATTERNS should be shared with smart staging exclusion filter. + +## Open Questions + +- None — all decisions resolved during discussion. + +## Per-Slice Reading Guide + +| Slice | Read before starting | +|---|---| +| S01 | `worktree.ts`, `worktree-manager.ts`, `gitignore.ts` (for SKIP_PATHS/BASELINE_PATTERNS) | +| S02 | S01 summary, `auto.ts` (lines 55-75, 350-380, 470-510, 980-1020, 2220-2230), `preferences.ts` | +| S03 | S02 summary, `worktree-command.ts` (lines 340-370, 660-710), `README.md` (lines 250-270), `GSD-WORKFLOW.md` (lines 540-590) | +| S04 | S02 summary, all prompt files in `prompts/` | +| S05 | S02 summary, `git-service.ts` (from S01), `preferences.ts` (from S02) | +| S06 | All prior summaries, root-level synthesis/audit files | diff --git a/.gsd/milestones/M001/M001-ROADMAP.md b/.gsd/milestones/M001/M001-ROADMAP.md new file mode 100644 index 000000000..cff3fefd7 --- /dev/null +++ b/.gsd/milestones/M001/M001-ROADMAP.md @@ -0,0 +1,142 @@ +# M001: Deterministic GitService + +**Vision:** Centralize all git mechanics into a single deterministic GitService, fixing the trust boundary where probabilistic LLM prompts currently run raw git commands. The result: reliable commits, typed history, merge guards, recovery snapshots, and zero git commands in prompts. + +## Success Criteria + +- All git operations in auto-mode route through GitService (no inline execSync git calls except `git status --porcelain` for idle detection and `git rev-parse --git-dir` for init check) +- `npm run build` passes +- `npm run test` passes (existing tests + new GitService tests) +- No raw git commands in LLM-facing prompts (except worktree-merge.md for conflict resolution) +- Git preferences recognized in preferences.md schema +- README and GSD-WORKFLOW doc claims match actual code behavior +- Squash merge commits use correct conventional types (not always `feat`) + +## Key Risks / Unknowns + +- **Facade wiring breaks callers** — worktree.ts has 6+ consumers. Any export signature change breaks the build. +- **auto.ts surgery** — 2600+ line orchestrator. Changes must be surgical to avoid regressions. +- **Smart staging edge cases** — Exclusion filter may miss patterns or over-filter. Fallback to `git add -A` is the safety net. + +## Proof Strategy + +- Facade wiring breaks callers → retire in S02 by proving `npm run build` and `npm run test` pass with the facade in place +- auto.ts surgery → retire in S02 by proving auto.ts compiles and existing tests pass +- Smart staging edge cases → retire in S01 by proving unit tests cover exclusion patterns and fallback behavior + +## Verification Classes + +- Contract verification: `npm run build`, `npm run test`, grep prompts for raw git commands +- Integration verification: Full slice lifecycle through GitService (exercised by existing worktree tests + new GitService tests) +- Operational verification: none — internal infrastructure +- UAT / human verification: Run a GSD auto-mode cycle and check git log for correct commit types + +## Milestone Definition of Done + +This milestone is complete only when all are true: + +- All slice deliverables are complete +- `npm run build` passes +- `npm run test` passes (existing + new) +- No raw git commands in execute-task.md, complete-slice.md, replan-slice.md, complete-milestone.md +- Git preferences parse and apply correctly +- README.md and GSD-WORKFLOW.md match actual behavior +- Design input files (synthesis/audit) are archived + +## Requirement Coverage + +- Covers: R001, R002, R003, R004, R005, R006, R007, R008, R009, R010, R011, R012, R013, R014, R015, R016, R017, R018 +- Partially covers: none +- Leaves for later: R019 (PR workflow), R020 (milestone tags), R021 (file ownership tracking) +- Orphan risks: none + +## Slices + +- [ ] **S01: GitService core implementation** `risk:high` `depends:[]` + > After this: `git-service.ts` exists with commit, autoCommit, ensureSliceBranch, switchToMain, mergeSliceToMain, inferCommitType, smart staging — all passing unit tests in temp git repos. + +- [ ] **S02: Wire GitService into codebase** `risk:high` `depends:[S01]` + > After this: auto.ts and worktree.ts delegate to GitService. Git preferences schema added to preferences.ts. `npm run build` passes. Existing worktree tests still pass. + +- [ ] **S03: Bug fixes and doc corrections** `risk:medium` `depends:[S02]` + > After this: Worktree create commits before fork. Worktree merge uses deterministic helper by default. README and GSD-WORKFLOW match actual branch deletion and snapshot behavior. Build passes. + +- [ ] **S04: Remove git commands from prompts** `risk:low` `depends:[S02]` + > After this: execute-task.md, complete-slice.md, replan-slice.md, complete-milestone.md contain no raw git commands. worktree-merge.md unchanged. Verified by grep. + +- [ ] **S05: Enhanced features — merge guards, snapshots, auto-push, rich commits** `risk:medium` `depends:[S02]` + > After this: Pre-merge verification auto-detects test runners and blocks broken merges. Snapshot refs created before merges (visible via `git for-each-ref refs/gsd/snapshots/`). auto_push preference pushes main after merge. Squash commits include task lists. Remote fetch before branching when remote exists. All verified by unit tests. + +- [ ] **S06: Cleanup and archive** `risk:low` `depends:[S05]` + > After this: CODEX-GIT-SYNTHESIS.md, CLAUDE-GIT-SYNTHESIS.md, GEMINI-GIT-SYNTHESIS.md, and ONBOARDING-PLAN.md are deleted. Final doc consistency check passes. + +## Boundary Map + +### S01 → S02 + +Produces: +- `git-service.ts` → `GitServiceImpl` class with constructor `(basePath: string, prefs: GitPreferences)` +- `git-service.ts` → `GitPreferences` interface (auto_push, push_branches, remote, snapshots, pre_merge_check, commit_type) +- `git-service.ts` → `commit(opts: CommitOptions)` — smart staging with exclusion filter, conventional commit message +- `git-service.ts` → `autoCommit(unitType: string, unitId: string)` — safety-net commit after LLM session +- `git-service.ts` → `ensureSliceBranch(milestoneId: string, sliceId: string)` — create/checkout slice branch +- `git-service.ts` → `switchToMain()` — switch to main, auto-commit dirty state first +- `git-service.ts` → `mergeSliceToMain(milestoneId: string, sliceId: string, sliceTitle: string)` — squash merge with inferred commit type +- `git-service.ts` → `inferCommitType(sliceTitle: string)` — keyword-based type inference +- `git-service.ts` → `getMainBranch()`, `getCurrentBranch()`, `isOnSliceBranch()`, `getActiveSliceBranch()` +- `git-service.ts` → Shared exclusion patterns (aligned with gitignore.ts BASELINE_PATTERNS) + +Consumes: +- nothing (first slice) + +### S02 → S03 + +Produces: +- `worktree.ts` — thin facade: all existing exports preserved, internals delegate to `GitServiceImpl` +- `auto.ts` — all git callsites route through GitService +- `preferences.ts` — `git?: GitPreferences` field with validation and merge logic +- `templates/preferences.md` — `git:` section in template +- `docs/preferences-reference.md` — git preferences documented + +Consumes from S01: +- `git-service.ts` → `GitServiceImpl`, `GitPreferences`, all public methods + +### S02 → S04 + +Produces: +- Same as S02 → S03 (prompts depend on the system committing automatically, which S02 enables) + +Consumes from S01: +- Same as S02 → S03 + +### S02 → S05 + +Produces: +- Same as S02 → S03 (enhanced features build on the GitService and preferences schema) + +Consumes from S01: +- Same as S02 → S03 + +### S03 → S06 + +Produces: +- Fixed `worktree-command.ts` — create ordering, merge dispatch +- Fixed `README.md` — branch lifecycle claims +- Fixed `GSD-WORKFLOW.md` — checkpoint/branch docs + +Consumes from S02: +- `worktree.ts` facade (for autoCommitCurrentBranch used in create ordering fix) +- `git-service.ts` (for mergeWorktreeToMain delegation) + +### S05 → S06 + +Produces: +- `git-service.ts` → `createSnapshot(label: string)` — hidden snapshot refs +- `git-service.ts` → `runPreMergeCheck()` — auto-detect and execute verification +- `git-service.ts` → auto-push logic in mergeSliceToMain +- `git-service.ts` → rich squash commit message builder +- `git-service.ts` → remote fetch before branching + +Consumes from S02: +- `git-service.ts` core methods +- `preferences.ts` git preferences (pre_merge_check, auto_push, remote)