docs(M001): context, requirements, and roadmap
This commit is contained in:
parent
2a5c270bb0
commit
f18a547e05
6 changed files with 689 additions and 0 deletions
18
.gsd/DECISIONS.md
Normal file
18
.gsd/DECISIONS.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Decisions Register
|
||||
|
||||
<!-- Append-only. Never edit or remove existing rows.
|
||||
To reverse a decision, add a new row that supersedes it.
|
||||
Read this file at the start of any planning or research phase. -->
|
||||
|
||||
| # | 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 |
|
||||
33
.gsd/PROJECT.md
Normal file
33
.gsd/PROJECT.md
Normal file
|
|
@ -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
|
||||
345
.gsd/REQUIREMENTS.md
Normal file
345
.gsd/REQUIREMENTS.md
Normal file
|
|
@ -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/<branch>/<timestamp> 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
|
||||
21
.gsd/STATE.md
Normal file
21
.gsd/STATE.md
Normal file
|
|
@ -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)
|
||||
130
.gsd/milestones/M001/M001-CONTEXT.md
Normal file
130
.gsd/milestones/M001/M001-CONTEXT.md
Normal file
|
|
@ -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 |
|
||||
142
.gsd/milestones/M001/M001-ROADMAP.md
Normal file
142
.gsd/milestones/M001/M001-ROADMAP.md
Normal file
|
|
@ -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)
|
||||
Loading…
Add table
Reference in a new issue