Use this cockpit to prepare human and external evidence packets. Drafts are not accepted evidence, and this page never changes the ledger result.
+
Use this cockpit to prepare human and external evidence packets. Drafts are not accepted evidence, artifact prefill only inserts local SHA-256 digests, and this page never changes the ledger result.
{stat_html}
-
Workflow
Run the real provider, human review, native permission, or native client telemetry work first.
Edit the matching JSON draft with aggregate artifact references and provenance metadata.
Set template_only to false only after real evidence exists.
Validate intake, refresh the ledger, then guard public claims.
+
Workflow
Run the real provider, human review, native permission, or native client telemetry work first.
Edit the matching JSON draft with aggregate artifact references and provenance metadata.
Set template_only to false only after real evidence exists.
Use prefilled SHA-256 values as convenience data, not evidence acceptance.
Validate intake, refresh the ledger, then guard public claims.
Drafts
{render_html_files(report['files'])}
@@ -519,6 +594,7 @@ def build_submission_kit(
generated_at: str,
evidence_keys: list[str] | None = None,
overwrite: bool = False,
+ prefill_artifacts: bool = False,
output_html: Path | None = None,
) -> dict[str, Any]:
intake = build_intake(skill_dir, generated_at, submissions_dir=output_dir)
@@ -526,8 +602,20 @@ def build_submission_kit(
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)
+ ready_rows = artifact_rows_by_key_and_path(artifact_checklist)
+ files = [
+ copy_template(
+ skill_dir,
+ output_dir,
+ item,
+ template_results,
+ ready_rows,
+ overwrite,
+ prefill_artifacts,
+ )
+ for item in items
+ ]
source_checklist = build_source_checklist(items)
manifest_path = output_dir / "submission_manifest.json"
readme_path = output_dir / "README.md"
@@ -535,6 +623,8 @@ def build_submission_kit(
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")
+ prefilled_artifact_ref_count = sum(item.get("prefilled_artifact_ref_count", 0) for item in files)
+ unfilled_artifact_ref_count = sum(item.get("unfilled_artifact_ref_count", 0) for item in files)
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"))
@@ -557,6 +647,9 @@ def build_submission_kit(
"artifact_ready_count": artifact_ready_count,
"artifact_missing_count": artifact_missing_count,
"artifact_glob_expansion_count": artifact_glob_count,
+ "artifact_prefill_enabled": prefill_artifacts,
+ "artifact_ref_prefill_count": prefilled_artifact_ref_count,
+ "artifact_ref_unfilled_count": unfilled_artifact_ref_count,
**source_summary,
"drafts_count_as_evidence": False,
"ledger_counts_submission_as_completion": False,
@@ -574,6 +667,7 @@ def build_submission_kit(
},
"safety": {
"template_only_drafts": True,
+ "artifact_prefill_counts_as_evidence": False,
"real_evidence_required_before_template_only_false": True,
"raw_content_allowed": False,
"credentials_allowed": False,
@@ -599,6 +693,11 @@ def main() -> None:
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(
+ "--prefill-artifacts",
+ action="store_true",
+ help="Insert SHA-256 digests for currently available aggregate artifacts while keeping drafts template-only.",
+ )
parser.add_argument("--generated-at", default=date.today().isoformat())
parser.add_argument("--output-html")
args = parser.parse_args()
@@ -613,6 +712,7 @@ def main() -> None:
args.generated_at,
evidence_keys=args.evidence_key,
overwrite=args.overwrite,
+ prefill_artifacts=args.prefill_artifacts,
output_html=Path(args.output_html).resolve() if args.output_html else None,
)
print(json.dumps(report, ensure_ascii=False, indent=2))
diff --git a/scripts/yao_cli_parser.py b/scripts/yao_cli_parser.py
index 70c1ff76..4ad7c453 100644
--- a/scripts/yao_cli_parser.py
+++ b/scripts/yao_cli_parser.py
@@ -237,6 +237,11 @@ def build_parser(command_handlers: dict[str, Callable[[argparse.Namespace], int]
world_class_submission_kit_cmd.add_argument("--output-dir")
world_class_submission_kit_cmd.add_argument("--evidence-key", action="append", default=[])
world_class_submission_kit_cmd.add_argument("--overwrite", action="store_true")
+ world_class_submission_kit_cmd.add_argument(
+ "--prefill-artifacts",
+ action="store_true",
+ help="Insert SHA-256 digests for currently available aggregate artifacts while keeping drafts template-only.",
+ )
world_class_submission_kit_cmd.add_argument("--generated-at")
world_class_submission_kit_cmd.add_argument("--output-html")
world_class_submission_kit_cmd.set_defaults(func=_handler(command_handlers, "command_world_class_submission_kit"))
diff --git a/scripts/yao_cli_report_commands.py b/scripts/yao_cli_report_commands.py
index d7b8ed0a..e77698c4 100644
--- a/scripts/yao_cli_report_commands.py
+++ b/scripts/yao_cli_report_commands.py
@@ -196,6 +196,8 @@ def command_world_class_submission_kit(args: argparse.Namespace) -> int:
cmd.extend(["--evidence-key", key])
if args.overwrite:
cmd.append("--overwrite")
+ if args.prefill_artifacts:
+ cmd.append("--prefill-artifacts")
if args.generated_at:
cmd.extend(["--generated-at", args.generated_at])
if args.output_html:
diff --git a/tests/verify_world_class_evidence_intake.py b/tests/verify_world_class_evidence_intake.py
index 066aaf6b..14e1019b 100644
--- a/tests/verify_world_class_evidence_intake.py
+++ b/tests/verify_world_class_evidence_intake.py
@@ -499,6 +499,7 @@ def assert_documented_submission_commands() -> None:
'SUBMISSIONS_DIR="${SUBMISSIONS_DIR:-evidence/world_class/submissions}"',
'world-class-preflight . --submissions-dir "$SUBMISSIONS_DIR"',
'world-class-submission-kit . --output-dir "$SUBMISSIONS_DIR"',
+ 'world-class-submission-kit . --output-dir "$SUBMISSIONS_DIR" --prefill-artifacts',
'world-class-intake . --submissions-dir "$SUBMISSIONS_DIR"',
'world-class-submission-review . --submissions-dir "$SUBMISSIONS_DIR"',
'world-class-ledger . --submissions-dir "$SUBMISSIONS_DIR"',
@@ -614,8 +615,11 @@ def main() -> None:
kit_draft = json.loads((kit_dir / "provider-holdout.json").read_text(encoding="utf-8"))
assert kit_draft["template_only"] is True, kit_draft
assert kit_draft["attestation"]["real_external_or_human_evidence"] is False, kit_draft
+ assert "sha256" not in kit_draft["artifact_refs"][0], kit_draft
kit_manifest = json.loads((kit_dir / "submission_manifest.json").read_text(encoding="utf-8"))
assert kit_manifest["summary"]["ledger_counts_submission_as_completion"] is False, kit_manifest["summary"]
+ assert kit_manifest["summary"]["artifact_prefill_enabled"] is False, kit_manifest["summary"]
+ assert kit_manifest["summary"]["artifact_ref_prefill_count"] == 0, kit_manifest["summary"]
assert kit_manifest["artifact_checklist"] == kit_payload["artifact_checklist"], kit_manifest["artifact_checklist"]
assert kit_manifest["source_checklist"] == kit_payload["source_checklist"], kit_manifest["source_checklist"]
assert kit_manifest["artifacts"]["html"].endswith("tests/tmp_world_class_evidence_intake/submission_kit/index.html"), kit_manifest["artifacts"]
@@ -642,6 +646,33 @@ def main() -> None:
assert "output-exec --provider-runner openai" in kit_html, kit_html
assert "Do not include credentials, raw prompts, raw outputs, transcripts, notes, or private user content." in kit_html, kit_html
+ prefilled_kit_dir = TMP / "prefilled_submission_kit"
+ prefilled_proc = run_kit(
+ "--output-dir",
+ str(prefilled_kit_dir),
+ "--evidence-key",
+ "provider-holdout",
+ "--prefill-artifacts",
+ )
+ prefilled_payload = json.loads(prefilled_proc.stdout)
+ assert prefilled_payload["summary"]["artifact_prefill_enabled"] is True, prefilled_payload["summary"]
+ assert prefilled_payload["summary"]["artifact_ref_prefill_count"] == 1, prefilled_payload["summary"]
+ assert prefilled_payload["summary"]["artifact_ref_unfilled_count"] == 0, prefilled_payload["summary"]
+ assert prefilled_payload["summary"]["drafts_count_as_evidence"] is False, prefilled_payload["summary"]
+ assert prefilled_payload["safety"]["artifact_prefill_counts_as_evidence"] is False, prefilled_payload["safety"]
+ assert prefilled_payload["files"][0]["prefilled_artifact_ref_count"] == 1, prefilled_payload["files"]
+ prefilled_draft = json.loads((prefilled_kit_dir / "provider-holdout.json").read_text(encoding="utf-8"))
+ assert prefilled_draft["template_only"] is True, prefilled_draft
+ assert prefilled_draft["attestation"]["real_external_or_human_evidence"] is False, prefilled_draft
+ assert len(prefilled_draft["artifact_refs"][0]["sha256"]) == 64, prefilled_draft
+ assert prefilled_draft["artifact_refs"][0]["contains_raw_content"] is False, prefilled_draft
+ prefilled_readme = (prefilled_kit_dir / "README.md").read_text(encoding="utf-8")
+ assert "Optional artifact prefill only inserts SHA-256 digests" in prefilled_readme, prefilled_readme
+ assert "does not mark a draft as real evidence" in prefilled_readme, prefilled_readme
+ prefilled_html = (prefilled_kit_dir / "index.html").read_text(encoding="utf-8")
+ assert "artifact prefill only inserts local SHA-256 digests" in prefilled_html, prefilled_html
+ assert "