Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ records, generated release manifests, or the owning docs named above.
| BLOCKED | RELEASE-01 | Prove signed protected-tag release policy as provider-side release governance, not source-only intent. | Repository tag protection/ruleset and release workflow variables require signed annotated release tags; the next public release records provider-side evidence or the row is explicitly retired as an accepted non-claim. |
| DEFERRED | INSTALLED-CONSUMER-01 | Evaluate one carrier-neutral installed-contract and route-verification protocol without merging npm process transport with Python module transport. | Exact npm and wheel decision tables plus a shared mutant corpus first prove behavioral equivalence for contract admission, route/help identity, and byte-bound carrier checks; extract only the proven common protocol while retaining carrier-specific installation and execution owners, or retire the row if the common layer does not reduce semantic duplication. |
| DEFERRED | CLI-ARGS-01 | Evaluate one immutable typed parse result between descriptor admission and command execution instead of independently interpreting already-admitted command operands. | A reproducible descriptor-versus-handler drift falsifier establishes the defect class; a bounded prototype proves exact flag, multiplicity, value, help, input, and presentation parity across every affected command with no new ambient authority or generic option bag; otherwise retain the current bounded parsers and retire the row. |
| DEFERRED | WEB-PUBLISH-DESIGN-01 | Investigate optional publication of the specification browser at a configurable domain with authentication. Preserve local loopback serving and local browser opening as the default workflow; remote publication must be explicit and opt-in. | After the current program, compare static export with external hosting, a bounded deployment adapter, and an authenticated hosted server. Decide whether any capability belongs in Proofkit or should remain external, using a concrete consumer need and maintenance/security costs. The decision must define URL and authentication configuration, hosting/TLS/access-control ownership, source-disclosure and secret boundaries, content freshness, and preservation of derived-view authority. Require a feasibility witness and negative cases for unauthorized access and unintended publication before accepting an implementation plan; otherwise retain local-only behavior and retire the candidate with rationale. This row authorizes investigation, not exposure of the current server or deployment. |
81 changes: 81 additions & 0 deletions internal/app/adoption_input_guide_contract_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package app

import (
"fmt"
"slices"
"testing"
)

const inventoryInputGuideVersionSummary = "aggregate input contract v2; direct inventory schemaVersion=1; proof-binding-derived projection schemaVersion=2; discovery-draft projection schemaVersion=1"

// Only the admitted explanatory correction is normalized for historical ABI
// comparison. Every other field remains subject to the predecessor fingerprint.
func normalizeInventoryInputGuideContract(input map[string]any) (map[string]any, error) {
summary, ok := input["compatibilitySummary"].([]any)
if !ok || len(summary) == 0 || summary[0] != inventoryInputGuideVersionSummary {
return nil, fmt.Errorf("inventory input version summary differs from its declared correction")
}
input = clonePublicABIRecord(input)
summary = slices.Clone(summary)
summary[0] = "schemaVersion=2"
input["compatibilitySummary"] = summary
return input, nil
}

func normalizeInventoryInputGuidePublicABIDelta(current map[string]any) error {
commands, _, err := indexPublicABIRecords(current["commands"], "command")
if err != nil {
return err
}
command, ok := commands["test-evidence-inventory"]
if !ok {
return fmt.Errorf("inventory command is missing")
}
input, ok := command["inputContract"].(map[string]any)
if !ok {
return fmt.Errorf("inventory input contract is missing")
}
input, err = normalizeInventoryInputGuideContract(input)
if err != nil {
return err
}
command = clonePublicABIRecord(command)
command["inputContract"] = input
values := slices.Clone(current["commands"].([]any))
for index, raw := range values {
if raw.(map[string]any)["command"] == "test-evidence-inventory" {
values[index] = command
}
}
current["commands"] = values
return nil
}

func TestAdoptionInputGuideContractRejectsUndeclaredDelta(t *testing.T) {
for _, mutation := range []string{"old-summary", "wrong-version", "missing-summary", "extra-summary", "other-field"} {
t.Run(mutation, func(t *testing.T) {
current := readCLIContractRaw(t)
mutatePublicABIRecord(t, current, "commands", "command", "test-evidence-inventory", func(record map[string]any) {
input := clonePublicABIRecord(record["inputContract"].(map[string]any))
summary := slices.Clone(input["compatibilitySummary"].([]any))
switch mutation {
case "old-summary":
summary[0] = "schemaVersion=2"
case "wrong-version":
summary[0] = "aggregate input contract v2; direct inventory schemaVersion=2"
case "missing-summary":
summary = summary[1:]
case "extra-summary":
summary = append(summary, "Undeclared semantics.")
case "other-field":
input["contractId"] = "proofkit.undeclared.input.v1"
}
input["compatibilitySummary"] = summary
record["inputContract"] = input
})
if verifyManagedIntegrationPublicABIDiff(readFrozenManagedIntegrationPredecessor(t), current) == nil {
t.Fatal("inventory correction hid an undeclared contract change")
}
})
}
}
Loading
Loading