Meta3.0 / scripts /meta3_build_workpackets.py
smlflg's picture
Initial public upload from Projekte/Meta3.0
1219ee2 verified
Raw History Blame Contribute Delete
14.5 kB
#!/usr/bin/env python3
"""Build offline Meta3 workpackets for Qwen/API runs. No network calls."""
from __future__ import annotations
import argparse
import json
import math
from collections import defaultdict
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
def load_json(path: Path) -> dict[str, Any]:
with path.open("r", encoding="utf-8") as handle:
data = json.load(handle)
if not isinstance(data, dict):
raise ValueError(f"Expected JSON object: {path}")
return data
def write_json(path: Path, data: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
def write_jsonl(path: Path, rows: list[dict[str, Any]]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("w", encoding="utf-8") as handle:
for row in rows:
handle.write(json.dumps(row, ensure_ascii=False, sort_keys=True) + "\n")
def latest_run_dir() -> Path:
runs_root = ROOT / "runs"
candidates = sorted(p for p in runs_root.iterdir() if p.is_dir())
if not candidates:
raise FileNotFoundError("No run dirs found. Run scripts/meta3_prepare.py first.")
return candidates[-1]
def load_manifest(run_id: str | None) -> tuple[Path, dict[str, Any]]:
run_dir = ROOT / "runs" / run_id if run_id else latest_run_dir()
manifest_path = run_dir / "manifests/run_manifest.json"
return run_dir, load_json(manifest_path)
def load_jsonl(path: Path) -> list[dict[str, Any]]:
rows: list[dict[str, Any]] = []
with path.open("r", encoding="utf-8") as handle:
for line_no, line in enumerate(handle, start=1):
if not line.strip():
continue
data = json.loads(line)
if not isinstance(data, dict):
raise ValueError(f"Expected JSON object in {path}:{line_no}")
rows.append(data)
return rows
def source_manifest_for_run(run_dir: Path) -> dict[str, Any] | None:
path = run_dir / "manifests/source_snapshot_manifest.json"
return load_json(path) if path.exists() else None
def source_family(source_path: str) -> str:
if "/.claude/projects/" in source_path:
return "claude_projects"
if "/.hermes/profiles/" in source_path and "/tirith/" in source_path:
return "hermes_tirith_logs"
if "/.hermes/profiles/" in source_path and "/.codex/sessions/" in source_path:
return "hermes_codex_sessions"
if "/.codex/sessions/" in source_path:
return "codex_sessions"
return "unknown"
def stable_digest_key(row: dict[str, Any]) -> tuple[str, str]:
return (source_family(str(row.get("source_path") or "")), str(row.get("source_path") or ""))
def stratified_sample(rows: list[dict[str, Any]], size: int) -> list[dict[str, Any]]:
if size <= 0 or size >= len(rows):
return sorted(rows, key=stable_digest_key)
buckets: dict[str, list[dict[str, Any]]] = defaultdict(list)
for row in sorted(rows, key=stable_digest_key):
buckets[source_family(str(row.get("source_path") or ""))].append(row)
selected: list[dict[str, Any]] = []
family_names = sorted(buckets)
index = 0
while len(selected) < size and any(index < len(buckets[name]) for name in family_names):
for name in family_names:
bucket = buckets[name]
if index < len(bucket):
selected.append(bucket[index])
if len(selected) >= size:
break
index += 1
return selected
def compact_digest(row: dict[str, Any], index: int) -> dict[str, Any]:
source_path = str(row.get("source_path") or "")
return {
"digest_index": index,
"source_path": source_path,
"source_family": source_family(source_path),
"created_at": row.get("created_at"),
"headline": row.get("headline"),
"what_happened": row.get("what_happened"),
"tools_agents": row.get("tools_agents", []),
"outcomes": row.get("outcomes", []),
"frictions": row.get("frictions", []),
"patterns": row.get("patterns", []),
"decisions": row.get("decisions", []),
"artifacts": row.get("artifacts", []),
"open_questions": row.get("open_questions", []),
"evidence": row.get("evidence", []),
"strategic_relevance": row.get("strategic_relevance", []),
"confidence": row.get("confidence"),
}
def chunk_rows(rows: list[dict[str, Any]], shard_size: int) -> list[list[dict[str, Any]]]:
if shard_size <= 0:
raise ValueError("--shard-size must be positive")
return [rows[i : i + shard_size] for i in range(0, len(rows), shard_size)]
def output_contract(question: dict[str, Any], mode: str) -> dict[str, Any]:
return {
"format": "json",
"mode": mode,
"required_top_level_fields": [
"question_id",
"mode",
"canonical_thesis",
"claims",
"counterevidence_status",
"uncertainty",
"owner_next_step",
],
"claim_fields": [
"claim",
"supporting_digest_indices",
"supporting_source_paths",
"counterevidence_or_limit",
"confidence",
],
"question_answer_contract": question.get("answer_contract", []),
}
def build_prompt(packet: dict[str, Any]) -> str:
digest_lines = []
for digest in packet["digests"]:
digest_lines.append(
"\n".join(
[
f"Digest {digest['digest_index']} ({digest['source_family']}, {digest.get('confidence')}):",
f"source_path: {digest['source_path']}",
f"headline: {digest.get('headline')}",
f"what_happened: {digest.get('what_happened')}",
f"patterns: {digest.get('patterns')}",
f"outcomes: {digest.get('outcomes')}",
f"frictions: {digest.get('frictions')}",
f"evidence: {digest.get('evidence')}",
f"strategic_relevance: {digest.get('strategic_relevance')}",
]
)
)
return "\n\n".join(
[
"You are evaluating Samuel's agent-session corpus for Meta3.0.",
"Use only the provided digests as evidence. Do not invent sessions.",
"Every strong claim needs supporting digest indices and a counterevidence or limit field.",
"Prefer one canonical owner-useful thesis over many parallel possibilities.",
f"Mode: {packet['mode']}",
f"Question {packet['question_id']} - {packet['question_title']}",
packet["question_prompt"],
"Return strict JSON matching expected_output_contract.",
"expected_output_contract:",
json.dumps(packet["expected_output_contract"], ensure_ascii=False, indent=2),
"Digests:",
"\n\n---\n\n".join(digest_lines),
]
)
def build_packets(
*,
run_id: str,
mode: str,
questions: list[dict[str, Any]],
digests: list[dict[str, Any]],
sample_size: int,
shard_size: int,
max_packets: int,
) -> list[dict[str, Any]]:
if mode == "calibration":
selected = stratified_sample(digests, sample_size)
shards = [selected]
elif mode == "claim_ledger":
selected = sorted(digests, key=stable_digest_key)
shards = chunk_rows(selected, shard_size)
else:
raise ValueError(f"Unsupported mode: {mode}")
packets: list[dict[str, Any]] = []
for question in questions:
for shard_index, shard in enumerate(shards, start=1):
packet_id = f"{mode}__{question['id']}__shard-{shard_index:04d}"
compacted = [compact_digest(row, index) for index, row in enumerate(shard, start=1)]
packet = {
"schema": "meta3.workpacket.v1",
"run_id": run_id,
"packet_id": packet_id,
"mode": mode,
"question_id": question["id"],
"question_title": question.get("title"),
"question_prompt": question.get("prompt"),
"question_answer_contract": question.get("answer_contract", []),
"shard_index": shard_index,
"shard_count": len(shards),
"digest_count": len(compacted),
"digests": compacted,
"expected_output_contract": output_contract(question, mode),
}
packet["prompt"] = build_prompt(packet)
packets.append(packet)
if max_packets and len(packets) >= max_packets:
return packets
return packets
def build_call_ledger(run_id: str, packets: list[dict[str, Any]]) -> list[dict[str, Any]]:
created_at = datetime.now(timezone.utc).isoformat()
return [
{
"schema": "meta3.call_ledger_entry.v1",
"run_id": run_id,
"packet_id": packet["packet_id"],
"mode": packet["mode"],
"question_id": packet["question_id"],
"status": "planned",
"attempts": 0,
"network_calls_made": 0,
"created_at": created_at,
"updated_at": created_at,
"output_path": None,
"error": None,
}
for packet in packets
]
def main() -> int:
parser = argparse.ArgumentParser(description="Build Meta3 offline workpackets without API calls.")
parser.add_argument("--run-id", default=None, help="Run id under runs/. Defaults to latest run.")
parser.add_argument("--mode", choices=["calibration", "claim_ledger"], default="calibration")
parser.add_argument("--sample-size", type=int, default=24)
parser.add_argument("--shard-size", type=int, default=24)
parser.add_argument("--max-packets", type=int, default=0, help="0 means no cap.")
parser.add_argument("--allow-source-drift", action="store_true")
args = parser.parse_args()
run_dir, manifest = load_manifest(args.run_id)
profile = manifest["profile"]
questions_doc = load_json(Path(manifest["questions_path"]))
questions = questions_doc.get("questions", [])
if not isinstance(questions, list) or not questions:
raise ValueError("No questions found")
source_manifest = source_manifest_for_run(run_dir)
if source_manifest:
digest_path = Path(str(source_manifest["frozen_digest_path"]))
else:
digest_path = Path(profile["source_artifacts"]["layer1_digests"])
digests = load_jsonl(digest_path)
if not digests:
raise ValueError(f"No digests found in {digest_path}")
batch_plan_path = run_dir / "manifests/batch_plan.json"
if batch_plan_path.exists() and not source_manifest:
batch_plan = load_json(batch_plan_path)
source_snapshot = batch_plan.get("source_snapshot", {})
if isinstance(source_snapshot, dict):
audit_unique = int(source_snapshot.get("layer1_audit_unique_digest_paths") or 0)
raw_rows = int(source_snapshot.get("layer1_raw_digest_file_rows_counted") or 0)
if audit_unique != raw_rows and not args.allow_source_drift:
raise SystemExit(
"Source drift refused: layer1 audit unique digests "
f"({audit_unique}) != raw digest rows ({raw_rows}). "
"Refresh Meta2 audit or pass --allow-source-drift for an explicit non-final diagnostic run."
)
packets = build_packets(
run_id=manifest["run_id"],
mode=args.mode,
questions=questions,
digests=digests,
sample_size=args.sample_size,
shard_size=args.shard_size,
max_packets=args.max_packets,
)
call_ledger = build_call_ledger(manifest["run_id"], packets)
packets_dir = run_dir / "outputs/workpackets"
packet_path = packets_dir / f"{args.mode}_workpackets.jsonl"
call_ledger_path = run_dir / "state" / f"{args.mode}_call_ledger.jsonl"
packet_manifest_path = packets_dir / f"{args.mode}_packet_manifest.json"
write_jsonl(packet_path, packets)
write_jsonl(call_ledger_path, call_ledger)
source_families: dict[str, int] = defaultdict(int)
digest_refs_seen: set[str] = set()
for packet in packets:
for digest in packet["digests"]:
source_families[str(digest["source_family"])] += 1
digest_refs_seen.add(str(digest["source_path"]))
packet_manifest = {
"schema": "meta3.workpacket_manifest.v1",
"run_id": manifest["run_id"],
"mode": args.mode,
"created_at": datetime.now(timezone.utc).isoformat(),
"network_calls_made": 0,
"source_digest_path": str(digest_path),
"source_snapshot_manifest_path": str(run_dir / "manifests/source_snapshot_manifest.json") if source_manifest else None,
"source_snapshot_schema": source_manifest.get("schema") if source_manifest else None,
"available_digest_rows": len(digests),
"source_drift_allowed": args.allow_source_drift,
"packet_count": len(packets),
"planned_call_count": len(call_ledger),
"sample_size": args.sample_size,
"shard_size": args.shard_size,
"question_count": len(questions),
"unique_digest_refs_in_packets": len(digest_refs_seen),
"source_family_mentions": dict(sorted(source_families.items())),
"packet_path": str(packet_path),
"call_ledger_path": str(call_ledger_path),
"expected_response": "strict JSON per packet.expected_output_contract",
"next_step": "A future network runner may consume this packet file only after explicit approval.",
}
if args.mode == "claim_ledger":
packet_manifest["shard_count_per_question"] = math.ceil(len(digests) / args.shard_size)
write_json(packet_manifest_path, packet_manifest)
print(f"packet_manifest={packet_manifest_path}")
print(f"packet_file={packet_path}")
print(f"call_ledger={call_ledger_path}")
print(f"mode={args.mode}")
print(f"packets={len(packets)}")
print(f"planned_calls={len(call_ledger)}")
print(f"unique_digest_refs={len(digest_refs_seen)}")
print("network_calls_made=0")
return 0
if __name__ == "__main__":
raise SystemExit(main())