Generalizes the preferences-template-upgrade pattern to all scaffold-managed
documents with three states (pending/editing/completed), HTML-comment markers
on Markdown files, frontmatter on PREFERENCES.md, and a content-hash archive
for migrating legacy projects.
Operation is automatic-first, not command-driven:
- Synchronous on every SF startup (cheap path: missing + upgradable + legacy)
- Asynchronous after milestone completion: scaffold-keeper subagent runs the
existing records-keeper skill, treating code as the source of truth and
re-deriving doc content from source when drift is detected
- Surfaces results via the structured-notification model (kind:approval_request)
only when human review is warranted; silent runs produce no notification
- Manual /sf scaffold sync exists as an escape hatch for dry-run + forced
refresh, not as the primary interface
Five implementation phases (A-E), each independently shippable. Phase A
unlocks the architectural property; Phase D is what makes records-keeper
autonomous for code-derived docs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 1 — close SF-side polish gaps:
- codebase-generator: distinguish uv/poetry/pdm in Python stack-signals;
surface configured tooling (ruff/mypy/pyright) when config files exist
- doctor-environment: new checkPythonEnvironment — detects uv/poetry/pdm
via lockfile, verifies binary on PATH, warns with install hint when missing
- doctor-environment: new checkSiftAvailable — recommends sift install for
repos > 5000 source files when not on PATH
- tech-debt-tracker: documented future memory-as-sub-extension extraction
(defer until real backend-swap requirement)
Phase 2 — internal wire architecture:
- ADR-020: singularity-grpc as shared schema repo; gRPC + typed clients
for first-party services; MCP façade only at external-tool boundary
- ADR-019: trimmed MCP scope section to a 3-line summary linking to ADR-020
to avoid the wire-format table living in two places
- design-docs/index.md: ADR-020 added to ADR table
These changes make SF stronger for autonomous work on Python repos
(particularly ace-coder) and capture the internal wire architecture
decision as a durable ADR before any singularity-grpc code lands.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ADR-019 framing corrections:
- SF is single-machine, single-user, single-repo by design — character, not
limitation. Stays a standalone app permanently; does not get absorbed into ACE.
- Phase 6 reframed: "pattern transfer" not "orchestration convergence." ACE
ports patterns from SF, both apps remain independent.
- Phase 2 reframed: SF stays local. Federation is an ACE concern; SF doesn't
wire memory-store remote-mode against singularity-memory.
Detection strengthened for Python (priority for ace-coder work):
- Detect uv / poetry / pdm and prefix verification commands accordingly
- Emit ruff check when configured (file or [tool.ruff] in pyproject.toml)
- Emit mypy / pyright when configured — skip when no config to avoid false fails
- pyprojectHasTool helper for [tool.<name>] section detection
Detection strengthened for Rust:
- cargo fmt --check (fastest, catches style first)
- cargo check (type-only, faster than test)
- cargo clippy -- -D warnings (warnings as errors)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Internal services (SF↔memory, ACE↔memory, SF↔ACE) talk via typed direct
clients generated from the Go/TS APIs — HTTP/gRPC for memory, existing
JSON-RPC stdio for SF↔ACE. MCP is reserved for external LLM-driven coding
tools (Claude Code, Cursor) that don't share our build system; it is a
scaffold for the period when external coders help build the platform and
shrinks as the system becomes self-hosting.
Adds an explicit "MCP scope" table so the rule is stated once. Updates the
three-layer architecture diagram, Phase 2, and Phase 6 to remove the
inaccurate "all consumers over MCP" framing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Captures the SF↔ACE incremental convergence strategy: workspace VMs
(Firecracker) as the unified execution isolation primitive, the three-layer
architecture (orchestration/knowledge/execution), the 6-phase convergence
path, and ADR-014 Phase 4 cancellation (persistent-agent runtime reassigned
to ACE). Cross-references the matching ACE document at
docs/architecture/sf-ace-convergence.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add harness/ directory to SF repo (specs/, evals/, graders/ with AGENTS.md)
and seed harness/specs/bootstrap.md (agent-legibility verification)
- Extend agentic-docs-scaffold.ts: new repos get harness/ + ADR-TEMPLATE.md
and just adr / just spec / just harness-spec recipes via justfile
- Sync SF_RUNTIME_PATTERNS (gitignore.ts canonical) → git-service.ts and
worktree-manager.ts: add audit/, exec/, model-benchmarks/, reports/,
notifications.jsonl, routing-history.json, self-feedback.jsonl, repo-meta.json,
and milestone continue-marker patterns
- Inject ARCHITECTURE.md into system prompt via loadArchitectureBlock() in
system-context.ts (capped at 8 000 chars, after KNOWLEDGE block)
- Write real ARCHITECTURE.md for this repo (system map, .sf/ layout, key flows)
- Add ADR-TEMPLATE.md to docs/design-docs/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Gitignore (core change):
- Remove stale blanket .sf/ entries from .gitignore (migrated to
.git/info/exclude on 2026-04-29, never cleaned up)
- gitignore.ts: split SF_RUNTIME_EXCLUSION_PATTERNS into two modes —
SF_SYMLINK_EXCLUSION_PATTERNS (blanket .sf for symlink repos where
git cannot traverse the symlink) and SF_RUNTIME_EXCLUSION_PATTERNS
(granular runtime-only patterns for directory repos, enabling
.sf/milestones/ and other durable planning artifacts to be tracked)
- ensureGitInfoExclude() now detects symlink vs directory and writes
the correct patterns, handling transitions between modes cleanly
- ADR-001 status: Proposed → Accepted
Docs:
- Fill 11 placeholder scaffold docs with real SF-specific content:
PLANS, DESIGN, PRODUCT_SENSE, QUALITY_SCORE, RELIABILITY, SECURITY,
design-docs/index.md, exec-plans/active, exec-plans/completed,
exec-plans/tech-debt-tracker, records/index
- Add records note: docs/records/2026-05-01-repo-vcs-and-notifications.md
- ADR-008 status: Accepted → Proposed (deferred — not applicable to
current usage model where Claude Code assists externally, not as a
Pi provider inside SF's dispatch loop)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add repository-vcs-context.ts to detect and inject VCS context (Git/Jujutsu)
into the agent system prompt; wire in repo-vcs bundled skill trigger
- Add src/resources/skills/repo-vcs/ skill for commit, push, and safe-push workflows
- Add JSDoc Purpose/Consumer annotations to app-paths, bundled-extension-paths,
errors, extension-discovery, extension-registry, headless-types, headless, and traces
- Add justfile and just to flake.nix devShell
- Fill out new-user-onboarding.md spec (Draft) and core-beliefs.md (Status: Accepted)
- Add notification-event-model.md design doc and notification-source-hygiene.md spec
Co-Authored-By: Claude Sonnet 4.6 <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>
* docs: add PRD and ADR for pi clean seam refactor
Introduces two new planning documents for extracting GSD-authored code
out of the vendored pi packages into dedicated @gsd/agent-core and
@gsd/agent-modes workspace packages, establishing a module-system-enforced
boundary that makes future pi-mono upstream updates significantly easier.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: rename ADR-009 to ADR-010, update cross-references
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add comprehensive installation walkthroughs for macOS, Windows, Linux (Ubuntu/Debian,
Fedora/RHEL, Arch, nvm), and Docker. Each OS section follows a consistent numbered
step-by-step flow covering dependency install, verification, GSD install, provider
setup, first launch, and verification. Includes download links, platform-specific
tips, and a quick troubleshooting table.
Add Option C covering how Claude Pro/Max subscribers can use GSD's
workflow tools directly inside Claude Code via the MCP server — including
automatic setup, manual config, and verification steps.
Delete the Anthropic OAuth module, remove it from the built-in provider
registry, strip the OAuth client branch from the Anthropic streaming
provider, and replace the daemon orchestrator's token refresh with a
simple ANTHROPIC_API_KEY requirement.
Anthropic access is now API key or local Claude Code CLI only.
Closes#3952
Split flat docs/ into user-docs/ (guides, config, troubleshooting) and
dev/ (ADRs, architecture, extension guides, proposals). Updated
docs/README.md index to reflect new paths.
Update What's New section from v2.52 to v2.63, expand native engine
docs to cover all 20+ modules, add missing extensions and ADRs to
indexes, update version references and Node.js requirements.
* docs: add provider setup guide and improve onboarding hints
Fixes#2161
Add docs/providers.md with step-by-step setup instructions for every
supported LLM provider: OpenRouter, Ollama, LM Studio, vLLM, SGLang,
and all built-in providers. Includes env var names, example configs,
common pitfalls, and verification steps.
Improve onboarding wizard:
- Add URL hints to provider selection list
- Show common local endpoints when choosing Custom (OpenAI-compatible)
- Add post-setup guidance for OpenRouter and custom endpoints
- Reference docs/providers.md for compat troubleshooting
Update cross-references in getting-started.md, troubleshooting.md,
docs/README.md, and help-text.ts to link to the new guide.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: verify config help mentions OpenRouter, Ollama, and docs/providers.md
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: trek-e <trek-e@users.noreply.github.com>
* docs: add context optimization design spec, implementation plan, and pi-layer research
- Spec: 6-change design for GSD extension context optimization
- Plan: 9-task TDD implementation plan with exact file paths and code
- Pi-layer doc: 10 infrastructure opportunities (research only, not planned)
Part of #3171, #3406, #3452, #3433.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(context): add observation masking for auto-mode sessions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(context): add phase handoff anchors for auto-mode
Introduces PhaseAnchor read/write utilities so downstream agents can
inherit decisions, blockers, and intent written at phase boundaries
without re-inferring from conversation history.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(context): add capability-aware model routing and context management preferences
Implement ADR-004 Phase 2 capability scoring with 7-dimension model
profiles, task requirement vectors, and weighted scoring. Add
ContextManagementConfig preferences for observation masking thresholds.
Wire capability scoring into auto-model-selection dispatch path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(context): wire observation masking, phase anchors, and tool truncation
Register observation masker in before_provider_request hook to replace
old tool results with placeholders during auto-mode. Add tool result
truncation (configurable via context_management.tool_result_max_chars).
Inject phase handoff anchors into prompt builders so downstream phases
inherit decisions from research/planning. Write anchors after successful
phase completion. Update ADR-004 status to Implemented.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: remove internal planning artifacts from PR
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add capability routing, observation masking, and context management
Update dynamic-model-routing.md with capability-aware scoring section.
Update token-optimization.md with observation masking, tool truncation,
and phase handoff anchor documentation. Update configuration.md with
context_management preference block and capability_routing flag.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Merge branch 'main' into feat/gsd-context-optimization
* fix: add context_management to known keys and prevent tool truncation state corruption
- Add missing 'context_management' to KNOWN_PREFERENCE_KEYS set so users
don't get spurious unknown-key warnings when configuring it.
- Replace in-place mutation of tool result content with immutable spread
to prevent corrupting shared conversation message objects.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add stop and backtrack to triage-ui classification labels
The Classification type gained stop and backtrack variants from main
but triage-ui.ts was not updated, causing a TypeScript build failure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: context masker and tool truncation operate on correct pi-ai message format
The observation masker and tool result truncation in before_provider_request
were checking m.type === "toolResult" but the actual pi-ai payload uses
m.role === "toolResult" with content as TextContent[] arrays (not strings).
bashExecution messages are converted to {role:"user"} by convertToLlm before
the hook fires, so checking m.type === "bashExecution" was a no-op.
- Fix context-masker to match on role, handle array content, detect bash
results by their "Ran `" prefix
- Fix register-hooks truncation to operate on role:"toolResult" with
array content blocks
- Update tests to use correct pi-ai LLM payload format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- custom-models.md: add Command Allowlist section under Value Resolution
explaining the restriction, default list, and how to override via
allowedCommandPrefixes setting or GSD_ALLOWED_COMMAND_PREFIXES env var
- configuration.md: add URL Blocking (fetch_page) section documenting
what's blocked by default, why, and how to allowlist specific hosts
via fetchAllowedUrls setting or GSD_FETCH_ALLOWED_URLS env var
- configuration.md: add both env vars to the Environment Variables table
Closes#2699
The Discord badge in README.md pointed to https://discord.gg/gsd (expired
vanity URL) and the Pi ecosystem doc used an old invite code. Both now use
the canonical invite https://discord.com/invite/nKXTsAcmbT that was
established in commit 0a1dad9a.
Adds a regression test that validates all Discord invite links in
user-facing files match the canonical URL.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Flip two safety mechanisms from opt-in to opt-out so all users benefit
from rollback protection and merge regression checks without manual
configuration.
- git.snapshots: false → true (creates recovery refs before destructive ops)
- git.pre_merge_check: false → "auto" in solo mode (auto-detects test runner)
Both remain configurable; users can explicitly disable with snapshots: false
or pre_merge_check: false.
Closes#2677
All other .gsd/ state files use uppercase naming (DECISIONS.md,
REQUIREMENTS.md, PROJECT.md, etc). This renames the canonical
preferences file to PREFERENCES.md while keeping a migration
fallback — the loader checks PREFERENCES.md first, then falls
back to lowercase preferences.md for existing installations.
Closes#2700
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
osascript display notification is silently swallowed by macOS when the
calling terminal app (Ghostty, iTerm2, etc.) lacks notification
permissions in System Settings. The command exits 0 with no error,
making the failure invisible.
terminal-notifier registers as its own Notification Center app, so
macOS prompts the user for permission on first use — the expected UX.
Changes:
- Add findExecutable() helper to locate terminal-notifier on PATH
- buildDesktopNotificationCommand() prefers terminal-notifier when
available, falls back to osascript (preserving existing behavior)
- Update tests to handle both terminal-notifier and osascript paths
- Add macOS delivery note to docs/configuration.md notifications section
- Add troubleshooting entry for notifications not appearing on macOS
Fixes#2632
Co-authored-by: Yang Yang(NYC) <Yang.Yang2@bcg.com>