feat(uok,gate-runner): extend ctx with surface/runControl/permissionProfile/parentTrace

Slice 3b of "Make UOK the SF Control Plane". UokGateRunner.run now reads
the schema-v2 run-context fields off ctx and propagates them into every
gate_run trace event (unknown-gate path, circuit-breaker-blocked path,
normal execution path). Fields are omitted when absent so legacy callers
keep the pre-v2 shape and status-uok continues to classify them as
"legacy" rather than "incomplete".

Helper buildGateRunEvent centralizes the trace shape so the three sites
stay in sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mikael Hugo 2026-05-14 18:13:45 +02:00
parent 61d3031007
commit cf52aceb64
73 changed files with 68 additions and 1298 deletions

View file

@ -1,3 +0,0 @@
{
"lastFullVacuumAt": "2026-05-14T08:46:30.761Z"
}

View file

@ -1,64 +0,0 @@
{
"nodes": [
{
"id": "concept:phase:summarizing",
"label": "Phase: summarizing",
"type": "concept",
"confidence": "EXTRACTED",
"sourceFile": "STATE.md"
},
{
"id": "milestone:M001",
"label": "M001",
"type": "milestone",
"confidence": "EXTRACTED"
},
{
"id": "slice:M001:S01",
"label": "S01: Recover corrupted DB from backup",
"type": "slice",
"confidence": "EXTRACTED",
"sourceFile": "milestones/M001/slices/S01/S01-PLAN.md"
},
{
"id": "slice:M001:S02",
"label": "S02: Execute S01-T01 — CLI/help doctrine fix",
"type": "slice",
"confidence": "EXTRACTED",
"sourceFile": "milestones/M001/slices/S02/S02-PLAN.md"
},
{
"id": "milestone:M002",
"label": "M002",
"type": "milestone",
"confidence": "EXTRACTED"
}
],
"edges": [
{
"from": "milestone:M001",
"to": "slice:M001:S01",
"type": "contains",
"confidence": "EXTRACTED"
},
{
"from": "milestone:M001",
"to": "slice:M001:S02",
"type": "contains",
"confidence": "EXTRACTED"
},
{
"from": "milestone:M001",
"to": "slice:M001:S01",
"type": "contains",
"confidence": "EXTRACTED"
},
{
"from": "milestone:M001",
"to": "slice:M001:S02",
"type": "contains",
"confidence": "EXTRACTED"
}
],
"builtAt": "2026-05-13T19:56:58.373Z"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1 +0,0 @@
{"fetchedAt":"2026-05-14T02:00:36.613Z","modelIds":["gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.5-pro","gemini-3-flash-preview","gemini-3-pro-preview","gemini-3.1-flash-lite-preview","gemini-3.1-pro-preview"]}

View file

@ -1 +0,0 @@
{"fetchedAt":"2026-05-14T00:25:22.079Z","modelIds":["mistral-medium-2505","mistral-medium-2508","mistral-medium-latest","mistral-medium","mistral-vibe-cli-with-tools","open-mistral-nemo","open-mistral-nemo-2407","mistral-tiny-2407","mistral-tiny-latest","codestral-2508","codestral-latest","devstral-2512","devstral-medium-latest","devstral-latest","mistral-small-2603","mistral-small-latest","mistral-vibe-cli-fast","magistral-small-latest","magistral-medium-2509","magistral-medium-latest","labs-leanstral-2603","mistral-large-2512","mistral-large-latest","mistral-large-2512","mistral-large-latest","ministral-3b-2512","ministral-3b-latest","ministral-8b-2512","ministral-8b-latest","ministral-14b-2512","ministral-14b-latest","mistral-medium-3-5","mistral-medium-3.5","mistral-medium-3","mistral-medium-2604","mistral-medium-c21211-r0-75","mistral-vibe-cli-latest","mistral-large-2411","pixtral-large-2411","pixtral-large-latest","mistral-large-pixtral-2411","devstral-small-2507","devstral-medium-2507","magistral-small-2509","mistral-small-2506"]}

View file

@ -1 +0,0 @@
{"fetchedAt":"2026-05-14T02:00:35.580Z","modelIds":["gpt-5.5","gpt-5.4","gpt-5.4-mini","gpt-5.3-codex","gpt-5.2"]}

File diff suppressed because one or more lines are too long

View file

@ -1,144 +0,0 @@
{
"research-slice": {
"kimi-coding/kimi-k2.6": {
"successes": 5,
"failures": 0,
"timeouts": 0,
"totalTokens": 4682735,
"totalCost": 0.25357486,
"lastUsed": "2026-05-12T20:54:43.410Z",
"successRate": 1,
"total": 5
},
"minimax/MiniMax-M2.7": {
"successes": 1,
"failures": 0,
"timeouts": 0,
"totalTokens": 1101124,
"totalCost": 0.6158798199999999,
"lastUsed": "2026-05-10T07:19:50.702Z",
"successRate": 1,
"total": 1
}
},
"plan-slice": {
"zai/glm-4.5": {
"successes": 1,
"failures": 0,
"timeouts": 0,
"totalTokens": 0,
"totalCost": 0,
"lastUsed": "2026-05-10T00:25:29.268Z",
"successRate": 1,
"total": 1
},
"minimax/MiniMax-M2.7-highspeed": {
"successes": 3,
"failures": 0,
"timeouts": 0,
"totalTokens": 891034,
"totalCost": 0.20030757,
"lastUsed": "2026-05-10T02:32:24.115Z",
"successRate": 1,
"total": 3
},
"minimax/MiniMax-M2.7": {
"successes": 2,
"failures": 0,
"timeouts": 0,
"totalTokens": 6498562,
"totalCost": 2.22445842,
"lastUsed": "2026-05-10T07:26:04.505Z",
"successRate": 1,
"total": 2
},
"kimi-coding/kimi-k2.6": {
"successes": 1,
"failures": 0,
"timeouts": 0,
"totalTokens": 476746,
"totalCost": 0,
"lastUsed": "2026-05-12T20:56:35.833Z",
"successRate": 1,
"total": 1
}
},
"discuss-milestone": {
"minimax/MiniMax-M2.7-highspeed": {
"successes": 3,
"failures": 0,
"timeouts": 0,
"totalTokens": 10591636,
"totalCost": 2.6534383800000003,
"lastUsed": "2026-05-10T08:13:47.678Z",
"successRate": 1,
"total": 3
}
},
"run-uat": {
"minimax/MiniMax-M2.7-highspeed": {
"successes": 1,
"failures": 0,
"timeouts": 0,
"totalTokens": 0,
"totalCost": 0,
"lastUsed": "2026-05-10T05:22:57.604Z",
"successRate": 1,
"total": 1
},
"google-gemini-cli/gemini-3.1-pro-preview": {
"successes": 2,
"failures": 0,
"timeouts": 0,
"totalTokens": 1700534,
"totalCost": 0.14063507999999997,
"lastUsed": "2026-05-10T05:40:27.616Z",
"successRate": 1,
"total": 2
}
},
"execute-task": {
"minimax/MiniMax-M2.7-highspeed": {
"successes": 1,
"failures": 0,
"timeouts": 0,
"totalTokens": 12233288,
"totalCost": 0.3431336426,
"lastUsed": "2026-05-10T15:16:08.120Z",
"successRate": 1,
"total": 1
},
"kimi-coding/kimi-k2.6": {
"successes": 3,
"failures": 0,
"timeouts": 0,
"totalTokens": 11531975,
"totalCost": 0.34663680939999986,
"lastUsed": "2026-05-13T00:28:04.098Z",
"successRate": 1,
"total": 3
}
},
"complete-slice": {
"kimi-coding/kimi-k2.6": {
"successes": 2,
"failures": 0,
"timeouts": 0,
"totalTokens": 814376,
"totalCost": 0.053080319800000005,
"lastUsed": "2026-05-12T23:54:01.143Z",
"successRate": 1,
"total": 2
},
"google-gemini-cli/gemini-3-flash-preview": {
"successes": 1,
"failures": 0,
"timeouts": 0,
"totalTokens": 133175,
"totalCost": 0.060173695400000005,
"lastUsed": "2026-05-13T19:58:46.688Z",
"successRate": 1,
"total": 1
}
}
}

View file

@ -1,3 +0,0 @@
{
"lastFullVacuumAt": "2026-05-08T20:29:49.200Z"
}

View file

@ -1,51 +0,0 @@
# SF Reflection — 2026-05-14
## Pattern clusters
**The Self-Feedback Data Plane is Isolated and Unstructured**
- **Entries:** sf-mp4rp6y2-31jfau, sf-mp4rxkwt-sfthez, sf-mp4rxkwx-jz0soh, sf-mp4rxkx0-fkt3e2
- **Structural commonality:** The self-feedback system operates as a primitive, disconnected FIFO list. It lacks relational semantics (duplicate/supersedes), taxonomy (unbounded kind strings), prioritization (no impact scoring), and cross-channel knowledge sharing (resolutions don't populate the memory graph). This prevents systemic pattern matching and prioritization.
- **Suggested rollup:** File a single `architecture-defect` to overhaul the self-feedback schema (add relations, impact scoring, kind taxonomy) and wire resolution events into the `memory-store`.
**Trust Gaps in the Agentic Resolution Pipeline**
- **Entries:** sf-mp4vxusa-pn2tnd (open), sf-mp4rxkwn-jmp039 (resolved), sf-mp4qoby4-meiir7 (resolved)
- **Structural commonality:** The system allows agents to self-report issue resolutions without cryptographically or structurally verifying the evidence. While recent commits closed some loopholes (AC1 commit existence, canonical evidence shape), the system still structurally trusts the agent's claim about *what* a commit does (AC2 file matching is missing) rather than independently verifying it.
- **Suggested rollup:** Promote to requirement. The pipeline must shift from "trust agent claims" to "empirically verify agent evidence" across all resolution paths.
**Core Capabilities Decoupled from Peripheral Flows**
- **Entries:** sf-mp4w2dij-xm6cwj, sf-mp4rxkwb-l4baga
- **Structural commonality:** Powerful core SF primitives are built but not applied to edge workflows. The autonomous dispatcher does not schedule the triage worker (leaving it manual), and the LLM safety/reasoning stack is bypassed by a legacy regex security gate.
- **Suggested rollup:** No action because these are appropriately covered by their existing entries, but they share a root cause of siloed feature development.
## Commit / ledger gap
- **Silent Fix / Stale Ledger:** Commits `62b19d7ba` and `e161a59e2` explicitly implement Phase 1A and 1B of the reflection layer, yet entry `sf-mp4uzvcd-pazg6v` (architecture-defect:no-reflection-layer-over-self-feedback-corpus) remains OPEN in the ledger.
- **Partial Execution Splitting:** Commit `4af10ac1b` partially addresses outcomes verification (AC1), and `sf-mp4vxusa-pn2tnd` was appropriately filed to track the remainder (AC2). The ledger accurately reflects this split.
## Stale validation drift
- **M001-6377a4:** The validation verdict is `needs-attention` and the milestone is `[active]`, yet its internal state shows slices S01 through S05 are all `[complete]` with 12/12 tasks completed. This is severe drift: the execution plane thinks it is completely finished, but the validation plane is holding the milestone open, likely based on stale diagnostic data from before the tasks were completed.
## Deepest architectural concern
**The Self-Feedback Data Plane is Isolated and Unstructured.**
The single highest-leverage change is redesigning the self-feedback subsystem from a flat log into a structured graph that integrates with SF's memory. As long as kinds are unbounded, relations are impossible, and resolutions are hidden from the memory graph, SF will continue to "forget" its own triaged solutions and fail to cluster identical root causes.
*Concrete refactor:* Execute a schema migration to add `self_feedback_relations` (supersedes/blocks), `impact_score`, and enforce a `domain:family` taxonomy on `kind`. Wire the `markResolved` success path to push a summarized memory into `memory-store`.
## Recommended new self-feedback entries
- **kind:** `reflection:self-feedback-schema-and-integration`
**severity:** high
**summary:** Overhaul self-feedback to support relations, impact scoring, kind taxonomy, and memory-store integration.
**transitively addresses:** sf-mp4rp6y2-31jfau, sf-mp4rxkwt-sfthez, sf-mp4rxkwx-jz0soh, sf-mp4rxkx0-fkt3e2
- **kind:** `reflection:stale-ledger-reflection-phase1`
**severity:** low
**summary:** Close sf-mp4uzvcd-pazg6v (no-reflection-layer) as it was implemented in commits 62b19d7ba and e161a59e2.
**transitively addresses:** sf-mp4uzvcd-pazg6v
## Compared to last report
(No prior report available for comparison. All patterns are new findings.)
REFLECTION_COMPLETE

View file

@ -1,244 +0,0 @@
[
{
"kind": "edit",
"toolCallId": "tool_Ca8DVl3y7fTqNLC5XPq0Pwk1",
"path": "src/resources/extensions/sf/verification-evidence.js",
"timestamp": 1778424928174
},
{
"kind": "edit",
"toolCallId": "tool_xVkmHZTHvJP7RwJWVqUORsz4",
"path": "src/resources/extensions/sf/verification-evidence.js",
"timestamp": 1778424949674
},
{
"kind": "edit",
"toolCallId": "tool_EiDPzaZO49a4LKnYvuvFaS8e",
"path": "src/resources/extensions/sf/auto-verification.js",
"timestamp": 1778424983294
},
{
"kind": "edit",
"toolCallId": "tool_pNt9nP10Us3CPrsqlnWwtQ8l",
"path": "src/resources/extensions/sf/auto-verification.js",
"timestamp": 1778425005515
},
{
"kind": "edit",
"toolCallId": "tool_Bl3x74Ojz6aenqD3nYqxkdlO",
"path": "src/resources/extensions/sf/auto-verification.js",
"timestamp": 1778425108830
},
{
"kind": "edit",
"toolCallId": "tool_RHLdM0SZK4ffIIokuqNruHbn",
"path": "src/resources/extensions/sf/auto-verification.js",
"timestamp": 1778425162119
},
{
"kind": "edit",
"toolCallId": "tool_mAdgaYCgksHmjAI45ZuSnMk5",
"path": "src/resources/extensions/sf/auto-verification.js",
"timestamp": 1778425187240
},
{
"kind": "edit",
"toolCallId": "tool_HMsSokItiWF9y6ctKvFSkyE3",
"path": "src/resources/extensions/sf/auto-verification.js",
"timestamp": 1778425206204
},
{
"kind": "edit",
"toolCallId": "tool_Jbd8uJQ6ZV4PeF8P91s2OvFG",
"path": "src/resources/extensions/sf/uok/unit-runtime.js",
"timestamp": 1778425258651
},
{
"kind": "edit",
"toolCallId": "tool_m1a9UNWqpwBIJvzB9LtlVTBN",
"path": "src/cli-status.ts",
"timestamp": 1778425298174
},
{
"kind": "edit",
"toolCallId": "tool_zcSH4Fx3bOumjphAgYisPyhE",
"path": "src/cli-status.ts",
"timestamp": 1778425348170
},
{
"kind": "edit",
"toolCallId": "tool_UjLWJsxhCI2bAt3kYl4QEhNK",
"path": "src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs",
"timestamp": 1778425381561
},
{
"kind": "edit",
"toolCallId": "tool_1owe7a26pVq3k18x59p6Sy1J",
"path": "src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs",
"timestamp": 1778425414995
},
{
"kind": "bash",
"toolCallId": "tool_zgJvYKclL8xmY8DE4c8nluTk",
"command": "npx vitest run src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs --config vitest.config.ts -t \"getRecoveryDiagnostics\"",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs \u001b[2m(\u001b[22m\u001b[2m38 tests\u001b[22m\u001b[2m | \u001b[22m\u001b[33m35 skipped\u001b[39m\u001b[2m)\u001b[22m\u001b[32m 33\u001b[2mms\u001b[22m\u001b[39m\n\n\u001b[2m Test Files \u001b[22m \u001b[1m\u001b[32m1 passed\u001b[39m\u001b[22m\u001b[90m (1)\u001b[39m\n\u001b[2m Tests \u001b[22m \u001b[1m\u001b[32m3 passed\u001b[39m\u001b[22m\u001b[2m | \u001b[22m\u001b[33m35 skipped\u001b[39m\u001b[90m (38)\u001b[39m\n\u001b[2m Start at \u001b[22m 17:03:54\n\u001b[2m Duration \u001b[22m 1.01s\u001b[2m (transfor",
"timestamp": 1778425433765
},
{
"kind": "bash",
"toolCallId": "tool_c9hBKD3D1Ojayl25rr7Mu3UW",
"command": "npx vitest run src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs --config vitest.config.ts",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs \u001b[2m(\u001b[22m\u001b[2m38 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[32m 140\u001b[2mms\u001b[22m\u001b[39m\n\n\u001b[2m Test Files \u001b[22m \u001b[1m\u001b[32m1 passed\u001b[39m\u001b[22m\u001b[90m (1)\u001b[39m\n\u001b[2m Tests \u001b[22m \u001b[1m\u001b[32m38 passed\u001b[39m\u001b[22m\u001b[90m (38)\u001b[39m\n\u001b[2m Start at \u001b[22m 17:04:12\n\u001b[2m Duration \u001b[22m 1.16s\u001b[2m (transform 552ms, setup 0ms, import 742ms, tests 140ms, environment 0ms",
"timestamp": 1778425451405
},
{
"kind": "bash",
"toolCallId": "tool_jrt7lAB8i6qBOnOePlNhiFR2",
"command": "npx biome check src/resources/extensions/sf/verification-evidence.js src/resources/extensions/sf/auto-verification.js src/resources/extensions/sf/uok/unit-runtime.js src/cli-status.ts src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs",
"exitCode": 1,
"outputSnippet": "src/cli-status.ts format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n × Formatter would have printed the following content:\n \n 240 240 │ if (!targetUnitId) {\n 241 241 │ const records = listUnitRuntimeRecords(basePath);\n 242 │ - → → → const·mostRecent·=·records.sort((a,·b)·=>\n 243 │ - → → → → (b.updatedAt·??·0)·-·(a.updatedAt·??·0),\n 242 │ + → → → const·mostRecent·=·records.sort(\n 243 │ + → → → → (a,·b)·=>·(b.updat",
"timestamp": 1778425466821
},
{
"kind": "bash",
"toolCallId": "tool_lpaw0h5RHFke7wyq5gw8sJKp",
"command": "npx biome check --write src/resources/extensions/sf/verification-evidence.js src/resources/extensions/sf/auto-verification.js src/resources/extensions/sf/uok/unit-runtime.js src/cli-status.ts src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs",
"exitCode": 0,
"outputSnippet": "Checked 5 files in 160ms. Fixed 3 files.\n",
"timestamp": 1778425501417
},
{
"kind": "bash",
"toolCallId": "tool_so1U8wV32tA70qs55EtB7Pke",
"command": "npx vitest run src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs --config vitest.config.ts",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs \u001b[2m(\u001b[22m\u001b[2m38 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[32m 152\u001b[2mms\u001b[22m\u001b[39m\n\n\u001b[2m Test Files \u001b[22m \u001b[1m\u001b[32m1 passed\u001b[39m\u001b[22m\u001b[90m (1)\u001b[39m\n\u001b[2m Tests \u001b[22m \u001b[1m\u001b[32m38 passed\u001b[39m\u001b[22m\u001b[90m (38)\u001b[39m\n\u001b[2m Start at \u001b[22m 17:05:15\n\u001b[2m Duration \u001b[22m 1.16s\u001b[2m (transform 554ms, setup 0ms, import 758ms, tests 152ms, environment 0ms",
"timestamp": 1778425514641
},
{
"kind": "bash",
"toolCallId": "tool_xBsWuLSrGmQHcVUWydLtioru",
"command": "npx tsc --noEmit src/cli-status.ts --skipLibCheck --module NodeNext --moduleResolution NodeNext --target ES2022 --esModuleInterop --allowJs --strict 2>&1 | head -30",
"exitCode": 0,
"outputSnippet": "error TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.\n",
"timestamp": 1778425532429
},
{
"kind": "bash",
"toolCallId": "tool_lnBQh90rfwsYyVvqmIdq8pH7",
"command": "npx tsc --noEmit --project tsconfig.json --skipLibCheck 2>&1 | grep -E \"cli-status|auto-verification|unit-runtime|verification-evidence\" | head -20",
"exitCode": 0,
"outputSnippet": "src/cli-status.ts(237,4): error TS7016: Could not find a declaration file for module './resources/extensions/sf/uok/unit-runtime.js'. '/home/mhugo/code/singularity-forge/src/resources/extensions/sf/uok/unit-runtime.js' implicitly has an 'any' type.\nsrc/cli-status.ts(243,6): error TS7006: Parameter 'a' implicitly has an 'any' type.\nsrc/cli-status.ts(243,9): error TS7006: Parameter 'b' implicitly has an 'any' type.\n",
"timestamp": 1778425546375
},
{
"kind": "bash",
"toolCallId": "tool_L5EQX39mZFzmJbRkCACrnkcM",
"command": "npx tsc --noEmit --project tsconfig.json --skipLibCheck 2>&1 | grep \" Could not find a declaration file\" | head -10",
"exitCode": 0,
"outputSnippet": "src/cli-status.ts(237,4): error TS7016: Could not find a declaration file for module './resources/extensions/sf/uok/unit-runtime.js'. '/home/mhugo/code/singularity-forge/src/resources/extensions/sf/uok/unit-runtime.js' implicitly has an 'any' type.\n",
"timestamp": 1778425700527
},
{
"kind": "edit",
"toolCallId": "tool_bMteIOMYNzppZgJRP2bDK14p",
"path": "src/cli-status.ts",
"timestamp": 1778425760653
},
{
"kind": "bash",
"toolCallId": "tool_kja8VArplGz7aqlFb1rZvh9M",
"command": "npx tsc --noEmit --project tsconfig.json --skipLibCheck 2>&1 | grep -E \"cli-status|auto-verification|unit-runtime|verification-evidence\" | head -20",
"exitCode": 0,
"outputSnippet": "src/cli-status.ts(237,4): error TS7016: Could not find a declaration file for module './resources/extensions/sf/uok/unit-runtime.js'. '/home/mhugo/code/singularity-forge/src/resources/extensions/sf/uok/unit-runtime.js' implicitly has an 'any' type.\n",
"timestamp": 1778425779047
},
{
"kind": "bash",
"toolCallId": "tool_xAMnWlYjFmPHJj2zb3YklZhI",
"command": "npx tsc --noEmit --project tsconfig.json --skipLibCheck 2>&1 | grep \"TS7016\" | head -20",
"exitCode": 0,
"outputSnippet": "src/cli-status.ts(237,4): error TS7016: Could not find a declaration file for module './resources/extensions/sf/uok/unit-runtime.js'. '/home/mhugo/code/singularity-forge/src/resources/extensions/sf/uok/unit-runtime.js' implicitly has an 'any' type.\n",
"timestamp": 1778425808025
},
{
"kind": "bash",
"toolCallId": "tool_N2K96iYZY9GgeXRHbsVIDJFn",
"command": "ls src/resources/extensions/sf/autonomous-command-args.* src/resources/extensions/sf/repo-identity.* src/resources/extensions/sf/trace-collector.*",
"exitCode": 0,
"outputSnippet": "src/resources/extensions/sf/autonomous-command-args.d.ts\nsrc/resources/extensions/sf/autonomous-command-args.js\nsrc/resources/extensions/sf/repo-identity.d.ts\nsrc/resources/extensions/sf/repo-identity.js\nsrc/resources/extensions/sf/trace-collector.d.ts\nsrc/resources/extensions/sf/trace-collector.js\n",
"timestamp": 1778425827433
},
{
"kind": "write",
"toolCallId": "tool_d6oIGASndyhbsF3ethH49BBC",
"path": "src/resources/extensions/sf/uok/unit-runtime.d.ts",
"timestamp": 1778425847941
},
{
"kind": "bash",
"toolCallId": "tool_8ipcG5bydJIBFOOfadbuRNzl",
"command": "npx tsc --noEmit --project tsconfig.json --skipLibCheck 2>&1 | grep -E \"cli-status|unit-runtime\" | head -20",
"exitCode": 0,
"outputSnippet": "(no output)",
"timestamp": 1778425863933
},
{
"kind": "bash",
"toolCallId": "tool_oas0rGaFmZW4i6dQZDfNbIOj",
"command": "npx tsc --noEmit --project tsconfig.json --skipLibCheck 2>&1 | head -20",
"exitCode": 0,
"outputSnippet": "(no output)",
"timestamp": 1778425882297
},
{
"kind": "bash",
"toolCallId": "tool_bWplHSK7Xw5d98Gzhf69rI3E",
"command": "npx tsc --noEmit --project tsconfig.extensions.json --skipLibCheck 2>&1 | head -20",
"exitCode": 0,
"outputSnippet": "packages/tui/src/index.ts(52,34): error TS6142: Module './ink-bridge.js' was resolved to '/home/mhugo/code/singularity-forge/packages/tui/src/ink-bridge.tsx', but '--jsx' is not set.\npackages/tui/src/tui.ts(14,34): error TS6142: Module './ink-bridge.js' was resolved to '/home/mhugo/code/singularity-forge/packages/tui/src/ink-bridge.tsx', but '--jsx' is not set.\npackages/tui/src/tui.ts(434,46): error TS7006: Parameter 'data' implicitly has an 'any' type.\n",
"timestamp": 1778425897974
},
{
"kind": "bash",
"toolCallId": "tool_R9DLuMbsvg7Lz87cGbyzuS01",
"command": "npx biome check src/resources/extensions/sf/verification-evidence.js src/resources/extensions/sf/auto-verification.js src/resources/extensions/sf/uok/unit-runtime.js src/resources/extensions/sf/uok/unit-runtime.d.ts src/cli-status.ts src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs",
"exitCode": 1,
"outputSnippet": "src/resources/extensions/sf/uok/unit-runtime.d.ts format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n × Formatter would have printed the following content:\n \n 28 28 │ ): RecoveryDiagnostics | null;\n 29 29 │ \n 30 │ - export·function·listUnitRuntimeRecords(basePath:·string):·Array<\n 31 │ - → Record<string,·unknown>·&·{·updatedAt?:·number;·unitId:·string·}\n 32 │ - >;\n 30 │ + export·function·listUnitRuntimeRecords(\n 31 │ + → basePath:·string,\n 32 │ + ",
"timestamp": 1778425942347
},
{
"kind": "bash",
"toolCallId": "tool_nQuAxzeREvyod0nBGyVPIvfJ",
"command": "npx biome check --write src/resources/extensions/sf/uok/unit-runtime.d.ts",
"exitCode": 0,
"outputSnippet": "Checked 1 file in 17ms. Fixed 1 file.\n",
"timestamp": 1778425957743
},
{
"kind": "bash",
"toolCallId": "tool_HZWYvGOveamvyW97wbv5A0Fv",
"command": "npx biome check src/resources/extensions/sf/verification-evidence.js src/resources/extensions/sf/auto-verification.js src/resources/extensions/sf/uok/unit-runtime.js src/resources/extensions/sf/uok/unit-runtime.d.ts src/cli-status.ts src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs",
"exitCode": 0,
"outputSnippet": "Checked 6 files in 70ms. No fixes applied.\n",
"timestamp": 1778425970841
},
{
"kind": "bash",
"toolCallId": "tool_SY84S3XYIIBJGZvUchG4qSRZ",
"command": "npx vitest run src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs --config vitest.config.ts",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/uok-unit-runtime.test.mjs \u001b[2m(\u001b[22m\u001b[2m38 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[32m 168\u001b[2mms\u001b[22m\u001b[39m\n\n\u001b[2m Test Files \u001b[22m \u001b[1m\u001b[32m1 passed\u001b[39m\u001b[22m\u001b[90m (1)\u001b[39m\n\u001b[2m Tests \u001b[22m \u001b[1m\u001b[32m38 passed\u001b[39m\u001b[22m\u001b[90m (38)\u001b[39m\n\u001b[2m Start at \u001b[22m 17:13:05\n\u001b[2m Duration \u001b[22m 1.11s\u001b[2m (transform 477ms, setup 0ms, import 702ms, tests 168ms, environment 0ms",
"timestamp": 1778425983954
},
{
"kind": "bash",
"toolCallId": "tool_SdyaSTc9h2LJD9pq5ZLR3Ehc",
"command": "git status --short",
"exitCode": 0,
"outputSnippet": " D .sf/backups/db/sf.db.2026-05-08T22-42-32-307Z\n D .sf/backups/db/sf.db.2026-05-09T17-40-16-600Z\n D .sf/backups/db/sf.db.2026-05-09T19-41-02-472Z\n M .sf/metrics.db\n M .sf/metrics.db-shm\n M .sf/metrics.db-wal\n D BUILD_PLAN_MILESTONE_MAP.md\n D PRODUCTION_AUDIT_COMPLETE.md\n D QUICK_WINS_IMPLEMENTATION.md\n D TRIAGE_COMPLETE.md\n D TRIAGE_README.md\n D autoresearch.md\n D copilot-thoughts.md\n M packages/coding-agent/src/modes/interactive/interactive-mode.ts\n M packages/tui/src/ink-bridge.tsx\n M package",
"timestamp": 1778425999682
}
]

View file

@ -1 +0,0 @@
[]

View file

@ -1,276 +0,0 @@
[
{
"kind": "write",
"toolCallId": "tool_MuEDanVQccNFg308TTKEsh43",
"path": "docs/dev/sf-ace-patterns.md",
"timestamp": 1778630671328
},
{
"kind": "bash",
"toolCallId": "tool_KHVFjUy0MZyPnrGJuKCdbsCH",
"command": "rm docs/dev/sf-ace-patterns.md.draft && test -f docs/dev/sf-ace-patterns.md && echo \"File exists\" && grep -c \"^## \" docs/dev/sf-ace-patterns.md && ! grep -q \"TODO\\|TBD\" docs/dev/sf-ace-patterns.md && echo \"No TODOs/TBDs\"",
"exitCode": 0,
"outputSnippet": "File exists\n7\nNo TODOs/TBDs\n",
"timestamp": 1778630681476
},
{
"kind": "edit",
"toolCallId": "tool_UPFe4zzqhzYN2bBDpHaRd7iw",
"path": "docs/dev/sf-ace-patterns.md",
"timestamp": 1778630693069
},
{
"kind": "bash",
"toolCallId": "tool_DT3rqKEIOU1gKOfCdlNnz3KI",
"command": "test -f docs/dev/sf-ace-patterns.md && grep -c \"^## \" docs/dev/sf-ace-patterns.md && ! grep -q \"TODO\\|TBD\" docs/dev/sf-ace-patterns.md && echo \"All checks passed\"",
"exitCode": 0,
"outputSnippet": "6\nAll checks passed\n",
"timestamp": 1778630699418
},
{
"kind": "bash",
"toolCallId": "tool_5Neos7DsZavn3HaIiQ7RWok8",
"command": "git status --short",
"exitCode": 0,
"outputSnippet": " M .sf/metrics.db\n M .sf/metrics.db-shm\n M .sf/metrics.db-wal\n D .sf/safety/evidence-M001-6377a4-S05-T01.json\n M .sf/traces/latest\n D docs/dev/sf-ace-patterns.md.draft\n?? .sf/safety/evidence-M001-6377a4-S05-T02.json\n?? docs/dev/sf-ace-patterns.md\n",
"timestamp": 1778630705763
},
{
"kind": "edit",
"toolCallId": "tool_WiPwvui2dfPrazaog1UlTscV",
"path": "src/resources/extensions/sf/doctor.js",
"timestamp": 1778631078725
},
{
"kind": "edit",
"toolCallId": "tool_k9RDaGqRyVuY78k6SEH278el",
"path": "src/resources/extensions/sf/doctor.js",
"timestamp": 1778631089493
},
{
"kind": "edit",
"toolCallId": "tool_8AXl5rylVOj8KHTbJ4DnjTFU",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631175917
},
{
"kind": "edit",
"toolCallId": "tool_MRt3KEakKSwMQ6KeFESHbQ7I",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631224258
},
{
"kind": "bash",
"toolCallId": "tool_xbiIjGe68bvZmREEa257Giiw",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs --reporter=verbose 2>&1",
"exitCode": 1,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n\n\u001b[31m⎯⎯⎯⎯⎯⎯\u001b[39m\u001b[1m\u001b[41m Failed Suites 1 \u001b[49m\u001b[22m\u001b[31m⎯⎯⎯⎯⎯⎯⎯\u001b[39m\n\n\u001b[41m\u001b[1m FAIL \u001b[22m\u001b[49m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m [ src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs ]\u001b[22m\n\u001b[31m\u001b[1mError\u001b[22m: Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sur",
"timestamp": 1778631232684
},
{
"kind": "edit",
"toolCallId": "tool_dz39sZOxkUes7tLsrDk58m5v",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631257305
},
{
"kind": "bash",
"toolCallId": "tool_LLm28HfWuK4pZqAercG0pwzN",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs --reporter=verbose 2>&1",
"exitCode": 1,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22mrunFlowAudit_when_optional_orphan_is_over_budget_and_cleanup_enabled_kills_without_warning\u001b[32m 22\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22m",
"timestamp": 1778631264805
},
{
"kind": "edit",
"toolCallId": "tool_AHVI28B1ZqQXUX6AdG1sS1TG",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631371934
},
{
"kind": "edit",
"toolCallId": "tool_ugsNouhScVZgGv9o5au36yVm",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631390368
},
{
"kind": "edit",
"toolCallId": "tool_muPmveJKZ16JKEozOi18GHP2",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631401609
},
{
"kind": "bash",
"toolCallId": "tool_vu64gBGMnLirmnAwSFxEGjEQ",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs --reporter=verbose 2>&1",
"exitCode": 1,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22mrunFlowAudit_when_optional_orphan_is_over_budget_and_cleanup_enabled_kills_without_warning\u001b[32m 33\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22m",
"timestamp": 1778631409131
},
{
"kind": "edit",
"toolCallId": "tool_ohIytfwfFMf0gDVgWhOZ0aZT",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631484338
},
{
"kind": "bash",
"toolCallId": "tool_JqC553ZmzdcFz8YmZmh91x3n",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs --reporter=verbose 2>&1 | tail -40",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n\n\u001b[31m⎯⎯⎯⎯⎯⎯\u001b[39m\u001b[1m\u001b[41m Failed Suites 1 \u001b[49m\u001b[22m\u001b[31m⎯⎯⎯⎯⎯⎯⎯\u001b[39m\n\n\u001b[41m\u001b[1m FAIL \u001b[22m\u001b[49m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m [ src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs ]\u001b[22m\n\u001b[31m\u001b[1mError\u001b[22m: Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sur",
"timestamp": 1778631493098
},
{
"kind": "edit",
"toolCallId": "tool_vpLugwHPrMCIKMufhATSzVr4",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631505110
},
{
"kind": "bash",
"toolCallId": "tool_meozIeEkqfC9L9XYMb6pzTqS",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs --reporter=verbose 2>&1 | tail -50",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n\u001b[90mstdout\u001b[2m | src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22m\u001b[2mflow audit optional child cleanup\u001b[2m > \u001b[22m\u001b[2mrunFlowAudit_when_repeated_failures_on_same_milestone_files_rollup_with_enriched_evidence\n\u001b[22m\u001b[39mDEBUG feedback count: \u001b[33m0\u001b[39m\nDEBUG activeMilestone: { id: \u001b[32m'M001'\u001b[39m }\nDEBUG feedback kinds: []\n\n \u001b[32m✓\u001b[39m src/resources/extensions",
"timestamp": 1778631513173
},
{
"kind": "edit",
"toolCallId": "tool_BTkfYkpapQCGeCbVhKED5E1e",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631600771
},
{
"kind": "bash",
"toolCallId": "tool_ghlRixQlDP8q5zyqVqXeDHlQ",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs --reporter=verbose 2>&1 | grep -A 20 \"DEBUG\"",
"exitCode": 0,
"outputSnippet": "\u001b[22m\u001b[39mDEBUG feedback count: \u001b[33m0\u001b[39m\nDEBUG activeMilestone: { id: \u001b[32m'M001'\u001b[39m }\nDEBUG feedback kinds: []\n\n\u001b[90mstdout\u001b[2m | src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22m\u001b[2mflow audit optional child cleanup\u001b[2m > \u001b[22m\u001b[2mrunFlowAudit_when_repeated_failures_on_same_milestone_files_rollup_with_enriched_evidence\n\u001b[22m\u001b[39mDEBUG jsonl exists: {\"id\":\"sf-runaway-1\",\"ts\":\"2026-05-06T11:00:00.000Z\",\"kind\":\"runaway-guard-hard-pause\",\"severity\":\"medium\"",
"timestamp": 1778631610226
},
{
"kind": "edit",
"toolCallId": "tool_FrvJH7nTYJHdWWsJjWLVBIRc",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631758083
},
{
"kind": "edit",
"toolCallId": "tool_Xfn2I8YFtQURxxVa168i9f9W",
"path": "src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"timestamp": 1778631827123
},
{
"kind": "bash",
"toolCallId": "tool_4pxjZrINMg2kLl5CEdgQULhL",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs --reporter=verbose 2>&1 | tail -40",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22mrunFlowAudit_when_optional_orphan_is_over_budget_and_cleanup_enabled_kills_without_warning\u001b[32m 37\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22m",
"timestamp": 1778631837280
},
{
"kind": "bash",
"toolCallId": "tool_u2BYAaBQ6orBVWV6uP7dia8U",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs src/resources/extensions/sf/tests/doctor.test.mjs --reporter=verbose 2>&1 | tail -30",
"exitCode": 0,
"outputSnippet": "\n\u001b[1m\u001b[30m\u001b[46m RUN \u001b[49m\u001b[39m\u001b[22m \u001b[36mv4.1.5 \u001b[39m\u001b[90m/home/mhugo/code/singularity-forge\u001b[39m\n\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22mrunFlowAudit_when_optional_orphan_is_over_budget_and_cleanup_enabled_kills_without_warning\u001b[32m 31\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22m",
"timestamp": 1778631859286
},
{
"kind": "bash",
"toolCallId": "tool_Ht3CX8xH6WHLkUpdpOkZx4d6",
"command": "git status --short",
"exitCode": 0,
"outputSnippet": " M .sf/metrics.db\n M .sf/metrics.db-shm\n M .sf/metrics.db-wal\n D .sf/safety/evidence-M001-6377a4-S05-T01.json\n M .sf/traces/latest\n D docs/dev/sf-ace-patterns.md.draft\n M src/resources/extensions/sf/doctor.js\n M src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\n M src/resources/extensions/sf/tests/schedule-e2e.test.ts\n M src/tests/integration/e2e-smoke.test.ts\n?? .sf/safety/evidence-M001-6377a4-S05-T02.json\n?? docs/dev/sf-ace-patterns.md\n",
"timestamp": 1778631879171
},
{
"kind": "bash",
"toolCallId": "tool_zAufnT85qSehPwnApqH2qmQF",
"command": "git diff --name-only",
"exitCode": 0,
"outputSnippet": ".sf/metrics.db\n.sf/metrics.db-shm\n.sf/metrics.db-wal\n.sf/safety/evidence-M001-6377a4-S05-T01.json\n.sf/traces/latest\ndocs/dev/sf-ace-patterns.md.draft\nsrc/resources/extensions/sf/doctor.js\nsrc/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\nsrc/resources/extensions/sf/tests/schedule-e2e.test.ts\nsrc/tests/integration/e2e-smoke.test.ts\n",
"timestamp": 1778631894077
},
{
"kind": "bash",
"toolCallId": "tool_zBaPabwtV486PXoxJR3BRPfy",
"command": "git diff src/resources/extensions/sf/tests/schedule-e2e.test.ts src/tests/integration/e2e-smoke.test.ts",
"exitCode": 0,
"outputSnippet": "diff --git a/src/resources/extensions/sf/tests/schedule-e2e.test.ts b/src/resources/extensions/sf/tests/schedule-e2e.test.ts\nindex f03b20703..a417f1b61 100644\n--- a/src/resources/extensions/sf/tests/schedule-e2e.test.ts\n+++ b/src/resources/extensions/sf/tests/schedule-e2e.test.ts\n@@ -195,7 +195,9 @@ describe(\"schedule-e2e round-trip\", () => {\n \n \t\tassert.equal(entries.length, count);\n \n-\t\tconst thresholdMs = process.env.CI ? 200 : 50;\n+\t\t// This is a smoke-scale regression guard, not a microbenc",
"timestamp": 1778631905803
},
{
"kind": "bash",
"toolCallId": "tool_p2qqwtuecDX4rlUryRL4rZVD",
"command": "git add src/resources/extensions/sf/doctor.js src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs",
"exitCode": 0,
"outputSnippet": "(no output)",
"timestamp": 1778631917795
},
{
"kind": "bash",
"toolCallId": "tool_rwS3ziyWRLjZoJ1qnLHbcf8l",
"command": "git commit -m \"fix(doctor): enrich flow-audit repeated-failure rollup with full diagnostic context\n\nThe flow-audit repeated-milestone-failure rollup now includes:\n- Active milestone/unit and session pointer (AC1)\n- Stale dispatched units (AC2)\n- Runaway history (AC3)\n- Over-budget child processes (AC3)\n\nThis satisfies the acceptance criteria of self-feedback entry\nsf-mp3ati7u-qqxcyi so operators can use the rollup evidence to\nrepair stale dispatch, missing summary, runaway, or child-process\nhandling without needing to re-run the flow audit manually.\n\nRefs: sf-mp3ati7u-qqxcyi\"",
"exitCode": 0,
"outputSnippet": "secret-scan: no secrets detected ✓\ncheck-protected-deletions: ok\n[main 2cad6d54f] fix(doctor): enrich flow-audit repeated-failure rollup with full diagnostic context\n 2 files changed, 164 insertions(+), 1 deletion(-)\n",
"timestamp": 1778631929417
},
{
"kind": "bash",
"toolCallId": "tool_qgauURpv3HTucvnFmexkBJFC",
"command": "git rev-parse HEAD",
"exitCode": 0,
"outputSnippet": "2cad6d54f484ca0576bb86fe7d655d443f044679\n",
"timestamp": 1778631938674
},
{
"kind": "bash",
"toolCallId": "tool_KwXZYc7bejNCt99vBVHO0KJQ",
"command": "grep -r \"sf-mp3ati7u-qqxcyi\" .sf/ 2>/dev/null | head -5",
"exitCode": 0,
"outputSnippet": ".sf/journal/2026-05-13.jsonl:{\"schemaVersion\":1,\"ts\":\"2026-05-13T00:25:29.419Z\",\"flowId\":\"execution-policy:tool_rwS3ziyWRLjZoJ1qnLHbcf8l\",\"seq\":0,\"eventType\":\"execution-policy-decision\",\"unitType\":\"execute-task\",\"unitId\":\"M001-6377a4/S05/T02\",\"data\":{\"toolCallId\":\"tool_rwS3ziyWRLjZoJ1qnLHbcf8l\",\"toolName\":\"bash\",\"input\":\"git commit -m \\\"fix(doctor): enrich flow-audit repeated-failure rollup with full diagnostic context\\n\\nThe flow-audit repeated-milestone-failure rollup now includes:\\n- Active m",
"timestamp": 1778631962770
},
{
"kind": "bash",
"toolCallId": "tool_8FkOYCbBMGd6naAkTricEpQ3",
"command": "npx vitest run src/resources/extensions/sf/tests/doctor --reporter=verbose 2>&1 | tail -20",
"exitCode": 0,
"outputSnippet": " \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22mrunFlowAudit_when_only_old_errors_exist_does_not_warn_before_dispatch\u001b[32m 4\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m src/resources/extensions/sf/tests/doctor-flow-audit-auto-cleanup.test.mjs\u001b[2m > \u001b[22mflow audit optional child cleanup\u001b[2m > \u001b[22mrunFlowAudit_when_recent_error_exists_warns_before_dispatch\u001b[32m 4\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m src/resources/extensions/",
"timestamp": 1778631983507
},
{
"kind": "bash",
"toolCallId": "tool_mqWwqpyGJKWXMv8nCPhaq8mU",
"command": "git diff --cached --stat",
"exitCode": 0,
"outputSnippet": "(no output)",
"timestamp": 1778632007409
},
{
"kind": "bash",
"toolCallId": "tool_nAuIjU36zsbfqQsMRfirsnD0",
"command": "git log --oneline -3",
"exitCode": 0,
"outputSnippet": "2cad6d54f fix(doctor): enrich flow-audit repeated-failure rollup with full diagnostic context\n65e195a9f feat: Created draft mapping of SF patterns to ACE reference draft\n1ed505669 fix(sf-db,autonomous-solver): resolve schema-drift and checkpoint runaway loop\n",
"timestamp": 1778632015241
},
{
"kind": "bash",
"toolCallId": "tool_LLn6mxg7gvf2UUt3SyIh3EFw",
"command": "git status --short",
"exitCode": 0,
"outputSnippet": " M .sf/metrics.db\n M .sf/metrics.db-shm\n M .sf/metrics.db-wal\n D .sf/safety/evidence-M001-6377a4-S05-T01.json\n M .sf/traces/latest\n D docs/dev/sf-ace-patterns.md.draft\n M src/resources/extensions/sf/tests/adaptive-verification-policy.test.mjs\n M src/resources/extensions/sf/tests/headless-uok-status.test.mjs\n M src/resources/extensions/sf/tests/post-execution-checks.test.mjs\n M src/resources/extensions/sf/tests/schedule-e2e.test.ts\n M src/tests/integration/e2e-smoke.test.ts\n?? .sf/safety/evidence",
"timestamp": 1778632036582
},
{
"kind": "bash",
"toolCallId": "tool_prPZtTTR1si12TM4gMk4UWew",
"command": "git diff src/resources/extensions/sf/tests/adaptive-verification-policy.test.mjs src/resources/extensions/sf/tests/headless-uok-status.test.mjs src/resources/extensions/sf/tests/post-execution-checks.test.mjs",
"exitCode": 0,
"outputSnippet": "diff --git a/src/resources/extensions/sf/tests/adaptive-verification-policy.test.mjs b/src/resources/extensions/sf/tests/adaptive-verification-policy.test.mjs\nindex 13611745c..6eb971f99 100644\n--- a/src/resources/extensions/sf/tests/adaptive-verification-policy.test.mjs\n+++ b/src/resources/extensions/sf/tests/adaptive-verification-policy.test.mjs\n@@ -1,5 +1,5 @@\n import assert from \"node:assert/strict\";\n-import { describe, it } from \"node:test\";\n+import { describe, it } from \"vitest\";\n import { ",
"timestamp": 1778632055879
}
]

View file

@ -1,16 +0,0 @@
{
"M001-6377a4/S04": {
"provider": "minimax",
"id": "MiniMax-M2.1",
"ts": "2026-05-12T23:54:01.079Z",
"lastUnitType": "complete-slice",
"lastUnitId": "M001-6377a4/S04"
},
"M001-6377a4/S05": {
"provider": "minimax",
"id": "MiniMax-M2.7",
"ts": "2026-05-13T19:58:46.652Z",
"lastUnitType": "complete-slice",
"lastUnitId": "M001-6377a4/S05"
}
}

View file

@ -1 +0,0 @@
{"ts":"2026-05-12T20:56:39.435Z","type":"gate_run","traceId":"guard:76c7c307-91b4-426e-8fad-4ff951d5a52e","turnId":"iter-4","gateId":"plan-gate","gateType":"policy","unitType":"execute-task","unitId":"M001-6377a4/S04/T01","milestoneId":"M001-6377a4","sliceId":"S04","outcome":"pass","failureClass":"none","rationale":"Plan files verified","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:56:39.435Z","durationMs":0}

View file

@ -1 +0,0 @@
pre-dispatch:0046474d-b25d-4b8f-ab67-7c6e1f6a4829.jsonl

View file

@ -1,2 +0,0 @@
{"ts":"2026-05-12T20:52:04.171Z","type":"gate_run","traceId":"pre-dispatch:2e5b5158-453c-4b09-8dd2-26fa87c8ded5","turnId":"iter-1","gateId":"resource-version-guard","gateType":"policy","unitType":"pre-dispatch","unitId":"iter-1","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"resource version guard passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:52:04.167Z","durationMs":0}
{"ts":"2026-05-12T20:52:04.988Z","type":"gate_run","traceId":"pre-dispatch:2e5b5158-453c-4b09-8dd2-26fa87c8ded5","turnId":"iter-1","gateId":"pre-dispatch-health-gate","gateType":"execution","unitType":"pre-dispatch","unitId":"iter-1","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"pre-dispatch health gate passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:52:04.987Z","durationMs":0}

View file

@ -1,3 +0,0 @@
{"ts":"2026-05-12T20:56:38.487Z","type":"gate_run","traceId":"pre-dispatch:76c7c307-91b4-426e-8fad-4ff951d5a52e","turnId":"iter-4","gateId":"resource-version-guard","gateType":"policy","unitType":"pre-dispatch","unitId":"iter-4","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"resource version guard passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:56:38.485Z","durationMs":0}
{"ts":"2026-05-12T20:56:39.307Z","type":"gate_run","traceId":"pre-dispatch:76c7c307-91b4-426e-8fad-4ff951d5a52e","turnId":"iter-4","gateId":"pre-dispatch-health-gate","gateType":"execution","unitType":"pre-dispatch","unitId":"iter-4","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"pre-dispatch health gate passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:56:39.307Z","durationMs":0}
{"ts":"2026-05-12T20:56:39.313Z","type":"gate_run","traceId":"pre-dispatch:76c7c307-91b4-426e-8fad-4ff951d5a52e","turnId":"iter-4","gateId":"planning-flow-gate","gateType":"policy","unitType":"pre-dispatch","unitId":"iter-4","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"planning flow compile gate passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:56:39.312Z","durationMs":0}

View file

@ -1,2 +0,0 @@
{"ts":"2026-05-12T20:56:36.969Z","type":"gate_run","traceId":"pre-dispatch:7b06b885-0539-40d2-81c1-066c2b2f20c5","turnId":"iter-3","gateId":"resource-version-guard","gateType":"policy","unitType":"pre-dispatch","unitId":"iter-3","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"resource version guard passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:56:36.968Z","durationMs":0}
{"ts":"2026-05-12T20:56:37.702Z","type":"gate_run","traceId":"pre-dispatch:7b06b885-0539-40d2-81c1-066c2b2f20c5","turnId":"iter-3","gateId":"pre-dispatch-health-gate","gateType":"execution","unitType":"pre-dispatch","unitId":"iter-3","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"pre-dispatch health gate passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:56:37.700Z","durationMs":0}

View file

@ -1,3 +0,0 @@
{"ts":"2026-05-12T15:25:46.384Z","type":"gate_run","traceId":"pre-dispatch:952f3f1c-1861-4637-a706-54141371ebc7","turnId":"iter-1","gateId":"resource-version-guard","gateType":"policy","unitType":"pre-dispatch","unitId":"iter-1","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"resource version guard passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T15:25:46.383Z","durationMs":0}
{"ts":"2026-05-12T15:25:47.104Z","type":"gate_run","traceId":"pre-dispatch:952f3f1c-1861-4637-a706-54141371ebc7","turnId":"iter-1","gateId":"pre-dispatch-health-gate","gateType":"execution","unitType":"pre-dispatch","unitId":"iter-1","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"pre-dispatch health gate passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T15:25:47.103Z","durationMs":0}
{"ts":"2026-05-12T15:25:47.110Z","type":"gate_run","traceId":"pre-dispatch:952f3f1c-1861-4637-a706-54141371ebc7","turnId":"iter-1","gateId":"planning-flow-gate","gateType":"policy","unitType":"pre-dispatch","unitId":"iter-1","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"planning flow compile gate passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T15:25:47.109Z","durationMs":0}

View file

@ -1,2 +0,0 @@
{"ts":"2026-05-12T20:54:44.467Z","type":"gate_run","traceId":"pre-dispatch:9ed021af-f7d3-4d67-bfae-5ecbfcbd08b6","turnId":"iter-2","gateId":"resource-version-guard","gateType":"policy","unitType":"pre-dispatch","unitId":"iter-2","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"resource version guard passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:54:44.466Z","durationMs":0}
{"ts":"2026-05-12T20:54:45.217Z","type":"gate_run","traceId":"pre-dispatch:9ed021af-f7d3-4d67-bfae-5ecbfcbd08b6","turnId":"iter-2","gateId":"pre-dispatch-health-gate","gateType":"execution","unitType":"pre-dispatch","unitId":"iter-2","milestoneId":"M001-6377a4","outcome":"pass","failureClass":"none","rationale":"pre-dispatch health gate passed","findings":"","attempt":1,"maxAttempts":1,"retryable":false,"evaluatedAt":"2026-05-12T20:54:45.217Z","durationMs":0}

View file

@ -1,29 +0,0 @@
Here are the triage decisions for the open self-feedback entries. Both entries propose significant architectural rewrites that are either out of scope or not worth the complexity at current priorities.
### Decision for `sf-mp4rxkwb-l4baga`
**Outcome:** C. Close it.
**Reason:** Redesigning the inline-fix worker from a `followUp` message to a first-class autonomous unit type requires major cross-cutting changes to the dispatcher and autonomous loop. The current sidecar model works fine for user-initiated turns. Fixing this purely for headless autonomous edge cases is an over-investment and not worth a fix at SF's current priorities.
### Decision for `sf-mp4w2dij-xm6cwj`
**Outcome:** C. Close it.
**Reason:** Wiring an LLM agent, memory-store, and snapshot-safety into a git pre-commit hook is severe over-engineering. Pre-commit hooks must remain exceptionally fast, deterministic, and functional offline. Introducing network-dependent LLM calls and complex safety stack integrations to a fast-path security gate introduces unacceptable latency and fragility. The 250-LOC regex scanner is the correct architectural choice for this layer.
***
**Executing resolutions:**
```javascript
resolve_issue({
issueId: "sf-mp4rxkwb-l4baga",
evidence: { kind: "human-clear" },
reason: "Redesigning the inline-fix worker as a first-class autonomous unit requires major architectural changes to the dispatcher. The followUp model suffices for user turns; this edge case is not worth fixing at current priorities."
});
resolve_issue({
issueId: "sf-mp4w2dij-xm6cwj",
evidence: { kind: "human-clear" },
reason: "Integrating an LLM and the full safety stack into a git pre-commit hook risks unacceptable latency, flakiness, and offline failures. The current regex scanner is appropriate for local git hooks; out of scope and not worth fixing."
});
```
Self-feedback triage complete.

View file

@ -1,67 +0,0 @@
# Architecture
*Generated: 2026-05-11 | Source: ARCHITECTURE.md, docs/adr/*
## Overview
SF is a Purpose-to-Software Compiler (ADR-0000). It runs long-horizon coding work through the **Unified Operation Kernel (UOK)**: milestones → slices → tasks. A deterministic controller (not an LLM) reads canonical DB state and decides what to dispatch next. Each dispatch unit gets a fresh AI context.
**Key invariant:** `sf.db` (SQLite via `node:sqlite`) is the single source of truth for all structured state. Markdown files are rendered projections or human-editable inputs, not authoritative sources.
## Subsystems at a Glance
| Subsystem | Path | Purpose |
|-----------|------|---------|
| CLI entry | `src/loader.ts` | Initializes resources, registers extension |
| Headless driver | `src/headless.ts` | Non-interactive mode, exit codes 0/1/10/11/12 |
| SF extension | `src/resources/extensions/sf/` | All SF autonomous flow logic |
| UOK orchestrator | `src/resources/extensions/sf/auto/` | Dispatch loop, lifecycle, planning |
| Context injection | `src/resources/extensions/sf/bootstrap/` | System prompt assembly |
| Prompt templates | `src/resources/extensions/sf/prompts/` | `.md` templates loaded at runtime |
| Agent core | `packages/coding-agent/` | Tools (bash, grep, read…), models, sessions, settings |
| LLM providers | `packages/ai/` | Anthropic, OpenAI, Google, Moonshot, etc. |
| Terminal UI | `packages/tui/` | Ink-based TUI |
| Daemon | `packages/daemon/` | Background process |
| RPC client | `packages/rpc-client/` | RPC adapter |
| Native addon | `packages/native/` | Rust N-API bindings (grep, glob, ps, highlight, ast, diff) |
## Autonomous Dispatch Loop
1. UOK reconciles DB-backed ledger + runtime diagnostics → typed state snapshot
2. Controller selects next unit (research → plan → implement → verify) from DB state
3. Fresh agent context started, task plan injected via `system-context.js`
4. Agent writes artifacts, commits, exits
5. UOK records completion/recovery, updates projections, repeats
## System Context Assembly (per turn)
`system-context.js` `buildBeforeAgentStartResult` assembles blocks in order:
```
escalation-policy → system.md → preferences → knowledge (DB) → ARCHITECTURE.md
→ tacit-knowledge → wiki (.sf/wiki/) → CODEBASE.md → code-intelligence
→ memories (DB) → new-skills → self-feedback → worktree/VCS → model identity
```
## State Layout
**Tracked in git:**
- `.sf/milestones/` — plans, summaries (rendered projections)
- `.sf/PROJECT.md`, `.sf/REQUIREMENTS.md`, `.sf/DECISIONS.md`, etc.
**Gitignored (runtime):**
- `.sf/sf.db*` — canonical SQLite state
- `.sf/wiki/` — generated + hand-curated wiki (this directory; **tracked in git**)
- `.sf/CODEBASE.md` — generated file map
- `.sf/runtime/`, `.sf/activity/`, `.sf/worktrees/`, etc.
## Tools in bash tool
Bash tool has a 120s default timeout (prevents autonomous mode hangs). Override via `settings.json → bash.defaultTimeoutSeconds`. Prefer dedicated tools: `grep`, `find`, `ls`, `read` over bash for file operations.
## ADRs
- `docs/adr/0000-purpose-to-software-compiler.md` — foundational product contract
- `docs/adr/0001-sf-state-directory.md``.sf/` state model
- `docs/adr/0004-capability-aware-routing.md` — model routing
- `docs/adr/0005-multi-model-provider-strategy.md` — provider strategy

View file

@ -1,119 +0,0 @@
# Glossary
*Generated: 2026-05-11 | Hand-editable — tracked in git*
Project-specific terms only. General software terms not listed.
---
## A
**ADR** — Architecture Decision Record. Promoted from `.sf/DECISIONS.md` to `docs/adr/`. Numbered `0000`, `0001`, … Immutable once accepted.
**Auto-bootstrap context** — The set of files (wiki pages, spec files, CODEBASE.md) injected as initial context for an autonomous run that has no active milestone to draw context from. Built by `auto-bootstrap-context.js` and `headless-context.ts`.
**Autonomous mode** — SF running the full UOK dispatch loop without human confirmation per unit. Enabled via `sf run --autonomous` or the TUI `Ctrl+Y` (YOLO flag). The controller drives planning → implementation → verification non-stop.
---
## B
**Blast radius** — The set of systems, users, or data that a task could affect if it produces a wrong output. One of the eight run-control fields used to determine whether a task requires human confirmation.
**Build mode** — The SF work mode where agent can make file changes. One of two modes (Ask/Build). Toggled via `Shift+Tab`. YOLO is a flag on top of Build, not a third mode.
---
## C
**CODEBASE.md** — Auto-generated file map of the repo. Gitignored. Regenerated by SF on each autonomous run start. Lives at `.sf/CODEBASE.md`.
**Coding agent** (`packages/coding-agent/`) — The Pi SDK package that provides tool execution, model sessions, settings, retry logic, and context management. SF wraps this to run agent units.
**copy-resources** — The npm script (`npm run copy-resources`) that compiles `src/resources/extensions/sf/` TypeScript + copies prompt templates into `dist/resources/`. Required after any edit to extension source files.
---
## D
**DB-first** — The project invariant that all structured state lives in SQLite (`node:sqlite`, `.sf/sf.db`). No file-based fallbacks for state that belongs in the DB. Never use `better-sqlite3`.
---
## E
**Escalation policy** — Tiers of context sources the agent should consult before acting on ambiguity. Tier 1: `.sf/` files, wiki. Tier 2: `docs/adr/`, `docs/specs/`. Tier 3: source code. Defined in `system-context.js`.
---
## F
**FTS5** — SQLite full-text search extension. Used for semantic memory search and session history search in `sf.db`. Queries use `WHERE search_index MATCH 'term OR synonym'` syntax.
---
## H
**Headless mode** — Machine-surface entry point: `sf headless`. JSON I/O. Exit codes: 0 = success, 1 = error, 10 = plan needed, 11 = blocked, 12 = budget exhausted. Not synonymous with JSON output or autonomous mode.
---
## M
**Milestone** — Top-level unit of planned work. Identified as `M001`, `M002`, … Stored in `sf.db`. Rendered as markdown to `.sf/milestones/M001/`. A milestone contains slices; slices contain tasks.
---
## N
**node:sqlite** — Node.js built-in SQLite module (Node 26+). The only allowed SQLite interface in this codebase. Never import `better-sqlite3` or any native SQLite addon.
---
## P
**PDD** — Purpose-Driven Development. The eight fields (intent, value, consumer, falsifier, risk, reversibility, blast-radius, cost/compliance) that define what a task is and how to run it safely.
**Pi SDK** — The underlying agent SDK (`packages/coding-agent`, `packages/ai`, `packages/agent-core`, `packages/tui`, etc.) that SF is built on.
**Promote-only rule** — Runtime agent artifacts (`.sf/milestones/`, `.sf/evals/`, locks, journals) are gitignored and never committed directly. Durable artifacts are promoted to `docs/plans/`, `docs/adr/`, `docs/specs/`.
**Purpose-to-Software Compiler** — The foundational product model (ADR-0000): SF captures bounded intent, translates it into PDD fields, applies run-control policy, generates milestone/slice/task contracts, writes failing tests first, implements the smallest satisfying change, then records evidence and continues.
---
## R
**Run-control policy** — The framework that maps confidence, risk, reversibility, blast radius, cost, compliance, and production impact to a decision on whether to proceed autonomously or ask the human. Part of PDD.
---
## S
**sf.db** — The canonical SQLite database at `.sf/sf.db`. Contains milestones, slices, tasks, memories, schedule entries, session logs, FTS5 search indexes. The single source of truth for all structured SF state.
**Slice** — A scoped, deliverable unit within a milestone. Identified as `S01`, `S02`, … Each slice maps to a coherent set of tasks. Stored in `sf.db`, rendered to `.sf/milestones/M001/S01/`.
**Spec-first TDD** — The project doctrine: write a failing test (the spec) before writing implementation code. `THE TEST IS THE SPEC`. See `docs/SPEC_FIRST_TDD.md`.
---
## T
**Task** — The smallest schedulable work unit. Identified as `T01`, `T02`, … within a slice. Stored in `sf.db`. Each task gets its own agent session context and dispatch lifecycle.
**Tacit knowledge** — Project-specific conventions, patterns, and institutional knowledge stored in `.sf/KNOWLEDGE.md`. Injected into system context before every SF turn.
---
## U
**UOK** — Unified Operation Kernel. The deterministic (non-LLM) controller that reads `sf.db`, selects the next unit, launches a fresh agent session, and records results. Lives in `src/resources/extensions/sf/auto/`.
---
## W
**Wiki** (`.sf/wiki/`) — Human-curated + agent-generated reference pages injected into every SF system context turn. Tracked in git (not gitignored). Hand edits persist across commits and clones. Uppercase filenames (`INDEX.md`, `ARCHITECTURE.md`, etc.) matching the `.sf/` operational file convention.
**YOLO** — A flag on top of Build mode that disables all safety confirmations (no git prompts, no write-gate approvals). Enabled via `Ctrl+Y` or `/mode yolo`. Not a third mode — it does not appear as a `Shift+Tab` stop.

View file

@ -1,53 +0,0 @@
# singularity-forge — Index
*Generated: 2026-05-11 | Commit: see `git rev-parse HEAD` | Commands: see WORKFLOWS.md*
## What this repo is
SF (Singularity Forge) is a standalone autonomous repo operator CLI built on the [Pi SDK](https://github.com/badlogic/pi-mono). It compiles purpose into software via a Purpose-to-Software Compiler model (ADR-0000). One command (`sf`) runs an LLM-powered agent that plans, implements, tests, commits, and advances through milestones autonomously.
**Version:** 2.75.3
**Package:** `singularity-forge` on npm
**Bin:** `sf`
**Node:** 26.1+ required (`.mise.toml`, `.nvmrc`, `.node-version` pin)
## How to run it
```bash
npm install -g singularity-forge@latest
sf # interactive TUI
sf headless ... # machine surface (JSON I/O)
```
Dev from source:
```bash
npm install
npm run build # full build (packages + web)
npm run build:core # packages + tsc + resources only
npm run dev # hot reload
npm run copy-resources # rebuild dist/resources/ (extension JS/prompts)
```
## Where to start
| Goal | Start here |
|------|-----------|
| Understand the product | `README.md`, `VISION.md`, `ARCHITECTURE.md` |
| Understand SF's architecture decisions | `docs/adr/` |
| Understand spec-first TDD doctrine | `docs/SPEC_FIRST_TDD.md` |
| Understand the runtime state model | `.sf/PROJECT.md`, `AGENTS.md` |
| Find a subsystem | `SUBSYSTEMS.md` |
| Build/test commands | `WORKFLOWS.md` |
| Understand SF autonomous mode | `src/resources/extensions/sf/` |
| Understand the Pi SDK packages | `packages/` |
## Key files
- `src/loader.ts` — CLI entry point (`dist/loader.js`, bin `sf`)
- `src/headless-context.ts` — headless context loading + auto-bootstrap
- `src/resources/extensions/sf/` — SF autonomous mode extension (compile via `copy-resources`)
- `packages/coding-agent/` — Pi agent core (tools, models, sessions, settings)
- `packages/ai/` — LLM provider adapters
- `packages/tui/` — Terminal UI
- `packages/daemon/` — Background daemon process
- `.sf/sf.db` — canonical structured state (SQLite, `node:sqlite`)

View file

@ -1,71 +0,0 @@
# Subsystems
*Generated: 2026-05-11 | Hand-editable — tracked in git*
## Core CLI
| Subsystem | Path | Purpose | Tests |
|-----------|------|---------|-------|
| Loader / entry | `src/loader.ts` | CLI bootstrap — initialises resources, resolves extension, starts TUI or headless | `tests/smoke/` |
| Headless driver | `src/headless.ts` | Machine-surface command (`sf headless`), JSON I/O, exit codes 0/1/10/11/12 | `tests/smoke/` |
| Headless context | `src/headless-context.ts` | Bootstrap context loader for headless runs — wiki, spec files, auto-bootstrap | — |
## SF Extension (`src/resources/extensions/sf/`)
Compiled from TS → JS via `npm run copy-resources`. Edit `.ts`/`.js` source; changes only land in `dist/` after that command.
| Subsystem | Path (relative to extension) | Purpose |
|-----------|------------------------------|---------|
| UOK main loop | `auto/loop.js` | Autonomous dispatch loop — tick, gate, recovery |
| Dispatch | `auto/phases-dispatch.js` | Selects and launches the next unit (research/plan/implement/verify) |
| Phases helpers | `auto/phases-helpers.js` | Shared helpers for phase state transitions |
| Unit runner | `auto/run-unit.js` | Executes a single task plan via a fresh agent session |
| Session state | `auto/session.js` | Runtime session DB model (active unit, locks, lease) |
| Supervisor | `auto-supervisor.js` | Monitors agent runs, enforces turn/token budgets |
| Recovery | `auto-recovery.js` | Handles stuck/timeout/crash recovery for units |
| System context | `bootstrap/system-context.js` | Assembles full system prompt for every SF-managed turn |
| Auto-bootstrap context | `auto-bootstrap-context.js` | Loads context (wiki, specs, codebase) for headless auto runs with no milestones |
| DB tools | `bootstrap/db-tools.js` | SF's database query tools exposed to the agent |
| Query tools | `bootstrap/query-tools.js` | Higher-level query helpers over the DB schema |
| Memory tools | `bootstrap/memory-tools.js` | Semantic memory read/write over `sf.db` |
| Ask gate | `bootstrap/ask-gate.js` | Intercepts agent tool calls that need human confirmation |
| Write gate | `bootstrap/write-gate.js` | Intercepts destructive write operations for approval |
| Exec tools | `bootstrap/exec-tools.js` | Execution tool registration (shell commands, file ops) |
| Dynamic tools | `bootstrap/dynamic-tools.js` | Runtime tool registration based on current milestone/slice |
| Auto-prompts | `auto-prompts.js` | Loads task-execute prompt template and fills variables |
| Auto-model selection | `auto-model-selection.js` | Picks model for each unit based on capability/cost routing |
| Auto-budget | `auto-budget.js` | Tracks and enforces token and turn budgets per unit |
| Runaway guard | `auto-runaway-guard.js` | Detects infinite loop / runaway execution patterns |
| Abandon detect | `abandon-detect.js` | Detects when an agent unit has stalled or abandoned work |
| AI memory tools | `ai-memory-tools.js` | Agent-facing memory tools (store/recall facts) |
| Git runtime patterns | `git-runtime-patterns.js` | Defines which `.sf/` paths are gitignored at runtime |
| Activity log | `activity-log.js` | Appends structured activity events to `.sf/activity/` |
| Auto-dashboard | `auto-dashboard.js` | Terminal dashboard rendering during autonomous runs |
| Completion nudge | `auto-completion-nudge.js` | Prompts agent to finish when near budget limits |
## Packages (`packages/`)
| Package | Path | Purpose | Tests |
|---------|------|---------|-------|
| coding-agent | `packages/coding-agent/` | Agent core — tools (bash, grep, read…), models, sessions, settings, retry | `packages/coding-agent/tests/` |
| ai | `packages/ai/` | LLM provider adapters — Anthropic, OpenAI, Google, Moonshot, etc. | `packages/ai/tests/` |
| agent-core | `packages/agent-core/` | Shared agent abstractions, message types, streaming | — |
| tui | `packages/tui/` | Ink-based terminal UI | — |
| daemon | `packages/daemon/` | Background daemon process for persistent state | — |
| rpc-client | `packages/rpc-client/` | RPC adapter — JSON-RPC / HTTP wire protocol | — |
| native | `packages/native/` | Rust N-API bindings — grep, glob, ps, highlight, AST, diff (napi-rs) | `packages/native/tests/` |
| google-gemini-cli-provider | `packages/google-gemini-cli-provider/` | Gemini CLI Core auth provider (alternative to API key) | — |
## Key Singleton Files
| File | Role |
|------|------|
| `.sf/sf.db` | Canonical SQLite state (milestones, slices, tasks, memories, schedule, sessions) |
| `src/resources/extensions/sf/prompts/system.md` | System prompt template injected at every SF turn |
| `src/resources/extensions/sf/prompts/execute-task.md` | Per-unit task plan template |
| `.sf/PROJECT.md` | Hand-authored project identity and goals |
| `.sf/REQUIREMENTS.md` | Current requirements register |
| `.sf/DECISIONS.md` | Architecture decision log |
| `.sf/KNOWLEDGE.md` | Tacit knowledge and conventions |
| `.sf/CODEBASE.md` | Auto-generated file map (gitignored) |
| `.sf/wiki/` | Reference wiki — tracked in git, hand-editable |

View file

@ -1,76 +0,0 @@
# Workflows
*Generated: 2026-05-11 | Source: package.json, CONTRIBUTING.md, AGENTS.md*
## Build
```bash
npm run build # full (packages + tsc + resources + web)
npm run build:core # packages + tsc + resources only (no web)
npm run copy-resources # rebuild dist/resources/ ONLY (extension JS + prompts, ~60-90s)
```
**Critical:** editing `.ts` files in `src/resources/extensions/sf/` has no effect until `copy-resources` runs. The loader resolves from `dist/resources/extensions/sf/` (compiled JS).
## Test
```bash
npm test # unit + integration
npm run test:unit # vitest unit tests
npm run test:integration # integration tests
npm run test:coverage # coverage (thresholds: 40/40/20/20)
npm run test:smoke # smoke tests
npx vitest run <file> --config vitest.config.ts # single file
npx vitest run --changed --config vitest.config.ts # affected only
```
Test files: `*.test.ts` and `*.test.mjs` under `packages/*/src/`, `src/tests/`, `src/resources/extensions/*/tests/`.
## Lint
```bash
npm run lint # Biome over src/
npm run lint:fix # autofix
npm --prefix web run lint # ESLint over web/
npx biome check --write <paths> # format specific files
npm run typecheck:extensions # tsc --noEmit for extensions
```
## Release
```bash
npm run release:changelog # generate CHANGELOG entry
npm run release:bump # bump version
```
## SF Autonomous Flow
```
sf → TUI (interactive)
sf headless ... → machine surface (JSON I/O)
```
**Autonomous mode commands (headless):**
```bash
node dist/loader.js headless next # dispatch next ready unit
node dist/loader.js headless autonomous # run full autonomous loop
node dist/loader.js headless status # show current state
node dist/loader.js headless query # query DB state
```
**Note:** use `node dist/loader.js` not `npx sf` in this repo to avoid npm download hangs.
## Dev workflow
```bash
npm run dev # hot reload (tsc watch + copy-resources watch)
```
After editing prompts or extension JS, run `copy-resources` then test with headless.
## Git conventions
- Branch: `<type>/<short-desc>` (feat/, fix/, chore/, refactor/, etc.)
- Commits: Conventional Commits format
- No merge commits — rebase onto main
- PRs must link an issue; one concern per PR

View file

@ -71,6 +71,59 @@ function nowIso() {
return new Date().toISOString();
}
/**
* Build a gate_run trace event payload from a runner ctx + result.
*
* Carries the schema-v2 UOK run-context fields (surface, runControl,
* permissionProfile, parentTrace) onto every gate_run event when the
* caller supplies them. When absent, the fields are omitted entirely
* status-uok's classifier reads the event as "legacy" rather than
* "incomplete", matching the pre-v2 behavior.
*
* Slice 3b of "Make UOK the SF Control Plane" wires the autonomous
* loop's gate emissions into the v2 control plane without forcing
* every caller to know the column shape.
*/
function buildGateRunEvent(ctx, result, durationMs) {
const event = {
type: "gate_run",
traceId: ctx.traceId,
turnId: ctx.turnId,
gateId: result.gateId,
gateType: result.gateType,
unitType: ctx.unitType,
unitId: ctx.unitId,
milestoneId: ctx.milestoneId,
sliceId: ctx.sliceId,
taskId: ctx.taskId,
outcome: result.outcome,
failureClass: result.failureClass,
rationale: result.rationale,
findings: result.findings,
attempt: result.attempt,
maxAttempts: result.maxAttempts,
retryable: result.retryable,
evaluatedAt: result.evaluatedAt,
durationMs,
};
if (typeof ctx.surface === "string" && ctx.surface.length > 0) {
event.surface = ctx.surface;
}
if (typeof ctx.runControl === "string" && ctx.runControl.length > 0) {
event.runControl = ctx.runControl;
}
if (
typeof ctx.permissionProfile === "string" &&
ctx.permissionProfile.length > 0
) {
event.permissionProfile = ctx.permissionProfile;
}
if (typeof ctx.parentTrace === "string" && ctx.parentTrace.length > 0) {
event.parentTrace = ctx.parentTrace;
}
return event;
}
/**
* Enrich gate result with memory context for diagnostics.
*
@ -268,27 +321,11 @@ export class UokGateRunner {
},
}),
);
appendTraceEvent(ctx.basePath, ctx.traceId, {
type: "gate_run",
traceId: ctx.traceId,
turnId: ctx.turnId,
gateId: unknownResult.gateId,
gateType: unknownResult.gateType,
unitType: ctx.unitType,
unitId: ctx.unitId,
milestoneId: ctx.milestoneId,
sliceId: ctx.sliceId,
taskId: ctx.taskId,
outcome: unknownResult.outcome,
failureClass: unknownResult.failureClass,
rationale: unknownResult.rationale,
findings: unknownResult.findings,
attempt: unknownResult.attempt,
maxAttempts: unknownResult.maxAttempts,
retryable: unknownResult.retryable,
evaluatedAt: unknownResult.evaluatedAt,
durationMs: 0,
});
appendTraceEvent(
ctx.basePath,
ctx.traceId,
buildGateRunEvent(ctx, unknownResult, 0),
);
return unknownResult;
}
@ -325,27 +362,11 @@ export class UokGateRunner {
},
}),
);
appendTraceEvent(ctx.basePath, ctx.traceId, {
type: "gate_run",
traceId: ctx.traceId,
turnId: ctx.turnId,
gateId: cbResult.gateId,
gateType: cbResult.gateType,
unitType: ctx.unitType,
unitId: ctx.unitId,
milestoneId: ctx.milestoneId,
sliceId: ctx.sliceId,
taskId: ctx.taskId,
outcome: cbResult.outcome,
failureClass: cbResult.failureClass,
rationale: cbResult.rationale,
findings: cbResult.findings,
attempt: cbResult.attempt,
maxAttempts: cbResult.maxAttempts,
retryable: cbResult.retryable,
evaluatedAt: cbResult.evaluatedAt,
durationMs: 0,
});
appendTraceEvent(
ctx.basePath,
ctx.traceId,
buildGateRunEvent(ctx, cbResult, 0),
);
return cbResult;
}
@ -414,27 +435,11 @@ export class UokGateRunner {
},
}),
);
appendTraceEvent(ctx.basePath, ctx.traceId, {
type: "gate_run",
traceId: ctx.traceId,
turnId: ctx.turnId,
gateId: final.gateId,
gateType: final.gateType,
unitType: ctx.unitType,
unitId: ctx.unitId,
milestoneId: ctx.milestoneId,
sliceId: ctx.sliceId,
taskId: ctx.taskId,
outcome: final.outcome,
failureClass: final.failureClass,
rationale: final.rationale,
findings: final.findings,
attempt: final.attempt,
maxAttempts: final.maxAttempts,
retryable: final.retryable,
evaluatedAt: final.evaluatedAt,
durationMs,
});
appendTraceEvent(
ctx.basePath,
ctx.traceId,
buildGateRunEvent(ctx, final, durationMs),
);
if (!retryable) break;
}