CRW-582: stop an interrupted receipt test at once and write no receipt - #548
Conversation
|
You have reached your Codex usage limits for security reviews. Please try again later. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e826b135c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…sigint # Conflicts: # cmd/crw/main.go # docs/port-cxc/known-defects.md
The coordinator refreshed the base. The only conflict was in docs/port-cxc/known-defects.md, where both sides appended lines at the same place (1 block(s)); both sets are kept, dev's lines first, then this branch's.
Change
The first SIGINT sent to the
crwprocess duringcrw pabcd receipt test --session s1 -- <command>was swallowed:serve(cmd/crw/main.go:68-73) turned it into a cancelled context, but the pabcd row (cmd/crw/main.go:181) dropped that context and the receipt row passed noContextinto the CLI (internal/harness/pabcd_cli.go:29-45), so the check command ran to completion and a success receipt was published. An interrupted check could therefore produce the evidence its own gate reads.This change carries the invocation context through the pabcd dispatch into the receipt row, so the first SIGINT reaches the check command at once.
Acceptance example: with a session at phase C and a check binding,
crw pabcd receipt test --session s1 -- /bin/sh -c ': > "$1"; exec sleep 30' sh <marker>used to ignore a SIGINT to the crw pid, keep waiting for the command and (after it ended) exit 0 having written.crw/evidence/s1/test-receipt.json. After this change the same SIGINT ends the run with exit code 1, printsreceipt test: the command did not run to completion (terminated by signal); no receipt written, and leaves no receipt.Files
Verbgains an optionalRunContext func(ctx context.Context, ...); the formerPabcdbody becomesPabcdContext(ctx, ...), which passes ctx to a row'sRunContextwhen it is set and callsRunotherwise;Pabcdkeeps its signature and callsPabcdContext(context.Background(), ...); the row match keeps a row with neither function an invalid choice{Name: "receipt", RunContext: receiptVerb};receiptVerb(ctx, ...)passescli.ReceiptRunOptions{Context: ctx, ...}; no other row changesharness.PabcdContext(c.ctx, ...); serve, releaseAfterFirst and every other mode are unchangedTestPabcdVerbsbuilt[]Verbwith positional literals, which the new field breaks; they become named-field literals with unchanged semantics (the nil row is still reported as an invalid choice, exit 2)Oracle parity
Ported from CXC v0.2.40 (
3c1459acadeb1906d97c00a598e1457327ae372d),plugins/codexclaw/components/pabcd-state/src/receipt-cli.ts:75-185for the verb and:120-137for the run. The oracle runs the command throughspawnSync, which blocks until the child exits and defers the signal: the recorder confirmed the Node process died by the deferred SIGINT (rc -2) only after the child had completed, and wrote no receipt. This port stops the child at once instead - intentionally-changed timing with the same observable outcome (no receipt, non-zero exit), recorded in the appended known-defects section.Verification
561c9d107on the untouched base13c9f41efails withthe command was still running 10 s after the SIGINT(10.83 s,go testexit 1; output saved with the task's evidence, no private path here).--- PASS: TestPabcdReceiptTestStopsOnFirstInterrupt (0.66s).2e826b135):go test -count=1 ./cmd/crw/ ./internal/harness/ ./internal/pabcd/cli/exit 0;make lintexit 0;go vet ./...exit 0;GOOS=darwin go vet ./...exit 0;CGO_ENABLED=0 go build ./...exit 0;BLOB_RANGE_BASE=origin/dev go run -tags dev ./cmd/crw-dev ci validateexit 0;crw-dev ci contractsexit 0;crw-dev ci pluginexit 0 with digest0236789ec4aa1c59(unchanged from the base, so no activation-surface file changed);go test -count=1 ./internal/contracttest/ -run TestDomainexit 0 (570 cxc subtests pass).exitCode 0for the focused test command on this head.Corpus fixtures for this unit
crw pabcd receipt --help(the row table)crw pabcd receipt testguard pathcrw pabcd orchestrate ...thencrw pabcd receipt testNo corpus fixture exercises the SIGINT path (the oracle defers the signal), so this PR claims no fixture green;
contract/notes/cxc/CRW-582.jsonregisters an empty claim set.Size
214 changed lines (202 insertions, 12 deletions) across 7 files; no generated data, fixtures or goldens.
Review findings (Devin and Codex, one run each on head 2e826b1)
Both reviews finished; three findings arrived, all anchored at internal/harness/pabcd_cli.go:41. The two blocking ones (marked below as not fixed here) were closed in the generation-2 correction section further down. Each got a code-grounded reply and is resolved on its thread; none is a security finding.
The docs-only commit after that head (the residual-deviation line above) does not touch the code the reviews read; no second review was requested.
Generation 2 correction (relay revision request del-2bea97319ae1-a1)
Head
6401c9264(commitsfa0cc18easeam and failing test,ecd7c8238the check,6401c9264the docs) closes the two blocking findings above:internal/pabcd/cli/receipt.go: RunReceiptCLI calls the unexportedreceiptLateCancelHook(no initializer, nil in production, no package-level work at start) and then checks the caller's context at the last moment publication can still be skipped - after the command has returned and after the second source capture, immediately before the receipt directory is created - refusing withreceipt test: the command did not run to completion (interrupted); no receipt written, exit code 1, nothing written.internal/pabcd/cli/receipt_late_cancel_test.go(new): cancels the context through that seam after the command exits and before publication, asserting the exact text, code 1 and the absence of the receipt; red by assertion atfa0cc18ea(the run published and returned 0), green atecd7c8238.docs/port-cxc/known-defects.md: the late-interrupt line now reads port: fixed with that mechanism; the descendant case is recorded as port: kept (parity: the oracle never kills the check, and ReceiptRunOptions documents that cancellation kills only the process the call started).go test -count=1 ./internal/pabcd/cli ./internal/harness ./cmd/crwexit 0;make lint,go vet ./...,CGO_ENABLED=0 go build ./..., file-scopedgofmt -landgit diff --check origin/dev...HEADexit 0;crw-dev ci validate|contracts|pluginexit 0 (plugin digest unchanged); CRW CI run37251599680on this head - all 10 jobs success. Both late-interrupt threads are replied with the fix commit; no second review was requested.Generation 3 base refresh
dev's recall-clock-seam change (PR #556) touched the recall row of cmd/crw/main.go next to the pabcd row, so the pull request conflicted in code. The refresh merged origin/dev once - merge commit
b1c546c99d15fdfa3f1d6fc7f1e238b7d9921d2b, parents6401c9264andb32b55ea- and resolved exactly:cmd/crw/main.gokeeps dev's recall row and then the three-lineharness.PabcdContextpabcd row with nothing else changed in the file;docs/port-cxc/known-defects.mdkeeps dev's sections first and the CRW-582 section last, nothing dropped. gofmt, go build, go vet andgo test -count=1 ./internal/pabcd/cli ./internal/harness ./cmd/crwpass on temporary homes. With no conflict left thepull_requestCI ran automatically: run 37254049625, all 10 jobs success on this head; no review was requested, as the one Devin and one Codex review already ran. dev has since advanced (PR #558) and the only conflict now is again the appended known-defects section, which the parent unions in its merge lane.Risks and remaining work