71 lines
3.1 KiB
Python
71 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Extract user-role language from the current Codex rollout without copying hidden context."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
SOURCE = Path("/Users/bingshuo/.codex/sessions/2026/08/23/rollout-2026-08-23T00-26-28-01a02a4b-8ab1-7f53-8df8-787cbc2909ad.jsonl")
|
|
ROOT = Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/CODEX-DEV-20260823/DEV-20260823-001-HANDOFF-20260823")
|
|
DIRECT = ROOT / "sources/CURRENT-THREAD-BINGSHUO-DIRECT-NATURAL-LANGUAGE.jsonl"
|
|
HEARTBEATS = ROOT / "sources/CURRENT-THREAD-AUTOMATION-HEARTBEATS.jsonl"
|
|
AUDIT = ROOT / "sources/CURRENT-THREAD-USER-MESSAGE-AUDIT.json"
|
|
|
|
|
|
def sha(data: bytes) -> str:
|
|
return hashlib.sha256(data).hexdigest()
|
|
|
|
|
|
def stable(obj: object) -> str:
|
|
return json.dumps(obj, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
|
|
|
|
|
|
def main() -> None:
|
|
source_bytes = SOURCE.read_bytes()
|
|
direct, heartbeats = [], []
|
|
for line in source_bytes.splitlines():
|
|
envelope = json.loads(line)
|
|
if envelope.get("type") != "response_item":
|
|
continue
|
|
payload = envelope.get("payload") or {}
|
|
if payload.get("type") != "message" or payload.get("role") != "user":
|
|
continue
|
|
parts = [item.get("text", "") for item in payload.get("content", []) if isinstance(item, dict) and item.get("type") == "input_text"]
|
|
text = "\n".join(parts)
|
|
is_heartbeat = text.lstrip().startswith("<heartbeat>")
|
|
record = {
|
|
"schema": "guanghu.user-language-handoff/v1",
|
|
"classification": "AUTOMATION_HEARTBEAT_REPLAY" if is_heartbeat else "S01_BINGSHUO_DIRECT_CURRENT_CHANNEL",
|
|
"source_file": str(SOURCE),
|
|
"source_file_sha256_at_extraction": sha(source_bytes),
|
|
"rollout_ordinal": envelope.get("ordinal"),
|
|
"occurred_at_utc": envelope.get("timestamp"),
|
|
"message_id": payload.get("id"),
|
|
"text_sha256": sha(text.encode("utf-8")),
|
|
"text": text,
|
|
}
|
|
(heartbeats if is_heartbeat else direct).append(record)
|
|
DIRECT.parent.mkdir(parents=True, exist_ok=True)
|
|
DIRECT.write_text("".join(stable(x) + "\n" for x in direct), encoding="utf-8")
|
|
HEARTBEATS.write_text("".join(stable(x) + "\n" for x in heartbeats), encoding="utf-8")
|
|
audit = {
|
|
"schema": "guanghu.user-language-handoff-audit/v1",
|
|
"extracted_at_utc": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
|
|
"source_file": str(SOURCE),
|
|
"source_file_sha256_at_extraction": sha(source_bytes),
|
|
"source_file_size": len(source_bytes),
|
|
"direct_message_count": len(direct),
|
|
"automation_heartbeat_count": len(heartbeats),
|
|
"direct_output_sha256": sha(DIRECT.read_bytes()),
|
|
"heartbeat_output_sha256": sha(HEARTBEATS.read_bytes()),
|
|
"exclusion": "System, developer, assistant, tool calls, tool outputs and hidden reasoning are not copied.",
|
|
}
|
|
AUDIT.write_text(json.dumps(audit, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps(audit, ensure_ascii=False, indent=2))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|