Files
FreeCADWasmDev/tools/prepare_failure_reconciliation_batch.py
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

50 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Schedule bounded failure review alongside the owning module's business."""
import argparse
import hashlib
import json
from datetime import datetime, timezone
from failure_reconciliation import ROOT, synchronize, write, read
from scheduler_progress import cooling_ids, retry_details
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--module")
options = parser.parse_args()
ledger = synchronize()
rows = [row for row in ledger["records"].values() if row["status"] == "pending"
and (options.module is None or options.module in row["modules"])]
for row in rows:
owner = options.module or next((module for module in row["modules"] if module != "Shared"), "Web")
row["queueModule"] = owner
row["queueId"] = f"failure:{owner}:{row['key']}"
cooling = cooling_ids(candidates={row["queueId"] for row in rows})
deferred = {row["queueId"] for row in rows if row["queueId"] in cooling}
pending = [row for row in rows if row["queueId"] not in cooling]
output = ROOT / "docs/current/module-batch-manifest.json"
if not pending:
payload = {"schema": "freecad-web-module-business-batch/v1", "status": "no_ready_batch", "records": [],
"strategy": "module-business-first-deferred-validation", **retry_details(deferred)}
else:
pending.sort(key=lambda row: (row["queueModule"], row["legacyValidation"], row["category"], row["key"]))
module = pending[0]["queueModule"]
selected = [row for row in pending if row["queueModule"] == module][:4]
ids = [row["queueId"] for row in selected]
identity = "|".join([module, "failure-reconciliation", "failure-reconciliation", *ids])
payload = {"schema": "freecad-web-module-business-batch/v1", "status": "ready",
"strategy": "module-business-first-deferred-validation", "taskId": read(ROOT / "docs/current/task-state.json").get("active_task"),
"batchId": hashlib.sha256(identity.encode()).hexdigest()[:24], "minimumRecords": 1, "singletonFallback": len(ids) == 1,
"selected": {"module": module, "tier": "failure-reconciliation", "family": "failure-reconciliation", "recordCount": len(ids)},
"records": [[row["queueId"], row["category"], "pending", "tools/failure_reconciliation.py", 1] for row in selected],
"failureKeys": [row["key"] for row in selected], "queue": []}
payload["generatedAt"] = datetime.now(timezone.utc).isoformat()
write(output, payload)
print(json.dumps({"status": payload["status"], "selected": payload.get("selected"), "pendingFailures": len(rows)}, ensure_ascii=False))
return 0
if __name__ == "__main__":
raise SystemExit(main())