feat(dirty-content-fingerprint): Makefile computes dev-loop fingerprint
Adds an independent DIRTY_FINGERPRINT computation to src/frontend/Makefile,
mirroring xce-build.sh's task 2.1 algorithm exactly, wired into
VERSION_LDFLAGS as -X main.DirtyFingerprint=. GIT_COMMIT/GIT_STATUS/
BUILD_TIME (including GIT_COMMIT's own -dirty suffix) are completely
untouched.
This took two rejected review rounds to get the failure-detection right:
round 1 found a `{ git diff HEAD; ...; } >file` grouped command whose exit
status only reflected the last command, silently swallowing a git diff
failure and fabricating a hash from incomplete data. Round 2 found the
identical bug class one step further down (git ls-files | sort | xargs
cat's pipe swallowing an ls-files failure). Fixed by pulling git ls-files
out of the pipe into its own directly-redirected, individually-checked
step, deliberately chosen over `set -o pipefail;` (which also worked)
because this repo's own build-deployment.md documents a past incident of
code silently relying on /bin/sh happening to be bash with no SHELL:=bash
pin.
One narrow, explicitly-disclosed residual gap remains (a sort-only
failure, not cat, in the trailing pipe) and was assessed as acceptable
low risk after independent verification across three review rounds.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
995673e7cf
commit
aa3391a93e
2 changed files with 117 additions and 5 deletions
|
|
@ -54,10 +54,11 @@
|
|||
- _Boundary: apiserver/meson.build, xcecli/meson.build_
|
||||
- _Depends: 4.1_
|
||||
|
||||
- [ ] 4.3 (P) Makefile dev-loop path computes the same fingerprint, independently of GIT_COMMIT
|
||||
- `src/frontend/Makefile`'s existing `GIT_COMMIT`/`GIT_STATUS` computation (original feature, task 4.3, including its own `-dirty` suffix) is **not touched**
|
||||
- Compute a `DIRTY_FINGERPRINT` value directly (git diff + untracked files, dev-loop path, no meson involved) using the identical logic as task 2.1 (empty when clean or on computation failure, real hash otherwise), and pass it via the identical `-ldflags -X main.DirtyFingerprint=` shape
|
||||
- Observable: `go version -m` on a Makefile-built binary shows the same fingerprint format/value as a meson-built binary from the identical tree state; `GIT_COMMIT`'s own `-dirty` behavior is unaffected
|
||||
- [x] 4.3 (P) Makefile dev-loop path computes the same fingerprint, independently of GIT_COMMIT
|
||||
- `GIT_COMMIT`/`GIT_STATUS`/`BUILD_TIME` (and `GIT_COMMIT`'s own `-dirty` suffix) confirmed byte-for-byte untouched throughout two rounds of adversarial remediation
|
||||
- `DIRTY_FINGERPRINT` computed independently, mirroring task 2.1's algorithm exactly (cross-checked byte-identical on the real dirty tree); failure-detection required two remediation rounds to get right -- round 1 fixed a `{ git diff HEAD; ...; } >file` grouped command silently swallowing a `git diff HEAD` failure (only the last command's exit status was checked); round 2 found the SAME class of bug one step further down (`git ls-files | sort | xargs cat`'s pipe also swallowing an `ls-files` failure) and fixed it by pulling `git ls-files` out of the pipe entirely into its own directly-redirected, individually-checked step -- deliberately choosing this over a `set -o pipefail;` prefix (which empirically also worked) because this repo's own `build-deployment.md` documents a past incident of code silently relying on `/bin/sh` happening to be bash with no `SHELL:=bash` pin
|
||||
- One narrow, explicitly-disclosed residual gap remains and was assessed as acceptable: a `sort`-only failure (not `cat`) in the trailing `sort -z | xargs -0 -r cat --` pipe can still be masked -- independently confirmed present, low-risk, and accurately scoped, not grounds for further rejection
|
||||
- Observable confirmed live (independently re-verified across 3 review rounds, real builds + two independently-reproduced failure-injection wrappers with control tests proving each wrapper genuinely triggers the old bug): `make -n build-cli`'s fingerprint matches a standalone reference computation byte-for-byte; both the `git diff`-fails and `git ls-files`-fails scenarios correctly degrade to empty, not a fabricated hash; `GIT_COMMIT`'s `-dirty` behavior unaffected throughout
|
||||
- _Requirements: 1.1, 1.2, 1.3, 1.4, 5.1_
|
||||
- _Boundary: Makefile_
|
||||
- _Depends: 4.1_
|
||||
|
|
@ -111,3 +112,6 @@
|
|||
- Observable: the fingerprint values from two builds of the same commit with different tracked-file edits are different, and no `--impure` flag or `git` invocation inside the sandbox was required
|
||||
- _Requirements: 1.1, 1.2, 1.3, 5.1_
|
||||
- _Depends: 2.2_
|
||||
|
||||
## Implementation Notes
|
||||
- **Task 4.3**: a `{ cmd1; cmd2; } >file` or `cmd1 | cmd2 | cmd3` shell construct's exit status (as checked by `if ! ... ; then ...; fi`) only reflects the LAST command's exit status, not any earlier command's -- this silently swallows an earlier failure and can produce fabricated output from partial/incomplete data instead of the intended graceful-degradation path. Took two rejected review rounds to fully generalize (first fixed for `git diff HEAD`, then found again one step later for `git ls-files | sort | xargs`). When writing any multi-stage shell pipeline whose failure must be individually detectable, either enable `pipefail` explicitly (verify the actual invoking shell first -- `$(shell ...)` in Make does NOT inherit a Makefile's `SHELL`/`.SHELLFLAGS` settings) or restructure each stage to its own directly-redirected, individually-`$?`-checked step (the safer default absent a `SHELL:=bash`-style pin, per this repo's own documented `/bin/sh`-is-not-guaranteed-bash incident in `build-deployment.md`).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue