Implements all fixes from the auto-hardening audit plan:
P1-A: Per-phase timeout watchdog — withPhaseTimeout() wraps preDispatch/dispatch/finalize;
on timeout emits warning, increments consecutiveFinalizeTimeouts, continues loop.
Configurable via preferences.auto_supervisor.phase_timeout_minutes (default: 10).
P1-B: Verified already wired (MAX_COOLDOWN_RETRIES → stopAuto+break). No change needed.
P1-C: Worker timeout in parallel orchestrator — kills workers running beyond
parallel.worker_timeout_minutes (default: 120 min) in refreshWorkerStatuses().
P2-A: Memory injection into dispatch prompts — buildMemoriesBlock() appended to
plan-milestone inlined[] context and added as memoriesSection in execute-task.
P2-B: Memory extraction retry — one 2s-delayed retry in the catch block of
extractMemoriesFromUnit(); second failure is silently swallowed (non-fatal).
P3-A: Partial verification state in DB — verificationStatus ("all_pass"/"partial"/"all_fail")
derived from verificationEvidence.exitCode array and stored in new tasks column.
New dispatch rule blocks next task when prior task has all_fail status.
P3-B: Gate omission rationale enforcement — minOmissionWords added to GateDefinition
(Q3=20, Q5=15, Q6=10, Q7=15). Short rationale upgrades verdict "omitted" → "flag".
P4-A: Doctor issues → reassess escalation — pre-dispatch health check in loop.ts detects
issues referencing slice IDs and queues reassess-roadmap sidecar instead of pausing.
P4-B: File overlap preemption — analyzeParallelEligibility() sets eligible:false when
the overlapping milestone is currently running (not just eligible/queued).
P5-A: Deferred requirement tracking — parseDeferredRequirements() added to files.ts;
completing-milestone rule warns (via logWarning) when deferred reqs targeting
the milestone were not validated before completion.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cherry-pick of gsd-build/gsd-2@0b7a05491 adapted for sf/ paths:
- Expand RATE_LIMIT_RE to cover quota-window phrasing (hit your limit, usage limit, quota reached)
- Rate-limit errors bypass transient-deferral early return so model fallback executes
- Add setCurrentDispatchedModelId() to keep AUTO dashboard label in sync after fallback switch
- 4 regression tests for classifier coverage and structural guards
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
RTK seam tests: SF_RTK_PATH was set then immediately deleted in withFakeRtk
due to copy-paste duplication from the GSD→SF rename — fake RTK binary was
never injected, so all 5 seam tests ran the raw command instead of the
rewritten one.
Remaining 21 fixes from the GSD→SF rebrand:
- initial-gsd-header-filter.test.ts: import renamed filterInitialSfHeader
- dist-redirect.mjs: doubled scope prefix @singularity-forge/@singularity-forge/*
→ @singularity-forge/* (5 specifiers affected)
- forensics-issue-routing.test.ts: regex used sf-build/sf-2, prompt says
singularity-forge/sf-run — align regex to match the actual prompt
- key-manager.test.ts: GROQ_API_KEY set in dev env made empty-key test
report configured:true — isolate with save/delete/restore
- create-gsd-extension-paths.test.ts: skill dir doesn't exist in this repo,
skip both tests gracefully with t.skip()
- sf-usage-bar/index.ts: replace execSync(`which ${cmd}`) with spawnSync to
fix unescaped shell interpolation static analysis failure
- sf-notify/index.ts: convert enum to const object — strip-only TS mode
does not support enums
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows tool input to be passed to vibe setter for future context-aware
customization.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consolidated into unified sf-tui extension. Removed old git-footer
extension in favor of sf-tui footer implementation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integrates footer rendering, working vibes, prompt history stash,
and git status tracking into unified TUI enhancement extension.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides shared stash management functions and overlay UI for browsing
and selecting previous prompts. Supports 1-9 quick picking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Displays git branch status, dirty state, extension statuses, model info,
cost, and context usage percentage in the footer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides context-aware working status messages based on prompt keywords
and tool names, with random emoji for visual interest.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides GitStatus interface and refreshGitStatus function for displaying
repository branch, dirty state, untracked files, and commit counts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- registers hook to trigger vibe state based on tool name and input
- enables working-vibes extension to respond to tool invocations
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- genai-proxy: disable full proxy implementation due to auth bootstrap
limitations at package boundary; throw clear error instead
- proxy-command: add try-catch error handling around startProxy
- prompt-history: new extension with Ctrl+Alt+H (or Ctrl+Shift+H fallback)
to navigate and insert previously-stashed prompts. Stash limited to 20
entries in ~/.sf/agent/prompt-history.json
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Updates workflow tool names, documentation references, and internal naming
conventions across MCP server, CLI, tests, and web components to complete
the singularity-forge rebrand from gsd to sf.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updates channel prefixes, log messages, comments, and configuration values
across daemon, mcp-server, and related packages to complete the rebrand from
gsd to sf-run naming.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Final rebrand: rename remaining Rust source file to complete the gsd → forge
transition. All parser references already use forge_parser after earlier commits.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Accept deletion of gsd-phase-state.ts (renamed to forge-phase-state.ts earlier)
- Accept deletion of create-gsd-extension/ (renamed to create-forge-extension/ earlier)
- These renames were part of the rebrand and are preserved in commit history
Stabilize git state after restoration operations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Print mode was constructing DefaultResourceLoader directly, which
bypassed the GSD extension registry filter and let disabled bundled
extensions leak through. With the community @0xkobold/pi-ollama
installed, every `gsd -p` invocation printed an /ollama command
conflict because the bundled ollama extension (explicitly disabled
in ~/.gsd/extensions/registry.json) was still being loaded.
- Add extension-manifest.json for the bundled ollama extension so the
registry's id-keyed disable entry can actually target it.
- Extend buildResourceLoader() with an options bag for print-mode
callers (additionalExtensionPaths, appendSystemPrompt).
- Switch print mode to buildResourceLoader() so the registry filter
(extensionPathsTransform) runs in both TUI and print paths.
Also fix a stderr leak in the GSD codebase-generator: execSync("git
ls-files") was inheriting stderr to the parent, so running gsd from a
non-repo cwd (e.g. $HOME) printed "fatal: not a git repository" before
the catch silently returned []. Pipe stderr so it lands in the thrown
Error instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Analyzes completed milestone artifacts (PLAN.md, SUMMARY.md, and
optionally VERIFICATION.md + UAT.md) and dispatches an LLM turn that
extracts institutional knowledge into four categories — Decisions,
Lessons, Patterns, Surprises — with source attribution per item.
Output: .gsd/milestones/<id>/<id>-LEARNINGS.md with YAML frontmatter
(counts per category, list of missing optional artifacts). Running
twice overwrites the previous file. Integrates with capture_thought
when available; silently skips if not.
New files:
- commands-extract-learnings.ts — handler + pure helpers
- tests/commands-extract-learnings.test.ts — 32 unit tests (TDD)
Ports the v1 graphify system to v2 as a native TypeScript implementation.
The knowledge graph builds semantic relationships between milestones, slices,
tasks, and knowledge entries — and injects relevant subgraphs automatically
into every agent dispatch prompt.
## Core implementation (packages/mcp-server/src/readers/graph.ts)
- `buildGraph(projectDir)` — walks all .gsd/ artifacts (STATE.md,
milestone PLANs, slice PLANs, KNOWLEDGE.md), extracts nodes and edges
with confidence tiers (EXTRACTED / INFERRED / AMBIGUOUS). Parse errors
skip the node rather than crashing.
- `writeGraph(gsdRoot, graph)` — atomic write via tmp file + rename.
- `writeSnapshot(gsdRoot)` — saves a diff baseline before each rebuild.
- `graphQuery(projectDir, term, budget?)` — BFS subgraph search with
case-insensitive matching on label + description; trims AMBIGUOUS edges
first, then INFERRED, respecting the token budget (default 4 000).
- `graphStatus(projectDir)` — freshness check; stale = older than 24 h.
- `graphDiff(projectDir)` — compares current graph to last snapshot,
returns added / removed / changed counts for nodes and edges.
## MCP tool (packages/mcp-server/src/server.ts)
Registers `gsd_graph` immediately after `gsd_knowledge` with four modes:
build | query | status | diff. All errors returned as isError: true.
## CLI subcommand (src/cli.ts, src/help-text.ts)
`gsd graph build|status|query <term>|diff` — follows the established
`if (cliFlags.messages[0] === '...')` dispatch pattern. Uses
`resolveGsdRoot()` for git-root-aware path resolution (not a naive
`.gsd` append). Help text updated with correct positional argument format.
## Auto-rebuild after slice completion
(src/resources/extensions/gsd/tools/complete-slice.ts)
Fire-and-forget `buildGraph → writeGraph` triggered after every slice
completion. Uses `@gsd-build/mcp-server` package import (not a relative
src path) and `resolveGsdRoot()` for correct path resolution in monorepos.
## Graph-aware dispatch injection
(src/resources/extensions/gsd/graph-context.ts,
src/resources/extensions/gsd/auto-prompts.ts)
`inlineGraphSubgraph(projectDir, term, { budget })` queries the graph and
formats the result as a `### Knowledge Graph Context` markdown block,
consistent with all other inlined context blocks. Adds a stale warning
annotation when the graph is older than 24 h. Returns null (graceful
skip) when graph.json is missing, the query returns zero nodes, or the
import fails — no agent dispatch is ever blocked by graph availability.
Injected into three prompt builders:
- `buildResearchSlicePrompt` — 3 000 token budget
- `buildPlanSlicePrompt` — 3 000 token budget
- `buildExecuteTaskPrompt` — 2 000 token budget
## Tests
- 22 tests for the core graph reader (graph.test.ts)
- 14 tests for the dispatch injection helper (graph-context.test.ts)
- All tests use real on-disk fixtures (no module mocking needed)
- Full suite: 6 318 passed, 0 failed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- pr-branch: use execFileSync everywhere, validate --name with git check-ref-format,
cherry-pick --no-commit + path-level reset to strip .gsd/.planning/PLAN.md from
mixed commits, and assert no excluded paths leak into the final branch
- ship: argv-safe git push and gh pr create, validate base/current refs, and
resolve ROADMAP/SUMMARY via resolveMilestoneFile/resolveSliceFile
- add-tests: resolve slice SUMMARY via resolveSliceFile instead of hardcoded path
- Fix ProjectTotals field names (totalCost→cost, totalDuration→duration, etc.)
- Fix UnitMetrics field names (status→finishedAt, unitId→id)
- Fix ModelAggregate field name (count→units)
- Fix ActiveRef usage (no phase/slices fields)
- Remove commands-slice-mutation.ts (depends on single-writer engine)
- Remove slice mutation routes from catalog, do command, and workflow handler
- Update backlog promote to work without engine slice commands
Drop map-codebase from the v1→v2 parity PR: handler, prompt template,
catalog entry, nested completions, route in ops.ts, and keyword route
in the do command.
Add 12 commands that exist in GSDv1 but had no v2 equivalent:
High priority:
- ship: Create PR from milestone artifacts (title, body, metrics)
- add-slice: Append slice to roadmap via engine updateRoadmap()
- insert-slice: Insert slice at position with reordering
- remove-slice: Remove pending slice (--force for planned slices)
- do: Natural language routing via keyword matching (30 routes)
- session-report: Session cost/tokens/work summary (--json, --save)
Medium priority:
- backlog: Structured backlog with 999.x numbering (add/promote/remove)
- pr-branch: Clean PR branch filtering .gsd/ commits via cherry-pick
- add-tests: LLM-dispatched test generation for completed slices
- map-codebase: Codebase analysis (tech/arch/quality/concerns)
All slice mutations go through the engine's updateRoadmap() command,
preserving the single-writer architecture. No direct markdown edits.
Includes 46 unit tests across 6 test files, 2 prompt templates,
catalog entries with nested completions for all commands.