Commit graph

3733 commits

Author SHA1 Message Date
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
ed47951960 feat(pi-ai): delegate google-gemini-cli auth + project to cli-core
Replace ~700 LOC of hand-rolled OAuth and onboarding with cli-core's own
getOauthClient + setupUser. The provider now reads ~/.gemini/oauth_creds.json
itself (via cli-core), refreshes tokens, and discovers the Code Assist
project + tier server-side — exactly like the real gemini CLI does.

- provider/google-gemini-cli.ts: drop apiKey={token,projectId} JSON
  plumbing; getCodeAssistServer() uses cli-core for everything
- delete utils/oauth/google-gemini-cli.ts (457 LOC: hand-rolled login,
  PKCE, callback server, discoverProject, onboardUser, tier handling)
- delete utils/oauth/google-oauth-utils.ts (201 LOC: only consumed by
  the deleted gemini-cli helper)
- oauth/index.ts: remove gemini-cli from BUILT_IN_OAUTH_PROVIDERS
  registry; google-gemini-cli is no longer SF-managed
- auth-storage.ts: update 3 error messages to direct users to the real
  gemini CLI for authentication instead of the removed /login command

Login UX: users authenticate with the real gemini CLI; we just consume
~/.gemini/oauth_creds.json. Whole-provider disable goes through manual
settings.json edit (per-model toggle still works in interactive UI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 01:47:48 +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
eb56173fe5 ADR-021: versioned documents + automatic upgrade via records-keeper
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>
2026-05-02 00:18:16 +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
2280893464 ADR-019: clarify MCP is a temporary external-coder scaffold, not production wire
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>
2026-05-01 23:38:25 +02:00
Mikael Hugo
0976bbbb83 docs: add ADR-019 workspace VM convergence architecture
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>
2026-05-01 23:21:23 +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
51202225ec test: Add canonicalizePath() utility using fs.realpathSync() with symli…
SF-Task: S01/T02
2026-04-30 22:42:08 +02:00
Mikael Hugo
8418e88730 feat: Port R101 setWorkingVisible API and R104 Azure Cognitive Services…
SF-Task: S01/T01
2026-04-30 22:28:01 +02:00
Mikael Hugo
2bc8d0cdd3 fix: route vision debate subagents correctly 2026-04-30 22:02:41 +02:00
Mikael Hugo
9a0fdbe7bd chore: stop tracking generated native npm output 2026-04-30 22:00:36 +02:00
Mikael Hugo
cd7a3ba58f chore: auto-commit after complete-milestone
SF-Unit: M005
2026-04-30 21:57:46 +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
8e4081e6f1 test: Verified existing tests cover skill proposal writer and all four…
SF-Task: S03/T02
2026-04-30 19:33:16 +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
Mikael Hugo
b26dca40ec fix: Stop milestone completion git archaeology 2026-04-30 13:34:24 +02:00
Mikael Hugo
0f27ffe865 fix: Let safe smoke tasks use LLM approval 2026-04-30 13:11:26 +02:00
Mikael Hugo
085d3b7705 fix: Show headless source startup progress 2026-04-30 12:19:52 +02:00
Mikael Hugo
6a33357df5 fix: Add production mutation approval gate 2026-04-30 12:17:35 +02:00