fix(web): keep unattended planner state auditable
This commit is contained in:
@@ -188,6 +188,7 @@ def fast_path_status(status: dict) -> dict:
|
||||
latest_batch = scheduler.get("latestBatch") if isinstance(scheduler.get("latestBatch"), dict) else {}
|
||||
cache = _read_json(CONTROL_ROOT / "context-cache.json")
|
||||
ledger = _read_json(CONTROL_ROOT / "failure-ledger.json")
|
||||
planner = _read_json(CONTROL_ROOT / "auto-planner.json")
|
||||
return {
|
||||
"batch": {
|
||||
"batchId": latest_batch.get("batchId"),
|
||||
@@ -204,6 +205,12 @@ def fast_path_status(status: dict) -> dict:
|
||||
"entryCount": len(ledger.get("entries", [])) if isinstance(ledger.get("entries"), list) else 0,
|
||||
"hydratedLogs": len(ledger.get("hydratedLogs", [])) if isinstance(ledger.get("hydratedLogs"), list) else 0,
|
||||
},
|
||||
"autoPlanner": {
|
||||
"status": planner.get("status", "MISSING"),
|
||||
"reason": planner.get("reason"),
|
||||
"pending": planner.get("pending", {}).get("count") if isinstance(planner.get("pending"), dict) else None,
|
||||
"nextAction": planner.get("nextAction"),
|
||||
},
|
||||
"commandBudget": {"maxCommands": 48, "maxReadCommands": 16},
|
||||
"verificationPolicy": "incremental-context-only-until-final-audit",
|
||||
}
|
||||
@@ -219,6 +226,7 @@ def format_progress(progress: dict, fast_path: dict | None = None) -> list[str]:
|
||||
batch = fast_path.get("batch", {})
|
||||
context_cache = fast_path.get("contextCache", {})
|
||||
ledger = fast_path.get("failureLedger", {})
|
||||
planner = fast_path.get("autoPlanner", {})
|
||||
return [
|
||||
"",
|
||||
"Project migration progress",
|
||||
@@ -233,6 +241,7 @@ def format_progress(progress: dict, fast_path: dict | None = None) -> list[str]:
|
||||
f" fast path: batch={batch.get('batchId') or 'none'} selected={batch.get('selectedRecordCount', 0)} completed={batch.get('completed', False)}",
|
||||
f" context cache: {context_cache.get('status', 'MISSING')} task={context_cache.get('task') or 'none'} inputs={context_cache.get('inputCount', 0)}; failure ledger entries={ledger.get('entryCount', 0)} hydratedLogs={ledger.get('hydratedLogs', 0)}",
|
||||
f" command budget: max={fast_path.get('commandBudget', {}).get('maxCommands', 48)}, read/exploration max={fast_path.get('commandBudget', {}).get('maxReadCommands', 16)}; verification={fast_path.get('verificationPolicy', 'n/a')}",
|
||||
f" auto planner: {planner.get('status', 'MISSING')} pending={planner.get('pending', 'n/a')} next={planner.get('nextAction') or 'none'}",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
},
|
||||
"taskContext": {
|
||||
"path": "tests/golden/WBV2-P1162-001/task-context.json",
|
||||
"sha256": "376f89e31e0d34a413c9aff68780cf005f26d6cf2a5ebe51e38673cc8b9a5af5"
|
||||
"sha256": "296e19f4147f8d9fa324f118c02ebb08af98c787e52fdc0670c76e475f93820f"
|
||||
}
|
||||
},
|
||||
"assertions": {
|
||||
|
||||
@@ -90,7 +90,17 @@ const collect = () => {
|
||||
const supervisorLock = lockInfo(supervisorLockPath);
|
||||
const handoff = latestHandoff();
|
||||
const active = schedulerLock.alive || (guardianLock.alive && supervisorLock.alive);
|
||||
const blocked = scheduler?.state === "blocked" || guardian?.state === "blocked" || supervisor?.state === "blocked";
|
||||
let terminalQueue = false;
|
||||
try {
|
||||
const manifest = queue.task ? readJson(`tests/golden/${queue.task}/manifest.json`) : null;
|
||||
const index = readJson("tests/golden/WBV2/task-index.json");
|
||||
terminalQueue = !active && index?.activeTask === null && manifest?.status === "done" && manifest?.nextTask === null;
|
||||
} catch { /* A malformed pointer remains visible as a normal checkpoint failure. */ }
|
||||
const checkpointBlocked = scheduler?.state === "blocked" || guardian?.state === "blocked" || supervisor?.state === "blocked";
|
||||
// A terminal task can leave a historical blocked checkpoint behind (for
|
||||
// example, after a push retry). The watchdog owns the next planner attempt;
|
||||
// do not report that stale checkpoint as a live execution block.
|
||||
const blocked = checkpointBlocked && !terminalQueue;
|
||||
const state = blocked ? "BLOCKED" : active ? "RUNNING" : "IDLE";
|
||||
const phase = blocked ? "blocked" : scheduler?.state === "running" ? "scheduler-task" : supervisor?.state === "running" ? "task-or-gate" : scheduler?.state ?? supervisor?.state ?? "unknown";
|
||||
const observed = new Date().toISOString();
|
||||
|
||||
Reference in New Issue
Block a user