Repository navigation
feat(play): carry cause_source so a receipt can vouch for its classification - #837
Merged
Merged
Conversation
added 2 commits
October 29, 2026 14:55
…ication A receipt records provider_cause but not whether that cause came from a Google identifier or was inferred from the message text. Today's upload_mapping failure shows why that matters: FAILED_PRECONDITION is not in the structured vocabulary, so VERSION_CODE_CONFLICT came from prose, and the receipt presents that guess exactly like a stated fact. The adapter already emits cause_source (structured | message); the worker dropped it. It is now carried on both paths that build a cause -- the promote rejection and the mapping-file rejection -- and bounded to those two values rather than passed through as free text. The type addition was not optional: without declaring the field on AdapterDeobfuscationFile, tsc rejects the access, which vitest does not check. That is the gate that caught it, and the reason a deploy dispatch follows worker changes. Tests assert the field survives on the mapping path and that removing it fails. worker suite 1210 passed.
Codex's review is right: I pinned cause_source only on the deobfuscation-file rejection. The path that produced the real receipt -- play_upload_interrupted through receiptCause -- had no cause_source in its fixture, so deleting the new code would have left every test green. That is the vacuous-assertion shape again, in my own work. The receiptCause fixture now carries cause_source: "message" plus an out-of-vocabulary value that must be dropped, and the toEqual pins the field. Removing the new code fails that test. Also widens the trailing type assertion on receiptCause's return, which narrowed away the field the declared return type already named -- a cast that silently hides a value. worker suite 1210 passed.
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.
Problem
A receipt records
provider_causebut not whether that cause was read from a Google identifier or inferred from the message text. Today'supload_mappingfailure shows why the difference matters:FAILED_PRECONDITIONis not in the structured vocabulary, soVERSION_CODE_CONFLICTwas inferred from prose — and the receipt presents that inference exactly like a fact Google stated.The adapter already emits
cause_source: "structured" | "message"(provider_errors.ts:75). The worker'sreceiptCausepicked onlystageandprovider_cause, so it was dropped.Changes
cause_sourceis carried on both paths that build a cause — the promote rejection and the mapping-file rejection — bounded to those two values rather than passed through as free text.AdapterDeobfuscationFilenow declares the field. That was not optional: without ittscrejects the access while vitest stays green.Testing
cause_sourcesurvives; removing the field from the builder fails it.tscreports nocause_sourcediagnostics (theEnvbinding noise in that file comes from a locally generated type file and is pre-existing).Follow-up
This does not change any classification. It makes existing receipts honest about which of two very different things they contain, so a future reader does not treat an inferred cause as a provider-confirmed one.