feat(craft): receipt deep links, provider verdicts, and upload coalescing - #14345
Open
nmgarza5 wants to merge 4 commits into
Open
feat(craft): receipt deep links, provider verdicts, and upload coalescing#14345nmgarza5 wants to merge 4 commits into
nmgarza5 wants to merge 4 commits into
Conversation
Contributor
|
Full-stack Preview (frontend + backend)
|
Contributor
Greptile SummaryThe PR enriches Craft action receipts with provider-aware destinations, deep links, provider-level verdicts, and Slack upload coalescing while bounding recorded response capture.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Sequence DiagramsequenceDiagram
participant Agent
participant Gate as Sandbox Gate
participant Provider
participant Recorder
participant DB
participant Redis
Agent->>Gate: Provider write request
Gate->>Recorder: Record pending receipt + request facts
Recorder->>DB: Insert or coalesce receipt
Recorder-->>Redis: Announce newly created receipt
Gate->>Provider: Forward approved request
Provider-->>Gate: Stream response
Gate->>Gate: Capped capture and bounded decode
Gate->>Recorder: Finalize with response facts
Recorder->>DB: Set operation key, link, and verdict
Recorder-->>Redis: Announce changed receipt
Gate-->>Agent: Forward provider response
Reviews (5): Last reviewed commit: "fix(craft): capped observer for every re..." | Re-trigger Greptile |
Contributor
Author
The extractors turn transport receipts into user-grade proof. Request-side facts name the destination (#exec-team from the Slack payload, JSON or form-encoded) and key the upload flow's final step, response-side facts build deep links from shape-checked provider ids (Slack permalink, Drive by mime type, Gmail message), override the verdict when a provider hides failure inside a 200 (Slack ok=false, Linear errors), and claim late-learned coalescing keys so the Slack three-request upload lands on one receipt, the raw-bytes step resolved through a short-lived session-scoped token map. A later step's failure downgrades the coalesced receipt's early CONFIRMED, and coalesced repeats never re-announce. Linear's canonical URL is accepted only through an anchored shape check, everything else is constructed from validated ids, never trusted. A recorded flow's response stays buffered unless declared oversize and is read Content-Encoding decoded, with the cap applied to the decoded length.
An undeclared-length recorded response streams through a capped observer instead of buffering whole, and decoding is bounded (zlib with a capped output) so neither a chunked origin nor a compression bomb can grow proxy memory before the refine cap applies. Google editor APIs link through their product id keys (documentId, spreadsheetId, presentationId, which carry no mimeType), and Gmail draft receipts link the drafts view since a draft is not in #all until sent.
nmgarza5
force-pushed
the
nikg/craft-receipt-extractors
branch
from
August 27, 2026 21:37
c926d44 to
fa0ba53
Compare
nmgarza5
force-pushed
the
nikg/craft-receipt-recording
branch
from
August 27, 2026 21:37
09066d4 to
4402909
Compare
Contributor
Author
int() accepts a leading minus, so a negative Content-Length slipped the refine cap's bounds check and kept the response buffered.
Contributor
Author
…inks Recorded flows no longer trust the declared length at all: every one streams through the capped observer, so no origin claim can grow proxy memory past the refine cap. gmail.drafts.send returns the sent Message, so it links #all, and only create/update link the drafts view.
Contributor
Author
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.
Description
Why. After #14341, a receipt proves an action left the sandbox, but says nothing a user can act on: no link to the thing that was created, a Slack failure inside a 200 still shows CONFIRMED, and one file upload shows as three receipts. This PR makes receipts user-grade proof.
What.
receipt_extractors.py: pure per-provider refinement. Request side names the destination (#exec-team, JSON or form-encoded bodies) and keys the upload flow's final step. Response side builds deep links from shape-checked provider ids (Slack permalink, Drive by mime type, Gmail message), and overrides the verdict when the provider hides failure inside a 200 (Slackok:false, Linear GraphQLerrors). Linear is the one provider whose canonical URL is accepted, behind an anchored shape check. Everything else is constructed from validated ids, never trusted from payloads.insert/finalizenow report created/changed).Example receipt after this PR:
slack.messages.write → #exec-team, CONFIRMED, https://slack.com/archives/C0123/p17123456.How Has This Been Tested?
tests/unit/sandbox_proxy+external_apps+server791 passed, craft ext-dep suite 377 passed + 1 xfailed,ty checkandruffclean.Additional Options