Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# BLO-34872: the vendored adapter's per-patch log is append-only, so every PR
# touching that tree used to conflict with every other one on it — 4 rebases on
# PR #1873 alone, PROVENANCE.md the only conflicting file each time. Union merge
# keeps both sides' appended rows instead.
#
# Scoped to this one file deliberately, and it must stay scoped. A union merge
# is only safe on an append-only list of independent rows: it resolves by
# keeping both sides' added lines, so it cannot reconcile an interior edit and
# cannot choose between two values of a field that has only one. PROVENANCE.md
# is prose and single-valued tables, so union-merging it would interleave both
# sides' text rather than merge it.
#
# That is also why nothing single-valued may move *into* this file. BLO-35109
# deleted the 64-hex integrity hash that used to live in PROVENANCE.md for
# exactly this reason: under a union both candidates survive, and CI's
# `grep … | head -1` would then resolve the provenance verdict by sort order
# rather than by the tree. `provenance-union-merge.test.mjs` asserts both
# halves -- that this file is union-merged, that PROVENANCE.md is not, and that
# neither carries a 64-hex line.
vendor/paperclip-adapter-claude-k8s/PROVENANCE-CHANGES.md merge=union
53 changes: 31 additions & 22 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,29 @@ jobs:
run: node --test ./scripts/__tests__/merge-group-concurrency.test.mjs
timeout-minutes: 1

- name: Test vendored-provenance union-merge invariants (BLO-34872)
if: ${{ !cancelled() }}
run: node --test ./scripts/__tests__/provenance-union-merge.test.mjs
timeout-minutes: 1

- name: Require vendored-adapter source changes to be logged (BLO-35109)
# Replaces the stored 64-hex integrity manifest that used to live in
# vendor/paperclip-adapter-claude-k8s/PROVENANCE.md and was verified by
# the vendor_claude_k8s job. That hash was single-valued by construction,
# so every pair of concurrent vendored PRs produced two different values
# on one line and always conflicted -- and `merge=union` (BLO-34872)
# structurally cannot reach a single-valued field. This asserts the same
# property the hash existed for -- vendored source does not change
# without a provenance row -- off the diff, which stores nothing and so
# cannot conflict.
#
# Runs in this job rather than in vendor_claude_k8s because this one
# already checks out full history (fetch-depth: 0); the vendored job
# checks out at depth 1 and cannot resolve $PR_BASE_SHA.
if: ${{ !cancelled() }}
run: node ./scripts/check-vendored-provenance-log.mjs --base "$PR_BASE_SHA" --head "$PR_HEAD_SHA"
timeout-minutes: 1

- name: Test policy node-test timeouts
if: ${{ !cancelled() }}
run: node --test ./scripts/__tests__/policy-node-test-timeouts.test.mjs
Expand Down Expand Up @@ -1218,28 +1241,14 @@ jobs:
- name: Test
run: npm test

# Guards the PROVENANCE.md integrity manifest. If someone edits the
# vendored source, this hash changes and PROVENANCE.md must be updated
# in the same PR — otherwise the recorded provenance silently drifts
# from what is actually in the tree.
- name: Verify provenance manifest
run: |
set -euo pipefail
actual=$(git ls-files \
| grep -vxE 'LICENSE|PROVENANCE\.md' \
| LC_ALL=C sort | xargs sha256sum | sha256sum | cut -d' ' -f1)
recorded=$(grep -oE '^[0-9a-f]{64}$' PROVENANCE.md | head -1)
echo "actual: $actual"
echo "recorded: $recorded"
if [ -z "$recorded" ]; then
echo "::error::No 64-hex integrity hash found in PROVENANCE.md."
exit 1
fi
if [ "$actual" != "$recorded" ]; then
echo "::error::Vendored source changed but PROVENANCE.md integrity hash was not updated."
echo "Update the hash in vendor/paperclip-adapter-claude-k8s/PROVENANCE.md to: $actual"
exit 1
fi
# The stored 64-hex integrity manifest that used to be verified here was
# removed under BLO-35109: it was single-valued, so every pair of
# concurrent vendored PRs conflicted on it, and it could not tell a bad
# merge from two good ones (it failed on every combination of two
# correctly-merged changes). The property it existed for -- vendored
# source does not change without a provenance row -- is now asserted off
# the diff by the `Require vendored-adapter source changes to be logged`
# step in the `policy` job, which stores nothing and so cannot conflict.

verify:
# Preserve the legacy required-check name while the underlying work runs in parallel.
Expand Down
Loading
Loading