#!/usr/bin/env python3 import argparse import hashlib import json import shlex import shutil from datetime import date from pathlib import Path from typing import Any from html_rendering import html_text from render_world_class_evidence_intake import build_intake from world_class_evidence_contract import DISALLOWED_REAL_ARTIFACTS from world_class_source_checks import build_source_checklist, summarize_source_checklist ROOT = Path(__file__).resolve().parent.parent SCRIPT_INTERFACE = "cli" SCRIPT_INTERFACE_REASON = "Prepares editable world-class evidence intake packets without counting drafts as accepted evidence." def rel_path(path: Path, root: Path) -> str: try: return str(path.resolve().relative_to(root.resolve())) except ValueError: return str(path.resolve()) def shell_path(path: Path, root: Path) -> str: return shlex.quote(rel_path(path, root)) def write_json(path: Path, payload: dict[str, Any]) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") def has_glob_pattern(value: str) -> bool: return any(token in value for token in ("*", "?", "[")) def sha256_file(path: Path) -> str: digest = hashlib.sha256() with path.open("rb") as handle: for chunk in iter(lambda: handle.read(1024 * 1024), b""): digest.update(chunk) return digest.hexdigest() def requested_checklist_items(intake: dict[str, Any], evidence_keys: list[str]) -> list[dict[str, Any]]: items = intake.get("operator_checklist", []) if not evidence_keys: return items requested = set(evidence_keys) return [item for item in items if item.get("evidence_key") in requested] def template_result_by_key(intake: dict[str, Any]) -> dict[str, dict[str, Any]]: return {str(item.get("evidence_key")): item for item in intake.get("templates", [])} def copy_template( skill_dir: Path, output_dir: Path, item: dict[str, Any], template_results: dict[str, dict[str, Any]], overwrite: bool, ) -> dict[str, Any]: key = str(item.get("evidence_key", "")) template_result = template_results.get(key, {}) template_path = skill_dir / str(item.get("template_path", "")) output_path = output_dir / f"{key}.json" errors: list[str] = [] if template_result.get("status") != "pass": errors.append("template failed intake validation") if not template_path.exists(): errors.append("template file is missing") if errors: return { "evidence_key": key, "status": "skipped", "template_path": rel_path(template_path, skill_dir), "output_path": rel_path(output_path, skill_dir), "errors": errors, } if output_path.exists() and not overwrite: return { "evidence_key": key, "status": "exists", "template_path": rel_path(template_path, skill_dir), "output_path": rel_path(output_path, skill_dir), "errors": [], } output_path.parent.mkdir(parents=True, exist_ok=True) shutil.copyfile(template_path, output_path) return { "evidence_key": key, "status": "written", "template_path": rel_path(template_path, skill_dir), "output_path": rel_path(output_path, skill_dir), "errors": [], } def artifact_row(skill_dir: Path, evidence_key: str, pattern: str, path: Path, status: str) -> dict[str, Any]: exists = path.exists() is_file = exists and path.is_file() relative = rel_path(path, skill_dir) if exists else pattern contains_raw_content = relative in DISALLOWED_REAL_ARTIFACTS digest = sha256_file(path) if is_file and not contains_raw_content else "" row_status = status if status else ("ready" if is_file else "missing") if contains_raw_content: row_status = "raw-content-disallowed" return { "evidence_key": evidence_key, "source_pattern": pattern, "path": relative, "status": row_status, "exists": exists, "is_file": is_file, "sha256": digest, "artifact_ref_ready": bool(is_file and digest and not contains_raw_content), "copy_path": relative if is_file else "", "copy_sha256": digest, "contains_raw_content": contains_raw_content, "concrete_reference_required": has_glob_pattern(pattern), } def artifact_checklist_for_item(skill_dir: Path, item: dict[str, Any]) -> list[dict[str, Any]]: key = str(item.get("evidence_key", "")) must_collect = item.get("must_collect", {}) if isinstance(item.get("must_collect", {}), dict) else {} artifacts = must_collect.get("evidence_artifacts", []) if not isinstance(artifacts, list): return [] rows: list[dict[str, Any]] = [] for artifact in artifacts: pattern = str(artifact or "").strip() if not pattern: continue if Path(pattern).is_absolute() or ".." in Path(pattern).parts: rows.append( { "evidence_key": key, "source_pattern": pattern, "path": pattern, "status": "unsafe-path", "exists": False, "is_file": False, "sha256": "", "artifact_ref_ready": False, "copy_path": "", "copy_sha256": "", "contains_raw_content": False, "concrete_reference_required": True, } ) continue if has_glob_pattern(pattern): matches = sorted(path for path in skill_dir.glob(pattern) if path.is_file()) if not matches: rows.append( { "evidence_key": key, "source_pattern": pattern, "path": pattern, "status": "glob-no-match", "exists": False, "is_file": False, "sha256": "", "artifact_ref_ready": False, "copy_path": "", "copy_sha256": "", "contains_raw_content": False, "concrete_reference_required": True, } ) continue for match in matches: rows.append(artifact_row(skill_dir, key, pattern, match, "ready")) continue rows.append(artifact_row(skill_dir, key, pattern, skill_dir / pattern, "")) return rows def build_artifact_checklist(skill_dir: Path, items: list[dict[str, Any]]) -> list[dict[str, Any]]: rows: list[dict[str, Any]] = [] for item in items: rows.extend(artifact_checklist_for_item(skill_dir, item)) return rows def render_readme(report: dict[str, Any]) -> str: commands = report["commands"] lines = [ "# World-Class Evidence Submission Kit", "", f"Generated at: `{report['generated_at']}`", "", "This kit contains editable drafts for human and external evidence packets. Drafts are not accepted evidence.", "", "## Workflow", "", "1. Run the real provider, human review, native permission, or native client telemetry work first.", "2. Edit the matching JSON draft with only aggregate artifact references and provenance metadata.", "3. Set `template_only` to `false` only after real evidence exists.", "4. Set attestation booleans truthfully; do not include credentials, raw prompts, raw outputs, transcripts, notes, or private user content.", "5. Validate the packet before asking the ledger reviewer to accept it.", "", "## Commands", "", f"- validate intake: `{commands['validate_intake']}`", f"- refresh ledger: `{commands['refresh_ledger']}`", f"- guard public claims: `{commands['guard_claim']}`", "", "## Drafts", "", "| Evidence | Draft | Status |", "| --- | --- | --- |", ] for item in report["files"]: lines.append(f"| `{item['evidence_key']}` | `{item['output_path']}` | `{item['status']}` |") lines.extend(["", "## Execution Runbook", ""]) for item in report.get("evidence_items", []): must_collect = item.get("must_collect", {}) if isinstance(item.get("must_collect", {}), dict) else {} runbook = must_collect.get("runbook", []) lines.extend(["", f"### {item.get('label', item.get('evidence_key', 'Evidence'))}", ""]) if runbook: for step in runbook: lines.append(f"- `{step}`" if str(step).startswith("python3 ") or "=" in str(step) else f"- {step}") else: lines.append("- No source runbook listed.") lines.extend( [ "", "## Artifact Checklist", "", "Use these paths and SHA-256 digests when filling `artifact_refs`. Glob patterns are expanded into concrete files; submissions must reference concrete paths, not globs.", "", "| Evidence | Path | Status | SHA-256 |", "| --- | --- | --- | --- |", ] ) for item in report.get("artifact_checklist", []): digest = item.get("sha256") or "n/a" lines.append( f"| `{item['evidence_key']}` | `{item['path']}` | `{item['status']}` | `{digest}` |" ) lines.extend( [ "", "## Source Evidence Snapshot", "", "These checks explain why a draft is not ready for ledger acceptance yet. They mirror current aggregate reports and do not accept evidence by themselves.", "", "| Evidence | Check | Current | Expected | Status |", "| --- | --- | --- | --- | --- |", ] ) for item in report.get("source_checklist", []): lines.append( f"| `{item['evidence_key']}` | {item['label']} | `{item['actual']}` | `{item['expected']}` | `{item['status']}` |" ) lines.extend( [ "", "## Anti-Overclaim", "", "- This kit never marks ledger evidence as accepted.", "- Planned work, metadata fallback, pending review, and local command-runner output remain non-evidence.", "- A valid intake packet means ready for ledger review, not world-class completion.", ] ) return "\n".join(lines).rstrip() + "\n" def render_html_list(values: list[Any], empty: str) -> str: if not values: return f"
  • {html_text(empty)}
  • " return "".join(f"
  • {html_text(value)}
  • " for value in values) def render_html_commands(commands: dict[str, str]) -> str: return "".join( f"
  • {html_text(label.replace('_', ' '))}{html_text(command)}
  • " for label, command in commands.items() ) def render_html_files(files: list[dict[str, Any]]) -> str: if not files: return "

    No submission drafts were requested.

    " return "".join( """
    {status}

    {key}

    Template
    {template}
    Draft
    {output}
    {errors}
    """.format( status=html_text(item.get("status", "")), key=html_text(item.get("evidence_key", "")), template=html_text(item.get("template_path", "")), output=html_text(item.get("output_path", "")), errors=( "" if item.get("errors") else "" ), ) for item in files ) def render_html_artifact_checklist(items: list[dict[str, Any]]) -> str: if not items: return "

    No required artifacts were listed for the requested evidence.

    " return "".join( """
    {key}

    {path}

    Pattern
    {pattern}
    Status
    {status}
    SHA-256
    {sha}
    """.format( status=html_text(item.get("status", "")), key=html_text(item.get("evidence_key", "")), path=html_text(item.get("path", "")), pattern=html_text(item.get("source_pattern", "")), sha=html_text(item.get("sha256") or "n/a"), ) for item in items ) def render_html_source_checklist(items: list[dict[str, Any]]) -> str: if not items: return "

    No source checks were listed for the requested evidence.

    " return "".join( """
    {key}

    {label}

    Field
    {field}
    Current
    {actual}
    Expected
    {expected}
    Action
    {action}
    """.format( status=html_text(item.get("status", "")), key=html_text(item.get("evidence_key", "")), label=html_text(item.get("label", "")), field=html_text(item.get("field", "")), actual=html_text(item.get("actual", "")), expected=html_text(item.get("expected", "")), action=html_text(item.get("next_action", "")), ) for item in items ) def render_html_item(item: dict[str, Any]) -> str: must_collect = item.get("must_collect", {}) if isinstance(item.get("must_collect", {}), dict) else {} runbook = must_collect.get("runbook", []) return f"""
    {html_text(item.get('category', ''))} ยท {html_text(item.get('readiness', ''))}

    {html_text(item.get('label', item.get('evidence_key', '')))}

    {html_text(item.get('blocking_reason', ''))}

    Owner
    {html_text(item.get('owner', ''))}
    Evidence
    {html_text(item.get('evidence_key', ''))}
    Submission
    {html_text(item.get('submission_path', ''))}

    Execution Runbook

    Must Collect

      {render_html_list(must_collect.get('provenance_requirements', []), 'No provenance requirements listed.')}

    Pass Checks

      {render_html_list(must_collect.get('success_checks', []), 'No success checks listed.')}

    Privacy

      {render_html_list(must_collect.get('privacy_contract', []), 'No privacy contract listed.')}
    """ def render_html(report: dict[str, Any]) -> str: summary = report["summary"] artifact_ready = summary.get("artifact_ready_count", 0) artifact_total = summary.get("artifact_checklist_count", 0) stats = [ ("Requested", summary["requested_count"]), ("Written", summary["written_count"]), ("Existing", summary["existing_count"]), ("Skipped", summary["skipped_count"]), ("Artifacts", f"{artifact_ready}/{artifact_total}"), ] stat_html = "".join(f"
    {html_text(label)}{html_text(value)}
    " for label, value in stats) evidence_html = "".join(render_html_item(item) for item in report.get("evidence_items", [])) artifact_html = render_html_artifact_checklist(report.get("artifact_checklist", [])) source_html = render_html_source_checklist(report.get("source_checklist", [])) return f""" World-Class Evidence Submission Kit
    Evidence Intake

    World-Class Evidence Submission Kit

    Use this cockpit to prepare human and external evidence packets. Drafts are not accepted evidence, and this page never changes the ledger result.

    {stat_html}

    Workflow

    1. Run the real provider, human review, native permission, or native client telemetry work first.
    2. Edit the matching JSON draft with aggregate artifact references and provenance metadata.
    3. Set template_only to false only after real evidence exists.
    4. Validate intake, refresh the ledger, then guard public claims.

    Drafts

    {render_html_files(report['files'])}

    Artifact Checklist

    Copy concrete paths and SHA-256 digests from here into artifact_refs after real evidence exists. Glob patterns are expanded for operator convenience only.

    {artifact_html}

    Source Evidence Snapshot

    This section shows current aggregate source checks. It explains remaining blockers without changing the ledger.

    {source_html}

    Evidence Requirements

    {evidence_html}

    Safety Boundary

    • Drafts never count as accepted ledger evidence.
    • Valid intake means ready for ledger review, not world-class completion.
    • Do not include credentials, raw prompts, raw outputs, transcripts, notes, or private user content.
    """ def build_submission_kit( skill_dir: Path, output_dir: Path, generated_at: str, evidence_keys: list[str] | None = None, overwrite: bool = False, output_html: Path | None = None, ) -> dict[str, Any]: intake = build_intake(skill_dir, generated_at, submissions_dir=output_dir) items = requested_checklist_items(intake, evidence_keys or []) valid_keys = {str(item.get("evidence_key")) for item in intake.get("operator_checklist", [])} unknown_keys = sorted(set(evidence_keys or []) - valid_keys) template_results = template_result_by_key(intake) files = [copy_template(skill_dir, output_dir, item, template_results, overwrite) for item in items] artifact_checklist = build_artifact_checklist(skill_dir, items) source_checklist = build_source_checklist(items) manifest_path = output_dir / "submission_manifest.json" readme_path = output_dir / "README.md" output_html = output_html or (output_dir / "index.html") written_count = sum(1 for item in files if item["status"] == "written") existing_count = sum(1 for item in files if item["status"] == "exists") skipped_count = sum(1 for item in files if item["status"] == "skipped") artifact_ready_count = sum(1 for item in artifact_checklist if item.get("artifact_ref_ready")) artifact_missing_count = sum(1 for item in artifact_checklist if not item.get("artifact_ref_ready")) artifact_glob_count = sum(1 for item in artifact_checklist if item.get("concrete_reference_required")) source_summary = summarize_source_checklist(source_checklist) ok = not unknown_keys and skipped_count == 0 report = { "schema_version": "1.0", "ok": ok, "generated_at": generated_at, "skill_dir": rel_path(skill_dir, ROOT), "output_dir": rel_path(output_dir, skill_dir), "summary": { "requested_count": len(items) + len(unknown_keys), "prepared_count": len(files), "written_count": written_count, "existing_count": existing_count, "skipped_count": skipped_count, "unknown_key_count": len(unknown_keys), "artifact_checklist_count": len(artifact_checklist), "artifact_ready_count": artifact_ready_count, "artifact_missing_count": artifact_missing_count, "artifact_glob_expansion_count": artifact_glob_count, **source_summary, "drafts_count_as_evidence": False, "ledger_counts_submission_as_completion": False, "decision": "submission-kit-ready" if ok else "fix-submission-kit", }, "unknown_evidence_keys": unknown_keys, "files": files, "artifact_checklist": artifact_checklist, "source_checklist": source_checklist, "evidence_items": items, "commands": { "validate_intake": f"python3 scripts/yao.py world-class-intake . --submissions-dir {shell_path(output_dir, skill_dir)}", "refresh_ledger": f"python3 scripts/yao.py world-class-ledger . --submissions-dir {shell_path(output_dir, skill_dir)}", "guard_claim": "python3 scripts/yao.py world-class-claim-guard .", }, "safety": { "template_only_drafts": True, "real_evidence_required_before_template_only_false": True, "raw_content_allowed": False, "credentials_allowed": False, "drafts_count_as_evidence": False, }, "artifacts": { "manifest": rel_path(manifest_path, skill_dir), "readme": rel_path(readme_path, skill_dir), "html": rel_path(output_html, skill_dir), }, } output_dir.mkdir(parents=True, exist_ok=True) write_json(manifest_path, report) readme_path.write_text(render_readme(report), encoding="utf-8") output_html.parent.mkdir(parents=True, exist_ok=True) output_html.write_text(render_html(report), encoding="utf-8") return report def main() -> None: parser = argparse.ArgumentParser(description="Prepare editable world-class evidence submission drafts.") parser.add_argument("skill_dir", nargs="?", default=".") parser.add_argument("--output-dir", default="evidence/world_class/submission-kit") parser.add_argument("--evidence-key", action="append", default=[]) parser.add_argument("--overwrite", action="store_true") parser.add_argument("--generated-at", default=date.today().isoformat()) parser.add_argument("--output-html") args = parser.parse_args() skill_dir = Path(args.skill_dir).resolve() output_dir = Path(args.output_dir) if not output_dir.is_absolute(): output_dir = skill_dir / output_dir report = build_submission_kit( skill_dir, output_dir.resolve(), args.generated_at, evidence_keys=args.evidence_key, overwrite=args.overwrite, output_html=Path(args.output_html).resolve() if args.output_html else None, ) print(json.dumps(report, ensure_ascii=False, indent=2)) if not report["ok"]: raise SystemExit(2) if __name__ == "__main__": main()