Files
workinf_Blender_Wasm/my-tools/prepare_behavior_pending.py
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

79 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""Prepare actionable repair tasks from declared workflow inputs and failures."""
import json
from pathlib import Path
from wbv2_autopilot import ROOT, read_json, write_json
REQUIRED = {
"positive": ["before", "after"],
"negative": ["before", "after"],
"undo_redo": ["before", "after", "undo", "redo"],
"save_reopen": ["saved", "reopened"],
"determinism": ["first", "second"],
}
def prepare(root=ROOT):
root = Path(root)
backlog = read_json(root / "tests/golden/WBV2/web-product-backlog.json", {})
records = read_json(root / "tests/golden/WBV2/autopilot/state.json", {}).get("jobs", {})
tasks = []
for job in backlog.get("tasks", []):
identifier = job["id"]
path = root / "my-tools/local-workflows" / (identifier + ".json")
if not path.is_file():
path = root / "tests/golden/WBV2/autopilot/local-plans" / (identifier + ".json")
contract = read_json(path, {})
result = contract.get("result", {})
record = records.get(identifier, {})
incomplete = result.get("contractKind") == "compilation_only" or not result.get("cases")
failed = record.get("state") in {"blocked", "provider_blocked", "needs_reconcile"} or (
record.get("state") == "retry_pending" and bool(record.get("reason")))
if not incomplete and not failed:
continue
declared = sorted(set(result.get("dependencies", [])))
fixtures = [p for p in declared if p.endswith(".blend") and (root / p).is_file()]
specs = sorted({p for check in result.get("checks", []) for p in check.get("argv", [])
if p.endswith(".spec.ts")})
specs = [p if p.startswith("web/") else "web/" + p for p in specs]
category = "behavior_contract_missing" if incomplete else "runtime_failure"
reason = record.get("reason") or category
if not incomplete and "receipt" in reason:
category = "receipt_producer_mismatch"
if not incomplete and not specs:
category = "receipt_producer_missing"
tasks.append({
"job": identifier, "module": job.get("module"), "workflow": job.get("title"),
"state": "behavior_pending" if incomplete else "repair_required",
"category": category, "reason": reason,
"fixtures": fixtures, "fixtureSelectionRequired": not bool(fixtures),
"routeIds": result.get("routeIds", []),
"sourceUnits": result.get("sourceUnits", []),
"sourceReferences": result.get("sourceReferences", []),
"candidateTests": [p for p in specs if (root / p).is_file()],
"missingTests": [p for p in specs if not (root / p).is_file()],
"requiredObservations": REQUIRED,
"nextActions": [
"Inspect the declared native route and fixture data",
"Implement assertions and independent replay for this workflow",
"Publish receipts only after assertions; bind exact caseId, kind and unitIds",
],
"runDirectory": record.get("runDirectory"),
})
destination = root / "tests/golden/WBV2/autopilot/behavior-pending.json"
document = {"schemaVersion": 2, "policy": "repair plan only; no contract or acceptance mutation", "tasks": tasks}
if read_json(destination, {}) != document:
write_json(destination, document)
return document
def main():
document = prepare()
print(json.dumps({"tasks": len(document["tasks"]),
"behaviorPending": sum(t["state"] == "behavior_pending" for t in document["tasks"]),
"repairRequired": sum(t["state"] == "repair_required" for t in document["tasks"])}))
if __name__ == "__main__":
main()