feat(auto/loop): mid-loop self-feedback inline-fix dispatcher
Some checks are pending
CI / detect-changes (push) Waiting to run
CI / docs-check (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
CI / build (push) Blocked by required conditions
CI / integration-tests (push) Blocked by required conditions
CI / windows-portability (push) Blocked by required conditions
CI / rtk-portability (linux, blacksmith-4vcpu-ubuntu-2404) (push) Blocked by required conditions
CI / rtk-portability (macos, macos-15) (push) Blocked by required conditions
CI / rtk-portability (windows, blacksmith-4vcpu-windows-2025) (push) Blocked by required conditions
Some checks are pending
CI / detect-changes (push) Waiting to run
CI / docs-check (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
CI / build (push) Blocked by required conditions
CI / integration-tests (push) Blocked by required conditions
CI / windows-portability (push) Blocked by required conditions
CI / rtk-portability (linux, blacksmith-4vcpu-ubuntu-2404) (push) Blocked by required conditions
CI / rtk-portability (macos, macos-15) (push) Blocked by required conditions
CI / rtk-portability (windows, blacksmith-4vcpu-windows-2025) (push) Blocked by required conditions
Bootstrap drains the triage queue once at session_start (headless.ts: 647 "[headless] autonomous: draining self-feedback triage queue first..."). Entries filed DURING the autonomous run previously sat until the next sf restart — defeating the self-heal thesis for long-running sessions like the 3-day dogfood the user is running now. dispatchSelfFeedbackInlineFixIfNeeded already exists in the extension (self-feedback-drain.js:277) and is wired into bootstrap/register- hooks at session_start. It selects high/critical candidates, debounces via a claim file (so concurrent invocations skip), and on the headless surface spawns a child `sf headless triage --apply` fire-and-forget — the autonomous loop continues unblocked while triage runs in a child. Hook it into the auto-loop top-of-iteration so it fires every MID_LOOP_TRIAGE_INTERVAL=5 iterations. The dispatcher's own claim-file debounce prevents re-dispatch of in-flight entries; pre-bootstrap- drained entries get re-evaluated only when something new shows up. Also ignores scripts/tmp-check-test-imports in biome — the check- test-imports.test.mjs self-test creates regression fixtures there and they triggered formatter errors on dirty exits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e8bbb477e6
commit
41276a7b7a
2 changed files with 33 additions and 1 deletions
|
|
@ -16,7 +16,8 @@
|
|||
"!!**/rust-engine/npm",
|
||||
"!!**/*.min.js",
|
||||
"!!packages/coding-agent/src/core/export-html/template.css",
|
||||
"!!src/resources/skills/create-sf-extension/templates"
|
||||
"!!src/resources/skills/create-sf-extension/templates",
|
||||
"!!scripts/tmp-check-test-imports"
|
||||
]
|
||||
},
|
||||
"formatter": {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { resolveEngine } from "../engine-resolver.js";
|
|||
import { getErrorMessage } from "../error-utils.js";
|
||||
import { NOTICE_KIND } from "../notification-store.js";
|
||||
import { sfRoot } from "../paths.js";
|
||||
import { dispatchSelfFeedbackInlineFixIfNeeded } from "../self-feedback-drain.js";
|
||||
import { recordSelfFeedback } from "../self-feedback.js";
|
||||
import { getDatabase } from "../sf-db.js";
|
||||
import {
|
||||
|
|
@ -613,6 +614,12 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|||
recentUnits: persisted.recentUnits,
|
||||
stuckRecoveryAttempts: persisted.stuckRecoveryAttempts,
|
||||
consecutiveFinalizeTimeouts: 0,
|
||||
// Iteration at which the autonomous loop last invoked the
|
||||
// self-feedback inline-fix dispatcher. Used by the mid-loop
|
||||
// triage-drain hook below to avoid spamming the dispatcher on
|
||||
// every iteration while still picking up entries filed during
|
||||
// the run (which previously sat until next session_start).
|
||||
lastInlineFixDispatchIteration: 0,
|
||||
};
|
||||
let consecutiveErrors = 0;
|
||||
let consecutiveCooldowns = 0;
|
||||
|
|
@ -632,6 +639,30 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|||
}
|
||||
iteration++;
|
||||
debugLog("autoLoop", { phase: "loop-top", iteration });
|
||||
// ── Mid-loop self-feedback inline-fix dispatcher ──────────────────
|
||||
// Bootstrap drains the triage queue once at session_start (see
|
||||
// src/headless.ts:647). Entries filed DURING the autonomous run
|
||||
// previously sat until the next sf restart — defeats the
|
||||
// self-heal thesis for long-running sessions. Re-invoke the
|
||||
// inline-fix dispatcher every MID_LOOP_TRIAGE_INTERVAL iterations
|
||||
// so any high/critical entry filed mid-run gets a triage pass
|
||||
// without waiting for restart. The dispatcher already debounces
|
||||
// via claim file (see dispatchSelfFeedbackInlineFixIfNeeded) and
|
||||
// is fire-and-forget on the headless surface, so this is safe to
|
||||
// call on every Nth iteration.
|
||||
const MID_LOOP_TRIAGE_INTERVAL = 5;
|
||||
if (
|
||||
iteration > 1 &&
|
||||
iteration - loopState.lastInlineFixDispatchIteration >=
|
||||
MID_LOOP_TRIAGE_INTERVAL
|
||||
) {
|
||||
try {
|
||||
dispatchSelfFeedbackInlineFixIfNeeded(s.basePath, ctx, pi);
|
||||
} catch {
|
||||
// Never block the loop on triage-dispatch failure.
|
||||
}
|
||||
loopState.lastInlineFixDispatchIteration = iteration;
|
||||
}
|
||||
// ── Halt watchdog: detect idle/stuck iterations ──
|
||||
const { stuck, elapsedMs } = watchdog.check(ctx, iteration);
|
||||
if (stuck) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue