From 6beb6fd412daea968ca7d9e9237eccc8145efec0 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Thu, 7 May 2026 05:52:25 +0200 Subject: [PATCH] docs: align replan and state source of truth --- README.md | 2 +- src/resources/extensions/sf/triage-resolution.js | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6beaff80e..b5f3ea386 100644 --- a/README.md +++ b/README.md @@ -698,7 +698,7 @@ sf (CLI binary) - **`pkg/` shim directory** — `PI_PACKAGE_DIR` points here (not project root) to avoid Pi's theme resolution collision with our `src/` directory. Contains only `piConfig` and theme assets. - **Two-file loader pattern** — `loader.ts` sets all env vars with zero SDK imports, then dynamic-imports `cli.ts` which does static SDK imports. This ensures `PI_PACKAGE_DIR` is set before any SDK code evaluates. - **Always-overwrite sync** — `npm update -g` takes effect immediately. Bundled extensions and agents are synced to `~/.sf/agent/` on every launch, not just first run. -- **State lives on disk** — `.sf/` is the source of truth. Auto mode reads it, writes it, and advances based on what it finds. No in-memory state survives across sessions. +- **State lives on disk** — `.sf/sf.db` is the structured source of truth for migrated runtime state, including planning hierarchy, ordering, validation, gates, UOK lifecycle, backlog, and schedule rows. Markdown/JSON files under `.sf/` are human views, generated projections, evidence, or explicit legacy import/recovery inputs. No in-memory state survives across sessions. --- diff --git a/src/resources/extensions/sf/triage-resolution.js b/src/resources/extensions/sf/triage-resolution.js index 6a3ea0082..9ceef26e6 100644 --- a/src/resources/extensions/sf/triage-resolution.js +++ b/src/resources/extensions/sf/triage-resolution.js @@ -4,7 +4,8 @@ * Provides resolution executors for each capture classification type: * * - inject: appends a new task to the current slice plan - * - replan: writes REPLAN-TRIGGER.md so next dispatchNextUnit enters replanning-slice + * - replan: stamps the slice DB row and writes REPLAN-TRIGGER.md evidence so + * next dispatchNextUnit enters replanning-slice * - defer/note: query helpers for loading deferred/replan captures * * Also provides detectFileOverlap() for surfacing downstream impact on quick tasks. @@ -76,9 +77,9 @@ export function executeInject(basePath, mid, sid, capture) { } } /** - * Trigger replanning by writing a REPLAN-TRIGGER.md marker file. + * Trigger replanning by stamping the slice DB row and writing compatibility evidence. * The existing state.ts derivation detects this and sets phase to "replanning-slice". - * Returns true if the trigger was written successfully. + * Returns true if the trigger was recorded successfully. */ export function executeReplan(basePath, mid, sid, capture) { try { @@ -98,7 +99,7 @@ export function executeReplan(basePath, mid, sid, capture) { `will detect it and enter the replanning-slice phase.`, ].join("\n"); atomicWriteSync(triggerPath, content, "utf-8"); - // Also write replan_triggered_at column for DB-backed detection + // Structured state is authoritative; the marker above remains evidence/import aid. try { if (isDbAvailable()) { setSliceReplanTriggeredAt(mid, sid, ts); @@ -373,7 +374,7 @@ export function buildQuickTaskPrompt(capture) { * quick-task) but haven't been executed yet, then: * * - inject: calls executeInject() to add a task to the current slice plan - * - replan: calls executeReplan() to write the REPLAN-TRIGGER.md marker + * - replan: calls executeReplan() to stamp DB state and write the marker evidence * - quick-task: collects for dispatch (caller handles dispatching quick-task units) * * Each capture is marked as executed after its resolution action succeeds,