From 8ac95c0231d416b744ae4781df5391e540a8318a Mon Sep 17 00:00:00 2001 From: garrytan Date: Fri, 6 Nov 2026 07:09:38 +0000 Subject: [PATCH] docs: the targeted record's change since the read is the PR's own (GST-1593) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- changelog.d/capy-gst-1593-targeted-main-merge.md | 1 + docs/review-policy.md | 5 ++++- docs/troubleshooting.md | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 changelog.d/capy-gst-1593-targeted-main-merge.md diff --git a/changelog.d/capy-gst-1593-targeted-main-merge.md b/changelog.d/capy-gst-1593-targeted-main-merge.md new file mode 100644 index 000000000..bea339844 --- /dev/null +++ b/changelog.d/capy-gst-1593-targeted-main-merge.md @@ -0,0 +1 @@ +- **A main merge after the targeted read no longer voids the record.** `gstack-ship-receipt write --review-targeted` refused with "the product changed after the read" whenever main brought in money- or secret-tagged files, though the PR's product patch was unchanged, because the classes changed since the read were computed across the merge commit (harness-evals #293, #292, #225). Write now computes those classes, and the plain-docs carry, over the PR's own change: the paths whose part of the PR's diff against its merge base differs between the read and HEAD. A branch-side edit to money, secret, auth or gate code after the read, or a merge resolution that changes the PR's own hunks, still refuses. (GST-1593) diff --git a/docs/review-policy.md b/docs/review-policy.md index d8bf3e620..d82049b9e 100644 --- a/docs/review-policy.md +++ b/docs/review-policy.md @@ -489,7 +489,10 @@ renders its brief; `verify --targeted-out .gstack/tmp/targeted.json` writes the the reader got its brief verbatim and its reply was collected on a committed diff, whatever happened to HEAD after, and it names the commit it read (`head`). `write` binds it only while that commit is an ancestor of HEAD, its product patch is the receipt's, and nothing changed -after it carries a targeted class, with the gate scan run over that range: any other product change +after it carries a targeted class, with the gate scan run over that change. What changed after the +read is the PR's own change, on `product_patch_id`'s basis: the paths whose part of the PR's diff +against its merge base differs between the read and HEAD, so files only a base merge brought in never +count, while a branch edit or a merge resolution that changes the PR's own hunks does (GST-1593). Any other product change after the read refuses with `RECEIPT_INVALID`, and so does a test edit the gate scan tags (a skipped case). A docs-only change after the read (TODOS.md included) carries the record only when it changes no binary file, adds no numeric claim, touches no results, prereg or eval path, diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 27fdf4e05..d4ef7286f 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -3493,7 +3493,9 @@ or when `--review-targeted` names a read commit that is not an ancestor of HEAD, or after which a change carries a targeted class (money, gate, auth or secret code changed after the targeted reader read it, a test edit the gate scan tags included), or whose product patch is not the receipt's and the change -since it is more than plain docs. A docs-only change after the read carries the +since it is more than plain docs. The change since the read is the PR's own: a +base merge after the read that leaves the PR's diff alone never voids the record, +whatever files it brought in (GST-1593). A docs-only change after the read carries the record only when it changes no binary file, adds no numeric claim, touches no results, prereg or eval path, and names no money, security, secret or auth topic; any other docs change needs the reader again (GST-1195).