Skip to content

Commit eb9ecfb

Browse files
frawarecursoragent
andcommitted
Emit labtrust_to_certifyedge_handoff.json in clean-chain staging
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 002fcde commit eb9ecfb

7 files changed

Lines changed: 106 additions & 19 deletions

File tree

examples/pcs_qc_release/scripts/_pcs_chain_env.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pcs_chain_init() {
1515
export WORK="${PCS_CHAIN_WORK:-$RELEASE_RUN_DIR}"
1616

1717
export TRACE_JSON="${WORK}/trace.json"
18+
export HANDOFF_CE_JSON="${WORK}/labtrust_to_certifyedge_handoff.json"
1819
export RUNTIME_RECEIPT_JSON="${WORK}/runtime_receipt.json"
1920
export PENDING_JSON="${WORK}/science_claim_bundle.pending.json"
2021
export TRACE_CERT_JSON="${WORK}/trace_certificate.json"

examples/pcs_qc_release/scripts/run_pcs_v01_clean_chain.ps1

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ Step "LabTrust-Gym: export PCS artifacts"
6464
& $Labtrust export-pcs --run $RunDir --out $PendingJson
6565
& $Pcs validate $PendingJson
6666

67+
$HandoffCeJson = Join-Path $Work "labtrust_to_certifyedge_handoff.json"
68+
Step "LabTrust-Gym: HandoffManifest.v0 (runtime_to_certificate) for CertifyEdge"
69+
& $Labtrust emit-handoff-to-certifyedge `
70+
--trace $TraceJson `
71+
--runtime-receipt $ReceiptJson `
72+
--out $HandoffCeJson `
73+
--release-mode
74+
& $Pcs validate $HandoffCeJson
75+
Copy-Item -Force $HandoffCeJson (Join-Path $Work "handoff_to_certifyedge.json")
76+
6777
if ($LabtrustOnly) {
6878
Step "LabTrust-only chain OK"
6979
& $Python (Join-Path $PSScriptRoot "verify_pcs_v01_chain.py") --work $Work --stage labtrust
@@ -77,8 +87,12 @@ if (-not $CeCmd) {
7787
}
7888
if (-not (Test-Path $CertifyEdgeSpec)) { throw "CertifyEdge spec not found: $CertifyEdgeSpec" }
7989

80-
Step "CertifyEdge: emit and verify TraceCertificate"
81-
& $CertifyEdgeBin emit-pcs-certificate --spec $CertifyEdgeSpec --trace $TraceJson --out $CertJson
90+
$HandoffOutJson = Join-Path $Work "certifyedge_to_labtrust_handoff.json"
91+
Step "CertifyEdge: emit and verify TraceCertificate (HandoffManifest input)"
92+
& $CertifyEdgeBin --release-mode emit-pcs-certificate `
93+
--handoff $HandoffCeJson `
94+
--out $CertJson `
95+
--handoff-out $HandoffOutJson
8296
& $Pcs validate $CertJson
8397
& $CertifyEdgeBin verify-certificate $CertJson --trace $TraceJson
8498

examples/pcs_qc_release/scripts/run_pcs_v01_clean_chain.sh

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ labtrust export-runtime-receipt --run "$RUN_DIR" --out "$RUNTIME_RECEIPT_JSON"
4141
labtrust export-pcs --run "$RUN_DIR" --out "$PENDING_JSON"
4242
pcs validate "$PENDING_JSON"
4343

44+
HANDOFF_CE_JSON="${WORK}/labtrust_to_certifyedge_handoff.json"
45+
pcs_step "LabTrust-Gym: HandoffManifest.v0 (runtime_to_certificate) for CertifyEdge"
46+
labtrust emit-handoff-to-certifyedge \
47+
--trace "$TRACE_JSON" \
48+
--runtime-receipt "$RUNTIME_RECEIPT_JSON" \
49+
--out "$HANDOFF_CE_JSON" \
50+
--release-mode
51+
pcs validate "$HANDOFF_CE_JSON"
52+
cp -f "$HANDOFF_CE_JSON" "${WORK}/handoff_to_certifyedge.json"
53+
4454
if [ "$LABTRUST_ONLY" -eq 1 ]; then
4555
pcs_step "LabTrust-only chain OK"
4656
python "$SCRIPT_DIR/verify_pcs_v01_chain.py" --work "$WORK" --stage labtrust
@@ -53,11 +63,12 @@ if [ ! -f "$CERTIFYEDGE_SPEC" ]; then
5363
exit 1
5464
fi
5565

56-
pcs_step "CertifyEdge: emit and verify TraceCertificate"
57-
"$CERTIFYEDGE_BIN" emit-pcs-certificate \
58-
--spec "$CERTIFYEDGE_SPEC" \
59-
--trace "$TRACE_JSON" \
60-
--out "$TRACE_CERT_JSON"
66+
HANDOFF_OUT_JSON="${WORK}/certifyedge_to_labtrust_handoff.json"
67+
pcs_step "CertifyEdge: emit and verify TraceCertificate (HandoffManifest input)"
68+
"$CERTIFYEDGE_BIN" --release-mode emit-pcs-certificate \
69+
--handoff "$HANDOFF_CE_JSON" \
70+
--out "$TRACE_CERT_JSON" \
71+
--handoff-out "$HANDOFF_OUT_JSON"
6172
pcs validate "$TRACE_CERT_JSON"
6273
"$CERTIFYEDGE_BIN" verify-certificate "$TRACE_CERT_JSON" --trace "$TRACE_JSON"
6374

src/labtrust_gym/pcs/handoff_manifest.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
HANDOFF_TO_PF_NAME = "handoff_to_pf.json"
2020
HANDOFF_TO_CERTIFYEDGE_NAME = "handoff_to_certifyedge.json"
21+
# Filename used by CertifyEdge release-run / clean-checkout staging (PCS Phase 2).
22+
LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME = "labtrust_to_certifyedge_handoff.json"
2123
CERTIFIED_BUNDLE_NAME = "science_claim_bundle.certified.json"
2224
TRACE_NAME = "trace.json"
2325
RUNTIME_RECEIPT_NAME = "runtime_receipt.json"
@@ -325,6 +327,39 @@ def emit_handoff_manifest(
325327
return doc
326328

327329

330+
def write_certifyedge_chain_handoffs(
331+
*,
332+
trace_path: Path,
333+
runtime_receipt_path: Path,
334+
work_dir: Path,
335+
policy_root: Path | None = None,
336+
property_id: str = DEFAULT_PROPERTY_ID,
337+
release_mode: bool | None = None,
338+
handoff_id: str | None = None,
339+
) -> dict[str, Any]:
340+
"""
341+
Write runtime_to_certificate HandoffManifest.v0 for CertifyEdge clean-chain staging.
342+
343+
Emits ``labtrust_to_certifyedge_handoff.json`` (CertifyEdge convention) and
344+
``handoff_to_certifyedge.json`` (release fixture name) under ``work_dir``.
345+
"""
346+
work_dir = work_dir.resolve()
347+
doc = emit_handoff_to_certifyedge(
348+
trace_path=trace_path,
349+
runtime_receipt_path=runtime_receipt_path,
350+
out_path=work_dir / LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME,
351+
policy_root=policy_root,
352+
property_id=property_id,
353+
release_mode=release_mode,
354+
handoff_id=handoff_id,
355+
)
356+
legacy = work_dir / HANDOFF_TO_CERTIFYEDGE_NAME
357+
staging = work_dir / LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME
358+
if legacy != staging:
359+
legacy.write_text(staging.read_text(encoding="utf-8"), encoding="utf-8")
360+
return doc
361+
362+
328363
def build_handoff_to_pf_from_release(
329364
release_root: Path,
330365
manifest: dict[str, Any],

src/labtrust_gym/pcs/release_protocol_producer.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
from labtrust_gym.pcs.handoff_manifest import (
2323
HANDOFF_TO_CERTIFYEDGE_NAME,
2424
HANDOFF_TO_PF_NAME,
25-
emit_handoff_to_certifyedge,
25+
LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME,
2626
emit_handoff_to_pf,
27+
write_certifyedge_chain_handoffs,
2728
)
2829
from labtrust_gym.pcs.manifest import resolve_pcs_core_root
2930
from labtrust_gym.pcs.release_fragment import (
@@ -48,6 +49,7 @@
4849

4950
LABTRUST_PROTOCOL_HANDOFF_ARTIFACTS: tuple[str, ...] = (
5051
HANDOFF_TO_CERTIFYEDGE_NAME,
52+
LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME,
5153
HANDOFF_TO_PF_NAME,
5254
LABTRUST_RELEASE_FRAGMENT_NAME,
5355
)
@@ -136,25 +138,24 @@ def regenerate_release_protocol(
136138
export_runtime_receipt(demo_run, work / "runtime_receipt.json", policy_root=root)
137139
export_pcs_bundle(demo_run, work / "science_claim_bundle.pending.json", policy_root=root)
138140

139-
emit_handoff_to_certifyedge(
141+
write_certifyedge_chain_handoffs(
140142
trace_path=work / "trace.json",
141143
runtime_receipt_path=work / "runtime_receipt.json",
142-
out_path=work / HANDOFF_TO_CERTIFYEDGE_NAME,
144+
work_dir=work,
143145
policy_root=root,
144146
property_id=property_id,
145147
release_mode=True,
146148
)
147149

148150
cert_path = work / "trace_certificate.json"
151+
handoff_ce = work / LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME
149152
subprocess.run(
150153
[
151154
ce_bin,
152155
"--release-mode",
153156
"emit-pcs-certificate",
154-
"--spec",
155-
str(spec),
156-
"--trace",
157-
str(work / "trace.json"),
157+
"--handoff",
158+
str(handoff_ce),
158159
"--out",
159160
str(cert_path),
160161
],
@@ -241,10 +242,10 @@ def emit_protocol_package_from_release(
241242
Returns summary dict with paths and digests.
242243
"""
243244
release_dir = release_dir.resolve()
244-
emit_handoff_to_certifyedge(
245+
write_certifyedge_chain_handoffs(
245246
trace_path=release_dir / "trace.json",
246247
runtime_receipt_path=release_dir / "runtime_receipt.json",
247-
out_path=release_dir / HANDOFF_TO_CERTIFYEDGE_NAME,
248+
work_dir=release_dir,
248249
policy_root=policy_root,
249250
property_id=property_id,
250251
release_mode=True,

src/labtrust_gym/pcs/release_run.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,11 @@ def write_run_manifests(
288288
(run_dir / RELEASE_HANDOFF_MANIFEST_NAME).write_text(
289289
json.dumps(handoff_manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8"
290290
)
291-
(run_dir / HANDOFF_TO_CERTIFYEDGE_NAME).write_text(
292-
json.dumps(handoff_ce, indent=2, sort_keys=True) + "\n", encoding="utf-8"
293-
)
291+
handoff_ce_text = json.dumps(handoff_ce, indent=2, sort_keys=True) + "\n"
292+
(run_dir / HANDOFF_TO_CERTIFYEDGE_NAME).write_text(handoff_ce_text, encoding="utf-8")
293+
from labtrust_gym.pcs.handoff_manifest import LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME
294+
295+
(run_dir / LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME).write_text(handoff_ce_text, encoding="utf-8")
294296
(run_dir / HANDOFF_FOR_PF_NAME).write_text(
295297
json.dumps(handoff_pf, indent=2, sort_keys=True) + "\n", encoding="utf-8"
296298
)

tests/pcs/test_release_protocol_producer.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
from labtrust_gym.pcs.handoff_manifest import (
1818
HANDOFF_TO_CERTIFYEDGE_NAME,
1919
HANDOFF_TO_PF_NAME,
20+
LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME,
2021
assert_handoff_manifest_valid,
2122
assert_handoff_registry_check,
2223
build_runtime_to_certificate_handoff,
2324
emit_handoff_manifest,
25+
write_certifyedge_chain_handoffs,
2426
)
2527
from labtrust_gym.pcs.mock_certificate import build_mock_trace_certificate
2628
from labtrust_gym.pcs.regenerate_release_chain import compare_release_hashes_to_canonical
@@ -52,6 +54,27 @@ def test_committed_release_protocol_package_complete(release_dir: Path) -> None:
5254
)
5355

5456

57+
def test_write_certifyedge_chain_handoffs_staging_filename(
58+
release_dir: Path, tmp_path: Path
59+
) -> None:
60+
work = tmp_path / "staging"
61+
work.mkdir()
62+
doc = write_certifyedge_chain_handoffs(
63+
trace_path=release_dir / "trace.json",
64+
runtime_receipt_path=release_dir / "runtime_receipt.json",
65+
work_dir=work,
66+
release_mode=True,
67+
)
68+
staging = work / LABTRUST_TO_CERTIFYEDGE_HANDOFF_NAME
69+
legacy = work / HANDOFF_TO_CERTIFYEDGE_NAME
70+
assert staging.is_file()
71+
assert legacy.is_file()
72+
assert staging.read_text(encoding="utf-8") == legacy.read_text(encoding="utf-8")
73+
assert doc["handoff_kind"] == "runtime_to_certificate"
74+
assert_handoff_manifest_valid(doc)
75+
assert_handoff_registry_check(staging)
76+
77+
5578
def test_emit_handoff_to_certifyedge_validates_against_pcs_core(
5679
release_dir: Path, tmp_path: Path
5780
) -> None:

0 commit comments

Comments
 (0)