Companion to b771dd0b3 (deep-mode prompt templates). Adds the five
auto-prompts.ts builders that load those templates with the
correct vars.
PDD spec for this change:
Purpose: complete the load path for deep-mode planning so dispatch
rules can call buildDiscussProjectPrompt(), etc., without crashing.
Consumer: auto-dispatch.ts deep-mode rules (next commit).
Contract: each builder returns a populated prompt string for its
unit type given (basePath, structuredQuestionsAvailable). All 5
load successfully against their respective .md templates with no
missing-var errors.
Failure boundary: loadPrompt throws SF_PARSE_ERROR if a template
variable is missing — surfaces a clear error rather than silently
rendering a half-substituted prompt.
Evidence: typecheck passes; loadPrompt verification in last fire's
log shows all 5 prompts render to non-empty strings (2.6k–7.7k
chars each).
Non-goals: dispatch wiring (separate commit, requires the
deep-project-setup-policy resolver SF already has).
Invariants:
- Safety: existing builders unchanged — no regression.
- Liveness: each builder returns within one prompt-load round-trip.
Assumptions verified:
- inlineTemplate('project'/'requirements') already exists in
prompt-loader.ts.
- sf_requirement_save and sf_summary_save tools exist in
db-tools.ts (referenced by the prompts they load).
- phases.planning_depth: 'light' | 'deep' already typed in
preferences-types.ts (line 425).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the prompt templates that gsd-2 uses for its 'deep' planning_depth
mode — a multi-stage discussion flow (project → requirements → research
decision → parallel research) that runs BEFORE any milestone-level
discussion. SF only had milestone-level discuss flow; this fills the
project-level and requirements-level gaps.
Ported files:
- guided-discuss-project.md — project-wide vision/users/anti-goals
- guided-discuss-requirements.md — structured R### requirements interview
- guided-research-decision.md — yes/no gate for parallel research
- guided-research-project.md — 4-way parallel research orchestrator
- guided-workflow-preferences.md — workflow + planning prefs collection
gsd→sf adaptations: GSD/gsd → SF/sf, .gsd/ → .sf/, gsd_*_save tool
names → sf_*_save, GSD Skill Preferences → SF Skill Preferences.
All 5 verified to load via loadPrompt with their required template
variables. The two sf_* tools they reference (sf_requirement_save and
sf_summary_save) already exist in db-tools.ts.
This is the first half of the deep-mode port. Remaining work for full
end-to-end:
- Port 5 builders to auto-prompts.ts (buildDiscussProjectPrompt, etc.)
- Port dispatch rules to auto-dispatch.ts (each gates on
prefs.planning_depth === 'deep')
- Port resolveDeepProjectSetupState helper for the research-decision
marker file
- Add planning_depth: 'deep' | 'light' to PhaseSkipPreferences
Default behavior preserved: without planning_depth set, current SF
'light' behavior is unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the last gap in the ADR-011 progressive planning chain. When
refine-slice runs and persists its full plan via sf_plan_slice, the
tool now zeros is_sketch atomically with the plan upsert (only when
the slice was actually a sketch — idempotent no-op otherwise).
This means the dispatch rule from 0c78b0038 will route to refine-slice
on the FIRST visit to a sketch slice, then route to plan-slice on any
subsequent visit because the flag is gone. No infinite refine loops.
sketch_scope is preserved on clear (clearSliceSketch only touches the
is_sketch column) so the original scope hint stays as an audit trail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the producer half of the ADR-011 rollout. With this commit, the
end-to-end progressive planning path is complete and runnable:
plan-milestone → insertSlice writes is_sketch=1 → dispatch reads it →
refine-slice expands → clearSliceSketch zeros the flag.
Changes:
sf-db.ts insertSlice: extends the typed payload with isSketch and
sketchScope (3-valued: true/false/undefined). The INSERT INTO and ON
CONFLICT clauses gain is_sketch + sketch_scope columns with the same
NULL-sentinel pattern (raw_is_sketch / raw_sketch_scope) used by every
other field — so a re-plan that omits these flags preserves any
existing sketch state rather than blanking it.
sf-db.ts clearSliceSketch: new exported helper for refine-slice to
call after persisting the full plan. Idempotent.
tools/plan-milestone.ts validateSlices: handles 3-valued isSketch
semantics. When isSketch=true, sketchScope is required (non-empty)
and the heavyweight planning fields (successCriteria, proofLevel,
integrationClosure, observabilityImpact) are optional. Non-sketches
keep current strict validation (no regression for existing callers).
tools/plan-milestone.ts persist loop: passes isSketch/sketchScope
through to insertSlice; skips upsertSlicePlanning entirely when
isSketch=true (the planning fields belong to refine-slice's output).
End-to-end DB test verified all four behaviors:
✅ isSketch=true + sketchScope writes is_sketch=1 + scope text
✅ Explicit isSketch=false writes is_sketch=0
✅ Omitted isSketch defaults to 0 on insert
✅ clearSliceSketch zeros the flag while preserving sketch_scope
✅ ON CONFLICT with omitted isSketch preserves existing row state
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors gsd-2's slices schema for progressive planning. Three changes
to sf-db.ts:
1. Fresh-install CREATE TABLE for slices (line 312) gains:
- is_sketch INTEGER NOT NULL DEFAULT 0 -- 1 = awaiting refine
- sketch_scope TEXT NOT NULL DEFAULT '' -- 2-3 sentence scope hint
2. Schema version 22 migration: ensureColumn for both fields so
existing installs upgrade without data loss. Wrapped in the same
currentVersion < N guard pattern as v6, v7, v8 ... v21.
3. rowToSlice() returns sketch_scope and is_sketch on the SliceRow
so the dispatch rule from 0c78b0038 can read them via getSlice().
End-to-end verified: fresh DB has both columns at defaults; getSlice()
returns is_sketch=0, sketch_scope='' on a freshly-inserted slice.
Closes the DDL-migration gap from the progressive-planning rollout
plan in fef2e4b6f. Remaining: plan-milestone tool needs to write
is_sketch=1 + sketch_scope when emitting sketches; refine-slice tool
needs to clear is_sketch=0 when persisting the full plan. Until those
land, the dispatch rule still falls through (sketches never created).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 'planning (sketch + progressive_planning) → refine-slice' rule
in auto-dispatch.ts, fired BEFORE the existing 'planning → plan-slice'
rule. Activates when:
- state.phase === 'planning'
- prefs?.phases?.progressive_planning === true
- slice has is_sketch=1 in the DB
When all three conditions hold, dispatches the refine-slice unit using
the existing buildRefineSlicePrompt + prompts/refine-slice.md (both
ported in earlier commits). Otherwise falls through to plan-slice
(graceful downgrade — current behavior is preserved when the flag is
off, which is the default).
Why this matters: without progressive planning, the milestone planner
has to either fully-plan every slice upfront (rots quickly) or hand-
wave each slice (executors overscope). Sketch+refine lets the planner
write 2-3 sentences of scope per slice and have refine-slice expand it
just-in-time using prior slice summaries as context — keeping each
plan sized for the actual current reality.
Defensive read of slice.is_sketch with try/catch: pre-migration installs
without the column simply fall through to plan-slice, no error. The DB
DDL migration will land separately as part of the full progressive-
planning rollout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three additive type changes that prepare SF to wire refine-slice
through the state machine. Pure type-level — no runtime behavior
change yet:
1. types.ts:14 — Phase union gains "refining" between "planning" and
"evaluating-gates". State derivation will yield this when a slice
has is_sketch=1 AND phases.progressive_planning=true.
2. types.ts:354 — PhaseSkipPreferences.progressive_planning?: boolean.
Off by default; turning it on enables sketch→refine flow.
3. sf-db.ts:2321 — SliceRow.is_sketch?: number. Column DDL not yet
added; this just lets the type compile when migration lands.
This is the smallest forward step toward closing the refine-slice gap
identified by sf-moojsmkg-72k3ei. Next steps (separate PRs):
- DB migration: ALTER TABLE slices ADD COLUMN is_sketch INTEGER NOT
NULL DEFAULT 0 (mirroring gsd-2 sf-db.ts:381,1074)
- state.ts: derivation rule emit phase="refining" when sketch+flag
- auto-dispatch.ts: "refining → refine-slice" rule + import
buildRefineSlicePrompt
- Tests: progressive-planning.test.ts equivalent
Existing buildRefineSlicePrompt + prompts/refine-slice.md already in
place — only the FSM path is missing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
src/resources/extensions/sf/auto-prompts.ts:2143 buildRefineSlicePrompt()
already existed, calling loadPrompt("refine-slice", ...) — but the
template file was missing, so the function would throw if ever called.
gsd-2 has the prompt; ported with /gsd → /sf, .gsd/ → .sf/, GSD → SF,
gsd_plan_slice → sf_plan_slice, gsd_self_report → sf_self_report,
gsd/templates → sf/templates substitutions.
Verified end-to-end: loadPrompt("refine-slice", { ...vars }) succeeds
and produces a 5906-char rendered prompt with all 12 template variables
satisfied by renderSlicePrompt's existing var-passing.
This is a partial fix for sf-moojsmkg-72k3ei — the prompt now loads,
but full feature wire-up still requires:
- new state.phase value "refining"
- new preference phases.progressive_planning (gsd-2 only enables refine
when this pref is true)
- dispatch rule "refining → refine-slice" in auto-dispatch.ts
- slice DB schema's sketch_scope already exists in the function body
but downstream FSM transitions need wiring
Without those, buildRefineSlicePrompt is loadable but uncalled. Decision
needed: port the full FSM path or remove the unused builder.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
templates/milestone-validation.md:60 was instructing the validating agent
to add 'enough context for Lex to make a decision'. Lex is the
developer's personal nickname; bundled templates ship to every SF user
and other users would write validation reports referencing a stranger.
Now reads 'enough context for the project owner to make a decision' —
generic and accurate for any project.
Tree-wide grep for Lex/Mikael/Mikki across bundled resources now
returns zero personal-name references.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three bundled files referenced /home/mhugo/code/singularity-forge in
example commands and prompt templates. They ship to every SF install,
where /home/mhugo/code/ doesn't exist:
- workflow-templates/full-project.md: "defined in SF-WORKFLOW.md" was
ambiguous (LLM resolves relative to cwd). Now points at the canonical
~/.sf/agent/SF-WORKFLOW.md install path (per loader.ts:236).
- skills/context-doctor/SKILL.md: Step 6 commit example used
"cd /home/mhugo/code/singularity-forge". Generic "<project-root>"
works for any user.
- skills/dispatching-subagents/SKILL.md: subagent task-prompt template
hardcoded "Repo: /home/mhugo/code/singularity-forge" in the CONTEXT
section. Same fix.
The acquiring-skills skill has more dev-specific content (mikki-bunker
host, /home/mhugo/code/, dev-tree copy paths) that's clearly a personal
workflow shipping in the bundled tree — left untouched here, needs a
real triage decision (delete from bundle vs generalize).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The github-workflows skill bundles a sub-tree at references/gh/ that was
historically a standalone 'gh' skill. After it got nested inside
github-workflows, the docs and scripts kept the old install path:
.claude/skills/gh/scripts/github_project_setup.py (stale)
When this skill is installed (as 'github-workflows'), the actual path is:
.claude/skills/github-workflows/references/gh/scripts/github_project_setup.py
Anyone copy-pasting an example uv run command from issue-stories.md,
milestones.md, labels.md, projects-v2.md, or the script's own help
output would hit ENOENT on the abbreviated path.
11 line replacements across 5 files (4 reference docs + 1 Python
script's own typer.echo).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step 1 said "Load the audit prompt at \`prompts/product-audit.md\`".
That's a relative path the dispatched LLM would resolve against the
project's working directory — but \`prompts/product-audit.md\` doesn't
live in the user's project; it lives in the bundled extension copied
to \`~/.sf/agent/extensions/sf/prompts/\` (per prompt-loader.ts:50
__extensionDir/prompts).
LLMs running this workflow would either fail to find the file, walk
the filesystem looking for it, or skip the guidance silently. Now
points at the canonical location and clarifies that the prompt holds
evidence-collection guidance and output schema (the structured tool
sf_product_audit handles persistence).
Partially addresses sf-monzctqw-w4g85x — the path is now right; the
broader prompt-vs-hardcoded-tool design tension is left for a real
triage decision.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After last fire fixed sf-skill-ecosystem.md, three more sites in the
create-skill skill were still teaching the legacy ~/.sf/agent/skills/
and .pi/agent/skills/ paths:
- create-skill/SKILL.md:91 quick reference
- create-skill/workflows/create-new-skill.md:18 (scope question)
- create-skill/workflows/create-new-skill.md:102 (Step 5 directory creation)
- create-skill/workflows/audit-skill.md:19,29 (skill enumeration ls commands)
Now point at the canonical four-directory ecosystem
(~/.agents/skills/, ~/.claude/skills/, plus project-local variants)
that the runtime actually scans (per skill-discovery.ts:16-17,
skill-telemetry.ts:34-35, preferences-skills.ts:39-43).
The audit-skill ls block now enumerates all four locations so the
audit report matches what SF will actually load.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
src/resources/skills/create-skill/references/sf-skill-ecosystem.md
documented skill paths that don't match what the SF runtime actually
scans:
- Doc said user-scope: `~/.sf/agent/skills/` and project-scope: `.pi/agent/skills/`
- Code (skill-discovery.ts:16-17, skill-telemetry.ts:34-35,
skill-health.ts:240-241, skill-catalog.ts:1014-1015,
preferences-skills.ts:39-43) actually scans:
- User: `~/.agents/skills/` + `~/.claude/skills/`
- Project: `<cwd>/.agents/skills/` + `<cwd>/.claude/skills/`
Anyone following the create-skill skill's reference doc would have
written skills to a path the runtime no longer actively reads —
`~/.sf/agent/skills/` is now legacy and only consulted if the
`.migrated-to-agents` marker is missing.
Also fixed:
- Telemetry path: said `~/.sf/metrics.json` (user-scope), actually
`<project>/.sf/metrics.json` (project-scope per metrics.ts:665)
- Doctor command: said `/doctor`, actual command is `/sf doctor`
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
prompts/system.md:106 told agents the isolation mode lives in
PREFERENCES.md under `taskIsolation.mode`. The preferences validator
(preferences-validation.ts:84-88) explicitly REJECTS that key — along
with task_isolation and bare isolation — with the error
'use "git.isolation" instead'. The canonical field is git.isolation
(verified in PREFERENCES.md template line 22 and preferences.ts:897).
Anyone following the system-prompt instruction would write the wrong
config, the validator would discard it, and isolation would silently
fall back to default 'none'.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final sweep after the prompt + script + README sweep for stale repo
references. These are pure code comments, not active behavior, but they
mislead readers about what repo this code lives in:
- src/resource-loader.ts: "sf-2 repo's working tree" → "sf-run repo's"
- src/web/safe-import-meta-resolve.ts: example URL hostname
- src/resources/extensions/sf/schemas/parsers.ts: dropped "sf-2 /" prefix
- src/resources/extensions/sf/schemas/validate.ts: same
- scripts/parallel-monitor.mjs: comment about "sf-2 repo itself"
Tests intentionally not touched — the test fixtures use @sf-build as a
generic scope name to exercise the symlink-merge logic, and the test
tmpdir prefixes (sf-2821-, sf-2945-) are just numeric tags from issue
numbers, not repo refs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same pattern fixed in scan.md last fire. The {{skillActivation}}
placeholder was the very last line of add-tests.md, after the
'Report sf-internal observations' section, so the default activation
sentence the prompt-loader injects landed where the agent only reads
it AFTER finishing test generation. Move to Instructions step 0 so
skills are activated before code reading begins.
Confirmed via sweep: no more prompts have a dangling {{skillActivation}}
at end-of-file.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
prompts/parallel-research-slices.md step 3 told the dispatcher to verify
research at `.sf/{{mid}}/`, but slice research files actually live at
`.sf/milestones/{{mid}}/slices/<sliceId>/<sliceId>-RESEARCH.md`. Step 3
verification could only ever fail.
prompts/validate-milestone.md sent the three milestone-validation reviewer
agents to wrong paths:
- parentTrace pointed at `.sf/{{milestoneId}}/S0X-SUMMARY.md` (slice
summaries actually live at `.sf/milestones/{{milestoneId}}/slices/S0X/`)
- Reviewer A read `.sf/{{milestoneId}}/REQUIREMENTS.md` (the file is at
project-level `.sf/REQUIREMENTS.md`)
- Reviewer A scanned `.sf/{{milestoneId}}/` for slice SUMMARYs (wrong dir)
- Reviewer C read `.sf/{{milestoneId}}/CONTEXT.md` (actual file is
`.sf/milestones/{{milestoneId}}/{{milestoneId}}-CONTEXT.md`)
Reviewers would either return false MISSING / FAIL verdicts or have to
re-discover the layout.
docs/dev/ADR-{008,009}-IMPLEMENTATION-PLAN.md "Related ADR" links pointed
to absolute paths inside a contributor's old Mac (`/Users/jeremymcspadden/
Github/sf-2/...`). Replaced with sibling-file relative paths.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After fixing forensics.md and error-classifier.ts last fire, swept the
rest of the tree for the same class of stale reference:
- scripts/validate-pack.js: criticalPackages list used \`@sf\` and
\`@sf-build\` scopes — neither exists in node_modules; this is in CI
(.github/workflows/ci.yml) + prepublishOnly, so the validation step
was failing to find anything. Now \`@singularity-forge/pi-coding-agent\`
and \`@singularity-forge/rpc-client\` (the actual scope).
- src/resources/skills/github-workflows/references/gh/SKILL.md: same
GraphQL bug as forensics.md — owner:"sf-build" name:"sf-2" — and
three \`gh project\` commands using owner sf-build. The gh issue
create command above already used singularity-forge/sf-run, so the
follow-up calls always failed. Also retitled "sf-2 Backlog" to
"sf-run Backlog".
- src/resources/extensions/sf/bootstrap/system-context.ts: deprecation
warning linked to https://github.com/sf-build/SF/issues/1492.
- packages/mcp-server/README.md, packages/rpc-client/README.md: 9 refs
to \`@sf-build/...\` for installable package names — would mislead
anyone copy-pasting into npm install.
- docs/user-docs/troubleshooting.md (+ zh-CN): GitHub Issues link
pointed at github.com/sf-build/SF/issues.
- docs/user-docs/getting-started.md (+ zh-CN): clone URL was correct
but the next \`cd\` was \`cd sf-2/docker\` — won't exist after a
fresh clone of sf-run.
- docs/dev/ci-cd-pipeline.md: GHCR org was \`sf-build\`.
Code comments containing "sf-2" / "sf-build" in non-active places
(parsers.ts banner, error message URLs in tests, dev-doc absolute
paths from a contributor's Mac) left alone — they're informational
and not addressed by users or runtime.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
forensics.md: GraphQL queries used owner:"sf-build" name:"sf-2" while
the gh issue create command above them correctly used
--repo singularity-forge/sf-run. This meant /sf forensics could create
the issue but the follow-up calls to set issue type would silently fail
against a non-existent repo. Both GraphQL queries now match the canonical
singularity-forge/sf-run.
error-classifier.ts: doc-comment @see link pointed to the old
sf-build/sf repo URL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The {{skillActivation}} placeholder was at the very bottom of scan.md,
after the 'Report sf-internal observations' section, with no header or
context. Since the default prompt-loader provides a one-sentence
'use the SF Skill Preferences block...' instruction, it landed as an
orphan footer the agent only encountered AFTER finishing the scan.
Move it to step 0 of the numbered Instructions so the agent activates
skills before exploring the codebase, matching the research-slice and
plan-milestone pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`/sf debug` was ported in 360208cba but never wired up:
- handleDebug exported but no caller anywhere in the tree
- not in commands/catalog.ts
- loadPrompt("debug-session-manager") and loadPrompt("debug-diagnose")
referenced prompts that never existed in prompts/ — guaranteed
runtime crash if the dispatch path were ever hit
- debug-session-store.ts only consumed by commands-debug.ts
- no tests reference any of it
887 LOC of dead code with a latent crash. Removing both files
eliminates the orphan-prompt callsite that gap-audit kept flagging
and the broken dispatch path. Resolves sf-moohvyzc-ll5bd0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirror the tiered Deep/Targeted/Light breakdown that research-slice.md
already had — same structure, milestone-scoped wording. Add explicit
'## Steps' header so the numbered steps no longer flow visually out of
the calibration paragraph.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Orphan-prompt detection only checked loadPrompt() callsites. Three
prompts (heal-skill, product-audit, review-migration) are loaded by
direct readFileSync of "<name>.md" — they got false-flagged as orphans.
Add a literal-filename check so any source file containing "<name>.md"
counts as a load. Cheap one-pass grep, same shape as the existing
loadPrompt patterns.
Verified with live runGapAudit: 0 new findings (was previously logging
the 3 false positives every session_start).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auto-mode prompts called legacy aliases (sf_complete_task, sf_complete_slice)
while guided used canonical (sf_task_complete, sf_slice_complete). The
divergence was locked in by the test 'auto execute-task requires legacy
completion alias until prompt contract is aligned' — explicit tech debt
marker.
Migrated:
- workflow-mcp.ts getRequiredWorkflowToolsForAutoUnit: returns canonical
- prompts/execute-task.md: 4 callsites
- prompts/complete-slice.md: 3 callsites
- prompts/reactive-execute.md: any (none on this file)
- workflow-mcp.test.ts: assertion + transport-error fixtures
- Test rename: 'requires legacy completion alias' → 'requires canonical'
The aliases stay registered (sf_complete_task → sf_task_complete) so
external callers and old session resumes don't break. Tool-naming.test.ts
still asserts both names route to the same handler.
Resolves: sf-moohqbza-yyq8sd.
Tests: workflow-mcp + tool-naming 29/29 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
29-line template with zero callers. inlineTemplate("reassessment")
isn't called anywhere; reassess-roadmap.md prompt has its own inline
structure. Removing prevents drift between dead template and live
prompt.
Resolves: orphan-template-reassessment.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
plan-slice was force-deep on every dispatch — full multi-task
decomposition + long architectural narration regardless of slice
complexity. research-slice has a 3-tier Calibrate Depth section
(Deep / Targeted / Light) that lets the agent right-size; plan-slice
now mirrors it.
Light tier explicitly authorizes 1-task plans for well-understood
work (CRUD, config changes, established-pattern wiring) — preventing
the synthesized 4-task decompositions that were a likely contributor
to recurring runaway-guard pauses on planning units.
Resolves: sf-moohebyg-y0hnhq.
Tests: plan-slice-prompt 16/16 still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
acquireSessionLock now accepts an optional sessionInfo arg (sessionId,
sessionFile) and writes both into the initial lockData JSON. The
caller in auto-start.ts:382 reads them from ctx.sessionManager.
updateSessionLock already writes these fields per-dispatch; this
closes the gap at acquire time.
Lets observers correlate the live auto.lock with the .sf/sessions/
event log (e.g. flow-auditor agents, dashboard, doctor).
Resolves: sf-moocx6lv-9grpvt (active-auto-session-pointer-missing).
Tests: 32/32 in session-lock + auto-start.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The auto-drain shipped hook-emitter.ts:80,93 logWarning calls with
component "hook-emitter" but that string wasn't in the LogComponent
union, blocking tsc compilation. Add 'hook' to the union (consistent
with the existing short component names like 'tool', 'dispatch',
'timer') and update the two callsites.
Without this, tsc fails and dist/resource-loader.js (which contains
the new verifyManifestFilesExist fix) can't update — leaving the
ask-user-questions.js boot failure unresolved despite the source-side
fix landing in aa7d3f10a.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- gap-audit prompt detection: Add DYNAMICALLY_LOADED_PROMPTS set for prompts
loaded through wrappers (research-slice, plan-slice, execute-task, etc.)
and detect loadPrompt calls with comma-separated args (#sf-moobj36l-ewu7js)
- gap-audit command detection: Detect exact match, prefix match, and
switch/case patterns for command dispatch (#sf-moobj36o-n8b7g9)
- empty task summary: Add isValidTaskSummary() to require non-empty content
with frontmatter or H1 before reconciliation marks task complete
(#sf-moobj36o-6rxy6e)
- journal write failures: Emit bounded health warning to .write-failures.jsonl
on journal write failure with per-session dedup (#sf-moobj36p-ikq3b2)
- resource sync manifest divergence: Add verifyManifestFilesExist() to check
all manifest-listed files exist on disk after hash match (#sf-moody5qi-8gbwp2)
- self-feedback markdown stale: Regenerate SELF-FEEDBACK.md from jsonl on
markResolved with resolved entries section (#sf-moobj36p-rlo95i)
- self-feedback context bloat: Cap entries to 20 max, 4000 chars, inject
compact summaries only with pointer to jsonl for full evidence
(#sf-moobj36p-ko6snt)
- hook-emitter types: Replace unknown with EventResult discriminated union,
implement emitExtensionEvent call with fallback warning when _pi missing
(#sf-moobmhwt-bxejb6, #sf-moobmhx4-gk9g83)
- export visualizer types: Add VisualizerExportData interface with proper
PhaseAggregate/SliceAggregate/ModelAggregate/ProjectTotals types
replacing any (#sf-moobmhx0-ow5fhy)
- native-edit-bridge: Already resolved (artifact removed from repo)
(#sf-moobj36q-z4id3u)
Switches the per-project sift warmup runtime dir field from cacheHome
(generic XDG_CACHE_HOME) to searchCache (specific SIFT_SEARCH_CACHE).
Narrower env var only redirects sift's search index, leaving sift's
other XDG_CACHE_HOME consumers (model downloads etc.) on the global
~/.cache/sift path so models are shared across projects.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>