backblaze-proofframe / tests /test_final_launch_plan.py
ADJCJH's picture
Sync B2 pre-key confirmation gate
a3aa614 verified
Raw
History Blame Contribute Delete
7.27 kB
import importlib.util
import json
from pathlib import Path
SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "final_launch_plan.py"
SPEC = importlib.util.spec_from_file_location("final_launch_plan", SCRIPT_PATH)
final_launch_plan = importlib.util.module_from_spec(SPEC)
assert SPEC.loader is not None
SPEC.loader.exec_module(final_launch_plan)
def write_json(root: Path, relative_path: str, payload: dict) -> None:
path = root / relative_path
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(payload), encoding="utf-8")
def write_tasks(root: Path, **overrides: str) -> None:
statuses = {
"T020": "doing",
"T021": "doing",
"T040": "done",
"T041": "todo",
"T041A": "todo",
"T042": "todo",
}
statuses.update(overrides)
write_json(
root,
"tasks.json",
{
"tasks": [
{"id": task_id, "title": task_id, "status": status}
for task_id, status in statuses.items()
]
},
)
def write_base_reports(root: Path) -> None:
write_tasks(root)
write_json(
root,
"docs/assets/live-credential-handoff.json",
{
"schema": "proofframe.live_credential_handoff.v1",
"ok": False,
"mode": "missing_live_env",
"missing_ids": ["b2_key_id", "b2_application_key", "genblaze_api_key"],
},
)
write_json(
root,
"docs/assets/final-operator-brief.json",
{
"schema": "proofframe.final_operator_brief.v1",
"ready_for_secret_entry": True,
"mode": "credential_entry_ready",
"safe_to_submit": False,
},
)
write_json(
root,
"docs/assets/b2-key-scope-checklist.json",
{
"schema": "proofframe.b2_key_scope_checklist.v1",
"pre_key_creation_confirmation": {
"status": "required_before_key_creation",
"required_phrase": (
"I confirm ProofFrame B2 key scope: standard key, bucket proofframe-demo-a6b4e49, "
"prefix campaigns/, no all-bucket access, no delete/admin permissions, "
"and no secrets in chat/docs/git."
),
"safe_to_store": True,
},
},
)
write_json(
root,
"docs/assets/final-submission-control.json",
{
"schema": "proofframe.final_submission_control.v1",
"mode": "pre_live_control",
"safe_to_submit": False,
"blocking_items": [
{"id": "b2_live_proof"},
{"id": "genblaze_live_proof"},
{"id": "credential_handoff"},
{"id": "public_video"},
{"id": "final_recording"},
{"id": "final_secret_scan"},
{"id": "final_submission_audit"},
{"id": "devpost_submitted"},
],
},
)
write_json(
root,
"docs/assets/recording-assets.json",
{"schema": "proofframe.recording_assets.v1", "final_video_ready": False},
)
write_json(
root,
"docs/assets/submission-audit-report.json",
{"schema": "proofframe.submission_audit.v1", "ok": False},
)
write_json(
root,
"docs/assets/devpost-submission-receipt.json",
{"schema": "proofframe.devpost_submission_receipt.v1", "ok": False},
)
def test_launch_plan_is_ready_for_credential_entry(tmp_path):
write_base_reports(tmp_path)
plan = final_launch_plan.build_report(tmp_path)
assert plan["ok"] is False
assert plan["mode"] == "ready_for_credential_entry"
assert plan["current_phase"] == "credential_entry"
assert plan["summary"] == {"total": 6, "done": 0, "ready": 1, "blocked": 5}
assert "final_env_wizard.py" in plan["next_command"]
assert "I confirm ProofFrame B2 key scope" in " ".join(plan["phases"][0]["expected_artifacts"])
assert "T020" in plan["phases"][1]["task_updates_after_success"][0]
assert plan["safety_policy"]["source_env_files"] is False
assert "source .env.final.local" not in json.dumps(plan)
def test_launch_plan_blocks_unexpected_credential_setup_gap(tmp_path):
write_base_reports(tmp_path)
handoff = json.loads((tmp_path / "docs/assets/live-credential-handoff.json").read_text())
handoff["missing_ids"] = ["b2_endpoint", "b2_key_id"]
write_json(tmp_path, "docs/assets/live-credential-handoff.json", handoff)
plan = final_launch_plan.build_report(tmp_path)
assert plan["mode"] == "blocked_at_credential_entry"
assert plan["phases"][0]["status"] == "blocked"
assert "unexpected setup values" in plan["phases"][0]["detail"]
def test_launch_plan_marks_devpost_ready_when_only_submission_remains(tmp_path):
write_base_reports(tmp_path)
write_tasks(tmp_path, T020="done", T021="done", T041="done", T041A="done")
write_json(
tmp_path,
"docs/assets/live-credential-handoff.json",
{"schema": "proofframe.live_credential_handoff.v1", "ok": True, "missing_ids": []},
)
write_json(
tmp_path,
"docs/assets/b2-live-proof-evidence.json",
{"ok": True, "mode": "b2_live_verified"},
)
write_json(
tmp_path,
"docs/assets/final-live-proof-evidence.json",
{"ok": True, "mode": "final_live_verified"},
)
write_json(
tmp_path,
"docs/assets/recording-assets.json",
{"schema": "proofframe.recording_assets.v1", "final_video_ready": True},
)
write_json(
tmp_path,
"docs/assets/submission-audit-report.json",
{"schema": "proofframe.submission_audit.v1", "ok": True},
)
write_json(
tmp_path,
"docs/assets/final-submission-control.json",
{
"schema": "proofframe.final_submission_control.v1",
"mode": "pre_live_control",
"safe_to_submit": False,
"blocking_items": [{"id": "devpost_submitted"}],
},
)
plan = final_launch_plan.build_report(tmp_path)
assert plan["mode"] == "ready_for_devpost_submit"
assert plan["current_phase"] == "devpost_submit"
assert plan["summary"] == {"total": 6, "done": 5, "ready": 1, "blocked": 0}
assert plan["phases"][-1]["status"] == "ready"
assert "devpost_submission_receipt.py" in plan["next_command"]
assert "T042" in plan["phases"][-1]["task_updates_after_success"][0]
def test_launch_plan_writes_outputs(tmp_path):
write_base_reports(tmp_path)
plan = final_launch_plan.build_report(tmp_path)
json_path = tmp_path / "out" / "launch.json"
markdown_path = tmp_path / "out" / "launch.md"
final_launch_plan.write_outputs(plan, json_path, markdown_path)
saved = json.loads(json_path.read_text(encoding="utf-8"))
markdown = markdown_path.read_text(encoding="utf-8")
assert saved["schema"] == final_launch_plan.SCHEMA
assert "# ProofFrame Final Launch Plan" in markdown
assert "I confirm ProofFrame B2 key scope" in markdown
assert "Task ledger updates after success" in markdown
assert "Do not source `.env.final.local`" in markdown