"""Separate verified business progress from supervisor liveness.""" import json import pathlib import re from datetime import datetime def _read(root, relative, maximum=2 * 1024 * 1024): if not isinstance(relative, str) or pathlib.Path(relative).is_absolute(): return {} path = root / relative try: if not path.resolve().is_relative_to(root.resolve()): return {} current = root for part in pathlib.Path(relative).parts: current /= part if current.is_symlink(): return {} if path.stat().st_size > maximum: return {} value = json.loads(path.read_text()) return value if isinstance(value, dict) else {} except (OSError, ValueError, TypeError): return {} def business_progress(root, state): root = pathlib.Path(root) backlog = _read(root, "tests/golden/WBV2/web-product-backlog.json") tasks = backlog.get("tasks", []) valid = set(state.get("verification", {}).get("validJobs", [])) stale = set(state.get("verification", {}).get("staleJobs", [])) assignments = _read(root, "tests/golden/WBV2/autopilot/local-task-assignments.json") assignment_map = {item.get("job"): item for item in assignments.get("assignments", []) if isinstance(item, dict)} blockers = [] retryable = [] failures = [] active = state.get("activeJob") records = state.get("jobs", {}) for task in tasks: identifier = task.get("id", "") if identifier in valid or identifier == active: continue record = records.get(identifier, {}) if record.get("state") == "behavior_pending": blockers.append({ "job": identifier, "module": task.get("module"), "category": "behavior_contract_missing", "reason": record.get("reason"), "workflow": task.get("implementation"), "commands": task.get("commands", [])[:8], "sourceUnits": [], "candidateTests": [], "nextActions": ["Implement route-specific assertions and fresh receipt producers"], }) continue if record.get("state") in {"blocked", "provider_blocked"}: failure = {"job": identifier, "reason": record.get("reason"), "runDirectory": record.get("runDirectory")} run_directory = record.get("runDirectory") if isinstance(run_directory, str): diagnostic_path = f"{run_directory}/cases/native-business-diagnostic.json" diagnostic = _read(root, diagnostic_path, 128 * 1024) if (diagnostic.get("schemaVersion") == 1 and diagnostic.get("job") == identifier and diagnostic.get("status") == "FAIL" and isinstance(diagnostic.get("findings"), list)): failure["diagnostic"] = diagnostic_path failure["repairActions"] = [finding for finding in diagnostic["findings"][:8] if isinstance(finding, dict)] failure["reproduce"] = diagnostic.get("reproduce") failures.append(failure) continue assignment = assignment_map.get(identifier, {}) if identifier in stale or assignment.get("state") == "ready": retryable.append(identifier) continue preparation = {} if re.fullmatch(r"[A-Z0-9][A-Z0-9_-]{0,95}", identifier): preparation = _read(root, f"tests/golden/WBV2/autopilot/preparation/{identifier}.json", 128 * 1024) blocker = preparation.get("businessBlocker", {}) blockers.append({ "job": identifier, "module": task.get("module"), "category": blocker.get("category", "preparation_required"), "workflow": preparation.get("workflow", task.get("implementation")), "firstSeenAt": blocker.get("firstSeenAt"), "inputChangedAt": blocker.get("inputChangedAt"), "commands": preparation.get("commands", task.get("commands", []))[:8], "sourceUnits": [unit.get("id") for unit in preparation.get("sourceUnits", [])[:8]], "candidateTests": preparation.get("candidateTests", [])[:4], "sourceSearch": blocker.get("sourceSearch"), "contractPath": blocker.get("contractPath"), "nextActions": preparation.get("nextActions", [])[:4], }) blockers.sort(key=lambda item: (not bool(item["sourceUnits"]), not bool(item["candidateTests"]), item["job"])) verified_times = [] for identifier in valid: receipt = _read(root, records.get(identifier, {}).get("receipt")) timestamp = receipt.get("verifiedAt") if receipt.get("status") != "verified" and receipt.get("status") != "PASS": continue if isinstance(timestamp, str): try: parsed = datetime.fromisoformat(timestamp.replace("Z", "+00:00")) if parsed.tzinfo is not None: verified_times.append((parsed, timestamp)) except ValueError: pass if active: phase = "executing" elif retryable: phase = "ready_for_validation" elif failures: phase = "waiting_for_failure_repair" elif blockers: phase = "waiting_for_implementation" else: phase = "registered_workflows_verified" categories = {} for blocker in blockers: categories[blocker["category"]] = categories.get(blocker["category"], 0) + 1 return { "state": phase, "registeredTasks": len(tasks), "validWorkflows": len(valid), "lastVerifiedAt": max(verified_times)[1] if verified_times else None, "activeJob": active, "readyForValidation": retryable, "validationFailures": failures, "needsImplementation": len(blockers), "blockerCategories": categories, "nextImplementationTasks": blockers[:5], "progressBasis": "Hash-valid workflow receipts; heartbeat and input changes are not business completion", }