Commit graph

2598 commits

Author SHA1 Message Date
Mikael Hugo
86026c9e4f feat(sf): final UOK parity pass + secondary agent sweep
Evidence-collector (matches gsd2 exactly):
- recordToolCall now takes toolCallId as first arg (parallel-call fix)
- recordToolResult matches by toolCallId, not last-unresolved heuristic
- saveEvidenceToDisk now atomic tmp-rename JSON (not appendFileSync JSONL)
- clearEvidenceFromDisk added; resetEvidence takes no args
- stricter isEvidenceArray validator

auto/loop.ts:
- PID guard in loadStuckState prevents cross-test state pollution
- pid field added to saveStuckState payload
- saveCustomVerifyRetryCounts uses atomicWriteSync (crash-safe)

auto/run-unit.ts:
- chdir failure marked isTransient:true (dir may exist on retry)

auto/session.ts:
- canAskUser field added with reset() support

auto/phases.ts:
- currentUnit = null in closeoutAndStop (no stale refs after stop)

bootstrap/provider-error-resume.ts:
- resetTransientRetryState injectable via ProviderErrorResumeDeps

Secondary sweep (worktree, workflow, token-counter, verification-gate,
activity-log, doctor-environment, json-persistence, scaffold-keeper tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 02:17:21 +02:00
Mikael Hugo
9db94ed77e chore(sf): residual session work — final consolidation
Last batch from the parallel swarm session: docstring tweaks,
verification-gate doc additions, workflow-reconcile and worktree-command
follow-ups, doctor-environment cleanup. Typecheck clean.

Most of the session work landed in earlier commits (8be8f4774, 3045538cb,
038938f2a, ed85252fc, 4f4b584e5, etc.); this commit is the residual
working-tree state after all swarms reported.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 02:17:03 +02:00
Mikael Hugo
f1cef7c476 feat(sf): multi-agent sweep — paths, verification, auto closeout, bootstrap, worktree
- paths.ts: add resolveSliceSummaryPath, resolveCheckpointPath, task-summary helpers
- bootstrap/system-context.ts: worktree active context + codebase-map inject
- auto.ts: plumb autonomousMode flag, startAuto options expansion
- auto/loop.ts: Math.max(0,...) clock-skew guard in enforceMinRequestInterval
- auto/session.ts: add lastUnitAgentEndMessages and PreExecFailure tracking
- auto-post-unit.ts: clearEvidenceFromDisk after verification, isDeterministicPolicyError
- auto-unit-closeout.ts: populate lastPreExecFailure on gate failures
- cache.ts: fix TTL helper arg counts
- codebase-generator.ts: add incremental refresh helpers
- commands/handlers/auto.ts: wire autonomousMode and plan-v2 flags
- context-budget.ts: remove stale context-budget trimming (was dead code)
- dispatch-guard.ts: trim unused guards
- doctor-{environment,runtime-checks}.ts: expand health checks
- execution-instruction-guard.ts: add approval-boundary guard
- gate-registry.ts: de-dup gate registration on reload
- gitignore.ts: add .sf/worktrees to default gitignore
- notification-store.ts: add dedup window + category grouping
- pre-execution-checks.ts: add provider-readiness pre-check
- preferences.ts: subscription cost helpers + allow_flat_rate_providers
- production-mutation-approval.ts: approval-required flag on mutation tools
- state.ts: remove redundant fallback (now handled in deriveState)
- token-counter.ts: subscription token usage tracking
- verification-gate.ts: gate retry on bounded failure class
- workflow-{projections,reconcile,template-compiler,templates}: hardening
- worktree-{command,manager}: path normalization + active-worktree tracking
- tests/verification-evidence.test.ts: new — evidence load/save/clear coverage
- tests/provider-errors.test.ts: add missing provider-delay tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 02:16:13 +02:00
Mikael Hugo
d828f9861f chore(sf): residual edits from parallel autonomous + bug-hunt sweep
Touches auto.ts, auto/loop.ts, preferences.ts, safety/git-checkpoint.ts,
token-counter.ts, tools/complete-slice.ts, verification-gate.ts,
workflow-logger.ts, workflow-migration.ts, plus new
tests/record-promoter.test.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 02:09:11 +02:00
Mikael Hugo
3045538cbe feat(sf): bug-hunt fixes, UOK phase hardening, model policy, record-promoter
- auto/loop.ts: runLegacyAutoLoop / runUokKernelLoop contract routing fixes
- auto/phases.ts: plan-gate in runDispatch, verification gate in runFinalize,
  consecutiveSessionTimeouts exponential backoff, structuredQuestionsAvailable
  passed to resolveDispatch (GAP-13)
- auto/run-unit.ts: _setSessionSwitchInFlight cleared on timeout (GAP-11)
- safety/git-checkpoint.ts: remove stash-before-rollback (user: never stash)
- bootstrap/system-context.ts: fix "system-context" → "bootstrap" LogComponent
- preferences-models.ts: fill missing unit-type routing buckets
- post-execution-checks.ts + tests: type-safe post-exec check expansion
- session-model-override.ts: add override-clear helper
- tests/provider-errors.test.ts: add resetTransientRetryState to all mocks
- memory-relations.ts: add cross-entity relation helpers
- memory-store.ts: fix ranked memory pagination
- onboarding-state.ts: add step-completion persistence
- cache.ts: add TTL-aware get helpers
- definition-io.ts: stricter parse with field validation
- blocked-models.ts: add provider-level block support
- worktree-{manager,resolver}: path normalization edge cases
- commands/catalog.ts: register skill-health and record-promoter commands
- workflow-mcp.ts: MCP tool registration improvements
- agentic-docs-scaffold.ts: clarify scaffold header comment
- headless-events.ts: EXIT_RELOAD + notification dedup boundary
- record-promoter.ts: new — promotes draft records to canonical location
- docs/records/2026-05-02-bug-hunt-findings.md: bug-hunt audit findings log

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 02:03:55 +02:00
Mikael Hugo
8be8f4774b feat(sf): autonomous agent sweep — docstrings, robustness, preferences, workflow reconcile
- headless-events: add EXIT_RELOAD handling and dedup boundary types
- atomic-write: improve tmp-file cleanup and error reporting
- auto-model-selection: add flat-rate provider filtering and cost-aware routing stubs
- auto-worktree: strengthen worktree validation paths
- auto/phases.ts: emit artifact-verification-retry journal event on bounded retry
- auto/run-unit.ts: anchor cwd before session init, add AbortController for timeout
- benchmark-selector, captures, definition-loader: docstring/robustness sweep
- bootstrap/{notify-interceptor,provider-error-resume,write-gate}: error path hardening
- branch-patterns, git-constants, git-self-heal: comment/constant clarifications
- commands-{logs,maintenance}: expose additional log and maintenance commands
- custom-verification, post-execution-checks, pre-execution-checks: defensive fixes
- doctor: expand check coverage and structured output
- gate-registry: improve gate deduplication and ordering
- json-persistence: add atomic-write path and versioned schema helpers
- notifications: add dedup window and notification grouping
- preferences-types: add subscription_monthly_cost_usd + subscription_monthly_tokens
- production-mutation-approval, skill-health, skill-manifest: hardening sweep
- structured-data-formatter: improve table rendering edge cases
- workflow-events, workflow-manifest, workflow-reconcile: reconcile robustness
- worktree-{manager,resolver}: path normalization fixes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 01:57:24 +02:00
Mikael Hugo
c6a7c7772d chore(sf): autonomous docstring sweep — additional SF extension files
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:52:37 +02:00
Mikael Hugo
038938f2ac fix: headless EXIT_RELOAD case + notification dedup boundary
- src/headless-events.ts: add case "reload" → EXIT_RELOAD (12).
  EXIT_RELOAD sentinel was defined but unused — "reload" status fell
  through to EXIT_ERROR (1).
- src/resources/extensions/sf/notification-store.ts:109: use <= for
  dedup window so a second identical notification at exactly
  DEDUP_WINDOW_MS still gets suppressed (was off-by-one at boundary).
- src/resources/extensions/sf/definition-loader.ts: pending docstring
  tweaks from autonomous sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:52:29 +02:00
Mikael Hugo
7824cb527c docs(sf): expand rebuildState docstring for clarity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 01:51:26 +02:00
Mikael Hugo
e7347fe499 chore(sf): docstring sweep across remaining SF extensions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:50:11 +02:00
Mikael Hugo
93b1841735 chore(sf): docstring tweaks in notification-overlay + self-feedback
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:49:10 +02:00
Mikael Hugo
229ade7e45 chore(sf): more docstring tweaks in auto/phases + bootstrap/write-gate
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:49:03 +02:00
Mikael Hugo
3dfc60e04b chore(sf): follow-up docstring tweaks in doctor.ts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:48:57 +02:00
Mikael Hugo
4f4b584e53 feat(sf): worktree hardening, skip-slice handler, cwd anchoring + docstrings
- new worktree-root.ts / worktree-session-state.ts: track and restore
  original project root after /worktree merge or /worktree return
- new tools/skip-slice.ts: cascade skip to tasks in the slice so milestone
  completion isn't blocked by pending tasks (#4375)
- auto/run-unit.ts: anchor cwd to basePath before newSession() captures it
  (GAP-10) — prevents tool runtime / system prompt from rooting on drifted
  cwd from async_bash, background jobs, or prior unit cleanup
- safety/git-checkpoint.ts: harden HEAD-rev-parse against execFileSync
  errors, surface stderr properly
- broad JSDoc / docstring pass across the rest of the SF extension surface

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:48:37 +02:00
Mikael Hugo
ed85252fc5 feat: plumb /sf autonomous full + add docstrings on the auto-command path
`/sf autonomous full` (or `--full`) plumbs through to AutoSession.fullAutonomy,
to be consumed at milestone-complete to skip the human-review pause and
auto-merge + chain to the next milestone. Git revert is the safety net
(see ADR-019/021 conversation on autonomy and reversibility).

Plumbing path:
- commands/handlers/auto.ts: parses `full` / `--full` modifier, threads
  fullAutonomy through launchAuto options
- commands/catalog.ts: completion entries for `full` and `--full`
- auto.ts: startAuto and startAutoDetached accept fullAutonomy in options;
  startAuto pins it on the session up-front so resume paths preserve it
- auto/session.ts: AutoSession.fullAutonomy field with full docstring

Behavior change is staged: the milestone-complete consumer that auto-merges
and chains is intentionally not in this commit (parallel session is active
in auto-post-unit.ts and auto/loop.ts; will land in a follow-up).

Also adds JSDoc to the functions on the touched path:
- handleAutoCommand (full command-family doc)
- launchAuto (headless vs detached routing)
- startAutoDetached (fire-and-forget rationale, why it diverges from startAuto)
- AutoSession.fullAutonomy (full inline doc)

Typecheck clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 01:36:29 +02:00
Mikael Hugo
356d1d1f99 feat(uok): port gsd2 resilience patterns — rate-limit, evidence reload, provider recovery
loop.ts:
- saveStuckState on main dev path (was only on custom-engine path — P1 fix)
- Add pid to stuck-state JSON to prevent test pollution across process runs
- Use atomicWriteSync in saveCustomVerifyRetryCounts for crash-safety
- Add enforceMinRequestInterval + call before both runUnitPhaseViaContract sites
- Update s.lastRequestTimestamp from requestDispatchedAt on each unit

session.ts:
- Add lastRequestTimestamp and lastUnitAgentEndMessages fields

phases.ts:
- Add consecutiveSessionTimeouts + exponential-backoff auto-resume (up to 3x)
  for session-creation timeouts before pausing for manual review
- Add loadEvidenceFromDisk after resetEvidence to rehydrate evidence on restart
- Add USER_DRIVEN_DEEP_UNITS + isAwaitingUserInput guard to skip artifact
  verification when a deep-planning unit is paused awaiting user input
- Store s.lastUnitAgentEndMessages after each unit run
- Add requestDispatchedAt to runUnitPhase return type

evidence-collector.ts: add loadEvidenceFromDisk export
auto-post-unit.ts: add USER_DRIVEN_DEEP_UNITS set + re-export isAwaitingUserInput
user-input-boundary.ts: port from gsd2 (isAwaitingUserInput + approval helpers)
run-unit.ts: capture requestDispatchedAt at API dispatch time
kernel.ts: remove redundant !legacyFallback guard (enabled already encodes it)
tests/uok-kernel-path.test.ts: add SF_UOK_AUDIT_ENVELOPE env var assertions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 01:27:37 +02:00
Mikael Hugo
dda1bc1206 test: make uok-gitops-wiring assertion whitespace-tolerant
The test was checking for a literal single-line ternary in auto-post-unit.ts,
but the formatter naturally renders the same ternary multi-line. The semantic
content is identical; the test was failing on whitespace alone.

Normalize runs of whitespace before substring-matching so the assertion
survives prettier/biome formatting changes.

After this fix: 39/39 uok tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 01:21:36 +02:00
Mikael Hugo
9c20ebd76b feat(uok): wire ExecutionGraphScheduler into kernel loop path
- loop.ts: add DispatchContract type, AutoLoopOptions, resolveDispatchNodeKind,
  runUnitPhaseViaContract — kernel path routes unit execution through
  ExecutionGraphScheduler; legacy path passes through directly
- loop.ts: export runUokKernelLoop (contract=uok-scheduler) and
  runLegacyAutoLoop (contract=legacy-direct)
- auto-loop.ts: re-export both new loop functions
- auto.ts: use runUokKernelLoop/runLegacyAutoLoop at both call sites
- phases.ts: use uokFlags.planningFlow for plan gate (was bypassing
  legacyFallback via raw pref read)
- auto-dispatch.ts: use hasFinalizedMilestoneContext for execution-entry
  context check (picks up SF_PROJECT_ROOT artifact fallback)
- tests: port uok-writer, uok-parity-report, uok-loop-adapter-writer,
  uok-kernel-path test files from gsd2 — all 8 tests pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:54:15 +02:00
Mikael Hugo
ca5d2880ec polish: tighten scaffold-keeper signature + dedupe Pending report row
Follow-up to commit 39e2dc70c. Two small improvements that surfaced when
the parallel Phase D subagent finished and inspected the worktree:

- commands-scaffold-sync.ts:
  - Tighten ScaffoldKeeperFn to match Phase D's actual dispatcher signature
    (basePath, ctx) => Promise<number>. Define a local minimal
    ScaffoldKeeperCtxShape for the lazy loader so we don't form a hard
    import dependency on scaffold-keeper.ts.
  - Remove duplicated "Upgradable" line from the report table — keep only
    "Pending" since ADR-021 §10 names that the user-facing label.
- tests/scaffold-keeper.test.ts: better-typed notify stub; covers Phase E
  arg-parser helpers (parseScaffoldSyncArgs, matchesOnly, applyOnlyFilter).

Typecheck clean. 49/49 scaffold tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:49:43 +02:00
Mikael Hugo
39e2dc70c9 feat: ADR-021 Phase D + E — scaffold-keeper agent + /sf scaffold sync command
Phase D: scaffold-keeper background agent
- scaffold-keeper.ts: dispatchScaffoldKeeperIfNeeded fires async after milestone
  completion and on stopAuto cleanup. Detects editing-drift items, writes
  <file>.proposed artifacts (template-only stub for now; later wires the
  records-keeper skill subagent for code-as-fact merging), emits a structured
  approval_request notification with stable dedupe_key so repeated runs don't
  spam the user.
- Wired into auto-post-unit.ts and auto.ts:stopAuto via fire-and-forget so
  the auto loop is never blocked by scaffold work.
- Failure modes non-fatal: try/catch around the dispatch, errors logged via
  logWarning("scaffold").

Phase E: /sf scaffold sync command (escape hatch)
- commands-scaffold-sync.ts: parseScaffoldSyncArgs + handleScaffoldSync.
- Flags:
    --dry-run         report what would change, no writes
    --include-editing run scaffold-keeper synchronously for editing-drift items
    --only=<glob>     scope to a path glob (suffix/prefix match)
- Wired into the SF command system via commands-bootstrap.ts, commands/catalog.ts,
  and commands/handlers/ops.ts following the existing /sf <verb> pattern.
- Reuses ensureAgenticDocsScaffold from Phase C — doesn't reimplement sync logic.

Doctor finding (checkScaffoldFreshness) refined to reference the new command.

Tests: 8 new cases in scaffold-keeper.test.ts. All 49 scaffold tests green.

Together with Phases A-C, this completes ADR-021. Documents are now versioned,
upgrades are automatic for the safe cases, and editing-drift surfaces through
.proposed artifacts and structured notifications. The scaffold-keeper agent
body is currently a template-only stub; replacing it with a real records-keeper
subagent dispatch is a follow-up that the architecture now enables.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:45:54 +02:00
Mikael Hugo
14b5c2b12c test: add Phase C coverage for drift-aware ensureAgenticDocsScaffold
Phase C (automatic silent sync) had no dedicated tests when committed.
Added 8 cases covering:
- ensureAgenticDocsScaffold on empty dir creates files with markers
- old-version pending marker silently re-renders to current
- editing-drift file left untouched
- legacy unmarked file matched against archive promoted to pending
- migrateLegacyScaffold idempotency

Total scaffold test count: 41 (was 33).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:43:19 +02:00
Mikael Hugo
d01b2f0b7f feat(uok): complete pipeline integration and close all parity gaps vs gsd2
- flags: gitopsTurnAction default → "commit" (ensures git history per turn)
- kernel: add runKernelLoop routing, parity label → "uok-kernel"
- auto: pass runKernelLoop at both call sites
- loop-adapter: already had writer token acquire/release (confirmed at parity)
- gate-runner: already had try/catch, dynamic ceiling, maxAttempts (confirmed)
- audit: isStaleWrite guard already present (confirmed at parity)
- plan-v2: add emptyGraph/sliceCount fields, isEmptyPlanV2GraphResult export,
  allow validating/completing-milestone with zero task nodes + slices present
- phases: add empty-graph recovery (invalidate-caches + re-derive) in runPreDispatch
- execution-graph: add ExecutionGraphSnapshot interface + buildExecutionGraphSnapshot
- auto-dispatch: wire buildDispatchEnvelope at all 3 dispatch exit points,
  emit dispatch-envelope audit event when gates or auditEnvelope enabled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:42:41 +02:00
Mikael Hugo
2cb3f5f75a feat: ADR-021 Phase C — automatic silent scaffold sync
The user-visible "automatic" upgrade behavior. After this lands, projects
pointed at SF silently catch up to the current scaffold without any user
action — for the simple cases.

Drift-aware ensureAgenticDocsScaffold:
- Step 1: migrateLegacyScaffold runs first to promote unmarked-but-recognised
  files via SCAFFOLD_VERSION_ARCHIVE hash matching
- Step 2: per-template walk:
  - Missing → create + stamp + manifest entry (existing behavior)
  - Present, marker, state=pending, version drifted, hash matches stamp
    → silent re-render with current template + restamp (NEW)
  - Editing/completed/customized → leave alone (Phase D handles editing-drift)
- Silent contract: no stdout/stderr, only logWarning("scaffold") for I/O
  failures. All failure modes non-fatal.

SCAFFOLD_VERSION_ARCHIVE bootstrap:
- Lazily seeded with current SF version's body hashes from SCAFFOLD_FILES
- Future SF releases append entries when templates change so legacy projects
  can match against any prior version

checkScaffoldFreshness doctor finding (ADR-021 §8):
- Surfaces missing/upgradable/editing-drift counts as "scaffold_drift" warning
- Auto-fix runs ensureAgenticDocsScaffold to handle missing+pending
- Non-fatal warning, never blocks dispatch
- Editing-drift left for Phase D (scaffold-keeper background agent)

Tests pass: 33/33 across scaffold-versioning + scaffold-drift suites.
Typecheck clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:39:44 +02:00
Mikael Hugo
deab93bed6 test: split scaffold tests into per-module files; fix require() in ESM test
Subagent split scaffold tests into scaffold-versioning.test.ts (Phase A)
and scaffold-drift.test.ts (Phase B). Fixed an ESM-incompatible
require("node:fs") in one drift test that was breaking with
--experimental-strip-types. All 33 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:35:12 +02:00
Mikael Hugo
6f9a99da0a feat: ADR-021 Phase A+B — scaffold versioning + drift detection
Foundation for automatic scaffold upgrades. Data plane only — Phase C
wires drift detection into the existing scaffold pipeline.

New modules:
- scaffold-versioning.ts: HTML-comment markers on Markdown scaffold
  files (sf-doc: version=X template=Y state=pending hash=sha256:Z),
  body-hash helpers, manifest read/write/dedup, stamp helpers.
  Manifest at .sf/scaffold-manifest.json.
- scaffold-drift.ts: detectScaffoldDrift returns five buckets
  (missing/upgradable/editing-drift/untracked/customized) per ADR-021.
  migrateLegacyScaffold stub for Phase C archive support.

Wired in:
- agentic-docs-scaffold.ts: new files get markers + manifest entries.
  NO_MARKER_PATHS list excludes .siftignore (per ADR-021 §2 — dotfile
  config tooling fights inline markers).
- gitignore.ts: PREFERENCES.md template gains sf_template_state and
  sf_template_hash frontmatter fields, extending the existing
  last_synced_with_sf pattern.
- preferences-types.ts: SFPreferences interface adds the two new
  optional fields; KNOWN_PREFERENCE_KEYS updated.

Tests (23 cases, all pass):
- parseMarker / formatMarker round-trip
- bodyHash determinism
- stampScaffoldFile new + replace-existing-marker
- manifest read/write/dedup
- detectScaffoldDrift bucket assignment

Behavior unchanged: existing files in existing projects are left alone.
Phase C uses these primitives to make automatic sync transparent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:32:15 +02:00
Mikael Hugo
851bd7fca3 feat(uok): enforce gates, port gsd2 modules, flip flags to on-by-default
- Wire plan-gate in runDispatch() and verification gate in runFinalize()
- Add planningFlow gate persistence in guided-flow.ts
- Add execution-graph gate event in auto-dispatch.ts
- Flip all UOK feature flags from opt-in (=== true) to on-by-default (?? true)
- Port dispatch-envelope.ts, parity-report.ts, writer.ts from gsd2
- Add DispatchReasonCode, UokDispatchEnvelope, WriterToken, WriteRecord,
  WriteSequence, DispatchExplanation to contracts.ts
- Add "refine" to UokNodeKind
- Extend auto-worktree.ts with workspace.after_create hook support
- Add workspace.after_create to preferences-types and preferences-validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:26:10 +02:00
Mikael Hugo
0399bb9c8c detection: fix 6 bugs surfaced by ace-coder validation
Phase 4-D fixes from the Phase 3 validation report. ace-coder is a
uv-managed Python repo with Rust crates in subdirectories; SF was
mis-detecting it in ways that would have failed every autonomous
verification.

1. detectPackageManager: return undefined when no root package.json
   (previously hallucinated "npm" as default, leaking into reports)
2. detectVerificationCommands: only synthesize npm runner when
   package.json actually present at root
3. ROOT_ONLY_PROJECT_FILES: expanded with Cargo.toml, go.mod,
   pyproject.toml, setup.py, pom.xml, pubspec.yaml, Package.swift,
   mix.exs — these are root-only signals; nested instances are
   handled explicitly by emitter logic
4. Cargo block: distinguishes workspace-root vs single-crate-root vs
   nested-only-crates layouts; emits per-crate bash loop for the last
   case (mirrors the Go multi-module branch pattern)
5. pyprojectHasTool: matches both [tool.X] and [tool.X.subkey] so
   ace-coder's [tool.ruff.lint] / [tool.ruff.format] are detected
6. Makefile branch: skip `make test` when (a) test command already
   emitted by another block, or (b) the test target depends on
   _verify_nix or similar nix-shell gates (ace-coder's case)

After these fixes, detectProjectSignals on ace-coder yields the
expected output: no spurious "npm", per-crate cargo loops, ruff/pyright
detected, no nix-gated `make test`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 00:19:49 +02:00
Mikael Hugo
064dff2f0f feat: SF strengthening + ADR-020 wire architecture (Phases 1-2)
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>
2026-05-02 00:03:34 +02:00
Mikael Hugo
3d8e8c5d57 detection: skip Python tool caches during project scans
Adds __pycache__, .pytest_cache, .mypy_cache, .ruff_cache, .tox, .eggs,
and htmlcov to RECURSIVE_SCAN_IGNORED_DIRS so SF doesn't walk into them
when scanning project files. These directories can contain thousands of
files in mature Python projects and were slowing down detection / scan
operations on Python codebases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 23:49:46 +02:00
Mikael Hugo
e7519e904d feat: SF stays standalone forever; strengthen Python/Rust detection
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>
2026-05-01 23:48:17 +02:00
Mikael Hugo
10936277a5 fix: make isMilestoneReadyNotification metadata-authoritative
When metadata is present, skip the text fallback entirely — the emitter
declared the event kind explicitly and the regex should not override it.
Add regression test file covering all acceptance criteria: metadata-first
classification, legacy fallback, dedupe_key dedup, and the key invariant
that automated notices cannot produce terminal/blocked signals.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 23:08:55 +02:00
Mikael Hugo
a055b3adf2 feat: structured notification event model with metadata-first classification
Replace brittle string-matching in headless-events.ts with structured
source/kind/blocking/dedupe_key metadata on notify() events. String
matching is preserved as a fallback for the ~940 untagged call sites.

- Add NotificationMetadata type to headless-types.ts (canonical definition)
- Extend rpc-types.ts notify event with optional metadata field
- Extend ExtensionUIContext.notify() signature with optional 3rd arg
- Pass metadata through RPC notify implementation in rpc-mode.ts
- Update headless-events.ts: isTerminalNotification, isBlockedNotification,
  isMilestoneReadyNotification, isPauseNotification all check metadata first
- Update notification-store.ts: store metadata on NotificationEntry; use
  metadata.dedupe_key as dedup key when provided (falls back to message hash)
- Update notify-interceptor.ts to thread metadata through to store + original
- Tag critical emit sites with structured metadata:
  stopAuto → { kind: "terminal" } (+ blocking: true when reason includes "block")
  pauseAuto → { kind: "terminal", blocking: true }
  guided-flow milestone ready → { kind: "approval_request", blocking: true }
- Update notification-overlay.ts to prefer metadata.source for [label] display
- Add 17-test regression suite (notification-event-model.test.ts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 23:07:57 +02:00
Mikael Hugo
6f877b61ab feat: harness scaffold, runtime pattern sync, and ARCHITECTURE injection
- 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>
2026-05-01 22:46:28 +02:00
Mikael Hugo
16ff608d80 feat: implement ADR-001 gitignore split and fill placeholder docs
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>
2026-05-01 22:32:28 +02:00
Mikael Hugo
a611cd5792 feat: introduce repo-vcs skill and add JSDoc annotations across core modules
- 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>
2026-05-01 21:36:32 +02:00
Mikael Hugo
12e7333f1c feat: stabilize autonomous workflow system 2026-05-01 20:18:50 +02:00
Mikael Hugo
15c3c2d077 sf snapshot: pre-dispatch, uncommitted changes after 41m inactivity 2026-04-30 23:55:20 +02:00
Mikael Hugo
9843425836 sf snapshot: pre-dispatch, uncommitted changes after 31m inactivity 2026-04-30 23:13:30 +02:00
Mikael Hugo
2bc8d0cdd3 fix: route vision debate subagents correctly 2026-04-30 22:02:41 +02:00
Mikael Hugo
78be73fcb8 fix: stabilize sf auto and subagent routing 2026-04-30 21:55:17 +02:00
Mikael Hugo
da324da27e test: Add idempotency, schema validation, and --ci behavior tests to co…
SF-Task: S04/T02
2026-04-30 21:43:49 +02:00
Mikael Hugo
a7b96cd004 sf snapshot: pre-dispatch, uncommitted changes after 46m inactivity 2026-04-30 21:07:36 +02:00
Mikael Hugo
b43bf6991e sf snapshot: pre-dispatch, uncommitted changes after 47m inactivity 2026-04-30 20:21:12 +02:00
Mikael Hugo
69be7aeeaa feat: Added renderSkillProposal() to detect recurring patterns in triag…
- src/resources/extensions/sf/commands-todo.ts
- src/resources/extensions/sf/tests/commands-todo.test.ts

SF-Task: S03/T01
2026-04-30 19:31:40 +02:00
Mikael Hugo
30586f36f8 feat: Add backlog JSONL writer to appendBacklogItems() with BacklogEntr…
- src/resources/extensions/sf/commands-todo.ts

SF-Task: S02/T01
2026-04-30 19:13:34 +02:00
Mikael Hugo
2111da8e60 sf snapshot: pre-dispatch, uncommitted changes after 53m inactivity 2026-04-30 19:10:38 +02:00
Mikael Hugo
40e0835d5e test: Add unit tests for triage routing and edge cases in commands-todo…
- src/resources/extensions/sf/tests/commands-todo.test.ts

SF-Task: S01/T02
2026-04-30 18:16:43 +02:00
Mikael Hugo
e90298f2e0 sf snapshot: pre-dispatch, uncommitted changes after 120m inactivity 2026-04-30 17:44:03 +02:00
Mikael Hugo
d8a9d63c87 feat: Replaced bare error writes in cli.ts, headless.ts, and startup-mo…
- src/cli.ts
- src/headless.ts
- src/startup-model-validation.ts

SF-Task: S04/T03
2026-04-30 15:43:29 +02:00
Mikael Hugo
8677e73046 sf snapshot: pre-dispatch, uncommitted changes after 97m inactivity 2026-04-30 15:11:45 +02:00