merge: resolve conflicts with origin/main for PR #2008
Merge main's userSubdirs guard pattern with ecosystem skills directory migration logic. Keep both detection.ts entry sets (PR's expanded markers + main's .NET/Xcode/Docker entries). Preserve PR's skills test assertion. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
91ec77291a
759 changed files with 66349 additions and 23688 deletions
53
.dockerignore
Normal file
53
.dockerignore
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# ── Build artifacts ──
|
||||
dist/
|
||||
build/
|
||||
coverage/
|
||||
*.tsbuildinfo
|
||||
|
||||
# ── Dependencies ──
|
||||
node_modules/
|
||||
packages/*/node_modules/
|
||||
|
||||
# ── Environment & secrets ──
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
.gsd/
|
||||
|
||||
# ── IDE & OS ──
|
||||
.idea/
|
||||
.vscode/
|
||||
*.code-workspace
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# ── Git ──
|
||||
.git/
|
||||
.github/
|
||||
|
||||
# ── Development files ──
|
||||
.claude/
|
||||
.plans/
|
||||
.artifacts/
|
||||
.bg-shell/
|
||||
.bg_shell
|
||||
*.log
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
tmp/
|
||||
.cache/
|
||||
|
||||
# ── Native build artifacts ──
|
||||
native/
|
||||
target/
|
||||
|
||||
# ── Test fixtures ──
|
||||
tests/
|
||||
|
||||
# ── Lock files (npm is canonical via package-lock.json) ──
|
||||
pnpm-lock.yaml
|
||||
bun.lock
|
||||
|
||||
# ── Tarballs ──
|
||||
*.tgz
|
||||
36
.github/CODEOWNERS
vendored
Normal file
36
.github/CODEOWNERS
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# CODEOWNERS
|
||||
# Defines required reviewers per path. GitHub enforces these on PRs.
|
||||
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
||||
#
|
||||
# Format: <pattern> <@user or @org/team>
|
||||
# Last matching rule wins.
|
||||
|
||||
# Default: maintainers review everything not explicitly matched below
|
||||
* @gsd-build/maintainers
|
||||
|
||||
# Core agent orchestration — RFC required, senior review only
|
||||
packages/pi-agent-core/ @gsd-build/maintainers
|
||||
src/resources/extensions/gsd/ @gsd-build/maintainers
|
||||
|
||||
# AI/LLM provider integrations
|
||||
packages/pi-ai/ @gsd-build/maintainers
|
||||
|
||||
# Terminal UI
|
||||
packages/pi-tui/ @gsd-build/maintainers
|
||||
|
||||
# Native bindings — platform-specific, needs careful review
|
||||
native/ @gsd-build/maintainers
|
||||
|
||||
# CI/CD and release pipeline — high blast radius
|
||||
.github/ @gsd-build/maintainers
|
||||
scripts/ @gsd-build/maintainers
|
||||
Dockerfile @gsd-build/maintainers
|
||||
|
||||
# Security-sensitive files — always require maintainer sign-off
|
||||
.secretscanignore @gsd-build/maintainers
|
||||
scripts/secret-scan.sh @gsd-build/maintainers
|
||||
scripts/install-hooks.sh @gsd-build/maintainers
|
||||
|
||||
# Contributor-facing docs — keep accurate, maintainers approve
|
||||
CONTRIBUTING.md @gsd-build/maintainers
|
||||
VISION.md @gsd-build/maintainers
|
||||
4
.github/workflows/ai-triage.yml
vendored
4
.github/workflows/ai-triage.yml
vendored
|
|
@ -12,9 +12,9 @@ permissions:
|
|||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
sparse-checkout: |
|
||||
VISION.md
|
||||
|
|
|
|||
7
.github/workflows/build-native.yml
vendored
7
.github/workflows/build-native.yml
vendored
|
|
@ -46,8 +46,9 @@ jobs:
|
|||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Add Rust compilation target
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
- name: Cache Rust build artifacts
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
|
@ -97,7 +98,7 @@ jobs:
|
|||
publish:
|
||||
needs: build
|
||||
if: startsWith(github.ref, 'refs/tags/v') || github.event.inputs.publish == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
name: Publish platform packages
|
||||
|
||||
steps:
|
||||
|
|
|
|||
28
.github/workflows/ci.yml
vendored
28
.github/workflows/ci.yml
vendored
|
|
@ -1,3 +1,4 @@
|
|||
# CI workflow — builds, tests, and gates merges to main
|
||||
name: CI
|
||||
|
||||
on:
|
||||
|
|
@ -24,7 +25,8 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
detect-changes:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
outputs:
|
||||
docs-only: ${{ steps.check.outputs.docs-only }}
|
||||
steps:
|
||||
|
|
@ -59,7 +61,8 @@ jobs:
|
|||
fi
|
||||
|
||||
docs-check:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
needs: detect-changes
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
|
@ -70,8 +73,9 @@ jobs:
|
|||
run: bash scripts/docs-prompt-injection-scan.sh --diff origin/main
|
||||
|
||||
lint:
|
||||
timeout-minutes: 5
|
||||
needs: detect-changes
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
|
|
@ -80,6 +84,9 @@ jobs:
|
|||
- name: Scan for hardcoded secrets
|
||||
run: bash scripts/secret-scan.sh --diff origin/main
|
||||
|
||||
- name: Scan for base64-encoded secrets
|
||||
run: bash scripts/base64-scan.sh --diff origin/main
|
||||
|
||||
- name: Ensure .gsd/ is not checked in
|
||||
run: |
|
||||
if [ -d ".gsd" ]; then
|
||||
|
|
@ -96,9 +103,10 @@ jobs:
|
|||
run: node scripts/check-skill-references.mjs
|
||||
|
||||
build:
|
||||
timeout-minutes: 15
|
||||
needs: detect-changes
|
||||
if: needs.detect-changes.outputs.docs-only != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
|
@ -131,15 +139,18 @@ jobs:
|
|||
- name: Run unit tests
|
||||
run: npm run test:unit
|
||||
|
||||
- name: Run package tests
|
||||
run: npm run test:packages
|
||||
|
||||
- name: Run integration tests
|
||||
run: npm run test:integration
|
||||
|
||||
windows-portability:
|
||||
timeout-minutes: 15
|
||||
needs: detect-changes
|
||||
if: >-
|
||||
needs.detect-changes.outputs.docs-only != 'true' &&
|
||||
github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
runs-on: windows-latest
|
||||
needs.detect-changes.outputs.docs-only != 'true'
|
||||
runs-on: blacksmith-4vcpu-windows-2025
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
|
@ -162,3 +173,6 @@ jobs:
|
|||
|
||||
- name: Run unit tests
|
||||
run: npm run test:unit
|
||||
|
||||
- name: Run package tests
|
||||
run: npm run test:packages
|
||||
|
|
|
|||
2
.github/workflows/cleanup-dev-versions.yml
vendored
2
.github/workflows/cleanup-dev-versions.yml
vendored
|
|
@ -11,7 +11,7 @@ permissions:
|
|||
jobs:
|
||||
cleanup:
|
||||
name: Remove stale -dev versions
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
|
|
|
|||
22
.github/workflows/pipeline.yml
vendored
22
.github/workflows/pipeline.yml
vendored
|
|
@ -7,7 +7,7 @@ on:
|
|||
branches: [main]
|
||||
|
||||
concurrency:
|
||||
group: pipeline-${{ github.sha }}
|
||||
group: pipeline-main
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
dev-publish:
|
||||
name: Dev Publish
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
container:
|
||||
image: ghcr.io/gsd-build/gsd-ci-builder:latest
|
||||
credentials:
|
||||
|
|
@ -71,7 +71,7 @@ jobs:
|
|||
test-verify:
|
||||
name: Test & Verify
|
||||
needs: dev-publish
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
|
|
@ -81,8 +81,15 @@ jobs:
|
|||
registry-url: https://registry.npmjs.org
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install gsd-pi@dev globally
|
||||
run: npm install -g gsd-pi@dev
|
||||
- name: Install gsd-pi@dev globally (with registry propagation retry)
|
||||
run: |
|
||||
for i in 1 2 3 4 5 6; do
|
||||
npm install -g gsd-pi@dev && exit 0
|
||||
echo "Attempt $i failed — waiting 10s for npm registry propagation..."
|
||||
sleep 10
|
||||
done
|
||||
echo "Failed to install gsd-pi@dev after 6 attempts"
|
||||
exit 1
|
||||
|
||||
- name: Run smoke tests (against installed binary)
|
||||
run: |
|
||||
|
|
@ -129,7 +136,7 @@ jobs:
|
|||
prod-release:
|
||||
name: Production Release
|
||||
needs: [dev-publish, test-verify]
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
environment: prod
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
|
@ -180,6 +187,7 @@ jobs:
|
|||
git add package.json package-lock.json CHANGELOG.md native/npm/*/package.json pkg/package.json packages/pi-coding-agent/package.json
|
||||
git commit -m "release: v${RELEASE_VERSION}"
|
||||
git tag "v${RELEASE_VERSION}"
|
||||
git pull --rebase origin main
|
||||
git push origin main
|
||||
git push origin "v${RELEASE_VERSION}"
|
||||
|
||||
|
|
@ -240,7 +248,7 @@ jobs:
|
|||
update-builder:
|
||||
name: Update CI Builder Image
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
|
|
|
|||
16
.github/workflows/pr-risk.yml
vendored
16
.github/workflows/pr-risk.yml
vendored
|
|
@ -14,19 +14,19 @@ permissions:
|
|||
jobs:
|
||||
risk-check:
|
||||
name: Classify changed files and assess risk
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
|
||||
steps:
|
||||
# Checkout the BASE branch — our trusted script and map, not fork code.
|
||||
- name: Checkout base
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.base_ref }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20'
|
||||
node-version: '24'
|
||||
|
||||
# Use the GitHub API to get changed files — no fork code is executed.
|
||||
- name: Get changed files
|
||||
|
|
@ -44,14 +44,14 @@ jobs:
|
|||
id: risk
|
||||
run: |
|
||||
REPORT=$(cat /tmp/changed-files.txt | node scripts/pr-risk-check.mjs --github || true)
|
||||
echo "report<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$REPORT" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
echo "report<<EOF" >> "$GITHUB_OUTPUT"
|
||||
echo "$REPORT" >> "$GITHUB_OUTPUT"
|
||||
echo "EOF" >> "$GITHUB_OUTPUT"
|
||||
|
||||
RISK_LEVEL=$(cat /tmp/changed-files.txt | node scripts/pr-risk-check.mjs --json 2>/dev/null \
|
||||
| node -e "let d=''; process.stdin.on('data',c=>d+=c); process.stdin.on('end',()=>{ try { console.log(JSON.parse(d).risk) } catch { console.log('low') } })" \
|
||||
|| echo "low")
|
||||
echo "level=$RISK_LEVEL" >> $GITHUB_OUTPUT
|
||||
echo "level=$RISK_LEVEL" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Write step summary
|
||||
run: echo "${{ steps.risk.outputs.report }}" >> $GITHUB_STEP_SUMMARY
|
||||
|
|
|
|||
1
.npmrc
Normal file
1
.npmrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
engine-strict=true
|
||||
396
.plans/single-writer-engine-v3-control-plane.md
Normal file
396
.plans/single-writer-engine-v3-control-plane.md
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
# Single-Writer Engine v3: Agent Control Plane
|
||||
# Plan: State machine guards + actor causation + reversibility
|
||||
# Created: 2026-03-25
|
||||
|
||||
---
|
||||
|
||||
## Background
|
||||
|
||||
v2 gave the engine **write discipline** — agents can't corrupt STATE.md directly,
|
||||
every mutation goes through the DB, event log is append-only.
|
||||
|
||||
What v2 did NOT give us: **behavioral control**. Agents can still:
|
||||
- Complete a task twice (silent overwrite)
|
||||
- Complete a slice with open tasks (if they bypass the slice status check)
|
||||
- Complete a milestone in any status
|
||||
- Re-plan already-completed slices/tasks
|
||||
- Call any tool on any unit regardless of ownership
|
||||
- Leave no trace of *who* did what or *why*
|
||||
|
||||
This plan bundles three work streams that close those gaps together, since they
|
||||
share infrastructure (WorkflowEvent schema, DB query surface, handler preconditions).
|
||||
|
||||
---
|
||||
|
||||
## Work Streams
|
||||
|
||||
### Stream 1 — State Machine Guards (P0)
|
||||
Add precondition checks to all 8 tool handlers so invalid transitions return an
|
||||
error instead of silently succeeding.
|
||||
|
||||
### Stream 2 — Actor Identity + Persistent Audit Log (P1)
|
||||
Extend `WorkflowEvent` with `actor_name` and `trigger_reason`. Flush the
|
||||
in-process `workflow-logger` buffer to a persistent `.gsd/audit-log.jsonl`
|
||||
after every tool invocation, so "who did what and why" is durable.
|
||||
|
||||
### Stream 3 — Reversibility + Unit Ownership (P2)
|
||||
Add `gsd_task_reopen` and `gsd_slice_reopen` tools. Add a unit-ownership
|
||||
validation layer so an agent can only complete/reopen units it explicitly claimed.
|
||||
|
||||
---
|
||||
|
||||
## Detailed Task Breakdown
|
||||
|
||||
---
|
||||
|
||||
### Stream 1: State Machine Guards
|
||||
|
||||
#### S1-T1: Add `getTask`, `getSlice`, `getMilestone` existence helpers to `gsd-db.ts`
|
||||
|
||||
**Files:** `src/resources/extensions/gsd/gsd-db.ts`
|
||||
|
||||
These are read-only DB helpers to confirm an entity exists and return its current
|
||||
`status` field before any mutation. Each returns `null` if not found.
|
||||
|
||||
```ts
|
||||
getTask(taskId: string, sliceId: string): { status: string } | null
|
||||
getSlice(sliceId: string, milestoneId: string): { status: string } | null
|
||||
getMilestoneById(milestoneId: string): { status: string } | null
|
||||
```
|
||||
|
||||
Note: `getSlice` may already exist — check before adding a duplicate. The audit
|
||||
report references it in `complete-slice.ts` line 207 but only to list tasks.
|
||||
Need a version that returns the slice row itself.
|
||||
|
||||
---
|
||||
|
||||
#### S1-T2: Guard `complete-task.ts` — enforce valid transitions
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/complete-task.ts`
|
||||
|
||||
Preconditions to add (before the transaction block):
|
||||
1. `getMilestoneById(milestoneId)` → must exist, must NOT be `"complete"` or `"done"`
|
||||
2. `getSlice(sliceId, milestoneId)` → must exist, must be `"pending"` or `"in_progress"`
|
||||
3. `getTask(taskId, sliceId)` → if exists, status must be `"pending"` (not already `"complete"`)
|
||||
|
||||
On failure: return `{ error: "<reason>" }` — do NOT throw.
|
||||
|
||||
---
|
||||
|
||||
#### S1-T3: Guard `complete-slice.ts` — enforce valid transitions
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/complete-slice.ts`
|
||||
|
||||
Preconditions to add:
|
||||
1. `getSlice(sliceId, milestoneId)` → must exist, status must be `"pending"` or `"in_progress"` (not already `"complete"`)
|
||||
2. `getMilestoneById(milestoneId)` → must exist, must NOT be `"complete"`
|
||||
3. All tasks in slice must be `"complete"` (already enforced — keep it, add explicit slice-status check before this)
|
||||
|
||||
---
|
||||
|
||||
#### S1-T4: Guard `complete-milestone.ts` — enforce valid transitions
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/complete-milestone.ts`
|
||||
|
||||
Preconditions to add:
|
||||
1. `getMilestoneById(milestoneId)` → must exist, status must be `"active"` (not already `"complete"`)
|
||||
2. Keep existing all-slices-complete check
|
||||
3. Add deep check: all tasks across all slices must also be `"complete"` (not just slice status)
|
||||
|
||||
---
|
||||
|
||||
#### S1-T5: Guard `plan-task.ts` — block re-planning completed tasks
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/plan-task.ts`
|
||||
|
||||
Preconditions to add:
|
||||
1. `getSlice(sliceId, milestoneId)` → must exist, status must NOT be `"complete"` (already blocks planning on a closed slice)
|
||||
2. If task exists (`getTask`), status must be `"pending"` — block re-planning a `"complete"` task
|
||||
|
||||
---
|
||||
|
||||
#### S1-T6: Guard `plan-slice.ts` — block re-planning completed slices
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/plan-slice.ts`
|
||||
|
||||
Preconditions to add:
|
||||
1. `getSlice(sliceId, milestoneId)` → if exists, status must NOT be `"complete"`
|
||||
2. `getMilestoneById(milestoneId)` → must exist, status must NOT be `"complete"`
|
||||
|
||||
---
|
||||
|
||||
#### S1-T7: Guard `plan-milestone.ts` — block re-planning completed milestones
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/plan-milestone.ts`
|
||||
|
||||
Preconditions to add:
|
||||
1. If milestone exists (`getMilestoneById`), status must NOT be `"complete"`
|
||||
2. Validate `depends_on` array: each referenced milestoneId must exist and be `"complete"` before this milestone can be planned
|
||||
|
||||
---
|
||||
|
||||
#### S1-T8: Guard `reassess-roadmap.ts` — verify completedSliceId is actually complete
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/reassess-roadmap.ts`
|
||||
|
||||
Gap: `completedSliceId` is accepted without confirming it is actually `"complete"` status.
|
||||
Also: no check that milestone is still `"active"` (could reassess after milestone is done).
|
||||
|
||||
Preconditions to add:
|
||||
1. `getSlice(completedSliceId, milestoneId)` → status must be `"complete"`
|
||||
2. `getMilestoneById(milestoneId)` → status must be `"active"`
|
||||
|
||||
---
|
||||
|
||||
#### S1-T9: Guard `replan-slice.ts` — verify blockerTaskId exists and is complete
|
||||
|
||||
**File:** `src/resources/extensions/gsd/tools/replan-slice.ts`
|
||||
|
||||
Gaps:
|
||||
- `blockerTaskId` is accepted without verifying it exists or is `"complete"`
|
||||
- No check that slice is still `"in_progress"` (could replan after slice is complete)
|
||||
|
||||
Preconditions to add:
|
||||
1. `getSlice(sliceId, milestoneId)` → status must be `"in_progress"` or `"pending"`, NOT `"complete"`
|
||||
2. `getTask(blockerTaskId, sliceId)` → must exist, status must be `"complete"`
|
||||
|
||||
---
|
||||
|
||||
### Stream 2: Actor Identity + Persistent Audit Log
|
||||
|
||||
#### S2-T1: Extend `WorkflowEvent` with actor identity and causation fields
|
||||
|
||||
**File:** `src/resources/extensions/gsd/workflow-events.ts`
|
||||
|
||||
Extend the `WorkflowEvent` interface:
|
||||
```ts
|
||||
export interface WorkflowEvent {
|
||||
cmd: string;
|
||||
params: Record<string, unknown>;
|
||||
ts: string;
|
||||
hash: string;
|
||||
actor: "agent" | "system";
|
||||
actor_name?: string; // ADD: e.g. "executor-agent-01", "gsd-orchestrator"
|
||||
trigger_reason?: string; // ADD: e.g. "plan-phase complete", "user invoked gsd_complete_task"
|
||||
session_id?: string; // ADD: process.env.GSD_SESSION_ID if set
|
||||
}
|
||||
```
|
||||
|
||||
Update `appendEvent` to accept and persist these new optional fields.
|
||||
Hash computation must remain stable (still hashes only `cmd + params`, not the new fields)
|
||||
so fork detection isn't broken.
|
||||
|
||||
---
|
||||
|
||||
#### S2-T2: Update all 8 tool handlers to pass actor identity to `appendEvent`
|
||||
|
||||
**Files:** All 8 handlers in `src/resources/extensions/gsd/tools/`
|
||||
|
||||
Each handler receives its inputs. Add a convention where params can include:
|
||||
- `actor_name` (optional string) — caller passes their agent identity
|
||||
- `trigger_reason` (optional string) — caller passes why this action was triggered
|
||||
|
||||
If not provided, default to `actor_name: "agent"`, `trigger_reason: undefined`.
|
||||
|
||||
Handlers pass these through to `appendEvent`.
|
||||
|
||||
The tool schemas (in the MCP tool definitions) should expose `actor_name` and
|
||||
`trigger_reason` as optional string params so agents can self-identify.
|
||||
|
||||
---
|
||||
|
||||
#### S2-T3: Persist `workflow-logger` to `.gsd/audit-log.jsonl`
|
||||
|
||||
**File:** `src/resources/extensions/gsd/workflow-logger.ts`
|
||||
|
||||
Current behavior: `_buffer` is in-process memory, drained per-unit and dropped.
|
||||
This means errors/warnings disappear across context resets.
|
||||
|
||||
Change: After `_push()` writes to the in-process buffer, also append the entry
|
||||
to `.gsd/audit-log.jsonl` (using `appendFileSync`). This requires the basePath
|
||||
to be available — either pass it as a module-level setter (`setLogBasePath(path)`)
|
||||
called at engine init, or accept it as a param on `logWarning`/`logError`.
|
||||
|
||||
The audit log format should match `LogEntry` serialized as JSON + newline,
|
||||
consistent with `event-log.jsonl`.
|
||||
|
||||
---
|
||||
|
||||
#### S2-T4: Add `readAuditLog` helper to `workflow-logger.ts`
|
||||
|
||||
**File:** `src/resources/extensions/gsd/workflow-logger.ts`
|
||||
|
||||
Expose a read function so the auto-loop and diagnostics can surface persistent
|
||||
audit entries without replaying the event log:
|
||||
|
||||
```ts
|
||||
export function readAuditLog(basePath: string): LogEntry[]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Stream 3: Reversibility + Unit Ownership
|
||||
|
||||
#### S3-T1: Add `updateTaskStatus` and `updateSliceStatus` DB helpers
|
||||
|
||||
**File:** `src/resources/extensions/gsd/gsd-db.ts`
|
||||
|
||||
If they don't already exist (check first):
|
||||
```ts
|
||||
updateTaskStatus(taskId: string, sliceId: string, status: string): void
|
||||
updateSliceStatus(sliceId: string, milestoneId: string, status: string): void
|
||||
```
|
||||
|
||||
These are the write primitives needed by reopen tools.
|
||||
|
||||
---
|
||||
|
||||
#### S3-T2: Implement `gsd_task_reopen` tool handler
|
||||
|
||||
**New file:** `src/resources/extensions/gsd/tools/reopen-task.ts`
|
||||
|
||||
Logic:
|
||||
1. Validate `taskId`, `sliceId`, `milestoneId` are non-empty strings
|
||||
2. `getTask(taskId, sliceId)` → must exist, status must be `"complete"` (can't reopen what isn't closed)
|
||||
3. `getSlice(sliceId, milestoneId)` → must exist, status must NOT be `"complete"` (can't reopen a task inside a closed slice — too late)
|
||||
4. `getMilestoneById(milestoneId)` → must exist, status must NOT be `"complete"`
|
||||
5. In a transaction: `updateTaskStatus(taskId, sliceId, "pending")`
|
||||
6. Append event: `cmd: "reopen_task"`, include `actor_name`, `trigger_reason`
|
||||
7. Invalidate state cache + render projections
|
||||
|
||||
---
|
||||
|
||||
#### S3-T3: Implement `gsd_slice_reopen` tool handler
|
||||
|
||||
**New file:** `src/resources/extensions/gsd/tools/reopen-slice.ts`
|
||||
|
||||
Logic:
|
||||
1. Validate `sliceId`, `milestoneId`
|
||||
2. `getSlice(sliceId, milestoneId)` → must exist, status must be `"complete"`
|
||||
3. `getMilestoneById(milestoneId)` → must NOT be `"complete"`
|
||||
4. In a transaction: `updateSliceStatus(sliceId, milestoneId, "in_progress")` + set all tasks back to `"pending"`
|
||||
5. Append event: `cmd: "reopen_slice"`
|
||||
6. Invalidate state cache + render projections
|
||||
|
||||
---
|
||||
|
||||
#### S3-T4: Add unit ownership claim/check mechanism
|
||||
|
||||
**New file:** `src/resources/extensions/gsd/unit-ownership.ts`
|
||||
|
||||
Lightweight JSON file at `.gsd/unit-claims.json` mapping unit IDs to agent names:
|
||||
```json
|
||||
{
|
||||
"M01/S01/T01": { "agent": "executor-01", "claimed_at": "2026-03-25T..." },
|
||||
"M01/S01": { "agent": "executor-01", "claimed_at": "2026-03-25T..." }
|
||||
}
|
||||
```
|
||||
|
||||
Functions:
|
||||
```ts
|
||||
claimUnit(basePath, unitKey, agentName): void // atomic write
|
||||
releaseUnit(basePath, unitKey): void
|
||||
getOwner(basePath, unitKey): string | null
|
||||
```
|
||||
|
||||
`unitKey` format: `"<milestoneId>/<sliceId>/<taskId>"` for tasks, `"<milestoneId>/<sliceId>"` for slices.
|
||||
|
||||
---
|
||||
|
||||
#### S3-T5: Wire ownership check into `complete-task` and `complete-slice`
|
||||
|
||||
**Files:** `complete-task.ts`, `complete-slice.ts`
|
||||
|
||||
If `actor_name` is provided AND `.gsd/unit-claims.json` exists AND the unit is claimed:
|
||||
- Verify `actor_name` matches the registered owner
|
||||
- If mismatch: return `{ error: "Unit <key> is owned by <owner>, not <actor>" }`
|
||||
- If no claim file / unit is unclaimed: allow the operation (opt-in ownership)
|
||||
|
||||
Ownership is enforced only when claims are present, keeping the feature opt-in.
|
||||
|
||||
---
|
||||
|
||||
## Files Changed Summary
|
||||
|
||||
| File | Change Type |
|
||||
|------|-------------|
|
||||
| `gsd-db.ts` | Add `getTask`, `getMilestoneById` existence helpers; add `updateTaskStatus`, `updateSliceStatus` |
|
||||
| `workflow-events.ts` | Extend `WorkflowEvent` with `actor_name`, `trigger_reason`, `session_id` |
|
||||
| `workflow-logger.ts` | Add persistent flush to `.gsd/audit-log.jsonl`; add `setLogBasePath`; add `readAuditLog` |
|
||||
| `tools/complete-task.ts` | State machine guards + ownership check + actor passthrough |
|
||||
| `tools/complete-slice.ts` | State machine guards + ownership check + actor passthrough |
|
||||
| `tools/complete-milestone.ts` | State machine guards + deep task check |
|
||||
| `tools/plan-task.ts` | Block re-planning complete tasks |
|
||||
| `tools/plan-slice.ts` | Block re-planning complete slices |
|
||||
| `tools/plan-milestone.ts` | Block re-planning complete milestones + depends_on validation |
|
||||
| `tools/reassess-roadmap.ts` | Verify completedSliceId status + milestone status check |
|
||||
| `tools/replan-slice.ts` | Verify blockerTaskId exists + slice status check |
|
||||
| `tools/reopen-task.ts` | NEW — gsd_task_reopen handler |
|
||||
| `tools/reopen-slice.ts` | NEW — gsd_slice_reopen handler |
|
||||
| `unit-ownership.ts` | NEW — claim/release/check ownership |
|
||||
|
||||
---
|
||||
|
||||
## Execution Order (Dependencies)
|
||||
|
||||
```
|
||||
S1-T1 (DB helpers)
|
||||
└── S1-T2 (complete-task guards)
|
||||
└── S1-T3 (complete-slice guards)
|
||||
└── S1-T4 (complete-milestone guards)
|
||||
└── S1-T5 (plan-task guards)
|
||||
└── S1-T6 (plan-slice guards)
|
||||
└── S1-T7 (plan-milestone guards)
|
||||
└── S1-T8 (reassess-roadmap guards)
|
||||
└── S1-T9 (replan-slice guards)
|
||||
└── S3-T1 (updateTask/SliceStatus helpers) ── S3-T2, S3-T3
|
||||
|
||||
S2-T1 (WorkflowEvent schema)
|
||||
└── S2-T2 (handler actor passthrough)
|
||||
|
||||
S2-T3 (audit-log flush)
|
||||
└── S2-T4 (readAuditLog)
|
||||
|
||||
S3-T4 (unit-ownership.ts)
|
||||
└── S3-T5 (wire into complete-task/slice)
|
||||
```
|
||||
|
||||
Parallelizable:
|
||||
- All of Stream 1 (S1-T2 through S1-T9) can run in parallel once S1-T1 is done
|
||||
- Stream 2 and Stream 3 are fully independent of Stream 1
|
||||
|
||||
---
|
||||
|
||||
## What Success Looks Like
|
||||
|
||||
After this phase:
|
||||
|
||||
1. **Double-complete** → returns `{ error: "Task T01 is already complete" }` instead of silently overwriting
|
||||
2. **Complete slice with open tasks** → still blocked (was already caught), plus slice status guard added
|
||||
3. **Re-plan closed work** → returns `{ error: "Cannot re-plan: slice S01 is already complete" }`
|
||||
4. **Wrong agent completes task** → returns `{ error: "Unit M01/S01/T01 is owned by executor-01, not executor-02" }`
|
||||
5. **Post-mortem** → `.gsd/audit-log.jsonl` has full trace with actor_name + trigger_reason across context resets
|
||||
6. **Oops recovery** → `gsd_task_reopen` / `gsd_slice_reopen` without manual SQL surgery
|
||||
7. **depends_on enforcement** → cannot plan M02 if M01 is not yet complete
|
||||
|
||||
---
|
||||
|
||||
## Decisions
|
||||
|
||||
1. **Ownership: opt-in** — enforced only when `.gsd/unit-claims.json` exists. Zero breaking change for existing workflows; teams adopt incrementally.
|
||||
|
||||
2. **Slice reopen: reset all tasks to `"pending"`** — simpler invariant. If you're reopening a slice, you're re-doing the work. Partial resets create ambiguous state.
|
||||
|
||||
3. **`trigger_reason`: caller-provided** — agents know *why* they acted; the engine can only know *what* was called. Default to `undefined` if not passed.
|
||||
|
||||
4. **Session ID: engine-generated** — UUID generated once at engine startup, stored in module state in `workflow-events.ts`. No reliance on agents setting env vars correctly.
|
||||
|
||||
5. **Idempotency: fix in this phase** — convert `insertAssessment` and `insertReplanHistory` to upserts (keyed on `milestoneId+sliceId` and `milestoneId+sliceId+ts` respectively). Accumulating duplicate records on retry is a bug, not a feature.
|
||||
|
||||
### Additional task from decision 5:
|
||||
#### S1-T10: Convert `insertAssessment` and `insertReplanHistory` to upserts
|
||||
|
||||
**File:** `src/resources/extensions/gsd/gsd-db.ts`
|
||||
|
||||
- `insertAssessment`: upsert keyed on `(milestone_id, completed_slice_id)` — one assessment per completed slice per milestone
|
||||
- `insertReplanHistory`: upsert keyed on `(milestone_id, slice_id, blocker_task_id)` — one replan record per blocker per slice
|
||||
292
CHANGELOG.md
292
CHANGELOG.md
|
|
@ -6,6 +6,287 @@ Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.49.0] - 2026-03-25
|
||||
|
||||
### Added
|
||||
- add --yolo flag to /gsd auto for non-interactive project init
|
||||
|
||||
### Fixed
|
||||
- use full git log in merge tests to match trailer-based milestone IDs
|
||||
- update parallel-merge test assertion for new trailer format
|
||||
- clarify regex alternation in test assertion
|
||||
- verdict gate accepts PARTIAL for mixed/human-experience/live-runtime UATs
|
||||
|
||||
### Changed
|
||||
- move GSD metadata from commit subject scopes to git trailers
|
||||
|
||||
## [2.48.0] - 2026-03-25
|
||||
|
||||
### Added
|
||||
- **discuss**: allow /gsd discuss to target queued milestones
|
||||
- enhance /gsd forensics with journal and activity log awareness
|
||||
|
||||
### Fixed
|
||||
- make journal scanning intelligent — limit parsed files, line-count older ones
|
||||
- **model-registry**: scope custom provider stream handlers to prevent clobbering built-in API handlers
|
||||
- **forensics**: filter benign bash exit-code-1 and user skips from error traces
|
||||
- **gsd**: clear stale milestone ID reservations at session start
|
||||
- render tool calls above text response for external providers
|
||||
- **auto**: skip CONTEXT-DRAFT warning for completed/parked milestones
|
||||
|
||||
### Changed
|
||||
- address review - extract RAPID_ITERATION_THRESHOLD_MS, simplify data access
|
||||
|
||||
### Removed
|
||||
- remove insertChildBefore usage in chat-controller
|
||||
|
||||
## [2.47.0] - 2026-03-25
|
||||
|
||||
### Added
|
||||
- **agent-core**: add externalToolExecution mode for external providers
|
||||
- **provider**: add Claude Code CLI provider extension
|
||||
|
||||
### Fixed
|
||||
- **claude-code-cli**: render tool calls above text response
|
||||
- **ci**: update FILE-SYSTEM-MAP.md path after docs→docs-internal move
|
||||
- isInheritedRepo false negative when parent has stale .gsd; defense-in-depth local .git check in bootstrap
|
||||
- **claude-code-cli**: resolve SDK executable path and update model IDs
|
||||
- make planning doctrine demoable definition audience-appropriate
|
||||
- **prompts**: migrate remaining 4 prompts to use DB-backed tool API instead of direct write
|
||||
- make workflow event hash platform-deterministic
|
||||
- reconcile stale task DB status from disk artifacts (#2514)
|
||||
|
||||
## [2.46.1] - 2026-03-25
|
||||
|
||||
### Fixed
|
||||
- **ci**: prevent windows-portability from blocking pipeline
|
||||
- **ci**: prevent pipeline race condition on release push
|
||||
- **gsd**: create empty DB for fresh projects with empty .gsd/ (#2510)
|
||||
- **remote-questions**: hydrate remote channel tokens from auth.json on startup
|
||||
|
||||
### Changed
|
||||
- trigger CI to pick up pipeline race condition fix
|
||||
- trigger pipeline with race condition fix
|
||||
|
||||
## [2.46.0] - 2026-03-25
|
||||
|
||||
### Added
|
||||
- **gsd**: single-writer engine v3 — state machine guards, actor identity, reversibility
|
||||
- **gsd**: single-writer state engine v2 — discipline layer on DB architecture
|
||||
- **gsd**: add workflow-logger and wire into engine, tool, manifest, reconcile paths (#2494)
|
||||
|
||||
### Fixed
|
||||
- **gsd**: align prompts with single-writer tool API
|
||||
- **gsd**: integration-proof — check DB state not roadmap projection after reset
|
||||
- **gsd**: block milestone completion when verification fails (#2500)
|
||||
- **ci**: add typecheck:extensions to pretest to prevent silent type drift
|
||||
- **gsd**: relax integration-proof cross-validation for table-format roadmap
|
||||
- **gsd**: update integration-proof tests for table-format roadmap projections
|
||||
- **gsd**: update test assertions for schema v11, prompt changes, and removed completedUnits
|
||||
- **gsd**: update test files for removed completedUnits, writeLock signature, and type changes
|
||||
- **gsd**: remove stale completedUnits refs, fix writeLock callers, add missing imports
|
||||
- **gsd**: harden single-writer engine — close TOCTOU, intercept bypasses, status inconsistencies
|
||||
- **write-intercept**: close bare-relative-path bypass in STATE.md regex
|
||||
- **voice**: fix misleading portaudio error on PEP 668 Linux systems (#2403) (#2407)
|
||||
- **core**: address PR review feedback for non-apikey provider support (#2452)
|
||||
- **ci**: retry npm install in pipeline to handle registry propagation delay (#2462)
|
||||
- **gsd**: change default isolation mode from worktree to none (#2481)
|
||||
- **loader**: add startup checks for Node version and git availability (#2463)
|
||||
- **gsd**: add worktree lifecycle events to journal (#2486)
|
||||
|
||||
## [2.45.0] - 2026-03-25
|
||||
|
||||
### Added
|
||||
- **web**: make web UI mobile responsive (#2354)
|
||||
- **gsd**: add `/gsd rethink` command for conversational project reorganization (#2459)
|
||||
- **gsd**: add renderCall/renderResult previews to DB tools (#2273)
|
||||
- add timestamps on user and assistant messages (#2368)
|
||||
- **gsd**: add `/gsd mcp` command for MCP server status and connectivity (#2362)
|
||||
- complete offline mode support (#2429)
|
||||
- **system-context**: inject global ~/.gsd/agent/KNOWLEDGE.md into system prompt (#2331)
|
||||
|
||||
### Fixed
|
||||
- **gsd**: handle retentionDays=0 on Windows + run windows-portability on PRs (#2460)
|
||||
- use Array.from instead of Buffer.from for native processStreamChunk state (#2348)
|
||||
- **gsd**: isInheritedRepo conflates ~/.gsd with project .gsd when git root is $HOME (#2398)
|
||||
- reconcile disk milestones missing from DB in deriveStateFromDb (#2416) (#2422)
|
||||
- **auto**: reset recoveryAttempts on unit re-dispatch (#2322) (#2424)
|
||||
- detect and preserve submodule state during worktree teardown (#2337) (#2425)
|
||||
- **auto-start**: handle survivor branch recovery in phase=complete (#2358) (#2427)
|
||||
- **gsd**: widen test search window for CRLF portability on Windows (#2458)
|
||||
- **gsd**: preserve rich task plans on DB roundtrip (#2450) (#2453)
|
||||
- merge worktree back to main when stopAuto is called after milestone completion (#2317) (#2430)
|
||||
- **gsd**: skip doctor directory checks for pending slices (#2446)
|
||||
- **gsd**: migrate completion/validation prompts to DB-backed tools (#2449)
|
||||
- **gsd**: prevent saveArtifactToDb from overwriting larger files with truncated content (#2442) (#2447)
|
||||
- stop auto loop on real code merge conflicts (#2330) (#2428)
|
||||
- classify terminated/connection errors as transient in provider error handler (#2309) (#2432)
|
||||
- archive completed-units.json on milestone transition and sync metrics.json (#2313) (#2431)
|
||||
- supervision timeouts now respect task est: annotations (#2243) (#2434)
|
||||
- auto_pr: true now actually creates PRs — fix 3 interacting bugs (#2302) (#2433)
|
||||
- **gsd**: insert DB row when generating milestone ID (#2416)
|
||||
- **gsd**: reconcile disk-only milestones into DB in deriveStateFromDb (#2416)
|
||||
- **preferences**: deduplicate unrecognized format warning on repeated loads (#2375)
|
||||
- gate auto-mode bootstrap on SQLite availability (#2419) (#2421)
|
||||
- block /gsd quick when auto-mode is active (#2420)
|
||||
- **ci**: add Rust target for all platforms, not just cross-compilation
|
||||
- **ci**: restore Rust target triple and separate cross-compilation setup
|
||||
- **ci**: separate cross-compilation target from toolchain install
|
||||
|
||||
### Changed
|
||||
- migrate D-G test files from createTestContext to node:test (#2418)
|
||||
- **test**: replace try/finally with beforeEach/afterEach in packages tests (#2390)
|
||||
- **test**: migrate gsd/tests s-z from custom harness to node:test (#2397)
|
||||
- **test**: migrate gsd/tests o-r from custom harness to node:test (#2401)
|
||||
- **test**: migrate gsd/tests i-n from custom harness to node:test (#2399)
|
||||
- **test**: migrate gsd/tests a-c from custom harness to node:test (#2400)
|
||||
- **test**: replace try/finally with t.after() in gsd/tests (e-i) (#2396)
|
||||
- **test**: replace try/finally with t.after() in gsd/tests (a-d) (#2395)
|
||||
- **test**: replace try/finally with t.after() in src/tests (o-z) (#2392)
|
||||
- **test**: replace try/finally with t.after() in src/tests (a-n) (#2394)
|
||||
|
||||
## [2.44.0] - 2026-03-24
|
||||
|
||||
### Added
|
||||
- **core**: support for 'non-api-key' provider extensions like Claude Code CLI (#2382)
|
||||
- **docker**: add official Docker sandbox template for isolated GSD auto mode (#2360)
|
||||
- **gsd**: show per-prompt token cost in footer behind show_token_cost preference (#2357)
|
||||
- **web**: add "Change project root" button to web UI (#2355)
|
||||
- **gsd**: Tool-driven write-side state transitions — replace markdown mutation with atomic SQLite tool calls (#2141)
|
||||
- **S06/T02**: Strip all 16 lazy createRequire fallback paths from migr…
|
||||
- **S05/T04**: Migrate remaining 6 callers (auto-prompts, auto-recovery…
|
||||
- **S05/T03**: Migrate 7 warm/cold callers (doctor, doctor-checks, visu…
|
||||
- **S05/T02**: Extend migrateHierarchyToDb to populate v8 planning colu…
|
||||
- **S05/T01**: Schema v10 adds replan_triggered_at column; deriveStateF…
|
||||
- **S04/T03**: Migrate auto-dispatch.ts (3 rules), auto-verification.ts…
|
||||
- **S04/T02**: Migrate dispatch-guard.ts to DB queries with isDbAvailab…
|
||||
- **S01/T03**: Migrate planning prompts to DB-backed tool guidance and…
|
||||
- **S01/T01**: Partially advanced schema v8 groundwork and documented t…
|
||||
- **gsd**: tool-driven write-side state transitions (M001)
|
||||
|
||||
### Fixed
|
||||
- post-migration cleanup — pragmas, rollbacks, tool gaps, stale code (#2410)
|
||||
- **test**: normalize CRLF in auto-stash-merge assertion for Windows
|
||||
- **test**: swallow EPERM on Windows temp dir cleanup in auto-stash-merge test
|
||||
- **gsd**: add file-based fallbacks for DB-dependent code paths and fix CI test failures
|
||||
- **gsd**: remove stale observabilityIssues reference in journal-integration test
|
||||
- **extensions**: detect TypeScript syntax in .js extension files and suggest renaming to .ts (#2386)
|
||||
- **gsd**: prevent planning data loss from destructive upsert and post-unit re-import (#2370)
|
||||
- **gsd**: use correct notify severity type ("warning" not "warn")
|
||||
- **web**: resolve compiled .js modules for all subprocess calls under node_modules (#2320)
|
||||
- **test**: increase perf assertion threshold to prevent CI flake (#2327)
|
||||
- add missing SQLite WAL sidecars and journal to runtime exclusion lists (#2299)
|
||||
- **gsd**: remove stale observability validator + fix greenfield worktree check
|
||||
- **memory**: fix memory and resource leaks across TUI, LSP, DB, and automation (#2314)
|
||||
- **gsd**: preserve freeform DECISIONS.md content on decision save (#2319)
|
||||
- **pi-ai**: restore alibaba-coding-plan provider via models.custom.ts (#2350)
|
||||
- **doctor**: skip false env_dependencies error in auto-worktrees (#2318)
|
||||
- **gsd**: auto-stash dirty files before squash merge and surface dirty filenames in error (#2298)
|
||||
- **gsd**: keep params as any in db-tools executors (CI tsconfig is stricter)
|
||||
- **gsd**: replace any types in db-tools executor signatures
|
||||
- **gsd**: resolve 4 TS compilation errors from parser migration
|
||||
- **gsd**: wrap plan-task DB writes in transaction + untrack .gsd/ artifacts
|
||||
- **S04/T04**: Add planning-crossval tests proving DB↔rendered↔parsed pa…
|
||||
- **S04/T01**: Add schema v9 migration with sequence column on slices/ta…
|
||||
- remove .gsd/ milestone artifacts from git index
|
||||
- **tests**: update remediation step assertions and crossval fixture
|
||||
- **gsd**: address all 7 review findings from PR #2141
|
||||
- **tests**: remove invalid `seq` property from insertMilestone calls
|
||||
|
||||
### Changed
|
||||
- **contrib**: add CODEOWNERS and team workflow docs (#2286)
|
||||
- **M001**: auto-commit after complete-milestone
|
||||
- **M001**: auto-commit after validate-milestone
|
||||
- **M001/S06**: auto-commit after complete-slice
|
||||
- **M001/S06**: auto-commit after plan-slice
|
||||
- **M001/S06**: auto-commit after research-slice
|
||||
- **M001/S05**: auto-commit after complete-slice
|
||||
- **M001/S05**: auto-commit after plan-slice
|
||||
- **M001/S05**: auto-commit after research-slice
|
||||
- **M001/S04**: auto-commit after complete-slice
|
||||
- **M001/S04**: auto-commit after research-slice
|
||||
- **M001/S03**: auto-commit after complete-slice
|
||||
- **M001/S03**: auto-commit after plan-slice
|
||||
- **M001/S03**: auto-commit after research-slice
|
||||
- **M001/S02**: auto-commit after complete-slice
|
||||
- **M001/S02**: auto-commit after plan-slice
|
||||
- **M001/S02**: auto-commit after research-slice
|
||||
- **M001/S01**: auto-commit after complete-slice
|
||||
|
||||
## [2.43.0] - 2026-03-23
|
||||
|
||||
### Added
|
||||
- **forensics**: opt-in duplicate detection before issue creation (#2105)
|
||||
|
||||
### Fixed
|
||||
- prevent banner from printing twice on first run (#2251)
|
||||
- **test**: Windows CI — use double quotes in git commit message (#2252)
|
||||
- **async-jobs**: suppress duplicate follow-up for awaited job results (#2248) (#2250)
|
||||
- **gsd**: remove force-staging of .gsd/milestones/ through symlinks (#2247) (#2249)
|
||||
- **gsd**: remove over-broad skill activation heuristic (#2239) (#2244)
|
||||
- **auth**: fall through to env/fallback when OAuth credential has no registered provider (#2097)
|
||||
- **lsp**: bound message buffer and clean up stale client state (#2171)
|
||||
- clean up macOS numbered .gsd collision variants (#2205) (#2210)
|
||||
- **search**: keep duplicate-search loop guard armed (#2117)
|
||||
- clean up extension error listener on session dispose (#2165)
|
||||
- **web**: resolve 4 pre-existing onboarding contract test failures (#2209)
|
||||
- async bash job timeout hangs indefinitely instead of erroring out (#2214)
|
||||
- **gsd**: apply fast service tier outside auto-mode (#2126)
|
||||
- **interactive**: clean up leaked SIGINT and extension selector listeners (#2172)
|
||||
- **ci**: standardize GitHub Actions and Node.js versions (#2169)
|
||||
- **native**: resolve memory leaks in glob, ttsr, and image overflow (#2170)
|
||||
- extension resource management — prune stale dirs, fix isBuiltIn, gate skills on Skill tool, suppress search warnings (#2235)
|
||||
- batch isolated fixes — error messages, preferences, web auth, MCP vars, detection, gitignore (#2232)
|
||||
- document iTerm2 Ctrl+Alt+G keybinding conflict and add helpful hint (#2231)
|
||||
- **footer**: display active inference model during execution (#1982)
|
||||
- **web**: kill stale server process before launch to prevent EADDRINUSE (#1934) (#2034)
|
||||
- **git**: force LC_ALL=C in GIT_NO_PROMPT_ENV to support non-English locales (#2035)
|
||||
- **forensics**: force gh CLI for issue creation to prevent misrouting (#2067) (#2094)
|
||||
- force-stage .gsd/milestones/ artifacts when .gsd is a symlink (#2104) (#2112)
|
||||
- **pi-ai**: correct Copilot context window and output token limits (#2118)
|
||||
|
||||
### Changed
|
||||
- startup optimizations — pre-compiled extensions, compile cache, batch discovery (#2125)
|
||||
|
||||
## [2.42.0] - 2026-03-22
|
||||
|
||||
### Added
|
||||
- **gsd**: declarative workflow engine — YAML-defined workflows through the auto-loop (#2024)
|
||||
- **gsd**: unified rule registry, event journal, journal query tool, and tool naming convention (#1928)
|
||||
- **ci**: PR risk checker — classify changed files by system and surface risk level (#1930)
|
||||
- ADR attribution — distinguish human vs agent vs collaborative decisions (#1830)
|
||||
- add /gsd fast command and gate service tier icon to supported models (#1848) (#1862)
|
||||
- add --host, --port, --allowed-origins flags for web mode (#1847) (#1873)
|
||||
|
||||
### Fixed
|
||||
- **tests**: wrap rmSync cleanup in try/catch for Windows EPERM
|
||||
- **tests**: add maxRetries to rmSync cleanup for Windows EPERM compatibility
|
||||
- recursive key sorting in tool-call loop guard hash function (#1962)
|
||||
- use path.sep for cross-platform path traversal guards and test assertions
|
||||
- **tests**: use cross-platform path split in run-manager timestamp test
|
||||
- prevent SIGTSTP crash on Windows (#2018)
|
||||
- add missing codeFilesChanged to journal integration test mock
|
||||
- **repo-identity**: use native realpath on Windows to resolve 8.3 short paths (#1960)
|
||||
- **doctor**: gate roadmap checkbox on summary existing on disk, not issue detection (#1915)
|
||||
- warn when milestone merge contains only metadata and no code (#1906) (#1927)
|
||||
- **worktree**: resolve 8.3 short paths and use shell mode for .bat hooks on Windows (#1956)
|
||||
- **web**: persist auth token in sessionStorage to survive page refreshes (#1877)
|
||||
- clean up SQUASH_MSG after squash-merge and guard worktree teardown against uncommitted changes (#1868)
|
||||
- populate RecoveryContext in hook unit supervision to prevent crash on stalled tool recovery (#1867)
|
||||
- resolve worktree path from git registry when .gsd/ symlink is shadowed (#1866)
|
||||
- resolve Node v24 web boot failure — ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING (#1864)
|
||||
- **auto**: broaden worktree health check to all ecosystems (#1860)
|
||||
- **doctor**: cascade slice uncheck when task_done_missing_summary unchecks tasks (#1850) (#1858)
|
||||
- defend exit path against ESM module cache mismatch (#1854)
|
||||
- escape parentheses in paths before bash shell-out, fix __extensionDir fallback (#1872)
|
||||
- use PowerShell Start-Process for Windows browser launch, prevent URL wrapping (#1870)
|
||||
- clear stale unit state and restore CWD when step-wizard exits auto-loop (#1869)
|
||||
- prevent cross-project state leak in brand-new directories (#1639) (#1861)
|
||||
- reconcile worktree HEAD with milestone branch ref before squash merge (#1846) (#1859)
|
||||
- normalize Windows backslash paths in bash command strings (#1436) (#1863)
|
||||
- parsePlan and verifyExpectedArtifact recognize heading-style task entries (#1691) (#1857)
|
||||
- sync all milestone dirs regardless of naming convention (#1547) (#1845)
|
||||
|
||||
## [2.41.0] - 2026-03-21
|
||||
|
||||
### Added
|
||||
|
|
@ -1598,7 +1879,16 @@ Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|||
### Changed
|
||||
- License updated to MIT
|
||||
|
||||
[Unreleased]: https://github.com/gsd-build/gsd-2/compare/v2.41.0...HEAD
|
||||
[Unreleased]: https://github.com/gsd-build/gsd-2/compare/v2.49.0...HEAD
|
||||
[2.49.0]: https://github.com/gsd-build/gsd-2/compare/v2.48.0...v2.49.0
|
||||
[2.48.0]: https://github.com/gsd-build/gsd-2/compare/v2.47.0...v2.48.0
|
||||
[2.47.0]: https://github.com/gsd-build/gsd-2/compare/v2.46.1...v2.47.0
|
||||
[2.46.1]: https://github.com/gsd-build/gsd-2/compare/v2.46.0...v2.46.1
|
||||
[2.46.0]: https://github.com/gsd-build/gsd-2/compare/v2.45.0...v2.46.0
|
||||
[2.45.0]: https://github.com/gsd-build/gsd-2/compare/v2.44.0...v2.45.0
|
||||
[2.44.0]: https://github.com/gsd-build/gsd-2/compare/v2.43.0...v2.44.0
|
||||
[2.43.0]: https://github.com/gsd-build/gsd-2/compare/v2.42.0...v2.43.0
|
||||
[2.42.0]: https://github.com/gsd-build/gsd-2/compare/v2.41.0...v2.42.0
|
||||
[2.41.0]: https://github.com/gsd-build/gsd-2/compare/v2.40.0...v2.41.0
|
||||
[2.40.0]: https://github.com/gsd-build/gsd-2/compare/v2.39.0...v2.40.0
|
||||
[2.39.0]: https://github.com/gsd-build/gsd-2/compare/v2.38.0...v2.39.0
|
||||
|
|
|
|||
162
CONTRIBUTING.md
162
CONTRIBUTING.md
|
|
@ -11,6 +11,59 @@ Read [VISION.md](VISION.md) before contributing. It defines what GSD-2 is, what
|
|||
3. **No issue? Create one first** for new features. Bug fixes for obvious problems can skip this step.
|
||||
4. **Architectural changes require an RFC.** If your change touches core systems (auto-mode, agent-core, orchestration), open an issue describing your approach and get approval before writing code. We use Architecture Decision Records (ADRs) for significant decisions.
|
||||
|
||||
## Branching and commits
|
||||
|
||||
Always work on a dedicated branch. Never push directly to `main`.
|
||||
|
||||
**Branch naming:** `<type>/<short-description>`
|
||||
|
||||
| Type | When to use |
|
||||
|------|-------------|
|
||||
| `feat/` | New functionality |
|
||||
| `fix/` | Bug or defect correction |
|
||||
| `refactor/` | Code restructuring, no behavior change |
|
||||
| `test/` | Adding or updating tests |
|
||||
| `docs/` | Documentation only |
|
||||
| `chore/` | Dependencies, tooling, housekeeping |
|
||||
| `ci/` | CI/CD configuration |
|
||||
|
||||
**Commit messages** must follow [Conventional Commits](https://www.conventionalcommits.org/). The commit-msg hook enforces this locally; CI enforces it on push.
|
||||
|
||||
```
|
||||
<type>(<scope>): <short summary>
|
||||
```
|
||||
|
||||
Valid types: `feat` `fix` `docs` `chore` `refactor` `test` `infra` `ci` `perf` `build` `revert`
|
||||
|
||||
```
|
||||
feat(pi-agent-core): add streaming output for long-running tasks
|
||||
fix(pi-ai): resolve null pointer on empty provider response
|
||||
chore(deps): bump typescript from 5.3.0 to 5.4.2
|
||||
```
|
||||
|
||||
Keep branches current by rebasing onto `main` — do not merge `main` into your feature branch:
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git rebase origin/main
|
||||
```
|
||||
|
||||
## Working with GSD (team workflow)
|
||||
|
||||
GSD uses worktree-based isolation for multi-developer work. If you're contributing with GSD running, enable team mode in your project preferences:
|
||||
|
||||
```yaml
|
||||
# .gsd/preferences.md
|
||||
---
|
||||
version: 1
|
||||
mode: team
|
||||
---
|
||||
```
|
||||
|
||||
This enables unique milestone IDs, branch pushing, and pre-merge checks — preventing milestone ID collisions when multiple contributors run auto-mode simultaneously. Each developer gets their own isolated worktree; squash merges to `main` happen independently.
|
||||
|
||||
For full details see [docs/working-in-teams.md](docs/working-in-teams.md) and [docs/git-strategy.md](docs/git-strategy.md).
|
||||
|
||||
## Opening a pull request
|
||||
|
||||
### PR description format
|
||||
|
|
@ -65,10 +118,12 @@ If your PR changes any public API, CLI behavior, config format, or file structur
|
|||
|
||||
AI-generated PRs are first-class citizens here. We welcome them. We just ask for transparency:
|
||||
|
||||
- **Disclose it.** Note that the PR is AI-assisted in your description.
|
||||
- **Disclose it.** Note that the PR is AI-assisted in your description. Do not credit the AI tool as an author or co-author in the commit or PR.
|
||||
- **Test it.** AI-generated code must be tested to the same standard as human-written code. "The AI said it works" is not a test plan.
|
||||
- **Understand it.** You should be able to explain what the code does and why. If a reviewer asks a question, "I'll ask the AI" is not an answer.
|
||||
|
||||
AI agents opening PRs must follow the same workflow as human contributors: clean working tree, new branch per task, CI passing before requesting review. Multi-phase work should start as a Draft PR and only move to Ready when complete.
|
||||
|
||||
AI PRs go through the same review process as any other PR. No special treatment in either direction.
|
||||
|
||||
## Architecture guidelines
|
||||
|
|
@ -103,12 +158,113 @@ PRs go through automated review first, then human review. To help us review effi
|
|||
- Respond to review comments. If you disagree, explain why — discussion is welcome.
|
||||
- If your PR has been open for a while without review, ping in Discord. We're a small team and things slip.
|
||||
|
||||
### What reviewers verify
|
||||
|
||||
Reading a diff is not the same as verifying a change. Our review standard is execution-based, not static-analysis-based.
|
||||
|
||||
**What reviewers do:**
|
||||
|
||||
1. **Check out the branch** — check out the PR branch locally (or in a worktree). Don't review from the diff view alone.
|
||||
2. **Build the branch** — run `npm run build`. A diff that doesn't compile is not reviewable.
|
||||
3. **Run the test suite** — run `npm test`. CI status is a signal, not a substitute for local verification.
|
||||
4. **Trace root cause for bug fixes** — confirm the diff addresses the root cause described in the issue, not just the symptom.
|
||||
5. **Check for a regression test** — bug fixes must include a test that would have caught the original bug. If it's absent, the fix is incomplete.
|
||||
|
||||
Only after completing these steps should a reviewer make claims about correctness.
|
||||
|
||||
**What "looks right" means:**
|
||||
|
||||
"Looks right" is the starting point for review, not the conclusion. "The tests pass" only means the tests pass — not that the claimed bug is fixed or the feature works as described. A well-written commit message on a broken change is still a broken change.
|
||||
|
||||
### What contributors must provide to unblock review
|
||||
|
||||
- **Bug fixes** — include a regression test. A fix without a test is an assertion, not a proof.
|
||||
- **Features** — include tests covering the primary success path and at least one failure path.
|
||||
- **Behavior changes** — update or replace any existing tests that cover the changed behavior. Don't leave passing-but-wrong tests in place.
|
||||
|
||||
If your PR claims to fix issue #N, reviewers will verify the fix addresses the root cause described in #N — not just that CI is green.
|
||||
|
||||
## Testing standards
|
||||
|
||||
This project uses Node.js built-in `node:test` as the test runner. All new tests must follow these patterns:
|
||||
|
||||
### Use `node:test` and `node:assert/strict`
|
||||
|
||||
```typescript
|
||||
import { describe, test, beforeEach, afterEach } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
```
|
||||
|
||||
Do not use `createTestContext()` from `test-helpers.ts` (legacy, being removed). Do not introduce Jest, Vitest, or other test frameworks.
|
||||
|
||||
### Use `beforeEach`/`afterEach` or `t.after()` for cleanup — never `try`/`finally`
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT — shared fixture with beforeEach/afterEach
|
||||
describe("feature", () => {
|
||||
let tmp: string;
|
||||
beforeEach(() => { tmp = mkdtempSync(join(tmpdir(), "test-")); });
|
||||
afterEach(() => { rmSync(tmp, { recursive: true, force: true }); });
|
||||
|
||||
test("case", () => { /* clean test body */ });
|
||||
});
|
||||
|
||||
// ✅ CORRECT — per-test cleanup with t.after()
|
||||
test("case", (t) => {
|
||||
const tmp = mkdtempSync(join(tmpdir(), "test-"));
|
||||
t.after(() => { rmSync(tmp, { recursive: true, force: true }); });
|
||||
// test body
|
||||
});
|
||||
|
||||
// ❌ WRONG — inline try/finally
|
||||
test("case", () => {
|
||||
const tmp = mkdtempSync(join(tmpdir(), "test-"));
|
||||
try {
|
||||
// test body
|
||||
} finally {
|
||||
rmSync(tmp, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**When to use which:**
|
||||
- `beforeEach`/`afterEach` — when all tests in a `describe` block share the same setup/teardown pattern
|
||||
- `t.after()` — when each test has unique cleanup (different fixtures, env vars, etc.)
|
||||
- `try`/`finally` — only inside standalone helper functions that don't have access to the test context `t` (e.g., `withEnv()`, `capture()`)
|
||||
|
||||
### Template literal fixture data
|
||||
|
||||
When constructing multi-line fixture content (markdown, YAML, etc.) inside indented test blocks, use array join to avoid unintended leading whitespace:
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT — no indentation leakage
|
||||
const content = [
|
||||
"## Slices",
|
||||
"- [x] **S01: First slice**",
|
||||
"- [ ] **S02: Second slice**",
|
||||
].join("\n");
|
||||
|
||||
// ❌ WRONG — template literal inside describe/test adds leading spaces
|
||||
const content = `
|
||||
## Slices
|
||||
- [x] **S01: First slice**
|
||||
`;
|
||||
// Each line now has 2 leading spaces, breaking ^## regex anchors
|
||||
```
|
||||
|
||||
### Test-first for bug fixes
|
||||
|
||||
Bug fixes must include a regression test that fails before the fix and passes after. Write the test first, confirm it fails, then apply the fix. See the `test-first-bugfix` skill.
|
||||
|
||||
## Local development
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm ci
|
||||
|
||||
# Install git hooks (secret scanning + commit message validation)
|
||||
npm run secret-scan:install-hook
|
||||
|
||||
# Build
|
||||
npm run build
|
||||
|
||||
|
|
@ -119,6 +275,10 @@ npm test
|
|||
npx tsc --noEmit
|
||||
```
|
||||
|
||||
Run `npm run secret-scan:install-hook` once after cloning. It installs two hooks:
|
||||
- **pre-commit** — blocks commits containing hardcoded secrets or credentials
|
||||
- **commit-msg** — validates Conventional Commits format before the commit lands
|
||||
|
||||
CI must pass before your PR will be reviewed. Run these locally to save time.
|
||||
|
||||
## Security
|
||||
|
|
|
|||
67
README.md
67
README.md
|
|
@ -9,6 +9,7 @@
|
|||
[](https://github.com/gsd-build/GSD-2)
|
||||
[](https://discord.gg/gsd)
|
||||
[](LICENSE)
|
||||
[](https://dexscreener.com/solana/dwudwjvan7bzkw9zwlbyv6kspdlvhwzrqy6ebk8xzxkv)
|
||||
|
||||
The original GSD went viral as a prompt framework for Claude Code. It worked, but it was fighting the tool — injecting prompts through slash commands, hoping the LLM would follow instructions, with no actual control over context windows, sessions, or execution.
|
||||
|
||||
|
|
@ -24,6 +25,58 @@ One command. Walk away. Come back to a built project with clean git history.
|
|||
|
||||
---
|
||||
|
||||
## What's New in v2.46.0
|
||||
|
||||
### Single-Writer State Engine
|
||||
|
||||
The biggest architectural change since DB-backed planning tools. The single-writer engine enforces disciplined state transitions through three iterations:
|
||||
|
||||
- **v2 — discipline layer** — adds a write-side discipline layer on top of the DB architecture, ensuring all state mutations flow through controlled tool calls.
|
||||
- **v3 — state machine guards, actor identity, reversibility** — introduces formal state machine guards, tracks which actor (human vs agent) initiated each transition, and makes transitions reversible.
|
||||
- **Hardened** — closes TOCTOU race conditions, intercepts bypass attempts, and resolves status inconsistencies.
|
||||
|
||||
All prompts are now aligned with the single-writer tool API, and a new **workflow-logger** is wired into the engine, tool, manifest, and reconcile paths for full observability. (#2494)
|
||||
|
||||
### v2.45.0 — New Commands and Capabilities
|
||||
|
||||
- **`/gsd rethink`** — conversational project reorganization. Rethink your milestone structure, slice decomposition, or overall approach through guided discussion. (#2459)
|
||||
- **`/gsd mcp`** — MCP server status and connectivity. Check which MCP servers are configured, connected, and healthy. (#2362)
|
||||
- **Complete offline mode** — GSD now works fully offline with local models. (#2429)
|
||||
- **Global KNOWLEDGE.md injection** — `~/.gsd/agent/KNOWLEDGE.md` is injected into the system prompt, so cross-project knowledge persists globally. (#2331)
|
||||
- **Mobile-responsive web UI** — the browser interface now works on phones and tablets. (#2354)
|
||||
- **DB tool previews** — `renderCall`/`renderResult` previews on DB tools show what each tool call does before and after execution. (#2273)
|
||||
- **Message timestamps** — user and assistant messages now include timestamps. (#2368)
|
||||
|
||||
### Key Changes
|
||||
|
||||
- **Default isolation mode changed to `none`** — `git.isolation` now defaults to `none` instead of `worktree`. Projects that rely on worktree isolation should set `git.isolation: worktree` explicitly in preferences. (#2481)
|
||||
- **Startup checks** — GSD now validates Node.js version and git availability at startup, with clear error messages. (#2463)
|
||||
- **Worktree lifecycle journaling** — worktree create, switch, merge, and remove events are recorded in the event journal. (#2486)
|
||||
- **Milestone verification gate** — milestone completion is blocked when verification fails, preventing premature closure. (#2500)
|
||||
|
||||
### Key Fixes
|
||||
|
||||
- **Auto-mode stability** — recovery attempts reset on unit re-dispatch (#2424), survivor branch recovery handles `phase=complete` (#2427), and auto mode stops on real merge conflicts (#2428).
|
||||
- **Supervision timeouts** — now respect task `est:` annotations, so complex tasks get proportionally longer timeouts. (#2434)
|
||||
- **`auto_pr: true` fixed** — three interacting bugs prevented auto-PR creation; all three are resolved. (#2433)
|
||||
- **Rich task plan preservation** — plans survive DB roundtrip without losing structured content. (#2453)
|
||||
- **Artifact truncation prevention** — `saveArtifactToDb` no longer overwrites larger files with truncated content. (#2447)
|
||||
- **Worktree teardown** — submodule state is detected and preserved during teardown (#2425), and worktree merge back to main works after `stopAuto` on milestone completion (#2430).
|
||||
- **Windows portability** — `retentionDays=0` handling and CRLF fixes on Windows. (#2460)
|
||||
- **Voice on Linux** — misleading portaudio error on PEP 668 systems replaced with actionable guidance. (#2407)
|
||||
|
||||
### Previous highlights (v2.42–v2.44)
|
||||
|
||||
- **Non-API-key provider extensions** — support for Claude Code CLI and similar providers. (#2382)
|
||||
- **Docker sandbox template** — official Docker template for isolated auto mode. (#2360)
|
||||
- **DB-backed planning tools** — write-side state transitions use atomic SQLite tool calls. (#2141)
|
||||
- **Declarative workflow engine** — YAML workflows through auto-loop. (#2024)
|
||||
- **`/gsd fast`** — toggle service tier for prioritized API routing. (#1862)
|
||||
- **Forensics dedup** — duplicate detection before issue creation. (#2105)
|
||||
- **Startup optimizations** — pre-compiled extensions, compile cache, batch discovery. (#2125)
|
||||
|
||||
---
|
||||
|
||||
## What's New in v2.41.0
|
||||
|
||||
### New Features
|
||||
|
|
@ -84,12 +137,14 @@ This release includes 7 fixes preventing silent data loss in auto-mode:
|
|||
|
||||
See the full [Changelog](./CHANGELOG.md) for all 70+ fixes in this release.
|
||||
|
||||
### Previous highlights (v2.39–v2.40)
|
||||
### Previous highlights (v2.39–v2.41)
|
||||
|
||||
- **Browser-based web interface** — run GSD from the browser with `gsd --web`
|
||||
- **GitHub sync extension** — auto-sync milestones to GitHub Issues, PRs, and Milestones
|
||||
- **Skill tool resolution** — skills auto-activate in dispatched prompts
|
||||
- **Health check phase 2** — real-time doctor issues in dashboard and visualizer
|
||||
- **Forensics upgrade** — full-access GSD debugger with anomaly detection
|
||||
- **7 data-loss prevention fixes** — hallucination guard, merge anchor verification, dirty tree detection, and more
|
||||
- **Pipeline decomposition** — auto-loop rewritten as linear phase pipeline
|
||||
- **Sliding-window stuck detection** — pattern-aware, fewer false positives
|
||||
- **Data-loss recovery** — automatic detection and recovery from v2.30–v2.38 migration issues
|
||||
|
|
@ -98,7 +153,7 @@ See the full [Changelog](./CHANGELOG.md) for all 70+ fixes in this release.
|
|||
|
||||
## Documentation
|
||||
|
||||
Full documentation is available in the [`docs/`](./docs/) directory:
|
||||
Full documentation is available at **[gsd.build](https://gsd.build)** (powered by Mintlify) and in the [`docs/`](./docs/) directory:
|
||||
|
||||
- **[Getting Started](./docs/getting-started.md)** — install, first run, basic usage
|
||||
- **[Auto Mode](./docs/auto-mode.md)** — autonomous execution deep-dive
|
||||
|
|
@ -118,7 +173,9 @@ Full documentation is available in the [`docs/`](./docs/) directory:
|
|||
- **[Visualizer](./docs/visualizer.md)** — workflow visualizer with stats and discussion status
|
||||
- **[Remote Questions](./docs/remote-questions.md)** — route decisions to Slack or Discord when human input is needed
|
||||
- **[Dynamic Model Routing](./docs/dynamic-model-routing.md)** — complexity-based model selection and budget pressure
|
||||
- **[Web Interface](./docs/web-interface.md)** — browser-based project management and real-time progress
|
||||
- **[Pipeline Simplification (ADR-003)](./docs/ADR-003-pipeline-simplification.md)** — merged research into planning, mechanical completion
|
||||
- **[Docker Sandbox](./docker/README.md)** — run GSD auto mode in an isolated Docker container
|
||||
- **[Migration from v1](./docs/migration.md)** — `.planning` → `.gsd` migration
|
||||
|
||||
---
|
||||
|
|
@ -218,7 +275,7 @@ Auto mode is a state machine driven by files on disk. It reads `.gsd/STATE.md`,
|
|||
|
||||
2. **Context pre-loading** — The dispatch prompt includes inlined task plans, slice plans, prior task summaries, dependency summaries, roadmap excerpts, and decisions register. The LLM starts with everything it needs instead of spending tool calls reading files.
|
||||
|
||||
3. **Git worktree isolation** — Each milestone runs in its own git worktree with a `milestone/<MID>` branch. All slice work commits sequentially — no branch switching, no merge conflicts. When the milestone completes, it's squash-merged to main as one clean commit.
|
||||
3. **Git isolation** — When `git.isolation` is set to `worktree` or `branch`, each milestone runs on its own `milestone/<MID>` branch (in a worktree or in-place). All slice work commits sequentially — no branch switching, no merge conflicts. When the milestone completes, it's squash-merged to main as one clean commit. The default is `none` (work on the current branch), configurable via preferences.
|
||||
|
||||
4. **Crash recovery** — A lock file tracks the current unit. If the session dies, the next `/gsd auto` reads the surviving session file, synthesizes a recovery briefing from every tool call that made it to disk, and resumes with full context. Parallel orchestrator state is persisted to disk with PID liveness detection, so multi-worker sessions survive crashes too. In headless mode, crashes trigger automatic restart with exponential backoff (default 3 attempts).
|
||||
|
||||
|
|
@ -354,6 +411,8 @@ On first run, GSD launches a branded setup wizard that walks you through LLM pro
|
|||
| `/gsd stop` | Stop auto mode gracefully |
|
||||
| `/gsd steer` | Hard-steer plan documents during execution |
|
||||
| `/gsd discuss` | Discuss architecture and decisions (works alongside auto mode) |
|
||||
| `/gsd rethink` | Conversational project reorganization |
|
||||
| `/gsd mcp` | MCP server status and connectivity |
|
||||
| `/gsd status` | Progress dashboard |
|
||||
| `/gsd queue` | Queue future milestones (safe during auto mode) |
|
||||
| `/gsd prefs` | Model selection, timeouts, budget ceiling |
|
||||
|
|
@ -501,7 +560,7 @@ auto_report: true
|
|||
| `skill_rules` | Situational rules for skill routing |
|
||||
| `skill_staleness_days` | Skills unused for N days get deprioritized (default: 60, 0 = disabled) |
|
||||
| `unique_milestone_ids` | Uses unique milestone names to avoid clashes when working in teams of people |
|
||||
| `git.isolation` | `worktree` (default), `branch`, or `none` — disable worktree isolation for projects that don't need it |
|
||||
| `git.isolation` | `none` (default), `worktree`, or `branch` — enable worktree or branch isolation for milestone work |
|
||||
| `git.manage_gitignore` | Set `false` to prevent GSD from modifying `.gitignore` |
|
||||
| `verification_commands`| Array of shell commands to run after task execution (e.g., `["npm run lint", "npm run test"]`) |
|
||||
| `verification_auto_fix`| Auto-retry on verification failures (default: true) |
|
||||
|
|
|
|||
38
docker/.env.example
Normal file
38
docker/.env.example
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# ──────────────────────────────────────────────
|
||||
# GSD Docker Sandbox — Environment Variables
|
||||
# Copy this file to .env and fill in your keys.
|
||||
# ──────────────────────────────────────────────
|
||||
|
||||
# ── LLM Provider API Keys (at least one required) ──
|
||||
|
||||
# Anthropic (Claude)
|
||||
# ANTHROPIC_API_KEY=sk-ant-...
|
||||
|
||||
# OpenAI
|
||||
# OPENAI_API_KEY=sk-...
|
||||
|
||||
# Google (Gemini)
|
||||
# GOOGLE_API_KEY=...
|
||||
|
||||
# OpenRouter (multi-provider gateway)
|
||||
# OPENROUTER_API_KEY=sk-or-...
|
||||
|
||||
# ── Optional: Research & Search Tools ──
|
||||
|
||||
# Brave Search API
|
||||
# BRAVE_API_KEY=...
|
||||
|
||||
# Tavily Search API
|
||||
# TAVILY_API_KEY=tvly-...
|
||||
|
||||
# Jina AI (reader/search)
|
||||
# JINA_API_KEY=...
|
||||
|
||||
# ── Optional: Git & GitHub ──
|
||||
|
||||
# GitHub personal access token (for PR operations)
|
||||
# GITHUB_TOKEN=ghp_...
|
||||
|
||||
# Git author identity inside the sandbox
|
||||
# GIT_AUTHOR_NAME=Your Name
|
||||
# GIT_AUTHOR_EMAIL=you@example.com
|
||||
38
docker/Dockerfile.sandbox
Normal file
38
docker/Dockerfile.sandbox
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# ──────────────────────────────────────────────
|
||||
# GSD Docker Sandbox Template
|
||||
# Base: docker/sandbox-templates:shell
|
||||
# Purpose: Isolated environment for GSD auto mode
|
||||
# Usage: docker sandbox create --template ./docker
|
||||
# ──────────────────────────────────────────────
|
||||
FROM node:22-bookworm-slim
|
||||
|
||||
# System dependencies required by GSD
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
openssh-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install GSD globally — version controlled via build arg
|
||||
ARG GSD_VERSION=latest
|
||||
RUN npm install -g gsd-pi@${GSD_VERSION}
|
||||
|
||||
# Create non-root user for sandbox isolation
|
||||
RUN groupadd --gid 1000 gsd \
|
||||
&& useradd --uid 1000 --gid gsd --shell /bin/bash --create-home gsd
|
||||
|
||||
# Persistent GSD state directory
|
||||
RUN mkdir -p /home/gsd/.gsd && chown -R gsd:gsd /home/gsd/.gsd
|
||||
|
||||
# Workspace directory — synced from host via Docker sandbox
|
||||
WORKDIR /workspace
|
||||
RUN chown gsd:gsd /workspace
|
||||
|
||||
USER gsd
|
||||
|
||||
# Expose default GSD web UI port
|
||||
EXPOSE 3000
|
||||
|
||||
ENTRYPOINT ["gsd"]
|
||||
CMD ["--help"]
|
||||
105
docker/README.md
Normal file
105
docker/README.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# GSD Docker Sandbox
|
||||
|
||||
Run GSD auto mode inside an isolated Docker sandbox so it cannot touch your host filesystem, SSH keys, or other projects.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker Desktop 4.58+ (macOS or Windows; Linux support is experimental)
|
||||
- At least one LLM provider API key
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Option A: Docker Sandbox CLI (recommended)
|
||||
|
||||
Docker Sandboxes provide MicroVM isolation — each sandbox runs in a lightweight VM with its own kernel and private Docker daemon.
|
||||
|
||||
```bash
|
||||
# Create a sandbox from the template
|
||||
docker sandbox create --template ./docker --name gsd-sandbox
|
||||
|
||||
# Shell into the sandbox
|
||||
docker sandbox exec -it gsd-sandbox bash
|
||||
|
||||
# Inside the sandbox, run GSD
|
||||
gsd auto "implement the feature described in issue #42"
|
||||
```
|
||||
|
||||
### Option B: Docker Compose
|
||||
|
||||
For environments without Docker Sandbox support, use Compose for container-level isolation:
|
||||
|
||||
```bash
|
||||
# 1. Configure API keys
|
||||
cp docker/.env.example docker/.env
|
||||
# Edit docker/.env with your keys
|
||||
|
||||
# 2. Start the sandbox
|
||||
docker compose -f docker/docker-compose.yml up -d
|
||||
|
||||
# 3. Shell into the container
|
||||
docker exec -it gsd-sandbox bash
|
||||
|
||||
# 4. Run GSD inside the container
|
||||
gsd auto "implement the feature described in issue #42"
|
||||
```
|
||||
|
||||
## Two-Terminal Workflow
|
||||
|
||||
GSD's recommended workflow uses two terminals — one for auto mode, one for interactive discussion:
|
||||
|
||||
```bash
|
||||
# Terminal 1: auto mode
|
||||
docker sandbox exec -it gsd-sandbox bash
|
||||
gsd auto "your task description"
|
||||
|
||||
# Terminal 2: discuss / monitor
|
||||
docker sandbox exec -it gsd-sandbox bash
|
||||
gsd discuss
|
||||
```
|
||||
|
||||
With Docker Compose, replace `docker sandbox exec` with `docker exec`.
|
||||
|
||||
## Credential Injection
|
||||
|
||||
### Docker Sandbox (automatic)
|
||||
|
||||
Docker's proxy layer forwards API keys set in your host shell config (`~/.bashrc`, `~/.zshrc`) into the sandbox automatically. Keys are never stored inside the sandbox.
|
||||
|
||||
### Docker Compose (manual)
|
||||
|
||||
Copy `docker/.env.example` to `docker/.env` and fill in your keys. The `.env` file is gitignored and never committed.
|
||||
|
||||
## Network Allowlisting
|
||||
|
||||
If you restrict outbound network access in your sandbox, GSD needs these endpoints:
|
||||
|
||||
| Purpose | Endpoints |
|
||||
|---------|-----------|
|
||||
| LLM APIs | `api.anthropic.com`, `api.openai.com`, `generativelanguage.googleapis.com`, `openrouter.ai` |
|
||||
| Package registry | `registry.npmjs.org` |
|
||||
| Research tools | `api.search.brave.com`, `api.tavily.com`, `r.jina.ai` |
|
||||
| GitHub | `api.github.com`, `github.com` |
|
||||
|
||||
## Customizing the Image
|
||||
|
||||
Build with a specific GSD version:
|
||||
|
||||
```bash
|
||||
docker compose -f docker/docker-compose.yml build --build-arg GSD_VERSION=2.43.0
|
||||
```
|
||||
|
||||
## Cleanup
|
||||
|
||||
```bash
|
||||
# Docker Sandbox
|
||||
docker sandbox rm gsd-sandbox
|
||||
|
||||
# Docker Compose
|
||||
docker compose -f docker/docker-compose.yml down -v
|
||||
```
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- **macOS/Windows only**: Docker Sandboxes require Docker Desktop 4.58+. Linux sandbox support is experimental.
|
||||
- **Environment parity**: The sandbox runs Ubuntu (Debian). macOS-only dependencies may not work inside the sandbox.
|
||||
- **Named agent registration**: Docker Desktop's built-in named agents (claude, codex, etc.) are registered by Docker itself. Third-party tools cannot register new named agents. GSD uses the generic shell sandbox type with a custom template instead.
|
||||
34
docker/docker-compose.yml
Normal file
34
docker/docker-compose.yml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Docker Compose for running GSD in a sandbox
|
||||
# Usage: docker compose -f docker/docker-compose.yml up
|
||||
#
|
||||
# Copy docker/.env.example to docker/.env and fill in your API keys first.
|
||||
# See docker/README.md for full setup instructions.
|
||||
|
||||
services:
|
||||
gsd:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.sandbox
|
||||
args:
|
||||
GSD_VERSION: latest
|
||||
container_name: gsd-sandbox
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
# Sync project code into the sandbox
|
||||
- ../:/workspace
|
||||
# Persistent GSD state across container restarts
|
||||
- gsd-state:/home/gsd/.gsd
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
user: "1000:1000"
|
||||
stdin_open: true
|
||||
tty: true
|
||||
# Override entrypoint for interactive shell access
|
||||
# entrypoint: /bin/bash
|
||||
|
||||
volumes:
|
||||
gsd-state:
|
||||
driver: local
|
||||
|
|
@ -217,18 +217,18 @@ For the same 4-slice, 3-task milestone:
|
|||
|
||||
#### 5. Replace validate-milestone with mechanical verification
|
||||
|
||||
**Current:** An LLM session re-reads the ROADMAP and all slice summaries, checks success criteria against delivery evidence, and writes a VALIDATION.md with a verdict. It also inlines UAT-RESULT artifacts from slices with `uat_dispatch` enabled.
|
||||
**Current:** An LLM session re-reads the ROADMAP and all slice summaries, checks success criteria against delivery evidence, and writes a VALIDATION.md with a verdict. It also inlines UAT artifacts from slices with `uat_dispatch` enabled.
|
||||
|
||||
**New:** The system mechanically aggregates verification results from all tasks and slices. The canonical verification data sources are:
|
||||
|
||||
1. **`T##-VERIFY.json`** files (written by `writeVerificationJSON()` in `verification-evidence.ts`) — machine-readable per-task verification results with command, exit code, verdict, duration, and blocking status.
|
||||
2. **`S##-UAT-RESULT.md`** files (when `uat_dispatch` is enabled) — human or artifact-driven UAT outcomes.
|
||||
2. **`S##-UAT.md`** files (when `uat_dispatch` is enabled) — human or artifact-driven UAT outcomes.
|
||||
3. **Task summary frontmatter** `verification_result` field — a human-readable pass/fail string (not structured, used as a secondary signal).
|
||||
|
||||
The aggregator reads `T##-VERIFY.json` as the primary source of truth, supplements with UAT-RESULT artifacts, and produces a deterministic VALIDATION.md.
|
||||
The aggregator reads `T##-VERIFY.json` as the primary source of truth, supplements with UAT artifacts, and produces a deterministic VALIDATION.md.
|
||||
|
||||
**What changes:**
|
||||
- A new `aggregateMilestoneVerification()` function collects `T##-VERIFY.json` files and `S##-UAT-RESULT.md` files across all slices.
|
||||
- A new `aggregateMilestoneVerification()` function collects `T##-VERIFY.json` files and `S##-UAT.md` files across all slices.
|
||||
- The function produces a VALIDATION.md with per-task and per-slice pass/fail status, UAT evidence, and an overall verdict.
|
||||
- The LLM-driven validate-milestone session is removed from the default pipeline.
|
||||
- The validate-milestone template is retained for explicit dispatch (users who want LLM-driven validation can run `/gsd dispatch validate`).
|
||||
|
|
@ -254,8 +254,8 @@ async function aggregateMilestoneVerification(base: string, mid: string): Promis
|
|||
}
|
||||
}
|
||||
|
||||
// Secondary source: S##-UAT-RESULT.md (when uat_dispatch enabled)
|
||||
const uatResultFile = resolveSliceFile(base, mid, slice.id, "UAT-RESULT");
|
||||
// Secondary source: S##-UAT.md (when uat_dispatch enabled)
|
||||
const uatResultFile = resolveSliceFile(base, mid, slice.id, "UAT");
|
||||
if (uatResultFile) {
|
||||
const uatContent = await loadFile(uatResultFile);
|
||||
if (uatContent) uatResults.push({ sliceId: slice.id, content: uatContent });
|
||||
|
|
@ -476,7 +476,7 @@ async function mechanicalSliceCompletion(base: string, mid: string, sid: string)
|
|||
|
||||
#### Mechanical milestone validation
|
||||
|
||||
See `aggregateMilestoneVerification()` above (Section 5). Reads `T##-VERIFY.json` and `S##-UAT-RESULT.md` as canonical sources.
|
||||
See `aggregateMilestoneVerification()` above (Section 5). Reads `T##-VERIFY.json` and `S##-UAT.md` as canonical sources.
|
||||
|
||||
#### Mechanical milestone summary
|
||||
|
||||
|
|
@ -547,7 +547,7 @@ At current Opus pricing ($15/MTok input, $75/MTok output — as of March 2026),
|
|||
| `auto-prompts.ts` — plan-milestone exploration | ~30 | Research instructions merged in |
|
||||
| `auto-prompts.ts` — plan-slice reassessment + exploration | ~25 | Reassessment + exploration preamble |
|
||||
| `auto-post-unit.ts` — `mechanicalSliceCompletion()` | ~80 | Structured frontmatter aggregation, UAT generation, artifact writes |
|
||||
| `auto-verification.ts` — `aggregateMilestoneVerification()` | ~60 | T##-VERIFY.json + UAT-RESULT aggregation |
|
||||
| `auto-verification.ts` — `aggregateMilestoneVerification()` | ~60 | T##-VERIFY.json + UAT aggregation |
|
||||
| `auto-unit-closeout.ts` — `generateMilestoneSummary()` | ~60 | Mechanical summary generation |
|
||||
| **Total added** | **~255** | |
|
||||
|
||||
|
|
@ -694,7 +694,7 @@ The mechanical summary quality might be insufficient for complex slices.
|
|||
13. Implement `mechanicalRequirementsUpdate()` and `appendNewDecisions()`
|
||||
|
||||
### Phase 3: Mechanical milestone validation + completion
|
||||
14. Implement `aggregateMilestoneVerification()` reading `T##-VERIFY.json` and `S##-UAT-RESULT.md`
|
||||
14. Implement `aggregateMilestoneVerification()` reading `T##-VERIFY.json` and `S##-UAT.md`
|
||||
15. Implement `generateMilestoneSummary()` from slice summary aggregation
|
||||
16. Wire into post-unit processing: after last slice completion, run mechanical validation + summary
|
||||
17. Make reassess-roadmap opt-in via `reassess_after_slice` preference (default: false)
|
||||
|
|
@ -723,14 +723,14 @@ The mechanical summary quality might be insufficient for complex slices.
|
|||
3. ✅ Token savings double-counting (eliminated sessions + re-ingestion) — **fixed**: removed overlap, noted savings are not additive
|
||||
4. ✅ Context inlining change (file paths vs inline) underanalyzed — **fixed**: expanded to dedicated risk section with enforcement strategy, phased rollout, and interaction with budget engine
|
||||
5. ✅ Budget engine interaction not discussed — **fixed**: addressed in context inlining section
|
||||
6. ✅ `aggregateMilestoneVerification()` reads wrong data source — **fixed**: now reads `T##-VERIFY.json` as primary source, supplemented by `S##-UAT-RESULT.md`
|
||||
6. ✅ `aggregateMilestoneVerification()` reads wrong data source — **fixed**: now reads `T##-VERIFY.json` as primary source, supplemented by `S##-UAT.md`
|
||||
7. ✅ Phase ordering creates heavy intermediate state (Phase 1 without Phase 4) — **fixed**: Phase 1 now includes targeted inlining reduction for planning sessions
|
||||
8. ✅ ADR number conflict — **fixed**: confirmed no ADR-003 exists in `docs/` (the referenced file doesn't exist in current git)
|
||||
|
||||
**OpenAI Codex** identified 6 issues:
|
||||
1. ✅ HIGH: Folding completion into execute-task breaks verification-retry model — **fixed**: moved completion to post-gate mechanical processing instead of executor prompt. Added Alternative D explaining why.
|
||||
2. ✅ HIGH: Mechanical validation reads nonexistent `verification_evidence` frontmatter — **fixed**: now reads `T##-VERIFY.json` (canonical machine-readable source from `verification-evidence.ts`)
|
||||
3. ✅ HIGH: Replacement validation drops UAT evidence — **fixed**: aggregator now reads both `T##-VERIFY.json` and `S##-UAT-RESULT.md`
|
||||
3. ✅ HIGH: Replacement validation drops UAT evidence — **fixed**: aggregator now reads both `T##-VERIFY.json` and `S##-UAT.md`
|
||||
4. ✅ HIGH: "State derivation stays unchanged" is false — **fixed**: explicitly documented that `deriveState()` phases are preserved, mechanical processing resolves them synchronously, fallback dispatch rules handle failures
|
||||
5. ✅ MEDIUM: Folded completion omits REQUIREMENTS.md and KNOWLEDGE.md updates — **fixed**: mechanical completion handles REQUIREMENTS.md and DECISIONS.md; KNOWLEDGE.md addressed in Risk 5
|
||||
6. ✅ MEDIUM: Session and token math inconsistent — **fixed**: complete rederivation with per-slice breakdown, corrected to 30 baseline sessions, noted profile variations
|
||||
|
|
@ -482,7 +482,6 @@
|
|||
| gsd/auto-loop.ts | Auto Engine, State Machine | Execution loop state and cycle management |
|
||||
| gsd/auto-supervisor.ts | Auto Engine | Supervision and oversight of autonomous runs |
|
||||
| gsd/auto-budget.ts | Auto Engine | Token/cost budgeting and tracking |
|
||||
| gsd/auto-observability.ts | Auto Engine | Observability hooks and telemetry |
|
||||
| gsd/auto-tool-tracking.ts | Auto Engine | Tool usage instrumentation |
|
||||
| gsd/doctor.ts | Doctor/Diagnostics | Health check and system diagnostics |
|
||||
| gsd/doctor-checks.ts | Doctor/Diagnostics | Individual diagnostic checks |
|
||||
|
|
@ -978,7 +977,7 @@ Quick lookup: which files are part of each system?
|
|||
| **Config** | src/app-paths.ts, src/models-resolver.ts, src/remote-questions-config.ts, src/wizard.ts, core/defaults.ts, core/constants.ts, config.ts |
|
||||
| **Context7** | src/resources/extensions/context7/index.ts |
|
||||
| **Doctor / Diagnostics** | gsd/doctor*.ts, gsd/collision-diagnostics.ts, core/diagnostics.ts, web/lib/diagnostics-types.ts, web/app/api/doctor/*, forensics/* |
|
||||
| **Event System** | pi-coding-agent/src/core/event-bus.ts, gsd/auto-observability.ts |
|
||||
| **Event System** | pi-coding-agent/src/core/event-bus.ts |
|
||||
| **Extension Registry** | src/extension-discovery.ts, src/extension-registry.ts, src/bundled-extension-paths.ts |
|
||||
| **Extensions** | pi-coding-agent/src/core/extensions/*, src/resource-loader.ts |
|
||||
| **File Search** | native/crates/engine/src/grep.rs, glob.rs, fd.rs, fs_cache.rs, packages/native/src/grep/*, fd/*, core/tools/grep.ts, find.ts |
|
||||
|
|
@ -9,12 +9,16 @@
|
|||
| `/gsd auto` | Autonomous mode — research, plan, execute, commit, repeat |
|
||||
| `/gsd quick` | Execute a quick task with GSD guarantees (atomic commits, state tracking) without full planning overhead |
|
||||
| `/gsd stop` | Stop auto mode gracefully |
|
||||
| `/gsd pause` | Pause auto-mode (preserves state, `/gsd auto` to resume) |
|
||||
| `/gsd steer` | Hard-steer plan documents during execution |
|
||||
| `/gsd discuss` | Discuss architecture and decisions (works alongside auto mode) |
|
||||
| `/gsd status` | Progress dashboard |
|
||||
| `/gsd widget` | Cycle dashboard widget: full / small / min / off |
|
||||
| `/gsd queue` | Queue and reorder future milestones (safe during auto mode) |
|
||||
| `/gsd capture` | Fire-and-forget thought capture (works during auto mode) |
|
||||
| `/gsd triage` | Manually trigger triage of pending captures |
|
||||
| `/gsd dispatch` | Dispatch a specific phase directly (research, plan, execute, complete, reassess, uat, replan) |
|
||||
| `/gsd history` | View execution history (supports `--cost`, `--phase`, `--model` filters) |
|
||||
| `/gsd forensics` | Full-access GSD debugger — structured anomaly detection, unit traces, and LLM-guided root-cause analysis for auto-mode failures |
|
||||
| `/gsd cleanup` | Clean up GSD state files and stale worktrees |
|
||||
| `/gsd visualize` | Open workflow visualizer (progress, deps, metrics, timeline) |
|
||||
|
|
@ -22,6 +26,11 @@
|
|||
| `/gsd export --html --all` | Generate retrospective reports for all milestones at once |
|
||||
| `/gsd update` | Update GSD to the latest version in-session |
|
||||
| `/gsd knowledge` | Add persistent project knowledge (rule, pattern, or lesson) |
|
||||
| `/gsd fast` | Toggle service tier for supported models (prioritized API routing) |
|
||||
| `/gsd rate` | Rate last unit's model tier (over/ok/under) — improves adaptive routing |
|
||||
| `/gsd changelog` | Show categorized release notes |
|
||||
| `/gsd logs` | Browse activity logs, debug logs, and metrics |
|
||||
| `/gsd remote` | Control remote auto-mode |
|
||||
| `/gsd help` | Categorized command reference with descriptions for all GSD subcommands |
|
||||
|
||||
## Configuration & Diagnostics
|
||||
|
|
@ -33,6 +42,9 @@
|
|||
| `/gsd config` | Re-run the provider setup wizard (LLM provider + tool keys) |
|
||||
| `/gsd keys` | API key manager — list, add, remove, test, rotate, doctor |
|
||||
| `/gsd doctor` | Runtime health checks with auto-fix — issues surface in real time across widget, visualizer, and HTML reports (v2.40) |
|
||||
| `/gsd inspect` | Show SQLite DB diagnostics |
|
||||
| `/gsd init` | Project init wizard — detect, configure, bootstrap `.gsd/` |
|
||||
| `/gsd setup` | Global setup status and configuration |
|
||||
| `/gsd skill-health` | Skill lifecycle dashboard — usage stats, success rates, token trends, staleness warnings |
|
||||
| `/gsd skill-health <name>` | Detailed view for a single skill |
|
||||
| `/gsd skill-health --declining` | Show only skills flagged for declining performance |
|
||||
|
|
@ -48,8 +60,10 @@
|
|||
| `/gsd new-milestone` | Create a new milestone |
|
||||
| `/gsd skip` | Prevent a unit from auto-mode dispatch |
|
||||
| `/gsd undo` | Revert last completed unit |
|
||||
| Park milestone | Available via `/gsd` wizard → "Milestone actions" → "Park" |
|
||||
| Unpark milestone | Available via `/gsd` wizard → "Milestone actions" → "Unpark" |
|
||||
| `/gsd undo-task` | Reset a specific task's completion state (DB + markdown) |
|
||||
| `/gsd reset-slice` | Reset a slice and all its tasks (DB + markdown) |
|
||||
| `/gsd park` | Park a milestone — skip without deleting |
|
||||
| `/gsd unpark` | Reactivate a parked milestone |
|
||||
| Discard milestone | Available via `/gsd` wizard → "Milestone actions" → "Discard" |
|
||||
|
||||
## Parallel Orchestration
|
||||
|
|
@ -65,6 +79,46 @@
|
|||
|
||||
See [Parallel Orchestration](./parallel-orchestration.md) for full documentation.
|
||||
|
||||
## Workflow Templates (v2.42)
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/gsd start` | Start a workflow template (bugfix, spike, feature, hotfix, refactor, security-audit, dep-upgrade, full-project) |
|
||||
| `/gsd start resume` | Resume an in-progress workflow |
|
||||
| `/gsd templates` | List available workflow templates |
|
||||
| `/gsd templates info <name>` | Show detailed template info |
|
||||
|
||||
## Custom Workflows (v2.42)
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/gsd workflow new` | Create a new workflow definition (via skill) |
|
||||
| `/gsd workflow run <name>` | Create a run and start auto-mode |
|
||||
| `/gsd workflow list` | List workflow runs |
|
||||
| `/gsd workflow validate <name>` | Validate a workflow definition YAML |
|
||||
| `/gsd workflow pause` | Pause custom workflow auto-mode |
|
||||
| `/gsd workflow resume` | Resume paused custom workflow auto-mode |
|
||||
|
||||
## Extensions
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/gsd extensions list` | List all extensions and their status |
|
||||
| `/gsd extensions enable <id>` | Enable a disabled extension |
|
||||
| `/gsd extensions disable <id>` | Disable an extension |
|
||||
| `/gsd extensions info <id>` | Show extension details |
|
||||
|
||||
## cmux Integration
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `/gsd cmux status` | Show cmux detection, prefs, and capabilities |
|
||||
| `/gsd cmux on` | Enable cmux integration |
|
||||
| `/gsd cmux off` | Disable cmux integration |
|
||||
| `/gsd cmux notifications on/off` | Toggle cmux desktop notifications |
|
||||
| `/gsd cmux sidebar on/off` | Toggle cmux sidebar metadata |
|
||||
| `/gsd cmux splits on/off` | Toggle cmux visual subagent splits |
|
||||
|
||||
## GitHub Sync (v2.39)
|
||||
|
||||
| Command | Description |
|
||||
|
|
@ -116,6 +170,14 @@ Enable with `github.enabled: true` in preferences. Requires `gh` CLI installed a
|
|||
| `gsd --print "msg"` (`-p`) | Single-shot prompt mode (no TUI) |
|
||||
| `gsd --mode <text\|json\|rpc\|mcp>` | Output mode for non-interactive use |
|
||||
| `gsd --list-models [search]` | List available models and exit |
|
||||
| `gsd --web [path]` | Start browser-based web interface (optional project path) |
|
||||
| `gsd --worktree` (`-w`) [name] | Start session in a git worktree (auto-generates name if omitted) |
|
||||
| `gsd --no-session` | Disable session persistence |
|
||||
| `gsd --extension <path>` | Load an additional extension (can be repeated) |
|
||||
| `gsd --append-system-prompt <text>` | Append text to the system prompt |
|
||||
| `gsd --tools <list>` | Comma-separated list of tools to enable |
|
||||
| `gsd --version` (`-v`) | Print version and exit |
|
||||
| `gsd --help` (`-h`) | Print help and exit |
|
||||
| `gsd sessions` | Interactive session picker — list all saved sessions for the current directory and choose one to resume |
|
||||
| `gsd --debug` | Enable structured JSONL diagnostic logging for troubleshooting dispatch and state issues |
|
||||
| `gsd config` | Set up global API keys for search and docs tools (saved to `~/.gsd/agent/auth.json`, applies to all projects). See [Global API Keys](./configuration.md#global-api-keys-gsd-config). |
|
||||
|
|
@ -648,6 +648,36 @@ dynamic_routing:
|
|||
cross_provider: true
|
||||
```
|
||||
|
||||
### `service_tier` (v2.42)
|
||||
|
||||
OpenAI service tier preference for supported models. Toggle with `/gsd fast`.
|
||||
|
||||
| Value | Behavior |
|
||||
|-------|----------|
|
||||
| `"priority"` | Priority tier — 2x cost, faster responses |
|
||||
| `"flex"` | Flex tier — 0.5x cost, slower responses |
|
||||
| (unset) | Default tier |
|
||||
|
||||
```yaml
|
||||
service_tier: priority
|
||||
```
|
||||
|
||||
### `forensics_dedup` (v2.43)
|
||||
|
||||
Opt-in: search existing issues and PRs before filing from `/gsd forensics`. Uses additional AI tokens.
|
||||
|
||||
```yaml
|
||||
forensics_dedup: true # default: false
|
||||
```
|
||||
|
||||
### `show_token_cost` (v2.44)
|
||||
|
||||
Opt-in: show per-prompt and cumulative session token cost in the footer.
|
||||
|
||||
```yaml
|
||||
show_token_cost: true # default: false
|
||||
```
|
||||
|
||||
### `auto_visualize`
|
||||
|
||||
Show the workflow visualizer automatically after milestone completion:
|
||||
|
|
@ -734,6 +764,13 @@ notifications:
|
|||
# Visualizer
|
||||
auto_visualize: true
|
||||
|
||||
# Service tier
|
||||
service_tier: priority # "priority" or "flex" (for /gsd fast)
|
||||
|
||||
# Diagnostics
|
||||
forensics_dedup: true # deduplicate before filing forensics issues
|
||||
show_token_cost: true # show per-prompt cost in footer
|
||||
|
||||
# Hooks
|
||||
post_unit_hooks:
|
||||
- name: code-review
|
||||
|
|
@ -39,6 +39,10 @@ GSD is also available as a VS Code extension. Install from the marketplace (publ
|
|||
|
||||
The CLI (`gsd-pi`) must be installed first — the extension connects to it via RPC.
|
||||
|
||||
### Web Interface
|
||||
|
||||
GSD also has a browser-based interface. Run `gsd --web` to start a local web server with a visual dashboard, real-time progress, and multi-project support. See [Web Interface](./web-interface.md) for details.
|
||||
|
||||
## First Launch
|
||||
|
||||
Run `gsd` in any directory:
|
||||
|
|
@ -36,10 +36,10 @@ Use this for hot-reload workflows where file isolation breaks dev tooling (e.g.,
|
|||
main ─────────────────────────────────────────────────────────
|
||||
│ ↑
|
||||
└── milestone/M001 (worktree) ────────────────────────┘
|
||||
commit: feat(S01/T01): core types
|
||||
commit: feat(S01/T02): markdown parser
|
||||
commit: feat(S01/T03): file writer
|
||||
commit: docs(M001/S01): workflow docs
|
||||
commit: feat: core types
|
||||
commit: feat: markdown parser
|
||||
commit: feat: file writer
|
||||
commit: docs: workflow docs
|
||||
...
|
||||
→ squash-merged to main as single commit
|
||||
```
|
||||
|
|
@ -56,13 +56,13 @@ With [parallel orchestration](./parallel-orchestration.md) enabled, multiple mil
|
|||
main ──────────────────────────────────────────────────────────
|
||||
│ ↑ ↑
|
||||
├── milestone/M002 (worktree) ─────────┘ │
|
||||
│ commit: feat(S01/T01): auth types │
|
||||
│ commit: feat(S01/T02): JWT middleware │
|
||||
│ commit: feat: auth types │
|
||||
│ commit: feat: JWT middleware │
|
||||
│ → squash-merged first │
|
||||
│ │
|
||||
└── milestone/M003 (worktree) ────────────────────────┘
|
||||
commit: feat(S01/T01): dashboard layout
|
||||
commit: feat(S01/T02): chart components
|
||||
commit: feat: dashboard layout
|
||||
commit: feat: chart components
|
||||
→ squash-merged second
|
||||
```
|
||||
|
||||
|
|
@ -75,13 +75,16 @@ Each worktree operates on its own branch with its own commit history. Merges hap
|
|||
|
||||
### Commit Format
|
||||
|
||||
Commits use conventional commit format with scope:
|
||||
Commits use conventional commit format with GSD metadata in trailers:
|
||||
|
||||
```
|
||||
feat(S01/T01): core type definitions
|
||||
feat(S01/T02): markdown parser for plan files
|
||||
fix(M001/S03): bug fixes and doc corrections
|
||||
docs(M001/S04): workflow documentation
|
||||
feat: core type definitions
|
||||
|
||||
GSD-Task: M001/S01/T01
|
||||
|
||||
feat: markdown parser for plan files
|
||||
|
||||
GSD-Task: M001/S01/T02
|
||||
```
|
||||
|
||||
## Worktree Management
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue