# Tech Debt Tracker ## Notification event classification — text matching only **Impact:** `src/headless-events.ts` classifies events (blocked, milestone-ready, auto-stopped) by regex against stderr text. Fragile: any wording change in a notification breaks classification silently. **Proposed fix:** Implement structured `source`/`kind`/`blocking` metadata per notification-event-model.md. Update headless event parser to use typed fields. **Verification:** Remove string-match classifiers; confirm headless exit-code logic still triggers correctly via integration test. **Tracked in:** [active/index.md — Notification Event Model](./active/index.md) --- ## External workflow mutations — RPC/headless only **Impact:** External orchestrators must advance SF through native SF commands, headless/RPC, or the daemon/RPC client path. SF must not expose workflow mutation tools through MCP. **Proposed fix:** Extract shared handlers from native tools behind an internal command/RPC boundary. Keep ADR-008 rejected: do not build or restore an SF MCP server. **Verification:** A daemon/RPC session completes a task through the native `sf_task_complete` path and produces the same DB/projection outcome as interactive SF. **Tracked in:** [ADR-008 tombstone](../dev/ADR-008-IMPLEMENTATION-PLAN.md) --- ## No ADR template or generation recipes **Impact:** Every ADR is hand-authored from scratch. No enforced schema means some ADRs omit falsifiers, status dates, or sequencing. No `just adr` recipe means the numbering is manual. **Proposed fix:** Add `docs/dev/ADR-TEMPLATE.md` with required sections (Status, Date, Context, Options, Decision, Consequences, Falsifiers, Verification). Add `just adr ` recipe that stamps the template. **Verification:** `just adr 019 my-decision` produces `docs/dev/ADR-019-my-decision.md` with all required section headings. --- ## Parallel milestone state locking — file-based, ad-hoc **Impact:** Concurrent milestone execution uses ad-hoc file locks on STATE.md and roadmap.md. Race condition possible under heavy parallelism; not blocking for serial execution (current default). **Proposed fix:** SQLite database in `.sf/sf.db` with atomic transactions for all state mutations. Deferred to ADR-018 Phase 1+. **Verification:** Two milestone workers simultaneously completing tasks produce consistent STATE.md with no lost updates. **Tracked in:** [ADR-018](../dev/ADR-018-repo-native-harness-evolution.md) sequencing stage 1. --- ## write-gate BASH_READ_ONLY_RE — monolithic regex **Location:** `src/resources/extensions/sf/bootstrap/write-gate.ts` **Impact:** 30+ command patterns are encoded in a single 900-character regex. Adding a new safe command requires editing the regex inline, with no unit coverage per command. Risk of subtle regex alternation bugs. **Proposed fix:** Replace with a data-driven allowlist (array of patterns with names and comments) that the gate compiles at startup. Each entry is individually testable. **Verification:** `write-gate.test.ts` achieves per-command coverage without a single monolithic regex match test. --- ## ADR-018 runtime — harness profiler not yet wired **Impact:** `repo-profiler.ts` exists but is not called during any autonomous dispatch phase. The harness evolution system (ADR-018) exists only as design documentation; no runtime behavior has shipped. **Proposed fix:** Wire `buildRepoProfile()` call into the pre-dispatch phase (Phase 1). Record result in `.sf/sf.db`. **Verification:** After any planning milestone, `.sf/sf.db` contains a `repo_profiles` row for the current session. **Tracked in:** [active/index.md — ADR-018 Phase 1](./active/index.md) --- ## Memory subsystem extraction into swappable sub-extension **Location:** `src/resources/extensions/sf/memory-store.ts`, `src/resources/extensions/sf/memory-extractor.ts`, `src/resources/extensions/sf/memory-relations.ts`, `src/resources/extensions/sf/memory-sleeper.ts` **Impact:** SF's memory subsystem (separate from singularity-memory, which serves hermes/ACE) is coupled directly into SF core. Plugging in a different backend — e.g. a vchord-in-docker container for local vector search — is harder than it needs to be. **Proposed fix:** Extract the four files above into a sub-extension at `src/resources/extensions/sf-memory/` behind a small backend interface, so SF can swap implementations without touching core. **When to do it:** Defer until a real backend-swap requirement appears (e.g. SF actually needs vector search). Not blocking. **Estimated effort:** Small — these files have clean module boundaries already.