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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ jobs:
run: |
test -z "$(gofmt -l .)"
go vet ./...
go test ./...
go test -count=1 ./...
CGO_ENABLED=0 go build -o "${RUNNER_TEMP:-/tmp}/ink" ./cmd/ink
CGO_ENABLED=0 go build -o "${RUNNER_TEMP:-/tmp}/ink-verify-server" ./cmd/ink-verify-server
CGO_ENABLED=0 go build -o "${RUNNER_TEMP:-/tmp}/ink-witness-server" ./cmd/ink-witness-server
Expand Down Expand Up @@ -222,9 +222,9 @@ jobs:
nix develop --command bash -c '
set -euo pipefail
cd go
go test ./ink/
go test -count=1 ./ink/
log="${RUNNER_TEMP:-/tmp}/staged.log"
go test ./ink/ -run TestAgentCardSignaturePhaseC -v | tee "$log"
go test -count=1 ./ink/ -run TestAgentCardSignaturePhaseC -v | tee "$log"
# A skip exits 0, so assert the staged test actually ran and passed.
grep -q "^--- PASS: TestAgentCardSignaturePhaseC" "$log"
'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/weekly-conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,17 +239,17 @@ jobs:

- name: Go conformance and manifest integrity
working-directory: go
run: go test ./...
run: go test -count=1 ./...

- name: Go verifier, staged vectors
working-directory: go
env:
INK_STAGED_CONFORMANCE: "1"
run: |
set -euo pipefail
go test ./ink/
go test -count=1 ./ink/
log="${RUNNER_TEMP:-/tmp}/staged.log"
go test ./ink/ -run TestAgentCardSignaturePhaseC -v > "$log"
go test -count=1 ./ink/ -run TestAgentCardSignaturePhaseC -v > "$log"
cat "$log"
grep -q '^--- PASS: TestAgentCardSignaturePhaseC' "$log"

Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ here. Pre-1.0 releases follow `0.Y.Z` semantics, see

### Changes

- Inclusion-receipt reject vectors name the check that must refuse them, and
both runners assert it. Every one of the 33 asserted a verdict and nothing
else, so a verifier that refused for an unrelated reason satisfied them. Go
gained a step alongside its verdict, the generator refuses to emit a reject
vector without one, and the corpus schema carries the member.
- Go conformance runs pass `-count=1`. The Go test cache does not track the
corpus files the tests read, so a vector edit could be validated against a
cached pass: mutating an expected step reported ok in 0.004 seconds and
caught nothing, while the same run with `-count=1` caught it. The rule is
gated, so an invocation without it fails the fact check.
- The Go conformance runner asserts a reject vector that its parser refused at
the boundary. Those cases used to skip every assertion, so a parser that
refused everything satisfied them.

- The card verifier rejects a present member of the wrong type wherever it
reads one, rather than at the top level only. A non-string
`currentSigningKeyId` was compared as a value by the reference and read as
Expand Down
50 changes: 49 additions & 1 deletion conformance/v1/generate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ function writeSchema() {
properties: {
result: { type: "string", enum: ["accept", "reject"] },
reason: { type: "string" },
// The check that refused, where the surface has one. A vector
// pinning only the verdict is satisfied by a refusal from the
// wrong check, so a reject vector names the step wherever the
// implementations can express it.
step: { type: "string" },
auditEvent: { type: "string" },
canonicalPrincipal: { type: "string" },
keyStatus: { type: "string", enum: ["active", "retired", "revoked"] },
Expand Down Expand Up @@ -1890,8 +1895,51 @@ const validReceipt = await makeReceipt();
function rcptAccept(caseId, description, input) {
return { caseId, description, input, expect: { result: "accept" } };
}
// The check that MUST refuse each rejected receipt, asserted by both runners.
// Coarser than a per-case reason, since thirteen cases share `structure`, but
// it is what both implementations can express today.
const RECEIPT_REJECT_STEP = {
"checkpoint-bad-root-rejects": "checkpoint",
"checkpoint-fork-rejects": "checkpoint",
"checkpoint-negative-size-rejects": "checkpoint",
"checkpoint-rollback-rejects": "checkpoint",
"empty-event-id-rejects": "structure",
"empty-signature-rejects": "structure",
"empty-timestamp-rejects": "structure",
"event-hash-bad-format-rejects": "proof",
"event-hash-not-in-tree-rejects": "proof",
"event-id-mismatch-rejects": "proof",
"event-leaf-not-at-index-rejects": "proof",
"event-missing-id-rejects": "proof",
"leaf-index-ge-tree-size-rejects": "structure",
"malformed-signature-rejects": "signature",
"negative-leaf-index-rejects": "structure",
"non-integer-leaf-index-rejects": "structure",
"null-event-rejects": "proof",
"proof-bad-element-rejects": "structure",
"proof-not-array-rejects": "structure",
"proof-too-long-rejects": "structure",
"receipt-not-object-rejects": "structure",
"short-root-hash-rejects": "structure",
"surrogate-in-event-id-rejects": "signature",
"surrogate-in-event-rejects": "proof",
"tampered-event-id-rejects": "signature",
"tampered-leaf-index-rejects": "signature",
"tampered-proof-rejects": "proof",
"tampered-root-hash-rejects": "signature",
"tampered-timestamp-rejects": "signature",
"tampered-tree-size-rejects": "signature",
"uppercase-root-hash-rejects": "structure",
"wrong-witness-key-rejects": "signature",
"zero-tree-size-rejects": "structure",
};

function rcptReject(caseId, description, input) {
return { caseId, description, input, expect: { result: "reject" } };
const step = RECEIPT_REJECT_STEP[caseId];
// A new reject vector has to declare which check refuses it. Generating one
// without a step would quietly reintroduce the verdict-only assertion.
if (!step) throw new Error(`inclusion-receipt: no reject step declared for ${caseId}`);
return { caseId, description, input, expect: { result: "reject", step } };
}
const wpk = { witnessPublicKeyHex: publicKeyHex };

Expand Down
2 changes: 1 addition & 1 deletion conformance/v1/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
"spec": "specs/ink-inclusion-receipt.md",
"summary": "Composite inclusion-receipt verification.",
"caseCount": 39,
"sha256": "e8f41905b2b482ac82cac2262f92f99b14045ffe8060c69a94de29e99b431e2f"
"sha256": "2be8699b9d047b6692c329902882ae12af99a00e9a4c7fd40b32164de2336ec0"
},
{
"id": "jcs-number",
Expand Down
3 changes: 3 additions & 0 deletions conformance/v1/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@
"reason": {
"type": "string"
},
"step": {
"type": "string"
},
"auditEvent": {
"type": "string"
},
Expand Down
Loading