From 6fda63090d6d5fd196f8e6dfc63d4ea71e4b9be4 Mon Sep 17 00:00:00 2001 From: iperev Date: Mon, 14 Sep 2026 17:00:44 +0200 Subject: [PATCH 1/2] fix(guidance): complete coverage and currentness recipes --- ADOPTION.md | 11 ++ internal/app/command_help.go | 8 + internal/app/currentness_input_guide_test.go | 165 ++++++++++++++++ .../app/evidence_completion_guide_test.go | 181 ++++++++++++++++++ internal/app/receipt_input_guide_test.go | 20 +- .../nativeevidenceguidance/guidance.go | 3 + .../receiptcurrentnessscope/input_guide.go | 94 +++++++++ .../requirementcoverageinput/input_guide.go | 84 ++++++++ internal/tools/releasechange/record_test.go | 8 +- package-lock.json | 4 +- package.json | 2 +- release/change-record.v2.json | 8 +- 12 files changed, 572 insertions(+), 16 deletions(-) create mode 100644 internal/app/currentness_input_guide_test.go create mode 100644 internal/app/evidence_completion_guide_test.go create mode 100644 internal/command/receiptcurrentnessscope/input_guide.go create mode 100644 internal/command/requirementcoverageinput/input_guide.go diff --git a/ADOPTION.md b/ADOPTION.md index e935807b..be9ea8be 100644 --- a/ADOPTION.md +++ b/ADOPTION.md @@ -333,6 +333,8 @@ agentic-proofkit requirement-authoring-plan --help agentic-proofkit native-evidence-guidance --help agentic-proofkit proof-receipt-admission --help agentic-proofkit spec-proof-bundle-admission --help +agentic-proofkit requirement-coverage-input-compose --help +agentic-proofkit receipt-currentness-scope --help ``` The authoring guide connects candidate materialization; native guidance names @@ -388,6 +390,15 @@ discovery, receipt admission and reverse-impact review without a documentation lookup or a new runner. Normal JSON and text guidance stay bounded to their existing slots; the longer recipe is loaded only on explicit help. +The coverage guide connects the original source, binding and inventory inputs +to the coverage composer and then its exact output to the view. Composer success +does not mean coverage passed: retain the downstream failures, unmapped tests +and declared dead zones. Currentness has a separate input guide that binds the +original receipt's recorded subjects to independently captured current subjects. +It does not discover files or authenticate supplied hashes; an inapplicable +scope is not a current passing test. Both templates deliberately reject until +the consumer supplies their missing operands. + Start with one owner-reviewed promise, such as rejecting an empty request. The connected `adopt materialize plan --help` example supplies its requirement, scenario and witness records. Replace fictional paths, selectors, command and diff --git a/internal/app/command_help.go b/internal/app/command_help.go index 29051e71..72265230 100644 --- a/internal/app/command_help.go +++ b/internal/app/command_help.go @@ -9,7 +9,9 @@ import ( "github.com/research-engineering/agentic-proofkit/internal/command/capabilitymapadmission" "github.com/research-engineering/agentic-proofkit/internal/command/nativeevidenceguidance" "github.com/research-engineering/agentic-proofkit/internal/command/proofreceiptadmission" + "github.com/research-engineering/agentic-proofkit/internal/command/receiptcurrentnessscope" "github.com/research-engineering/agentic-proofkit/internal/command/requirementauthoringplan" + "github.com/research-engineering/agentic-proofkit/internal/command/requirementcoverageinput" "github.com/research-engineering/agentic-proofkit/internal/command/specproofbundleadmission" "github.com/research-engineering/agentic-proofkit/internal/kernel/cliexec" ) @@ -130,6 +132,12 @@ func commandUsageWithRenderer(descriptor commandDescriptor, renderer cliexec.Ren if descriptor.name == "native-evidence-guidance" { lines = append(lines, "", strings.TrimSuffix(nativeevidenceguidance.TraceabilityGuide(renderer), "\n")) } + if descriptor.name == "requirement-coverage-input-compose" { + lines = append(lines, "", strings.TrimSuffix(requirementcoverageinput.InputGuide(renderer), "\n")) + } + if descriptor.name == "receipt-currentness-scope" { + lines = append(lines, "", strings.TrimSuffix(receiptcurrentnessscope.InputGuide(renderer), "\n")) + } if pointer := adoptionGuidePointer(descriptor.name); pointer != "" { lines = append(lines, "", "CLI authoring continuation:", " "+renderer.DisplayCommand("adopt", "materialize", "plan", "--help"), diff --git a/internal/app/currentness_input_guide_test.go b/internal/app/currentness_input_guide_test.go new file mode 100644 index 00000000..7b53b1ee --- /dev/null +++ b/internal/app/currentness_input_guide_test.go @@ -0,0 +1,165 @@ +package app + +import ( + "crypto/sha256" + "fmt" + "os" + "path/filepath" + "reflect" + "slices" + "testing" + + "github.com/research-engineering/agentic-proofkit/internal/kernel/cliexec" +) + +// This is the fixture consumer's mapping policy, not a public receipt adapter. +func checkCurrentnessGuideReceiptHandoff(t *testing.T, receipts, binding map[string]any, root string) { + t.Helper() + input, help := receiptHelpTemplate(t, "receipt-currentness-scope") + args := fillGuideOperands(t, guideCommands(t, help, "Receipt currentness input guide:", cliexec.PathRenderer())[0], map[string]string{"": "-"}) + r := receipt(receipts) + var bound map[string]any + for _, raw := range binding["bindings"].([]any) { + row := raw.(map[string]any) + if slices.Contains(row["commandIds"].([]any), r["receiptKind"]) && slices.Contains(r["witnessSelectors"].([]any), row["scenarioId"]) { + bound = row + break + } + } + if bound == nil { + t.Fatal("fixture has no qualified binding for the receipt") + } + var owner any + for _, raw := range binding["requirements"].([]any) { + row := raw.(map[string]any) + if row["requirementId"] == bound["requirementId"] { + owner = row["ownerId"] + } + } + input["admissionId"] = "example.currentness" + item := input["obligationReceipts"].([]any)[0].(map[string]any) + identity := map[string]any{ + "receiptId": r["receiptId"], "requirementId": bound["requirementId"], "proofRouteRef": r["receiptKind"], + "owner": owner, "obligationId": "example.obligation", + } + for key, value := range identity { + item[key] = value + } + item["reason"] = "Compare retained fixture subjects under explicit consumer policy." + item["evidenceRefs"] = r["evidenceRefs"] + checks := []any{} + recorded := map[string]any{} + fields := []string{"commandDigest", "environmentDigest", "preconditionDigest", "proofBindingDigest", "toolchainDigest", "witnessSelectorDigest"} + for index, field := range fields { + data, err := os.ReadFile(filepath.Join(root, field+".json")) + if err != nil { + t.Fatal(err) + } + actual := fmt.Sprintf("sha256:%x", sha256.Sum256(data)) + if actual != r[field] { + t.Fatal("retained bytes are not the receipt's recorded subject: " + field) + } + checks = append(checks, map[string]any{ + "checkId": fmt.Sprintf("example.check.%d", index), "checkClass": field, + "recordedDigest": r[field], "currentDigest": actual, + "evidenceRefs": []any{field + ".json"}, "nonClaims": []any{"Synthetic consumer capture is not authenticated."}, + }) + recorded[field] = r[field] + } + item["currentnessChecks"] = checks + scope := item["scopeChecks"].([]any)[0].(map[string]any) + for key, value := range map[string]any{ + "checkId": "example.scope", "scopeClass": "binding_scope", "admissionState": "admitted_current_scope", + "recordedScopeDigest": r["proofBindingDigest"], "currentScopeDigest": r["proofBindingDigest"], + "reason": "The fixture retains the same admitted binding scope.", "evidenceRefs": []any{"proofBindingDigest.json"}, + } { + scope[key] = value + } + if !currentnessGuideHandoffMatches(item, identity, recorded) { + t.Fatal("receipt-to-currentness handoff lost identity or recorded operands") + } + for _, mutation := range []string{"receipt", "recorded"} { + wrong := cloneMap(t, item) + if mutation == "receipt" { + wrong["receiptId"] = "example.other-receipt" + } else { + wrong["currentnessChecks"].([]any)[0].(map[string]any)["recordedDigest"] = fmt.Sprintf("sha256:%x", sha256.Sum256([]byte("foreign recorded subject"))) + } + if currentnessGuideHandoffMatches(wrong, identity, recorded) { + t.Fatalf("consumer mapping accepted a substituted %s", mutation) + } + } + positive := currentnessGuideReport(t, args, input, 0) + assertGuideCount(t, positive, "currentReceiptCount", 1) + assertGuideCount(t, positive, "staleReceiptCount", 0) + for index, field := range fields { + data, err := os.ReadFile(filepath.Join(root, field+".json")) + if err != nil { + t.Fatal(err) + } + changed := cloneMap(t, input) + current := changed["obligationReceipts"].([]any)[0].(map[string]any)["currentnessChecks"].([]any)[index].(map[string]any) + subject := decodeCLIJSON(t, string(data)) + switch field { + case "commandDigest": + subject.(map[string]any)["cwd"] = root + "-changed" + case "environmentDigest": + subject.(map[string]any)["class"] = "ci-go" + case "preconditionDigest": + subject.(map[string]any)["syntheticPolicy"] = false + case "proofBindingDigest": + subject.(map[string]any)["bindingId"] = "example.changed-binding" + case "toolchainDigest", "witnessSelectorDigest": + subject.([]any)[0] = "example.changed" + } + current["currentDigest"] = fmt.Sprintf("sha256:%x", sha256.Sum256(adoptionHelpJSON(t, subject))) + result := currentnessGuideReport(t, args, changed, 1) + assertGuideCount(t, result, "staleReceiptCount", 1) + assertGuideCount(t, result, "scopeFindingCount", 0) + } + for _, state := range []string{"not_admitted_current_scope", "unknown_current_scope", "not_applicable", "scope_digest"} { + changed := cloneMap(t, input) + changedScope := changed["obligationReceipts"].([]any)[0].(map[string]any)["scopeChecks"].([]any)[0].(map[string]any) + wantCode := 1 + if state == "scope_digest" { + changedScope["currentScopeDigest"] = fmt.Sprintf("sha256:%x", sha256.Sum256([]byte("independent changed scope"))) + } else { + changedScope["admissionState"] = state + } + if state == "not_applicable" { + wantCode = 0 + } + result := currentnessGuideReport(t, args, changed, wantCode) + assertGuideCount(t, result, "staleReceiptCount", 0) + if state == "not_applicable" { + assertGuideCount(t, result, "notApplicableCount", 1) + if result["ruleResults"].([]any)[0].(map[string]any)["status"] != "skipped" { + t.Fatal("inapplicability became a passing rule") + } + } else { + assertGuideCount(t, result, "unknownScopeCount", 1) + assertGuideCount(t, result, "scopeFindingCount", 1) + } + } + if restored := currentnessGuideReport(t, args, input, 0); !reflect.DeepEqual(positive, restored) { + t.Fatal("restored subjects did not recover the positive result") + } +} + +func currentnessGuideHandoffMatches(item, identity, recorded map[string]any) bool { + for key, value := range identity { + if !reflect.DeepEqual(item[key], value) { + return false + } + } + actual := map[string]any{} + for _, raw := range item["currentnessChecks"].([]any) { + check := raw.(map[string]any) + class := check["checkClass"].(string) + if _, exists := actual[class]; exists { + return false + } + actual[class] = check["recordedDigest"] + } + return reflect.DeepEqual(actual, recorded) +} diff --git a/internal/app/evidence_completion_guide_test.go b/internal/app/evidence_completion_guide_test.go new file mode 100644 index 00000000..7abb4573 --- /dev/null +++ b/internal/app/evidence_completion_guide_test.go @@ -0,0 +1,181 @@ +package app + +import ( + "bytes" + "fmt" + "reflect" + "strings" + "testing" + + "github.com/research-engineering/agentic-proofkit/internal/kernel/cliexec" +) + +func TestEvidenceCompletionGuidesAreLazyAndCarrierBound(t *testing.T) { + for _, item := range []struct { + command, marker string + commands [][]string + }{ + {"requirement-coverage-input-compose", "Declaration coverage input guide:", [][]string{ + {"requirement-coverage-input-compose", "--input", ""}, + {"requirement-coverage-view", "--input", "", "--format", "json"}, + }}, + {"receipt-currentness-scope", "Receipt currentness input guide:", [][]string{ + {"receipt-currentness-scope", "--input", ""}, + }}, + } { + t.Run(item.command, func(t *testing.T) { + packet, _ := receiptHelpTemplate(t, item.command) + code, output, diagnostic := executeAgentWorkflowCLI(t, []string{item.command, "--input", "-"}, bytes.NewReader(adoptionHelpJSON(t, packet)), PresentationCapabilities{}) + if code != 1 || output != "" || diagnostic == "" { + t.Fatal("unfilled template must not invent admissible evidence") + } + for _, carrier := range []struct{ profile, python string }{ + {cliexec.ProfilePath, ""}, {cliexec.ProfileNPMOffline, ""}, {cliexec.ProfilePythonModule, "/example/python 3"}, + } { + renderer, err := cliexec.AdmitLauncherProfile(carrier.profile, carrier.python) + if err != nil { + t.Fatal(err) + } + descriptor, _ := commandDescriptorFor(item.command) + if got := guideCommands(t, commandUsageWithRenderer(descriptor, renderer), item.marker, renderer); !reflect.DeepEqual(got, item.commands) { + t.Fatalf("guide argv differs: %v", got) + } + } + for _, args := range [][]string{{"help"}, {"help", "families"}, {"native-evidence-guidance"}, {"native-evidence-guidance", "--help"}, {"changed-path-set", "--help"}} { + _, output, _ := executeAgentWorkflowCLI(t, args, panicReader{}, PresentationCapabilities{}) + if strings.Contains(output, item.marker) { + t.Fatalf("nested recipe must stay lazy: %v", args) + } + } + }) + } +} + +func TestCoverageGuideComposesActualInputsAndRetainsGaps(t *testing.T) { + input, help := receiptHelpTemplate(t, "requirement-coverage-input-compose") + materialization := adoptionHelpPacket(t, t.TempDir(), "fresh") + input["composerInputId"], input["viewInputId"] = "example.compose", "example.view" + input["selectedOwnerIds"] = []any{"example.backend"} + input["requirementSource"] = materialization["requirementSources"].([]any)[0] + input["requirementProofBinding"] = materialization["requirementProofBinding"].(map[string]any)["record"] + input["testEvidenceInventory"] = materialization["testEvidenceInventory"].(map[string]any)["record"] + universe := input["coverageUniverse"].(map[string]any) + universe["universeId"], universe["completenessDeclaration"] = "example.universe", "selected_owner_surfaces" + universe["ownerIds"] = []any{"example.backend"} + universe["commandRefs"] = []any{"example.test.requests"} + universe["codeSurfaces"] = []any{map[string]any{"surfaceId": "example.code", "ownerId": "example.backend", "path": "src"}} + universe["specSurfaces"] = []any{map[string]any{"surfaceId": "example.spec", "ownerId": "example.backend", "path": "docs/specs/requests/requirements.v1.json"}} + universe["testSurfaces"] = []any{map[string]any{"surfaceId": "example.test", "ownerId": "example.backend", "path": "src/request_test.go"}} + commands := guideCommands(t, help, "Declaration coverage input guide:", cliexec.PathRenderer()) + composeArgs := fillGuideOperands(t, commands[0], map[string]string{"": "-"}) + viewArgs := fillGuideOperands(t, commands[1], map[string]string{"": "-"}) + for _, variant := range []string{"complete", "missing", "unmapped", "restored"} { + t.Run(variant, func(t *testing.T) { + candidate := decodeCLIJSON(t, string(adoptionHelpJSON(t, input))).(map[string]any) + inventory := candidate["testEvidenceInventory"].(map[string]any) + if variant == "missing" { + inventory["entries"] = []any{} + } + if variant == "unmapped" { + inventory["entries"] = append(inventory["entries"].([]any), map[string]any{ + "testId": "example.test.unmapped", "ownerId": "example.backend", "sourcePath": "src/unmapped_test.go", + "selector": "src/unmapped_test.go::TestUnmapped", "evidenceClass": "helper_or_testkit", + "requirementRefs": []any{}, "ownerInvariantRefs": []any{}, "commandRefs": []any{}, "witnessRefs": []any{}, + "falsifier": nil, "oracle": nil, "nonClaims": []any{"Unmapped fixture is not a declared semantic test."}, + }) + } + code, wire, diagnostic := executeAgentWorkflowCLI(t, composeArgs, bytes.NewReader(adoptionHelpJSON(t, candidate)), PresentationCapabilities{}) + if code != 0 || diagnostic != "" { + t.Fatalf("compose failed before downstream: %d %s", code, diagnostic) + } + composed := decodeCLIJSON(t, wire).(map[string]any) + if !equalCLIJSON(t, composed["requirementSource"], candidate["requirementSource"]) { + t.Fatal("composer lost source operands") + } + binding := composed["requirementProofBinding"].(map[string]any)["bindings"].([]any)[0].(map[string]any) + for field, want := range map[string]any{ + "requirementId": "REQ-EXAMPLE-001", "scenarioId": "example.requests.empty", "witnessId": "example.witness.empty", + "witnessPath": "src/request_test.go", "commandIds": []any{"example.test.requests"}, "environmentClasses": []any{"local-go"}, + } { + if !reflect.DeepEqual(binding[field], want) { + t.Fatalf("composer changed qualified %s: %v", field, binding[field]) + } + } + composedUniverse := composed["coverageUniverse"].(map[string]any) + for _, field := range []string{"ownerIds", "codeSurfaces", "specSurfaces", "commandRefs", "completenessDeclaration", "nonClaims"} { + if !reflect.DeepEqual(composedUniverse[field], universe[field]) { + t.Fatalf("composer changed declared universe %s", field) + } + } + // Consume the actual wire bytes, not a manually rebuilt view input. + code, output, diagnostic := executeAgentWorkflowCLI(t, viewArgs, strings.NewReader(wire), PresentationCapabilities{}) + if diagnostic != "" { + t.Fatalf("view input did not round trip: %s", diagnostic) + } + view := decodeCLIJSON(t, output).(map[string]any) + wantCode, wantState := 0, "passed" + if variant == "missing" { + wantCode, wantState = 1, "failed" + } + if code != wantCode || view["state"] != wantState || view["authority"] != "lookup_only" || view["viewKind"] != "proofkit.requirement-coverage-view" { + t.Fatalf("view outcome differs: %d %v", code, view) + } + row := view["requirementCoverage"].([]any)[0].(map[string]any) + wantIDs := []any{"example.test.empty"} + if variant == "missing" { + wantIDs = []any{} + } + if row["requirementId"] != "REQ-EXAMPLE-001" || row["ownerId"] != "example.backend" || row["specPath"] != "docs/specs/requests/requirements.v1.json" || !reflect.DeepEqual(row["testIds"], wantIDs) { + t.Fatalf("view changed identity or test linkage: %v", row) + } + if variant == "missing" && !reflect.DeepEqual(view["deadZones"], []any{map[string]any{ + "deadZoneKind": "unbound_test_surface", "ownerId": "example.backend", "path": "src/request_test.go", "surfaceId": "example.test", + }}) { + t.Fatalf("missing test lost its declared coordinates: %v", view["deadZones"]) + } + unmapped := view["unmappedTests"].([]any) + if variant == "unmapped" { + if len(unmapped) != 1 || unmapped[0].(map[string]any)["testId"] != "example.test.unmapped" { + t.Fatalf("unmapped test disappeared: %v", unmapped) + } + } else if len(unmapped) != 0 { + t.Fatalf("unexpected unmapped tests: %v", unmapped) + } + }) + } + for _, field := range []string{"compactProofContract", "normalizedTestEvidenceInventory"} { + candidate := cloneMap(t, input) + candidate[field] = nil + code, output, diagnostic := executeAgentWorkflowCLI(t, composeArgs, bytes.NewReader(adoptionHelpJSON(t, candidate)), PresentationCapabilities{}) + if code != 1 || output != "" || diagnostic == "" { + t.Fatal("direct-mode foreign key must be absent, not null: " + field) + } + } +} + +func currentnessGuideReport(t *testing.T, args []string, input map[string]any, wantCode int) map[string]any { + t.Helper() + code, output, diagnostic := executeAgentWorkflowCLI(t, args, bytes.NewReader(adoptionHelpJSON(t, input)), PresentationCapabilities{}) + if code != wantCode || diagnostic != "" { + t.Fatalf("currentness result differs: %d %q", code, diagnostic) + } + result := decodeCLIJSON(t, output).(map[string]any) + if result["reportKind"] != "proofkit.receipt-currentness-scope-admission" || result["reportId"] != "example.currentness" { + t.Fatalf("currentness report identity differs: %v", result) + } + wantState := "passed" + if wantCode != 0 { + wantState = "failed" + } + if result["state"] != wantState { + t.Fatalf("currentness state differs: %v", result["state"]) + } + return result +} + +func assertGuideCount(t *testing.T, result map[string]any, field string, want int) { + t.Helper() + if got := fmt.Sprint(result["summary"].(map[string]any)[field]); got != fmt.Sprint(want) { + t.Fatalf("%s=%s, want %d", field, got, want) + } +} diff --git a/internal/app/receipt_input_guide_test.go b/internal/app/receipt_input_guide_test.go index 955f05f4..9de4feb8 100644 --- a/internal/app/receipt_input_guide_test.go +++ b/internal/app/receipt_input_guide_test.go @@ -90,12 +90,21 @@ func TestReceiptInputGuideNativeHelper(t *testing.T) { return } switch os.Args[len(os.Args)-1] { - case "passed": + case "passed", "failed": + accept := func(request string) bool { return request != "" } + if os.Args[len(os.Args)-1] == "failed" { + accept = func(string) bool { return true } + } + if !accept("valid") { + fmt.Fprintln(os.Stderr, "nonempty control rejected") + os.Exit(2) + } + if accept("") { + fmt.Print("empty input accepted\n") + os.Exit(1) + } fmt.Print("empty input rejected\n") os.Exit(0) - case "failed": - fmt.Print("empty input accepted\n") - os.Exit(1) default: os.Exit(2) } @@ -226,6 +235,7 @@ func TestReceiptInputGuideExecutionAndBundleChain(t *testing.T) { if !bytes.Equal(payload, adoptionHelpJSON(t, packet)) { t.Fatal("composition modified the source receipt") } + checkCurrentnessGuideReceiptHandoff(t, packet, binding, root) checkReceiptGuideMutations(t, packet, bundle) }) } @@ -315,7 +325,7 @@ func TestNativeTraceabilityGuideIsLazyAndCarrierBound(t *testing.T) { actualLazy = append(actualLazy, line) } } - for _, command := range [][]string{{"adopt", "materialize", "plan", "--help"}, {"requirement-authoring-plan", "--help"}, {"proof-receipt-admission", "--help"}, {"spec-proof-bundle-admission", "--help"}, {"requirement-impact-input-compose", "--help"}} { + for _, command := range [][]string{{"adopt", "materialize", "plan", "--help"}, {"requirement-authoring-plan", "--help"}, {"requirement-coverage-input-compose", "--help"}, {"proof-receipt-admission", "--help"}, {"spec-proof-bundle-admission", "--help"}, {"receipt-currentness-scope", "--help"}, {"requirement-impact-input-compose", "--help"}} { expectedLazy = append(expectedLazy, " "+renderer.DisplayCommand(command...)) code, output, diagnostic := executeAgentWorkflowCLI(t, command, panicReader{}, PresentationCapabilities{}) if code != 0 || output == "" || diagnostic != "" { diff --git a/internal/command/nativeevidenceguidance/guidance.go b/internal/command/nativeevidenceguidance/guidance.go index 173c6991..279fb22e 100644 --- a/internal/command/nativeevidenceguidance/guidance.go +++ b/internal/command/nativeevidenceguidance/guidance.go @@ -77,6 +77,8 @@ Repository-specific adapter template (implement under consumer authority): Map requirementRefs, witnessRefs and commandRefs from the same matched rows; preserve unbound rows for review. Admission of separate ID sets is not proof of a valid qualified edge. Use currentness and native execution separately. + Inspect declaration coverage with the connected direct-input recipe: + {{cli}} requirement-coverage-input-compose --help 5. Run an independent positive control and a behavior-breaking near miss using approved argv, root, environment and bounds from the evidence-guidance slots. Also remove a discovered test, add an unmapped test, and replay evidence @@ -87,6 +89,7 @@ Repository-specific adapter template (implement under consumer authority): structurally valid failed/not-run receipt into a successful native result: {{cli}} proof-receipt-admission --help {{cli}} spec-proof-bundle-admission --help + {{cli}} receipt-currentness-scope --help Declaration coverage, actual execution, currentness, producer trust and merge approval are separate predicates. No step here grants those powers. 7. For a changed requirement, test, binding, command or environment, retain diff --git a/internal/command/receiptcurrentnessscope/input_guide.go b/internal/command/receiptcurrentnessscope/input_guide.go new file mode 100644 index 00000000..0cfac53e --- /dev/null +++ b/internal/command/receiptcurrentnessscope/input_guide.go @@ -0,0 +1,94 @@ +package receiptcurrentnessscope + +import ( + "strings" + + "github.com/research-engineering/agentic-proofkit/internal/kernel/cliexec" +) + +// InputGuide explains caller-owned capture without claiming file discovery. +func InputGuide(renderer cliexec.Renderer) string { + return strings.ReplaceAll(inputGuide, "{{cli}}", renderer.DisplayCommand()) +} + +const inputGuide = `Receipt currentness input guide: + Currentness compares caller-supplied identities. It does not read files, + compute receipt age, authenticate a producer, execute tests or approve merge. + First retain the original receipt input and the exact subjects it recorded: + {{cli}} proof-receipt-admission --help + Do not substitute that admission report for the receipt. Preserve receiptId; + select requirementId and proofRouteRef from its admitted binding route, and + obligationId/owner from the consumer's obligation policy. Check the qualified + relation, not separate sets of IDs. This command cannot verify that mapping + against an external receipt or detect deliberately invented equal digests. + + For every dependency relevant to reuse, supply a uniquely identified + currentnessChecks entry. Copy recordedDigest from the corresponding receipt + subject (binding, command, environment, precondition, selectors, toolchain, + or applicable dependency/lockfile). Independently capture current bytes with + the same encoding/version; calculate currentDigest from those actual bytes. + Never copy the old digest into both fields to obtain a pass. If a required + subject is unavailable, stop: this template cannot establish its currentness. + Keep sanitized source bytes/encoding and evidenceRefs for independent replay. + Do not claim whole-repository freshness from an incomplete dependency list. + + Every obligation needs nonempty currentnessChecks and scopeChecks. Check and + obligation IDs must be unique; checkClass/scopeClass name consumer-owned rules. + Choose scope admission from evidence: admitted_current_scope, + not_admitted_current_scope, unknown_current_scope, or not_applicable. + Include both recordedScopeDigest and currentScopeDigest keys. Admission allows + null values, but null does not prove equal scope. This reuse recipe requires + both observed digests for an equal-scope claim; otherwise use unknown scope + or a separately justified consumer policy. Digests are sha256:<64 lowercase + hex digits>. Paths are repository-relative; sort unique evidenceRefs and + nonClaims. Every evidenceRefs and nonClaims array must be nonempty; fill it + from retained evidence and actual limitations. Never include secrets. + +Currentness template (required null operands deliberately reject admission): +` + "```json\n" + `{ + "schemaVersion": 1, + "admissionId": null, + "obligationReceipts": [{ + "obligationId": null, + "requirementId": null, + "proofRouteRef": null, + "receiptId": null, + "owner": null, + "reason": null, + "currentnessChecks": [{ + "checkId": null, + "checkClass": null, + "recordedDigest": null, + "currentDigest": null, + "evidenceRefs": null, + "nonClaims": ["Consumer declarations require independent evidence."] + }], + "scopeChecks": [{ + "checkId": null, + "scopeClass": null, + "admissionState": null, + "recordedScopeDigest": null, + "currentScopeDigest": null, + "reason": null, + "evidenceRefs": null, + "nonClaims": ["Consumer declarations require independent evidence."] + }], + "evidenceRefs": null, + "nonClaims": ["Current subjects and scope are supplied by the consumer."] + }], + "nonClaims": ["Currentness is not producer authentication or merge approval."] +} +` + "```\n" + ` + Replace with the completed packet path, or - for stdin: + {{cli}} receipt-currentness-scope --input + Preserve stdout, stderr and exit independently. Malformed input exits1 with + a diagnostic; stale or unknown/not-admitted scope exits1 with a failed JSON + report. Inspect receiptCurrentnessScope diagnostics and ruleResults: digest + mismatch yields stale_receipt; scope mismatch yields unknown_scope. + An all-not_applicable scope can exit0 with skipped ruleResults: this is not + current execution evidence. Even current inputs may describe a failed or + not-run receipt; retain the original receipt status and separate trust policy. + Restore recorded subjects to test recovery, or run fresh approved checks for + intentionally changed subjects. Never replace historical evidence with + fabricated success or treat this comparison as automatic filesystem capture. +` diff --git a/internal/command/requirementcoverageinput/input_guide.go b/internal/command/requirementcoverageinput/input_guide.go new file mode 100644 index 00000000..2d0e1bdc --- /dev/null +++ b/internal/command/requirementcoverageinput/input_guide.go @@ -0,0 +1,84 @@ +package requirementcoverageinput + +import ( + "strings" + + "github.com/research-engineering/agentic-proofkit/internal/kernel/cliexec" +) + +// InputGuide owns the direct-mode recipe, not the child schemas or test policy. +func InputGuide(renderer cliexec.Renderer) string { + return strings.ReplaceAll(inputGuide, "{{cli}}", renderer.DisplayCommand()) +} + +const inputGuide = `Declaration coverage input guide: + This recipe uses direct inputs, not compact proof contracts or source sets. + Obtain connected source, binding and inventory shapes without writing files: + {{cli}} adopt materialize plan --help + Copy whole input records from that packet, not their admission reports: + requirementSource <- /requirementSources/0 + requirementProofBinding <- /requirementProofBinding/record + testEvidenceInventory <- /testEvidenceInventory/record + Its sourcePlan may stay null for this read-only operation. The inventory must + use caller_owned_inventory. Do not include compactProofContract or + normalizedTestEvidenceInventory, even as null, in this direct-mode input. + + Fill required nulls from reviewed records and actual native discovery. + selectedOwnerIds must equal coverageUniverse.ownerIds; every inventory entry + must belong to those owners. Choose full_repository only with a complete + repository inventory; selected_owner_surfaces makes declared gaps failures; + selected_paths_advisory keeps dead-zone findings advisory, not completeness. + Do not narrow scope just to hide an absent test. The CLI does not scan files. + Give each surface a stable surfaceId, ownerId and repository-relative path. + Include the required test surfaces independently of discovered entries so a + missing test remains visible. Include expected command IDs in commandRefs. + The composer adds inventory paths/commands; omission is not proof of absence. + Sort unique owner/command IDs and nonClaims; preserve source/binding identity. + For another source repeat this operation with its exact matching inputs. + +Coverage template (required null operands deliberately reject admission): +` + "```json\n" + `{ + "schemaVersion": 2, + "composerInputId": null, + "viewInputId": null, + "selectedOwnerIds": null, + "requirementSource": null, + "requirementProofBinding": null, + "testEvidenceInventory": null, + "coverageUniverse": { + "schemaVersion": 1, + "universeId": null, + "authority": "caller_owned_inventory", + "completenessDeclaration": null, + "ownerIds": null, + "codeSurfaces": [], + "specSurfaces": [], + "testSurfaces": [], + "commandRefs": [], + "nonClaims": ["Declared scope does not prove discovery or test execution."] + }, + "ownerInvariantRegistry": null, + "localEnvironmentPolicy": null, + "options": null +} +` + "```\n" + ` + Empty surface arrays are placeholders, not a claim that no surfaces exist. + A surface is {"surfaceId":"","ownerId":"","path":""}. + ownerInvariantRegistry may stay null when no ownerInvariantRefs are used. + localEnvironmentPolicy may stay null in direct mode; when supplied it is + {"authority":"caller_provided","localEnvironmentClasses":[""]}. + options may stay null. Never insert secrets into paths, records or diagnostics. + + Store the completed input at . Capture the first command's + stdout bytes as only after exit0, preserving stderr separately: + {{cli}} requirement-coverage-input-compose --input + {{cli}} requirement-coverage-view --input --format json + Do not pass the compose request to the view or rebuild its output by hand. + Composer exit0 proves downstream input admission, not coverage success. + The view may exit1 with JSON state failed; retain failures, warnings, + unmappedTests and deadZones. An unmapped test can be reported without causing + exit1: the consumer decides whether it blocks. A declared route is not a + proved assertion or executed test. Do not relabel these observations as pass. + Native execution and receipt/currentness/trust admission are separate: + {{cli}} native-evidence-guidance --help +` diff --git a/internal/tools/releasechange/record_test.go b/internal/tools/releasechange/record_test.go index 2ec00b9a..6f46f220 100644 --- a/internal/tools/releasechange/record_test.go +++ b/internal/tools/releasechange/record_test.go @@ -197,7 +197,7 @@ func TestCurrentChangeRecordNamesReviewedSemanticChanges(t *testing.T) { var currentBreakingChanges = []Change{} var currentAdditions = []Change{ - {ChangeID: "proofkit.readme.workflow-clarity", Summary: "Simplify the README overview while preserving repository-owned specification, execution and approval boundaries. Link to the existing connected materialization help, clarify declaration-only browsing and align the first input explanation with requirement-source admission. Protected runnable examples, runtime behavior, dependencies, supported platforms and public CLI contracts are unchanged."}, + {ChangeID: "proofkit.guidance.coverage-currentness", Summary: "Connect lazy CLI input recipes for declaration coverage and receipt currentness to the native traceability cookbook. Preserve composer-to-view handoff, original receipt subjects, scope decisions and separate execution, currentness and trust predicates. Add causal recipe tests without changing runtime admission, ordinary guidance outputs, machine CLI contracts, dependencies or supported platforms."}, } var currentMigrationSteps = []string{} @@ -220,7 +220,7 @@ func validateCurrentChangeRecord(record Record, notes string) error { func currentExpectedReleaseNotes() string { lines := []string{ - "# @research-engineering/agentic-proofkit 0.14.16", + "# @research-engineering/agentic-proofkit 0.14.17", "", "## Breaking Contract Changes", "", @@ -273,7 +273,7 @@ func currentExpectedReleaseNotes() string { "Primary npm channel:", "", "```bash", - "npm install --save-dev --save-exact @research-engineering/agentic-proofkit@0.14.16", + "npm install --save-dev --save-exact @research-engineering/agentic-proofkit@0.14.17", "```", "", "Pre-1.0 npm consumers must keep this dependency exact-pinned.", @@ -285,7 +285,7 @@ func currentExpectedReleaseNotes() string { "## Rollback", "", "- First follow the migration and persistent-state compatibility restrictions above; changing a package pin does not roll back repository state.", - "- Pin npm consumers to the previous admitted version 0.14.15 with `npm install --save-dev --save-exact @research-engineering/agentic-proofkit@0.14.15`.", + "- Pin npm consumers to the previous admitted version 0.14.16 with `npm install --save-dev --save-exact @research-engineering/agentic-proofkit@0.14.16`.", "- Treat local package artifacts as candidates until registry identity is proven.", ) return strings.Join(lines, "\n") + "\n" diff --git a/package-lock.json b/package-lock.json index e8f3a1d4..35b1b1a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@research-engineering/agentic-proofkit", - "version": "0.14.16", + "version": "0.14.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@research-engineering/agentic-proofkit", - "version": "0.14.16", + "version": "0.14.17", "cpu": [ "arm64", "x64" diff --git a/package.json b/package.json index 43f47cf5..97e02a1a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@research-engineering/agentic-proofkit", "description": "Reusable proof profile, report, graph, and witness-planning primitives.", - "version": "0.14.16", + "version": "0.14.17", "type": "module", "license": "MIT", "sideEffects": false, diff --git a/release/change-record.v2.json b/release/change-record.v2.json index d826d037..7ced6fca 100644 --- a/release/change-record.v2.json +++ b/release/change-record.v2.json @@ -1,13 +1,13 @@ { "schemaVersion": 2, - "previousVersion": "0.14.15", - "version": "0.14.16", + "previousVersion": "0.14.16", + "version": "0.14.17", "changeClass": "compatible", "breakingChanges": [], "additions": [ { - "changeId": "proofkit.readme.workflow-clarity", - "summary": "Simplify the README overview while preserving repository-owned specification, execution and approval boundaries. Link to the existing connected materialization help, clarify declaration-only browsing and align the first input explanation with requirement-source admission. Protected runnable examples, runtime behavior, dependencies, supported platforms and public CLI contracts are unchanged." + "changeId": "proofkit.guidance.coverage-currentness", + "summary": "Connect lazy CLI input recipes for declaration coverage and receipt currentness to the native traceability cookbook. Preserve composer-to-view handoff, original receipt subjects, scope decisions and separate execution, currentness and trust predicates. Add causal recipe tests without changing runtime admission, ordinary guidance outputs, machine CLI contracts, dependencies or supported platforms." } ], "migration": { From f47f3bda0026e6951e4cd9d708066a721643b6bd Mon Sep 17 00:00:00 2001 From: iperev Date: Mon, 14 Sep 2026 17:10:19 +0200 Subject: [PATCH 2/2] fix(contract): refresh native source provenance for guidance --- internal/app/cli_contract_test.go | 2 +- internal/app/command_contract_generated.go | 30 ++++++++-------- .../stackpreset/preset_ids_generated.go | 2 +- internal/tools/releasechange/record_test.go | 2 +- proofkit/cli-contract.v2.json | 34 +++++++++---------- release/change-record.v2.json | 2 +- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/internal/app/cli_contract_test.go b/internal/app/cli_contract_test.go index 72afd138..b913826e 100644 --- a/internal/app/cli_contract_test.go +++ b/internal/app/cli_contract_test.go @@ -24,7 +24,7 @@ import ( ) const ( - cliContractPublicABISHA256 = "147318e2449fd7f6cf51e81cba35d16a20c95fd82ab45ba4feadc1ced45eb67d" + cliContractPublicABISHA256 = "2867ea2c8caf03e5b88fa46cabee0697e781452af2a8049e70660796730d0b66" maxAggregateFileReadBytesForContractTest = 64 << 20 maxPackageManifestBytesForContractTest = 256 << 10 maxSourceFileBytesForContractTest = 8 << 20 diff --git a/internal/app/command_contract_generated.go b/internal/app/command_contract_generated.go index 2f0aca3d..cf3f8318 100644 --- a/internal/app/command_contract_generated.go +++ b/internal/app/command_contract_generated.go @@ -1,7 +1,7 @@ // Code generated by internal/tools/commandcontractgen; DO NOT EDIT. package app -const commandContractSourceSHA256 = "18144447341a97e4d498f99839fb45b252fedd1e98429e6f16c3a0f5b7a6ba94" +const commandContractSourceSHA256 = "40e21bb074eea37dba970d08cf06e1c5ee0ec1c1d7404fad1e7e28490a3924c4" type generatedCommandContractMetadata struct { InputContractSHA256 string @@ -12,15 +12,15 @@ type generatedCommandContractMetadata struct { } var generatedCommandContractMetadataByName = map[string]generatedCommandContractMetadata{ - "adopt-materialize-apply": {InputContractSHA256: "sha256:ff3aee6b2420c04d19afdf3a72ef2a73b731f25cc1abcb0f3fe1ffd0fc9ed06b", InputSchemaSummary: []string{"schemaVersion=1", "owner-admitted adoption plan, requirement sources, proof bindings, and direct test inventory", "root-shape-only definition proofkit.adoption-materialization.apply-input.v1.root-shape; nested fields, types, cardinalities, and cross-record closure remain native-owner claims"}, OutputContractSHA256: "sha256:84d40be39bab36983222afcde7d31115346262fa437d7d9eede390bc64aa0a69", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"adopt", "materialize", "apply"}}, - "adopt-materialize-plan": {InputContractSHA256: "sha256:484d8d867ff1080d14f14c9b82c9e02ce0bb10ded7713b8098b5a2f5128fefc2", InputSchemaSummary: []string{"schemaVersion=1", "owner-admitted adoption plan, requirement sources, proof bindings, and direct test inventory", "root-shape-only definition proofkit.adoption-materialization.plan-input.v1.root-shape; nested fields, types, cardinalities, and cross-record closure remain native-owner claims"}, OutputContractSHA256: "sha256:fbc9e87bd9794e1e2c15da9704a1a87eed1512f720033193237fb73a373f7c6c", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"adopt", "materialize", "plan"}}, - "adopt-materialize-recover": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:ed3a270b6a7256d59e59c4fb1af60dcb91097acc34e3d50fa44d47b78532d738", FlagChoices: map[string][]string{"--action": []string{"resume", "rollback"}, "--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"adopt", "materialize", "recover"}}, + "adopt-materialize-apply": {InputContractSHA256: "sha256:ff3aee6b2420c04d19afdf3a72ef2a73b731f25cc1abcb0f3fe1ffd0fc9ed06b", InputSchemaSummary: []string{"schemaVersion=1", "owner-admitted adoption plan, requirement sources, proof bindings, and direct test inventory", "root-shape-only definition proofkit.adoption-materialization.apply-input.v1.root-shape; nested fields, types, cardinalities, and cross-record closure remain native-owner claims"}, OutputContractSHA256: "sha256:0b6422c73221f2d45ab30c523bd467f8ca7e5871ad299ef4a4a65d2bb2d3f2b6", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"adopt", "materialize", "apply"}}, + "adopt-materialize-plan": {InputContractSHA256: "sha256:484d8d867ff1080d14f14c9b82c9e02ce0bb10ded7713b8098b5a2f5128fefc2", InputSchemaSummary: []string{"schemaVersion=1", "owner-admitted adoption plan, requirement sources, proof bindings, and direct test inventory", "root-shape-only definition proofkit.adoption-materialization.plan-input.v1.root-shape; nested fields, types, cardinalities, and cross-record closure remain native-owner claims"}, OutputContractSHA256: "sha256:96f5947637a274bd4995989da657b7091ca3c6a3dea4b4839da61ed727537cd5", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"adopt", "materialize", "plan"}}, + "adopt-materialize-recover": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:7f4260b4997bcefefee18a1a43b02f9955e064026e034c20fde641f163d07a9e", FlagChoices: map[string][]string{"--action": []string{"resume", "rollback"}, "--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"adopt", "materialize", "recover"}}, "adopt-plan": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:ba2bb3ce147ac37bde035334e0058820339b36de2a0ae270a9e5dbe00e6a3e6d", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}, "--mode": []string{"audit-from-code", "code-baseline", "fresh"}, "--stack": []string{"agentic_runtime_repo", "generated_docs_contract_repo", "python_service", "python_typescript_service", "typescript_monorepo", "typescript_workspace"}}, RouteTokens: []string{"adopt", "plan"}}, "adoption-checklist": {InputContractSHA256: "sha256:4e6c4c9b369279837a5894c0b3f842a411dce529b91c91cb2d4ec63eb5ee4c2c", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.adoption-checklist.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:9d0d0e60f0935407fd31007d8502459663eb4c7228dc5e3c7727ae2c9907bdc9", FlagChoices: map[string][]string{}, RouteTokens: []string{"adoption-checklist"}}, "adoption-contract-envelope": {InputContractSHA256: "sha256:c310214676ff4b6f536a5bc9d687f681a7e71f73d7a03ac932707d8cd3905cdf", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.adoption-contract-envelope.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:3efb2c5161fee16fd8ac6a40dcb6d9c41fbc23e468f60621436ae9e8076e0950", FlagChoices: map[string][]string{}, RouteTokens: []string{"adoption-contract-envelope"}}, "adoption-doctor": {InputContractSHA256: "sha256:efa9acfe32bff07f56d9dc9902530df2979794289bc2f7f547f7a108a7dd0f35", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.adoption-doctor.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:8fdfc6608f197e633f042f20031ae1014872a90aa3daa66885ffcaddca994766", FlagChoices: map[string][]string{}, RouteTokens: []string{"adoption-doctor"}}, "adoption-workflow-plan": {InputContractSHA256: "sha256:b32ae67179d7b6dcf1ea66cb6b2b2691c8367ce2e2be367619b65973166da55c", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.adoption-workflow-plan.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:8d64cb53ebd0307e3cebc3435286a3d2a1ee8a0ad6f7514fc0fb3285db0f565b", FlagChoices: map[string][]string{}, RouteTokens: []string{"adoption-workflow-plan"}}, - "agent-route": {InputContractSHA256: "sha256:c00e832b4e9eac6b858eec46e810431c0a5c9f56c5c50f055f39ee024f50014c", InputSchemaSummary: []string{"availableInputs", "browserMode", "goal", "knownChangedPaths", "mode", "nonClaims", "observedReports", "openBrowser", "routeId", "schemaVersion", "root-shape-only definition proofkit.agent-route.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:ec7f56330ac44ec879dfaa3a8ee92eb7f9165f77adab8892452400789012fde3", FlagChoices: map[string][]string{}, RouteTokens: []string{"agent-route"}}, + "agent-route": {InputContractSHA256: "sha256:c00e832b4e9eac6b858eec46e810431c0a5c9f56c5c50f055f39ee024f50014c", InputSchemaSummary: []string{"availableInputs", "browserMode", "goal", "knownChangedPaths", "mode", "nonClaims", "observedReports", "openBrowser", "routeId", "schemaVersion", "root-shape-only definition proofkit.agent-route.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:92f47b1f6d2a90d67a98242df788cb857a07c74267bdff2d99638ecd319e3122", FlagChoices: map[string][]string{}, RouteTokens: []string{"agent-route"}}, "binding-partition": {InputContractSHA256: "sha256:366ad082045af52b2ac6604f18626d0f285b2db73b45d9a82687b8d3b0d2b3fd", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.binding-partition.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:52840879e13a00ef9a4abaad6cdb33000511674d5f9003fb56f387fdf58fadc8", FlagChoices: map[string][]string{}, RouteTokens: []string{"binding-partition"}}, "branch-authority": {InputContractSHA256: "sha256:8a3ed74978898593fbdbf1f7fa684dae450fbd9019edcd60d07f818d63363ed4", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.branch-authority.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:3c7dc74842299b92cd5baf57cc8666e9415963091359e5faf654e28da89561f1", FlagChoices: map[string][]string{}, RouteTokens: []string{"branch-authority"}}, "capability-map-admission": {InputContractSHA256: "sha256:36025145e1be04f8da9baccd2161b4ccf04f5426e95084d9cccc01802970e29d", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.capability-map-admission.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:5100e56075f50435605264c6a835a60f24f6790479e2b4c623d359f1e7e78690", FlagChoices: map[string][]string{}, RouteTokens: []string{"capability-map-admission"}}, @@ -38,25 +38,25 @@ var generatedCommandContractMetadataByName = map[string]generatedCommandContract "gradual-adoption-guidance": {InputContractSHA256: "sha256:4752cbac81c864cb3e18a39facfd666a9707314233d54798c7f71e67d7f2800c", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.gradual-adoption-guidance.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:171fed4bb8d32a47fc5ec49796f5b0b55ed666feaccc2fbbfeb12da31d80ecc9", FlagChoices: map[string][]string{}, RouteTokens: []string{"gradual-adoption-guidance"}}, "help": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "", FlagChoices: map[string][]string{}, RouteTokens: []string{"help"}}, "impact": {InputContractSHA256: "sha256:41d3107414837955ee408d5ce94949a4c1a6b76f6949e6c1dc224bd06f6b09bc", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.impact.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:73066e9a5ca48f21936111ffb7223900fb629875997f4e7b16d7fef9c4177972", FlagChoices: map[string][]string{}, RouteTokens: []string{"impact"}}, - "integration-apply": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:af4aa081d8630bb31adc58c74952020709388a8978421f4819aeb57b4be46876", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}, "--operation": []string{"install", "remove", "update"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "apply"}}, - "integration-check": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:ae27e65745504494a4c748ab26d03264e77bf0b7db69cd8927378be5eda478e4", FlagChoices: map[string][]string{"--format": []string{"json", "text"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "check"}}, - "integration-plan": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:8b0f9e9253afc70aa9e0ec0567b86c54576feb319d7ed3eddda7574f1126b3af", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}, "--operation": []string{"install", "remove", "update"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "plan"}}, - "integration-recover": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:8be9cb5de470e32dc82e19836dccd51284e32f0f45da2105a5c2786e9a2fadd5", FlagChoices: map[string][]string{"--action": []string{"resume", "rollback"}, "--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"integration", "recover"}}, - "integration-source": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:fb566a960ef2a319d4790cb1fb9cb7ffc078560e6744ca93cbdea5ea901b01cf", FlagChoices: map[string][]string{"--format": []string{"json", "text"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "source"}}, + "integration-apply": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:65af409248c6413f9ce22e436cde242b3875451dcd8d761ea9d464f61c740a1a", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}, "--operation": []string{"install", "remove", "update"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "apply"}}, + "integration-check": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:447db19dd53276746654d272f300fd819e54ce037382d6bf983b0c07b524b66b", FlagChoices: map[string][]string{"--format": []string{"json", "text"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "check"}}, + "integration-plan": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:76359c885ae29c964c96f59fd626d7c576d1d75fb851f3993de841b9cdc2cee9", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}, "--operation": []string{"install", "remove", "update"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "plan"}}, + "integration-recover": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:880c85b05aa164985d4eee01352414d6a938b50bf46cdd1e31483ed609571d2b", FlagChoices: map[string][]string{"--action": []string{"resume", "rollback"}, "--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"integration", "recover"}}, + "integration-source": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:128d4a199f97dee063766b42156493eb19d267455df83f07613e3b052daf3f4c", FlagChoices: map[string][]string{"--format": []string{"json", "text"}, "--tool": []string{"claude", "codex"}}, RouteTokens: []string{"integration", "source"}}, "json-report-cli-adapter-source": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:6c3dd1c8507a90e055cf2c886089446d8560ff3e0d3ca9cc6360a3377d2d85da", FlagChoices: map[string][]string{}, RouteTokens: []string{"json-report-cli-adapter-source"}}, "migration-parity-admission": {InputContractSHA256: "sha256:0b36c0e68da3b857dac4b13e7b3bd523052459106133aa8c908a4352682e6c05", InputSchemaSummary: []string{"schemaVersion=1", "paritySetId", "sourceProofOwners[]", "targetProofkitRefs[]", "parityRecords[]", "nonClaims[]", "root-shape-only definition proofkit.migration-parity-admission.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:8e0f8af2b205817f018b0fe133fe789661caa29007695e036bfcab63c1830f47", FlagChoices: map[string][]string{}, RouteTokens: []string{"migration-parity-admission"}}, "migration-plan": {InputContractSHA256: "sha256:58a62759a634101ce2ca9218184175134bbe5633328e1b23797b94c19fc9b11a", InputSchemaSummary: []string{"schemaVersion=1", "migrationId", "sourceProofOwners[]", "targetProofkitRefs[]", "parityEvidenceRefs[]", "retainedOwners[]", "retirementCandidates[]", "followUpCommands[]", "nonClaims[]", "root-shape-only definition proofkit.migration-plan.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:f14f0381e9dc241357c346315b95b03ef5b23f1d1bbc3b00f111fbe1515ed3ff", FlagChoices: map[string][]string{}, RouteTokens: []string{"migration-plan"}}, - "native-evidence-guidance": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:81810202f3bb4379ed29a9195eaab84b1a9f8ef6327206199723d97d7ef49af9", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"native-evidence-guidance"}}, + "native-evidence-guidance": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:fe02404bbd97a6fc56911441688e74db4a45f3acacfbcbcfe22b5f1073758640", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"native-evidence-guidance"}}, "next": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:7394789ca6a1a275662109980d82d58f3586e6afb2689d0b3e54acb14d067c21", FlagChoices: map[string][]string{"--color": []string{"auto", "never"}, "--format": []string{"json", "text"}}, RouteTokens: []string{"next"}}, "obligation-decision": {InputContractSHA256: "sha256:1dea2ed5c5066451d6d49b815cea99df2cdae2ef05d42fed16c8aeb45eb7f445", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.obligation-decision.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:96dc074f611bcc12e511bc803c548e4df623e2de869d3add29a3ea6386e04330", FlagChoices: map[string][]string{}, RouteTokens: []string{"obligation-decision"}}, "package-runtime-dependency-admission": {InputContractSHA256: "sha256:fc85887af9b8fcd899d245f0db30b2f2f68609822fc268126bf999082bb4115f", InputSchemaSummary: []string{"schemaVersion=1", "reportId", "expectedDependencySpec", "expectedLockfileIntegrity", "expectedPackageName", "expectedPackageVersion", "admissibleLocations{}", "packageResolution{}", "nonClaims[]", "root-shape-only definition proofkit.package-runtime-dependency-admission.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:c012032e8c8212fd50bc2e85669cc610609ca2124ebc992c9e88f44a1ad2d5fc", FlagChoices: map[string][]string{}, RouteTokens: []string{"package-runtime-dependency-admission"}}, - "pilot-admission": {InputContractSHA256: "sha256:a1d9116ce619f7d705349ff4ae44c0f4399a281ebaa9e7d62ea304ac57af59ba", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.pilot-admission.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:b8e07ba46ce0b76f2627cd5c2eebcd07d23bc4a0001e51133a1003e90cf758a1", FlagChoices: map[string][]string{}, RouteTokens: []string{"pilot-admission"}}, + "pilot-admission": {InputContractSHA256: "sha256:a1d9116ce619f7d705349ff4ae44c0f4399a281ebaa9e7d62ea304ac57af59ba", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.pilot-admission.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:66c6995438128545e05d535484e399c5bf11fb0b257e156cf389505fdcc73025", FlagChoices: map[string][]string{}, RouteTokens: []string{"pilot-admission"}}, "producer-policy-self-proof": {InputContractSHA256: "sha256:d48e18826000c8d415f3c44b6c686e1da6ed962ef7ca36c9f705de8c68d034f9", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.producer-policy-self-proof.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:e82a3989a743f8babc6069f7af82b1dd1ea62bad8dbb18d95e105b36f74e4276", FlagChoices: map[string][]string{}, RouteTokens: []string{"producer-policy-self-proof"}}, "proof-obligation-algebra": {InputContractSHA256: "sha256:4f176b6bc9bdbd0d96d65c071d66447d246665bda7a23269e7927f1d0b80b043", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.proof-obligation-algebra.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:f9ee9e56b349756c55856a2dab198e1ad85db70a468c38e3aeca73cfe2ed66f6", FlagChoices: map[string][]string{}, RouteTokens: []string{"proof-obligation-algebra"}}, "proof-receipt-admission": {InputContractSHA256: "sha256:8ba257066e276a48de661e52cabd3be194cba31a8a45e082f3b013a5c9a9120c", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.proof-receipt-admission.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:40fd1426468aae342029e10dcc950e6a24142f9a09f0b3d4513622c7a2bff75c", FlagChoices: map[string][]string{}, RouteTokens: []string{"proof-receipt-admission"}}, "proof-slice": {InputContractSHA256: "sha256:eb057ad276f0dd19929a1d425cd3d7f3d6d36e71888041bc7da0652c5efcac2a", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.proof-slice.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:6750b4d516fff1c37e542b68884ad8ac3da65dd3d56d10596e801bc0965021c7", FlagChoices: map[string][]string{}, RouteTokens: []string{"proof-slice"}}, "readiness-closeout": {InputContractSHA256: "sha256:4f427c1d0cefb00133d0d9fdb15f75ca9d12a26746632914e82bf72710883b9b", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.readiness-closeout.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:427a227aa59d60739bc7bdea03363ece95070520dc154fff1f063e174027cc5e", FlagChoices: map[string][]string{}, RouteTokens: []string{"readiness-closeout"}}, - "receipt-currentness-scope": {InputContractSHA256: "sha256:a3787eaacabc8902e90a39fe7fa179df3464a93829991006f720d2bd30572f06", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.receipt-currentness-scope.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:007e38673d5e8bb4a5c9447a835a7692e544b0f6e1f077d6f4f109fd08e3bf2a", FlagChoices: map[string][]string{}, RouteTokens: []string{"receipt-currentness-scope"}}, + "receipt-currentness-scope": {InputContractSHA256: "sha256:2e2d3ea6aafa28e7f195217e4d262c41919a54531ce6ab9d1b9c74fa1f1f0f77", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.receipt-currentness-scope.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:879ae88369ab28e8db6bd94ffa61e42e550f094edc5a593e3b32ea131483f81b", FlagChoices: map[string][]string{}, RouteTokens: []string{"receipt-currentness-scope"}}, "receipt-producer-admission": {InputContractSHA256: "sha256:676aa03b2331a094e287dd3f2dfad3a74403b6f8dadb17e420b446aac0b3592c", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.receipt-producer-admission.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:626b910bb8110901d6769c0ec2a14d216d9ca422aaf2f73ef5fc851c60b0847a", FlagChoices: map[string][]string{}, RouteTokens: []string{"receipt-producer-admission"}}, "receipt-trust-class": {InputContractSHA256: "sha256:be11e398a8e138243a0440a57fafb2b8b47faff7daefb2727da16af3e0c9d649", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.receipt-trust-class.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:7eeba48696ce232f9d7af48cf90ad57705bdcfade5a8d8837704ae2f06f5a76e", FlagChoices: map[string][]string{}, RouteTokens: []string{"receipt-trust-class"}}, "registry-consumer": {InputContractSHA256: "sha256:b4c71b63507b262b84d510573aa094592ea94579c4f332833f787f1719fa012b", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.registry-consumer.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:0b557f1db529d4527807513a97ebaedc4ae0b3d61b4445647ccd77667674db4b", FlagChoices: map[string][]string{}, RouteTokens: []string{"registry-consumer"}}, @@ -70,7 +70,7 @@ var generatedCommandContractMetadataByName = map[string]generatedCommandContract "requirement-browser-server": {InputContractSHA256: "sha256:557d9f1e6919a6f40b831fb910340f85cdc0a0619d0c4895098308939a262e6e", InputSchemaSummary: []string{"workspace mode: schemaVersion=2", "workspace mode: workspaceId", "workspace mode: context=proofkit.requirement-context schemaVersion=2 with strict v1 adapter", "workspace mode: diffInput=proofkit.requirement-semantic-diff-input schemaVersion=2 (optional)", "workspace mode: graphInput=proofkit.requirement-traceability-graph-input schemaVersion=2 (optional)", "--session-mode values: browse|one-shot-question", "one-shot-question requires --view workspace --serve --open", "--session-timeout-seconds is 1..7200 and requires one-shot-question", "source|proof|coverage|spec-tree modes retain their owner input contracts", "root-shape-only definition proofkit.requirement-browser-server.input.v3.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:40a4ac0312d4fb921d572817331a73c629ed807caed789296f992f1482e0d932", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-browser-server"}}, "requirement-context-compose": {InputContractSHA256: "sha256:0b8d5eace6247fd8fa01ad7372f0395ea6fa10e7f0aa9fe5bab2ff4ed8a69384", InputSchemaSummary: []string{"schemaVersion=1", "catalogId", "specTree.path", "requirementSources[] (non-empty)", "requirementSources[].nodeId", "requirementSources[].path", "expectedSourceDigest (optional sha256 ref)", "proofBinding.path (optional)", "coverage.path (optional)", "exact catalog paths only; no discovery", "root-shape-only definition proofkit.requirement-context-compose.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:dd08c6e3e66349019a349049345e64fca3d31459e42fe634e98e9a9ade8101f4", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-context-compose"}}, "requirement-context-slice": {InputContractSHA256: "sha256:a97c99d2c36bdf90aa6f3f55adf3afff7d3576093ae3ed79bbde5aaccaf1249c", InputSchemaSummary: []string{"schemaVersion=1", "sliceId", "context=proofkit.requirement-context schemaVersion=2 with strict v1 adapter, or schemaVersion=3 closed captured project origin", "Project-origin v3 replay validates the exact canonical project and role/source partition; it does not reread live files or reinterpret the existing v1/v2 identities.", "query.profile=routing|specification|proof|coverage|review", "query.nodeIds[]|requirementIds[]|ownerIds[]|lifecycleStates[]", "query.maxDepth=0..512", "query.maxNodes=1..4096", "query.maxRequirements=1..16384", "root-shape-only definition proofkit.requirement-context-slice.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:f9dfb92adc6548f7e8171ad0e7261cf5d7ce3112f6ecd989acc8d1fb9ff5dd31", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-context-slice"}}, - "requirement-coverage-input-compose": {InputContractSHA256: "sha256:1980d1fc5c3c3cfe08f557e3c55f7128de5bae0d9b25bd2a46d7c6e47db73faa", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.requirement-coverage-input-compose.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:3a8686e91f3a229b273531d9c03cb6ce86ec76b66f8c35c6ca7f361b6e5eeaff", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-coverage-input-compose"}}, + "requirement-coverage-input-compose": {InputContractSHA256: "sha256:3b4fd5dd444259db4de81c4a0b5800e8106e6ce61fa91fb00419ce56c4f493fa", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.requirement-coverage-input-compose.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:bfc779b40b581207000080149d0876c1f90cf41080a83039af09ac71ced18682", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-coverage-input-compose"}}, "requirement-coverage-view": {InputContractSHA256: "sha256:202dfbf2b9929a9244ba067a6a57af361e8f7da245625d3d53f13d73e04f14e3", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.requirement-coverage-view.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:b5784b98b903ef9bf9ddbac047592c32baeda96a83c3e426dee51d64d3846269", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-coverage-view"}}, "requirement-impact-input-compose": {InputContractSHA256: "sha256:c80c57489205004f92603fec541ce3d36dd0d9b65109dcfefb97bcfb07b90679", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.requirement-impact-input-compose.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:b0b689f4d0b5bafc52c6041a2aa3583c9c8628aa0f13a0f0d7c42a610ed1a0d6", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-impact-input-compose"}}, "requirement-proof-resolver": {InputContractSHA256: "sha256:7ffedf651fbeda57f11f780373ae8f2b15dd587ce3aaddf739a092bc4835f2c5", InputSchemaSummary: []string{"schemaVersion=2", "root-shape-only definition proofkit.requirement-proof-resolver.input.v2.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:d6b1fbbf4a7fe3624c64f88c8e316fd927df8f35355198962110dab41113bc94", FlagChoices: map[string][]string{}, RouteTokens: []string{"requirement-proof-resolver"}}, @@ -89,7 +89,7 @@ var generatedCommandContractMetadataByName = map[string]generatedCommandContract "selective-gate-evidence": {InputContractSHA256: "sha256:8aa178ab7ca7c475c23707bc4e15fd3f9f8d57acf6f6dcf279677e7769a45586", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.selective-gate-evidence.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:723569262bb85d9674b2a78d3bcb6e9f4cab229b71e8c784ff1b804a7fcade71", FlagChoices: map[string][]string{}, RouteTokens: []string{"selective-gate-evidence"}}, "selective-gate-obligation-decision-input": {InputContractSHA256: "sha256:85761fcbc0ea94239d55bf379d0592a6ca814e6612a2d609a651f6cdaf8ca10a", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.selective-gate-obligation-decision-input.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:ab9dddabe975238d7019266c43350afa2df1a61d4c2eb7bc23afd520b588a2da", FlagChoices: map[string][]string{}, RouteTokens: []string{"selective-gate-obligation-decision-input"}}, "selective-gate-plan": {InputContractSHA256: "sha256:5293a5a4c7d8426cf637e6f8d252095ca0eb1714365bb89bec83307b778c678a", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.selective-gate-plan.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:d7bffed853af5595af08b03859be01c283a3bdff1b3502d94ddc190889977647", FlagChoices: map[string][]string{}, RouteTokens: []string{"selective-gate-plan"}}, - "self-check": {InputContractSHA256: "sha256:f91bf07b924dfce56c5d742783ad28e77af65a9a2ab0609d9fbf9cf298fa758d", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.self-check.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:22499f6cadfec5abf5d5ae706ddf503ec129902d8cffe2b0cf862af98b17ff86", FlagChoices: map[string][]string{}, RouteTokens: []string{"self-check"}}, + "self-check": {InputContractSHA256: "sha256:092ea3fb5c79214b1ed8e8573b59f90bd736fa62797a19f55da92fdaaa519eb6", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.self-check.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:455db6d1517cd174d84534473375c2f45e8b4ce4dcd78db89da46a5bd215cea8", FlagChoices: map[string][]string{}, RouteTokens: []string{"self-check"}}, "spec-overview-claims": {InputContractSHA256: "sha256:2490dcd34ba7485e13f8f33e8a288a0463c4c52cc6b0d82c57777466927e49a4", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.spec-overview-claims.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:554f3a7020e9820ccb90672629fd769c52b2f298f356040aa3b0a817666cbfbf", FlagChoices: map[string][]string{}, RouteTokens: []string{"spec-overview-claims"}}, "spec-proof-bundle-admission": {InputContractSHA256: "sha256:2dd04eb5ad2bd26758b434c2f427347efd491dab5a50b1197c8a9f98113be1b5", InputSchemaSummary: []string{"schemaVersion=1", "root-shape-only definition proofkit.spec-proof-bundle-admission.input.v1.root-shape; nested fields, types, and cardinalities are non-claims"}, OutputContractSHA256: "sha256:a6ac0c69d19caf97e9a8c95808b83cdb3f908720923739aa59ef646d27c90870", FlagChoices: map[string][]string{}, RouteTokens: []string{"spec-proof-bundle-admission"}}, "stack-preset": {InputContractSHA256: "", InputSchemaSummary: []string(nil), OutputContractSHA256: "sha256:ef5920f363a4a96dcac308ea8412260a06e64ba4876460a369aefb8983130a9d", FlagChoices: map[string][]string{"--preset": []string{"agentic_runtime_repo", "generated_docs_contract_repo", "python_service", "python_typescript_service", "typescript_monorepo", "typescript_workspace"}}, RouteTokens: []string{"stack-preset"}}, diff --git a/internal/command/stackpreset/preset_ids_generated.go b/internal/command/stackpreset/preset_ids_generated.go index bcff4727..b2f19a99 100644 --- a/internal/command/stackpreset/preset_ids_generated.go +++ b/internal/command/stackpreset/preset_ids_generated.go @@ -1,6 +1,6 @@ // Code generated by internal/tools/commandcontractgen; DO NOT EDIT. package stackpreset -const presetContractSourceSHA256 = "18144447341a97e4d498f99839fb45b252fedd1e98429e6f16c3a0f5b7a6ba94" +const presetContractSourceSHA256 = "40e21bb074eea37dba970d08cf06e1c5ee0ec1c1d7404fad1e7e28490a3924c4" var presetIDs = []string{"agentic_runtime_repo", "generated_docs_contract_repo", "python_service", "python_typescript_service", "typescript_monorepo", "typescript_workspace"} diff --git a/internal/tools/releasechange/record_test.go b/internal/tools/releasechange/record_test.go index 6f46f220..f11f352e 100644 --- a/internal/tools/releasechange/record_test.go +++ b/internal/tools/releasechange/record_test.go @@ -197,7 +197,7 @@ func TestCurrentChangeRecordNamesReviewedSemanticChanges(t *testing.T) { var currentBreakingChanges = []Change{} var currentAdditions = []Change{ - {ChangeID: "proofkit.guidance.coverage-currentness", Summary: "Connect lazy CLI input recipes for declaration coverage and receipt currentness to the native traceability cookbook. Preserve composer-to-view handoff, original receipt subjects, scope decisions and separate execution, currentness and trust predicates. Add causal recipe tests without changing runtime admission, ordinary guidance outputs, machine CLI contracts, dependencies or supported platforms."}, + {ChangeID: "proofkit.guidance.coverage-currentness", Summary: "Connect lazy CLI input recipes for declaration coverage and receipt currentness to the native traceability cookbook. Preserve composer-to-view handoff, original receipt subjects, scope decisions and separate execution, currentness and trust predicates. Add causal recipe tests and refresh source-checkout provenance digests without changing runtime admission, ordinary guidance outputs, machine schema semantics, dependencies or supported platforms."}, } var currentMigrationSteps = []string{} diff --git a/proofkit/cli-contract.v2.json b/proofkit/cli-contract.v2.json index 010841ec..edd2b330 100644 --- a/proofkit/cli-contract.v2.json +++ b/proofkit/cli-contract.v2.json @@ -143,7 +143,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -282,7 +282,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -396,7 +396,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -1187,7 +1187,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -2506,7 +2506,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -2612,7 +2612,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -2740,7 +2740,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -2867,7 +2867,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -2965,7 +2965,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -3281,7 +3281,7 @@ "rootDefinitionDigest": "sha256:218011a133540f57ef74f8748747e00d33b6757c9f77725ecef39f45fb19423f", "nativeSource": { "path": "internal/command/nativeevidenceguidance", - "canonicalDigest": "sha256:09c65c50c3b953691d3839400ba5739d386d7fab725fcd0aa3bbffce199ed9e2", + "canonicalDigest": "sha256:c94f5f4634ab6eb92f35da4069f294cea82999006faa8804afd7b173ae7cb19f", "evidenceClass": "source_checkout" }, "nativeOutputWitnessSelector": { @@ -3640,7 +3640,7 @@ "nativeSources": [ { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, { @@ -4035,7 +4035,7 @@ "rootDefinitionDigest": "sha256:912f60b637aa0ca917b1c90d4caa4e3e65ec60ad0c5529d0da9d815fc766c5f5", "nativeSource": { "path": "internal/command/receiptcurrentnessscope", - "canonicalDigest": "sha256:64fe8dfe45c5af89533bcc3bd7448977cf51b446df18eff11bf4dd3a8815c1d0", + "canonicalDigest": "sha256:2c66b3309cdd8d3ce6d0743c99ca2a526597bc85b87a5f47b9a629ddcc65654e", "evidenceClass": "source_checkout" }, "nativeAdmissionWitnessSelector": { @@ -4062,7 +4062,7 @@ "rootDefinitionDigest": "sha256:30a1b7ef616c1e44bbdbebc6e511231166a2d1ea600d8d5954484fe8c0e7cdf4", "nativeSource": { "path": "internal/command/receiptcurrentnessscope", - "canonicalDigest": "sha256:64fe8dfe45c5af89533bcc3bd7448977cf51b446df18eff11bf4dd3a8815c1d0", + "canonicalDigest": "sha256:2c66b3309cdd8d3ce6d0743c99ca2a526597bc85b87a5f47b9a629ddcc65654e", "evidenceClass": "source_checkout" }, "nativeOutputWitnessSelector": { @@ -5239,7 +5239,7 @@ "rootDefinitionDigest": "sha256:f6300d6d0f80f5066fe4079433978132ee2bb1df75e602e59cf3dc37a385d3ce", "nativeSource": { "path": "internal/command/requirementcoverageinput", - "canonicalDigest": "sha256:ca685e4dd96bcd3981443471bcb9ef6f2a74ca2d8c2f9926aba2662bf7876ab4", + "canonicalDigest": "sha256:e771d00233614e6a91fe27c35a84a23f7e26cb91dcb4d7b0f9b197489b4c6e66", "evidenceClass": "source_checkout" }, "nativeAdmissionWitnessSelector": { @@ -5287,7 +5287,7 @@ "rootDefinitionDigest": "sha256:0f264c996a058fb8aff102e42b95a4610d3a584b35687cc870b3d16c9589cfed", "nativeSource": { "path": "internal/command/requirementcoverageinput", - "canonicalDigest": "sha256:ca685e4dd96bcd3981443471bcb9ef6f2a74ca2d8c2f9926aba2662bf7876ab4", + "canonicalDigest": "sha256:e771d00233614e6a91fe27c35a84a23f7e26cb91dcb4d7b0f9b197489b4c6e66", "evidenceClass": "source_checkout" }, "nativeOutputWitnessSelector": { @@ -6935,7 +6935,7 @@ "rootDefinitionDigest": "sha256:3c842174dff5361e7f83166469b832805e05aa314b073c16234b5b64e346281e", "nativeSource": { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, "nativeAdmissionWitnessSelector": { @@ -6964,7 +6964,7 @@ "rootDefinitionDigest": "sha256:0ea95e277ebe44cd2de42c29b47c38686ac0b6b390d8965367437b3fe138e209", "nativeSource": { "path": "internal/app", - "canonicalDigest": "sha256:a1b281f736785bdc5b054f72c7f7467236e1b7226c691de8cec88ef83bc0cf5d", + "canonicalDigest": "sha256:c02f14fe65c88c21f7f6b867311d61def37378939dec88015abf9a085c4b93a7", "evidenceClass": "source_checkout" }, "nativeOutputWitnessSelector": { diff --git a/release/change-record.v2.json b/release/change-record.v2.json index 7ced6fca..8659292a 100644 --- a/release/change-record.v2.json +++ b/release/change-record.v2.json @@ -7,7 +7,7 @@ "additions": [ { "changeId": "proofkit.guidance.coverage-currentness", - "summary": "Connect lazy CLI input recipes for declaration coverage and receipt currentness to the native traceability cookbook. Preserve composer-to-view handoff, original receipt subjects, scope decisions and separate execution, currentness and trust predicates. Add causal recipe tests without changing runtime admission, ordinary guidance outputs, machine CLI contracts, dependencies or supported platforms." + "summary": "Connect lazy CLI input recipes for declaration coverage and receipt currentness to the native traceability cookbook. Preserve composer-to-view handoff, original receipt subjects, scope decisions and separate execution, currentness and trust predicates. Add causal recipe tests and refresh source-checkout provenance digests without changing runtime admission, ordinary guidance outputs, machine schema semantics, dependencies or supported platforms." } ], "migration": {