P1 (phase-timeout mutation race): withPhaseTimeout now stores the still-running
phase promise in _danglingPhasePromise when a timeout fires. Each loop iteration
drains that promise (with try/catch) before starting new work, preventing the
timed-out phase from mutating state concurrently with the next iteration.
P2 (verification_status backfill): Schema migration v17 now runs a backfill UPDATE
after adding the new column, deriving verification_status from existing
verification_evidence rows. Projects upgraded mid-slice will have correct
all_pass/partial/all_fail values immediately rather than empty strings that
bypass the prior-task guard.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- compaction: fix repeated compaction dropping kept messages (#2608)
Re-summarize from previous compaction's firstKeptEntryId instead of
prevCompactionIndex+1; use buildSessionContext for accurate tokensBefore
- edit: add multi-edit support via edits[] array
Single call can update multiple disjoint regions in one file;
applyEditsToNormalizedContent matches all edits against original content
and applies in reverse order for stable offsets
- bash: persist full output when line-count truncation occurs (#2852)
ensureTempFile now called on any truncation, not only byte overflow;
prevents data loss when output exceeds line limit before byte threshold
- bash-executor: same fix for remote/operations-based execution
ensureTempFile includes SF cleanup registration (registerTempCleanup,
bashTempFiles tracking)
- grep: include lineText from rg JSON events to avoid per-match file reads
Eliminates stall when context=0 on broad searches (#3148)
- agent-session: forward isError override from afterToolCall extension hook
Allows extensions to change error status of tool results (#3051)
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>
Anthropic OAuth was removed in v2.74.0 for TOS compliance (#3952). Users
who upgraded through that version still have type:"oauth" entries under
`anthropic` in auth.json which cannot resolve to a valid API key.
stale entry, so hasAuth("anthropic") kept reporting true and masked the
claude-code fallback path. Users had to hand-edit auth.json to recover.
Self-heal instead:
- AuthStorage.removeLegacyOAuthCredential(provider) strips only
type:"oauth" entries and preserves any api_key credentials.
- sdk.ts getApiKey() calls it when the legacy-OAuth branch triggers,
logs a one-line warning, and throws a message pointing the user at
the "claude-code" provider when the `claude` binary is in PATH, or
at ANTHROPIC_API_KEY otherwise.
Closes#4399
(cherry picked from commit b8ef6604617fda239a037cf5d5e6020b168d2e62)
ChatGPT-backed Codex sign-in no longer exposes the removed 5.1/5.2 Codex variants. Filter those models from openai-codex OAuth so GSD stops surfacing selections that immediately fail while leaving API-key-backed OpenAI models available.
(cherry picked from commit 1aedba583916826fc5c6129037f61e9802010e46)
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>
- 15 tests for ModelRegistry.getModelsForProxy covering family priority
ordering, auth-ready promotion, overrides, and edge cases
- Fix StreamOptions cast in proxy-server.ts (lost during rebase conflict)
- Fix .ts import extension in args.test.ts (pre-existing)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- model-registry: export PROXY_FAMILY_PRIORITY and GLOBAL_PROVIDER_FALLBACK
constants; add getModelsForProxy() returning candidates ordered by family
priority then global fallback (opencode → opencode-go → openrouter →
ollama-cloud); add getModel() convenience wrapper
- proxy-server: add priorityOverrides option; handleChat iterates all
candidates in priority order and falls through to the next on 429
- settings-manager: add ProxySettings type with providerPriority override
map; add getProxyProviderPriority() / setProxyFamilyProvider() accessors
- settings-selector: add ProxyPrioritySubmenu — a two-level TUI submenu
(family → provider) that dynamically generates entries from
PROXY_FAMILY_PRIORITY; wired in interactive-mode with full callback
Family defaults: MiniMax→minimax, GLM→zai, Kimi→kimi-coding,
MiMo→global-fallback, Gemini/Gemma→google-gemini-cli, Claude→anthropic,
GPT/o-series→openai
https://claude.ai/code/session_013BwmqG3NuwwZY3vsUb4Y9Y
Co-authored-by: Claude <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>
Align module declaration with file rename (gsd_parser.rs → forge_parser.rs)
that was completed in the rebrand.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Function hasMissingWorkspaceScopes() was checking for @gsd directories
but its comment and usage indicated it should check for @sf-run scopes.
Update the check to match the renamed scope.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Loader was creating @gsd directories in node_modules but cli.js imports
@sf-run/* packages. This mismatch caused module resolution failures.
Rename gsdScopeDir to sfRunScopeDir and update scope to @sf-run.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>