receipt-core: CoreDecisionOutputV1 semantic core (valid_until binding, normalize-before-hash)#4
Merged
Merged
Conversation
Ports the receipt-core v1 module (strict JCS, decision_ref construction, ReceiptV1, supporting records) with its test file. In-repo and tested, not part of the public API: nothing is exported from agent_passport/__init__.py. Signed-off-by: aeoess <signal@aeoess.com>
draft-pidlisnyi-aps-03 defines valid_until as the fifth member of CoreDecisionOutputV1. The implementations omitted it, so decision_ref did not bind the decision expiry. This adds the field to the type, the closed shape, verdict-dependent shape validation, and the hashed preimage. The cross-field rule requiring valid_until to be later than receipt issued_at, dispatch-time expiry and consumption enforcement, and strict duplicate-member parsing remain separate follow-up gates. The module is not exposed through the supported package entry points. Internal deep-import users, if any, may observe the changed digest. Signed-off-by: aeoess <signal@aeoess.com>
…truction Signed-off-by: aeoess <signal@aeoess.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
The core decision output becomes a closed five-member object and its digest path is enforced.
fix(receipt-core): bind valid_until in CoreDecisionOutputV1. The output object is exactlyprofile,verdict,effective_authority_ref,constraints,valid_until.valid_untilis required: an RFC 3339 UTC millisecond timestamp forpermitandnarrow, exactlynullfordeny. Draft -03 specifies the member; the prior code accepted outputs without it.fix(receipt-core): enforce normalize-before-hash in decision_ref construction. The builder normalizes the decision output at runtime before hashing, so an unnormalized or malformed output cannot reach the digest through the construction path.computeDecisionComponentRefV1is documented as the internal primitive that expects already normalized input.Python and Go additionally carry
feat(receipt-core): port receipt-core v1 moduleas the first commit: receipt-core previously existed only in the TypeScript repository, and the fixes land on top of the port. In Go the builder takes the typedCoreDecisionOutputV1struct, which turns the old opaque-value bypass into a compile error.Cross-language evidence
Five decision outputs through the builder in TypeScript, Python, and Go: 5/5 component digests match and 5/5 full
decision_refvalues match, including an NFC-decomposed constraint and a supplementary-plane (U+1F600) constraint. Five malformed outputs rejected in all three; the unknown-extra-member case is unrepresentable in Go and fails at compile time. One known-answer test per language pinned the previous digest shape and is repinned here: the pinneddecision_refmoves from2157809a…toe474f27b…, identical across the three languages, and the new component digest reproduces from stock JSON and SHA-256 libraries with no repository code.Suites at these heads: TypeScript 4351 passed, 0 failed; Python 762 passed; Go all packages ok. All exit 0.
Boundary, stated plainly
This PR does not claim conformance. Three gates remain open and are tracked as follow-up work: the receipt-level relation that
valid_untilmust be later than the receipt'sissued_at(the receipt carriesdecision_refas a digest, so neither validator currently sees both operands; the enforcement point is a design decision in progress), dispatch-level enforcement, and strict raw duplicate-member parsing. receipt-core remains unexported from the public API in all three repositories. Merged means the construction path is specified and tested, not that the semantic core is fully conformant.Sibling PRs: aeoess/agent-passport-system#84, aeoess/agent-passport-go#5