fix: resolve 3 test failures and 1 pre-existing code bug

- unit-runtime: fall back to STATE.md for nextActionAdvanced when DB is
  unavailable (restores test compat for reconcileDurableCompleteUnitRuntime-
  Records; DB path still preferred in production)
- browser-slash-command-dispatch: remove 'stop' from SF_PASSTHROUGH_COMMANDS
  so /stop correctly returns { kind: 'reject' } in browser mode (was falling
  through to prompt/rpc instead of builtin-reject)
- bg-events: export MAX_PENDING_ALERTS so process-manager can re-export it;
  satisfies session-memory-leaks contract test
- commands-handlers: guard effectiveScope assignment — only use requestedScope
  when mode=audit AND requestedScope is truthy (avoids undefined propagation)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Mikael Hugo 2026-05-10 04:55:56 +02:00
parent be785ea13f
commit 97619cbc74
5 changed files with 16 additions and 9 deletions

View file

@ -18,7 +18,7 @@ import { MAX_EVENTS } from "./types.js";
/** Pending alerts to inject into the next agent context */
export let pendingAlerts = [];
const MAX_PENDING_ALERTS = 50;
export const MAX_PENDING_ALERTS = 50;
/** Replace the pendingAlerts array (used by the extension entry point) */
export function setPendingAlerts(alerts) {

View file

@ -23,7 +23,7 @@ import { DEAD_PROCESS_TTL, MAX_BUFFER_LINES } from "./types.js";
import { formatUptime, restoreWindowsVTInput } from "./utilities.js";
// Re-export event/alert helpers so existing consumers (bg-shell-lifecycle.js)
// continue to work without changing their import paths.
export { addEvent, pendingAlerts, pushAlert, setPendingAlerts };
export { addEvent, MAX_PENDING_ALERTS, pendingAlerts, pushAlert, setPendingAlerts } from "./bg-events.js";
// ── Process Registry ───────────────────────────────────────────────────────
export const processes = new Map();
export function addOutputLine(bg, stream, line) {

View file

@ -207,7 +207,7 @@ export async function handleDoctor(args, ctx, pi) {
requestedScope,
} = parseDoctorArgs(args);
const scope = await selectDoctorScope(projectRoot(), requestedScope);
const effectiveScope = mode === "audit" ? requestedScope : scope;
const effectiveScope = mode === "audit" && requestedScope ? requestedScope : scope;
const report = await runSFDoctor(projectRoot(), {
fix: mode === "fix" || mode === "heal" || dryRun || fixFlag,
dryRun,

View file

@ -482,11 +482,19 @@ export async function inspectExecuteTaskDurability(basePath, unitId) {
const taskChecked =
!!planContent &&
new RegExp(`^- \\[[xX]\\] \\*\\*${escapedTid}:`, "m").test(planContent);
// Use DB task status instead of reading STATE.md — STATE.md is a display
// projection and may lag behind DB writes by a loop iteration.
const taskRow = isDbAvailable() ? getTask(mid, sid, tid) : null;
const taskStatus = taskRow?.status ?? "pending";
const nextActionAdvanced = taskStatus !== "pending" && taskStatus !== "in_progress";
// Prefer DB task status (authoritative) over STATE.md (display projection
// that can lag by a loop iteration). Fall back to STATE.md when DB is
// unavailable (e.g. in unit tests that don't initialise the database).
let nextActionAdvanced;
if (isDbAvailable()) {
const taskRow = getTask(mid, sid, tid);
const taskStatus = taskRow?.status ?? "pending";
nextActionAdvanced = taskStatus !== "pending" && taskStatus !== "in_progress";
} else {
const stateAbs = join(sfRoot(basePath), "STATE.md");
const stateContent = existsSync(stateAbs) ? readFileSync(stateAbs, "utf-8") : "";
nextActionAdvanced = !new RegExp(`Execute ${escapedTid}\\b`).test(stateContent);
}
// Must-have coverage: load task plan and count mentions in summary
let mustHaveCount = 0;
let mustHavesMentionedInSummary = 0;

View file

@ -141,7 +141,6 @@ const SF_SURFACE_COMMANDS = new Map<string, BrowserSlashCommandSurface>([
const SF_PASSTHROUGH_COMMANDS = new Set<string>([
"autonomous",
"next",
"stop",
"pause",
"skip",
"discuss",