Skip to content

Commit 4b2d015

Browse files
frawarecursoragent
andcommitted
Add canonical pcs-bench ingest producer for labtrust admission.
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2110119 commit 4b2d015

32 files changed

Lines changed: 1169 additions & 352 deletions

.github/workflows/pcs-ci.yml

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ on:
2525
- 'scripts/run-pcs-v01-clean-chain.sh'
2626
- 'scripts/pcs-benchmark-admission.sh'
2727
- 'scripts/pcs-bench-producer.sh'
28+
- 'scripts/pcs-bench-validate-ingest.sh'
29+
- 'scripts/pcs-bench-producer-contract-check.py'
2830
- 'scripts/validate-pf-pcs-bench-ingest.py'
2931
- 'scripts/materialize-admission-benchmark-cases.py'
3032
- 'benchmarks/admission/**'
@@ -56,6 +58,8 @@ on:
5658
- 'scripts/run-pcs-v01-clean-chain.sh'
5759
- 'scripts/pcs-benchmark-admission.sh'
5860
- 'scripts/pcs-bench-producer.sh'
61+
- 'scripts/pcs-bench-validate-ingest.sh'
62+
- 'scripts/pcs-bench-producer-contract-check.py'
5963
- 'scripts/validate-pf-pcs-bench-ingest.py'
6064
- 'scripts/materialize-admission-benchmark-cases.py'
6165
- 'benchmarks/admission/**'
@@ -500,38 +504,55 @@ jobs:
500504
OUT="$GITHUB_WORKSPACE/benchmark_runs"
501505
cd "$GITHUB_WORKSPACE/core/cli/pf"
502506
for SUITE in labtrust_qc_release tool_use_safety computation_reproducibility formal_trust_kernel; do
507+
if [[ "${SUITE}" == "labtrust_qc_release" ]]; then
508+
SUITE_OUT="labtrust_admission"
509+
else
510+
SUITE_OUT="${SUITE}_admission"
511+
fi
503512
go run . benchmark admission \
504513
--cases "$GITHUB_WORKSPACE/benchmarks/admission/${SUITE}" \
505514
--registry "$REG" \
506-
--out "${OUT}/${SUITE}_admission" \
515+
--out "${OUT}/${SUITE_OUT}" \
507516
--validate \
508517
--validate-pcs-core-output "$PCS_CORE_PATH"
509518
done
510-
test -f "${OUT}/labtrust_qc_release_admission/benchmark_report.v0.json"
511-
test -f "${OUT}/labtrust_qc_release_admission/benchmark_run.v0.json"
512-
test -f "${OUT}/labtrust_qc_release_admission/coverage_report.v0.json"
519+
LABTRUST="${OUT}/labtrust_admission"
520+
test -f "${LABTRUST}/benchmark_report.v0.json"
521+
test -f "${LABTRUST}/benchmark_run.v0.json"
522+
test -f "${LABTRUST}/coverage_report.v0.json"
513523
test -f "${OUT}/formal_trust_kernel_admission/explain_quality_report.v0.json"
514-
test -f "${OUT}/labtrust_qc_release_admission/pcs_bench_ingest.v0.json"
515-
test -f "${OUT}/labtrust_qc_release_admission/coverage/registry_coverage_report.v0.json"
516-
test -f "${OUT}/labtrust_qc_release_admission/coverage/formal_check_coverage_report.v0.json"
517-
test -f "${OUT}/labtrust_qc_release_admission/coverage/admission_profile_coverage_report.v0.json"
518-
test -f "${OUT}/labtrust_qc_release_admission/coverage/release_reproducibility_coverage_report.v0.json"
519-
test -f "${OUT}/labtrust_qc_release_admission/coverage/admission_profile.profile_coverage_report.v0.json"
520-
test -d "${OUT}/labtrust_qc_release_admission/explain_quality"
521-
test -d "${OUT}/labtrust_qc_release_admission/failure_localization"
522-
test -f "${OUT}/labtrust_qc_release_admission/failure_localization/bundle_hash_mismatch.failure_localization_result.v0.json"
523-
python3 -c "import json; m=json.load(open('${OUT}/labtrust_qc_release_admission/admission_benchmark_suite.v0.json'))['metrics']; assert m['valid_release_admission_rate']==1.0; assert m['invalid_release_rejection_rate']>=0.85; assert m['failure_localization_accuracy']>=0.85"
524+
test -f "${LABTRUST}/pcs_bench_ingest.v0.json"
525+
test -f "${LABTRUST}/coverage/registry_coverage_report.v0.json"
526+
test -f "${LABTRUST}/coverage/formal_check_coverage_report.v0.json"
527+
test -f "${LABTRUST}/coverage/admission_profile_coverage_report.v0.json"
528+
test -f "${LABTRUST}/coverage/release_reproducibility_coverage_report.v0.json"
529+
test -f "${LABTRUST}/coverage/admission_profile.profile_coverage_report.v0.json"
530+
test -d "${LABTRUST}/explain_quality"
531+
test -d "${LABTRUST}/failure_localization"
532+
test -f "${LABTRUST}/failure_localization/bundle_hash_mismatch.failure_localization_result.v0.json"
533+
python3 -c "import json; m=json.load(open('${LABTRUST}/admission_benchmark_suite.v0.json'))['metrics']; assert m['valid_release_admission_rate']==1.0; assert m['invalid_release_rejection_rate']>=0.85; assert m['failure_localization_accuracy']>=0.85"
524534
test -f "$GITHUB_WORKSPACE/benchmarks/admission/examples/labtrust_qc_release.pcs_bench_ingest.reference.json"
525535
cd "$GITHUB_WORKSPACE"
526536
go run ./tools/pcs-validate \
527-
"${OUT}/labtrust_qc_release_admission/benchmark_report.v0.json" \
528-
"${OUT}/labtrust_qc_release_admission/coverage_report.v0.json" \
529-
"${OUT}/labtrust_qc_release_admission/explain_quality_report.v0.json" \
530-
"${OUT}/labtrust_qc_release_admission/pcs_bench_ingest.v0.json"
531-
go run ./tools/pcs-validate --benchmark-bundle "${OUT}/labtrust_qc_release_admission" --pcs-core "$PCS_CORE_PATH"
537+
"${LABTRUST}/benchmark_report.v0.json" \
538+
"${LABTRUST}/coverage_report.v0.json" \
539+
"${LABTRUST}/explain_quality_report.v0.json" \
540+
"${LABTRUST}/pcs_bench_ingest.v0.json"
541+
go run ./tools/pcs-validate --benchmark-bundle "${LABTRUST}" --pcs-core "$PCS_CORE_PATH"
532542
pip install -q -e "${PCS_CORE_PATH}/python"
533-
pcs validate "${OUT}/labtrust_qc_release_admission/pcs_bench_ingest.v0.json"
543+
pcs validate "${LABTRUST}/pcs_bench_ingest.v0.json"
534544
pcs validate "$GITHUB_WORKSPACE/benchmarks/admission/examples/labtrust_qc_release.pcs_bench_ingest.reference.json"
545+
python3 "$GITHUB_WORKSPACE/scripts/pcs-bench-producer-contract-check.py" \
546+
--ingest "${LABTRUST}/pcs_bench_ingest.v0.json" \
547+
--bundle-dir "${LABTRUST}"
548+
python3 "$GITHUB_WORKSPACE/scripts/pcs-bench-producer-contract-check.py" \
549+
--ingest "$GITHUB_WORKSPACE/benchmarks/admission/examples/labtrust_qc_release.pcs_bench_ingest.reference.json" \
550+
--bundle-dir "${LABTRUST}"
551+
bash "$GITHUB_WORKSPACE/scripts/pcs-bench-validate-ingest.sh" \
552+
--input "$GITHUB_WORKSPACE/benchmarks/admission/examples/labtrust_qc_release.pcs_bench_ingest.reference.json" \
553+
--bundle-dir "${LABTRUST}" \
554+
--pcs-core "$PCS_CORE_PATH" \
555+
--release-grade
535556
cd "$GITHUB_WORKSPACE/core/cli/pf"
536557
go run . benchmark admission \
537558
--cases "$GITHUB_WORKSPACE/benchmarks/admission/labtrust_qc_release" \
@@ -543,10 +564,10 @@ jobs:
543564
grep -q '"suite_id": "pf-labtrust-admission-v0"' "$RUNNER_TEMP/admission_summary.json"
544565
grep -q '"workflow_id": "hospital_lab.qc_release"' "$RUNNER_TEMP/admission_summary.json"
545566
grep -q '"pcs_bench_ingest_path"' "$RUNNER_TEMP/admission_summary.json"
546-
python3 -c "import json; i=json.load(open('${OUT}/labtrust_qc_release_admission/pcs_bench_ingest.v0.json')); assert i['suite_id']=='pf-labtrust-admission-v0'; assert i['workflow_id']=='hospital_lab.qc_release'; assert all('/' in r['path'] or '\\\\' not in r['path'] for r in i.get('artifact_refs',[]))"
547-
python3 "$GITHUB_WORKSPACE/scripts/validate-pf-pcs-bench-ingest.py" \
548-
--ingest "${OUT}/labtrust_qc_release_admission/pcs_bench_ingest.v0.json" \
549-
--bundle-dir "${OUT}/labtrust_qc_release_admission" \
567+
python3 -c "import json; i=json.load(open('${LABTRUST}/pcs_bench_ingest.v0.json')); assert i['suite_id']=='pf-labtrust-admission-v0'; assert i['workflow_id']=='hospital_lab.qc_release'; assert all('/' in r['path'] or '\\\\' not in r['path'] for r in i.get('artifact_refs',[])); assert 'benchmarks/admission/labtrust_qc_release' in i['commands'][0]['command']"
568+
bash "$GITHUB_WORKSPACE/scripts/pcs-bench-validate-ingest.sh" \
569+
--input "${LABTRUST}/pcs_bench_ingest.v0.json" \
570+
--bundle-dir "${LABTRUST}" \
550571
--pcs-core "$PCS_CORE_PATH" \
551572
--release-grade
552573

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ workspaces_verify_preflight_smoke/
238238
# PCS admission benchmark run outputs (regenerated by make test-pcs-benchmark)
239239
/benchmark_runs/
240240

241+
# WSL path-duplication artifacts (accidental nested mounts)
242+
/mnt/
243+
241244
# Repo-root prediction artifacts from local bench runs
242245
/predictions*.jsonl
243246
/*.pfmeta.jsonl

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ export-pcs-benchmark-ingest-reference:
9999
@$(ECHOOK) "Materialize labtrust PcsBenchIngest reference artifact..."
100100
bash scripts/export-pcs-benchmark-ingest-reference.sh
101101

102+
validate-pcs-reference-ingest:
103+
@$(ECHOOK) "Validate committed labtrust reference ingest (producer contract)..."
104+
python3 scripts/pcs-bench-producer-contract-check.py \
105+
--ingest benchmarks/admission/examples/labtrust_qc_release.pcs_bench_ingest.reference.json \
106+
--bundle-dir benchmark_runs/labtrust_admission
107+
102108
ifeq ($(OS),Windows_NT)
103109
pcs-bench-producer:
104110
@$(ECHOOK) "PCS-bench producer gate (labtrust admission ingest)..."
@@ -109,7 +115,7 @@ pcs-bench-producer:
109115
@bash scripts/pcs-bench-producer.sh
110116
endif
111117

112-
test-pcs-full: test-pcs test-pcs-rc-gate test-pcs-phase2 validate-pcs-fixtures test-pcs-benchmark validate-pcs-benchmark-bundle pcs-bench-producer
118+
test-pcs-full: test-pcs test-pcs-rc-gate test-pcs-phase2 validate-pcs-fixtures test-pcs-benchmark validate-pcs-benchmark-bundle pcs-bench-producer validate-pcs-reference-ingest
113119
@$(ECHOOK) "OK: PCS full gate passed (unit, RC lock, Phase 2, fixtures, admission benchmarks)"
114120

115121
validate-pcs-fixtures:

adapters/pcs/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ pcs-bench producer gate (labtrust ingest at `benchmark_runs/labtrust_admission/p
8888
make pcs-bench-producer
8989
```
9090

91+
Validate an existing ingest (release-grade):
92+
93+
```bash
94+
bash scripts/pcs-bench-validate-ingest.sh \
95+
--input benchmark_runs/labtrust_admission/pcs_bench_ingest.v0.json \
96+
--bundle-dir benchmark_runs/labtrust_admission \
97+
--pcs-core ../pcs-core \
98+
--release-grade
99+
```
100+
101+
Labtrust failure-family case IDs: `pcs.LabtrustRequiredFailureFamilyCaseIDs` (see `admission_benchmark_labtrust_test.go`).
102+
91103
See [docs/guides/pcs-admission-benchmark.md](../../docs/guides/pcs-admission-benchmark.md).
92104

93105
## Tests

adapters/pcs/admission_benchmark.go

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ func RunAdmissionBenchmark(opts AdmissionBenchmarkOptions) (AdmissionBenchmarkSu
227227
if opts.SourceCommit == "" {
228228
opts.SourceCommit = ResolveSourceCommit()
229229
}
230+
if strings.TrimSpace(opts.RepoRoot) == "" {
231+
if root, err := FindRepoRoot(opts.CasesDir); err == nil {
232+
opts.RepoRoot = root
233+
}
234+
}
230235

231236
var results []AdmissionBenchmarkCaseResult
232237
var locCases []FailureLocalizationCaseResult
@@ -379,15 +384,60 @@ func admissionCasePassed(c AdmissionBenchmarkCase, cr AdmissionBenchmarkCaseResu
379384
}
380385

381386
func buildBenchmarkCommandLine(c AdmissionBenchmarkCase, workflow AdmissionBenchmarkWorkflow, opts AdmissionBenchmarkOptions) string {
382-
parts := []string{"pf", "benchmark", "admission", "--cases", opts.CasesDir}
383-
if opts.RegistryPath != "" {
384-
parts = append(parts, "--registry", opts.RegistryPath)
387+
repoRoot := strings.TrimSpace(opts.RepoRoot)
388+
if repoRoot == "" {
389+
repoRoot, _ = FindRepoRoot(opts.CasesDir)
390+
}
391+
casesDir := portableBenchmarkPath(repoRoot, opts.CasesDir)
392+
registry := portableBenchmarkPath(repoRoot, opts.RegistryPath)
393+
parts := []string{"pf", "benchmark", "admission", "--cases", casesDir}
394+
if registry != "" {
395+
parts = append(parts, "--registry", registry)
385396
}
386397
parts = append(parts, fmt.Sprintf("# case=%s mode=%s profile=%s", c.CaseID, c.VerifyMode, c.ProfileID))
387398
_ = workflow
388399
return strings.Join(parts, " ")
389400
}
390401

402+
func benchmarkPathKey(p string) string {
403+
abs := p
404+
if resolved, err := filepath.Abs(p); err == nil {
405+
abs = resolved
406+
}
407+
return strings.ToLower(filepath.ToSlash(filepath.Clean(abs)))
408+
}
409+
410+
// portableBenchmarkPath rewrites absolute filesystem paths to repo-relative forward-slash paths for reproducible command logs.
411+
func portableBenchmarkPath(repoRoot, path string) string {
412+
path = strings.TrimSpace(path)
413+
if path == "" {
414+
return ""
415+
}
416+
clean := filepath.Clean(path)
417+
absClean := clean
418+
if resolved, err := filepath.Abs(clean); err == nil {
419+
absClean = resolved
420+
}
421+
if repoRoot != "" {
422+
absRepo, _ := filepath.Abs(repoRoot)
423+
if rel, err := filepath.Rel(absRepo, absClean); err == nil && rel != "" && !strings.HasPrefix(rel, "..") {
424+
return filepath.ToSlash(rel)
425+
}
426+
siblingCore, _ := filepath.Abs(filepath.Join(absRepo, "..", "pcs-core"))
427+
keyClean := benchmarkPathKey(absClean)
428+
keySibling := benchmarkPathKey(siblingCore)
429+
if keySibling != "" && (keyClean == keySibling || strings.HasPrefix(keyClean, keySibling+"/")) {
430+
tail := strings.TrimPrefix(keyClean, keySibling)
431+
tail = strings.TrimPrefix(tail, "/")
432+
if tail == "" {
433+
return "../pcs-core"
434+
}
435+
return filepath.ToSlash(filepath.Join("..", "pcs-core", filepath.FromSlash(tail)))
436+
}
437+
}
438+
return filepath.ToSlash(clean)
439+
}
440+
391441
func explainFromPCSReport(r *PCSExplainQualityReport) *ExplainQualityCaseScore {
392442
if r == nil {
393443
return nil

adapters/pcs/admission_benchmark_bundle.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,27 @@ var RequiredAdmissionInvalidCaseIDs = []string{
3232
"scientific_memory_import_failure",
3333
}
3434

35+
// LabtrustRequiredFailureFamilyCaseIDs are negative admission cases the labtrust QC release suite must reject.
36+
// Unioned with the valid release case, this set is the PF producer contract for pcs-bench ingestion.
37+
var LabtrustRequiredFailureFamilyCaseIDs = []string{
38+
"missing_handoff",
39+
"legacy_handoff_in_release_mode",
40+
"missing_registry",
41+
"wrong_admission_profile",
42+
"rejected_certificate",
43+
"certificate_status_rejected",
44+
"trace_hash_mismatch",
45+
"bundle_hash_mismatch",
46+
"registry_wrong_producer",
47+
"registry_disallowed_status",
48+
"missing_proof_obligation",
49+
"missing_lean_check_result",
50+
"failed_lean_check",
51+
"failed_lean_theorem",
52+
"unauthorized_lean_theorem",
53+
"scientific_memory_import_failure",
54+
}
55+
3556
// writeAdmissionBenchmarkBundle emits a pcs-core benchmark bundle for pcs-bench ingestion.
3657
// When pcsCoreRoot is non-empty, per-artifact validation uses pcs-core/schemas.
3758
func writeAdmissionBenchmarkBundle(repoRoot, pcsCoreRoot, dir string, bundle PCSBenchmarkBundle, executions []benchmarkCaseExecution) error {
@@ -280,6 +301,21 @@ func mustJSONDoc(v any) any {
280301
return doc
281302
}
282303

304+
func benchmarkIngestPathForSummary(repoRoot, outDir string) string {
305+
ingestPath := filepath.Join(outDir, "pcs_bench_ingest.v0.json")
306+
if strings.TrimSpace(repoRoot) == "" {
307+
if root, err := FindRepoRoot(outDir); err == nil {
308+
repoRoot = root
309+
}
310+
}
311+
if repoRoot != "" {
312+
if rel, err := filepath.Rel(repoRoot, ingestPath); err == nil && rel != "" && !strings.HasPrefix(rel, "..") {
313+
ingestPath = rel
314+
}
315+
}
316+
return filepath.ToSlash(ingestPath)
317+
}
318+
283319
// FormatBenchmarkAdmissionSummaryJSON returns a compact JSON summary for --json-summary.
284320
func FormatBenchmarkAdmissionSummaryJSON(run AdmissionBenchmarkSuiteV0, outDir string) (string, error) {
285321
passed := 0
@@ -288,7 +324,7 @@ func FormatBenchmarkAdmissionSummaryJSON(run AdmissionBenchmarkSuiteV0, outDir s
288324
passed++
289325
}
290326
}
291-
ingestPath := filepath.Join(outDir, "pcs_bench_ingest.v0.json")
327+
ingestPath := benchmarkIngestPathForSummary("", outDir)
292328
summary := map[string]any{
293329
"producer_id": "provability-fabric",
294330
"suite_id": pcsBenchmarkSuiteID(run.Workflow),

adapters/pcs/admission_benchmark_flr_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/json"
88
"os"
99
"path/filepath"
10+
"strings"
1011
"testing"
1112

1213
pcs "github.com/SentinelOps-CI/provability-fabric/adapters/pcs"
@@ -82,9 +83,13 @@ func TestExportPCSBenchIngestReferenceArtifact(t *testing.T) {
8283
if _, err := os.Stat(path); err != nil {
8384
t.Skip("reference ingest not materialized; run scripts/export-pcs-benchmark-ingest-reference.sh")
8485
}
86+
pcsCore := pcsCoreRoot(t)
8587
if err := pcs.ValidateBenchmarkArtifactFile(root, path); err != nil {
8688
t.Fatal(err)
8789
}
90+
if err := pcs.ValidateBenchmarkArtifactFileWithPCSCore(pcsCore, path); err != nil {
91+
t.Fatal(err)
92+
}
8893
data, err := os.ReadFile(path)
8994
if err != nil {
9095
t.Fatal(err)
@@ -96,4 +101,23 @@ func TestExportPCSBenchIngestReferenceArtifact(t *testing.T) {
96101
if err := pcs.ValidatePCSBenchIngestSemantics(ingest); err != nil {
97102
t.Fatal(err)
98103
}
104+
if ingest.SuiteID != "pf-labtrust-admission-v0" || ingest.WorkflowID != "hospital_lab.qc_release" {
105+
t.Fatalf("reference ingest ids: suite=%q workflow=%q", ingest.SuiteID, ingest.WorkflowID)
106+
}
107+
if len(ingest.FailureLocalizationReports) == 0 || len(ingest.ExplainQualityReports) == 0 {
108+
t.Fatal("reference ingest missing FLR or explain quality reports")
109+
}
110+
if len(ingest.ArtifactRefs) == 0 {
111+
t.Fatal("reference ingest missing artifact_refs")
112+
}
113+
for _, cmd := range ingest.Commands {
114+
if strings.Contains(cmd.Command, `\`) {
115+
t.Fatalf("reference command must use portable paths: %q", cmd.Command)
116+
}
117+
}
118+
for _, ref := range ingest.ArtifactRefs {
119+
if strings.Contains(ref.Path, `\`) {
120+
t.Fatalf("reference artifact ref path must use forward slashes: %q", ref.Path)
121+
}
122+
}
99123
}

0 commit comments

Comments
 (0)