ship-receipt write: the targeted record survives a main merge (GST-1593) (#4058)

* ship-receipt write: the targeted record survives a main merge; classes since the read cover the PR's own change (GST-1593)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* 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>

* ship-receipt depth: a branch edit to a path whose base did not move always voids the targeted record; isolate the GST-1593 tests' gate scan from the real home (GST-1593)

ownChangeSince compared the PR's per-path hunks with line numbers stripped even when main had not moved the
path's base content, so a branch commit after the targeted read that relocated the PR's money line to an
identical-context block read as unchanged and the record bound (red-team, /ship #4058 pass 1). Hunk
comparison now applies only when the base blob moved. The four direct targetedClassesSince calls in the
GST-1593 tests now run with the fixture's env, so gstack-gate-diff no longer writes under the real
~/.gstack (CI run 42179129702, free-suite (4): FREE_SUBSHARD_REJECTED real home changed).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (GST-1593)

ownChangeSince: a path whose base content main also changed now moves unless replaying main's change onto
the read's content (git merge-file) gives HEAD's content exactly, so relocating the PR's money hunk to an
identical context after a main merge voids the targeted record; position-free hunk comparison is gone. The
built commit carries the branch's first-parent messages since the read, so a [skip ci] commit stays RH-14
gate class. Two red-first tests cover both.

Review-Finding: v1/outside-voice#1 reader=outside-voice
Review-Finding: v1/adversarial-native#1 reader=adversarial-native
Review-Finding: v1/outside-voice#2 reader=outside-voice
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* ci: run the checks at the review-fix head (GST-1593)

The previous commit's message quoted a CI skip marker, so no workflow ran at c462483. This commit changes
no file; the tree is c462483's.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes, fix-check round (GST-1593)

The built commit now carries the message of every commit since the read that origin/main does not hold,
so a CI-skip marker on a side-branch commit merged with --no-ff still tags RH-14. A path whose mode at
HEAD is not the replayed mode now moves, so a mode-only change after a main merge to the PR's own file
voids the record. Two red-first tests cover both.

Review-Finding: fc1/fix-check#1 reader=fix-check
Review-Finding: fc1/fix-check#2 reader=fix-check
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* changelog.d: plain-sentence wording for the GST-1593 fragment (prose lint)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
Garry Tanandcapy-ai[bot] authored and GitHub committed 2026-11-06 10:34:41 +00:00
1 parent 05114c8049
commit f7015fa72c
6 files changed
+244 -16

No files matched your search

+4 -1
View File
@@ -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,
+3 -1
View File
@@ -3502,7 +3502,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). With `--body`, write also refuses, writing