fix(release): validate compare links and protect checksum output (successor to #170) - #199
Conversation
…heading
The compare-link check used a `*` glob between `/compare/` and
`...v<version>`, so any start version passed validation. Derive the
expected start from the CHANGELOG's second versioned heading and compare
the full link as an exact string; fail closed when the heading is
missing. Also fix the releases/tag branch, whose `[${version}]` was a
glob character class rather than a literal match.
Bidirectional: 4 previously-passing tampered links now fail; correct
compare and releases/tag links still pass.
Replace GNU find -printf with -exec basename for macOS compatibility. Guard actual_assets expansion under set -u to prevent unbound variable error when the asset directory is empty.
(cherry picked from commit 11e02e2)
…2-pr170-release-successor
Address a baseline manifest-output symlink gap independently of the earlier basename enumeration fix. Preserve external files, reject existing output paths before hashing and publication, and cover late symlinks and randomized temporary staging.
|
Independent automated preflight — PASS, bounded checksum-output fix at Independent reviewer Ohm checked the complete safety delta against Existing output files/directories/symlinks, including dangling links, are rejected before hashing and before publication; private randomized staging and cleanup remain. This is controlled-release-staging protection, not a claim of atomic defense against a hostile process replacing paths after the final check. Independent Bash suites, ShellCheck and diff checks pass. Full guard validation on the reviewer Mac used GNU coreutils; no full stock-macOS portability claim is made. All 20 current checks pass, including every required check and all three concrete CodeQL languages: CI, acceptance, security. Main was integrated normally, original authorship is retained, and security workflows match main byte-for-byte. No blocker found in this delta. Human approval and normal merge are still required; this preflight does not authorize a release or transfer #170's old reviews. |
There was a problem hiding this comment.
Review
Overall quality is high — defensive programming is solid and test coverage is comprehensive. Here are a few observations:
1. awk logic for extracting compare base in validate_release_version.sh
/^## \[/ && $0 != "## [Unreleased]" {
if (seen++) { ... print; exit }
}This awk extracts the second versioned heading in the CHANGELOG (the second one after skipping Unreleased), but it does not validate whether the version corresponding to that heading is actually the one immediately preceding the current release version. If the CHANGELOG structure is abnormal (e.g., there are orphaned historical version headings), awk could extract the wrong compare base, leading to misleading error messages.
Consider adding a comment below the awk explaining the assumption, or passing the current version number as a parameter to awk so it only matches the heading immediately following the current version's heading.
2. TOCTOU in the dual require_absent_output calls
The script calls require_absent_output once at the beginning and once before mv, with a TOCTOU window between the two checks. The PR description explicitly states this is not a boundary against concurrent adversarial processes, which is a reasonable scope. The two checks do catch non-adversarial races (e.g., leftover files from a previous CI run), so keeping both checks is correct.
3. Portability of find -exec basename {} \;
Switching from -printf '%f\n' to -exec basename {} \; is a correct portability fix (BSD/macOS find does not support -printf). For a fixed set of 6 files, the per-process overhead is negligible.
4. Test quality
test_release_checksum_output_safety.shcovers 7 scenarios (symlinks to directories/files, dangling symlinks, pre-existing directories/files, symlinks appearing during hashing, pre-existing symlinks matching the template shape). Each scenario verifies side effects (external files were not modified) rather than just the exit code — this is critical, because the original bug wasmvwriting to the wrong location before returning failure.- Including spaces in directory names (
"assets with spaces") is good practice for catching quoting issues. - The negative test for an empty asset set verifies correct diagnostic output and the "no manifest generated" constraint.
Summary
No blocking issues found. Code logic is correct, tests are sufficient, and the CHANGELOG has been updated. The awk assumption in point 1 is worth a one-line comment, but it does not block merging.
A release link pointing at its own tag page satisfied the validator even when a preceding release existed, so the property the PR claims to enforce was enforceable only by maintainer habit. The correct form is now decided by whether a predecessor exists, and a regression test pins the bypass shut. - derive the compare base only from versioned headings, so a non-version heading between releases cannot be mistaken for the predecessor - count manifest rows without wc -l in both guard suites; BSD wc pads the count with blanks, which made the six-row assertion fail on stock macOS - assert manifest completeness in the generator itself, because the post-publish self-check uses --ignore-missing and tolerates a lost row - capture the asset listing before consuming it, so a failed listing is reported as a listing failure rather than an asset-set mismatch - make the new suite executable and add it to the ShellCheck list
# Conflicts: # CHANGELOG.md
waterbro-8
left a comment
There was a problem hiding this comment.
COMMENT — no objection to the code; the evidence ledger in the body describes a different commit
Not a vote, because the artifacts that would justify one are pinned to a head that this PR no
longer is.
The ledger is 10 commits behind
- Successor head today:
145a987e5. - Body tracking record: "Successor head:
260710d69a…". compare/260710d...145a987e5= 10 commits.
The one that matters is your own 23fe076de fix(release): close the compare-link bypass and
guard portable…, which touches 6 files and all 6 are in this PR's current diff:
scripts/generate_release_checksums.sh, scripts/test_release_checksum_output_safety.sh,
scripts/test_release_guards.sh, scripts/test_release_helpers_compat.sh,
scripts/validate_release_version.sh, .github/workflows/memory-validation.yml.
That is precisely the security-relevant change, and it landed after the snapshot the evidence
was collected against.
Two specific rows that no longer hold
bash scripts/test_release_checksum_output_safety.sh→ "seven focused cases on final
tree".final treewas260710d;23fe076dethen edits that script.Diff main..HEAD for all security/release/publish/policy/acceptance workflows→ "No
workflow changes | PASS, empty diff". This head's file list does include
.github/workflows/memory-validation.yml. Either that row's enumeration deliberately
excludes it — in which case please say so, because as written it reads as "no workflow in
this repo changed" — or the row is stale.
The body already states its own gate, "Fresh review of 260710d remains required" — right
instinct, but a fresh review of 260710d would still not cover 23fe076de.
What I'd ask for
Re-run the ledger's commands against 145a987e5, refresh the tracking-record SHAs, and re-word
or scope that "No workflow changes" row. That is a push away from this being an approval, and
the push is cheap: it is documentation of work you have probably already done.
On the code
No objection from what I read. 23fe076de reads as a genuine tightening (compare-link start
pinned to CHANGELOG's second heading, refusing to clobber an existing checksum output,
portable find/empty-array guards) — i.e. it narrows what passes rather than widening it. The
chore(web): carry audited lockfile baseline from #192 commit being separate is the right way
to keep that reviewable.
CI
mergeable_state=blocked; Validate Agent memory fails on this head with
pull access denied for minio/minio — the same Docker Hub anonymous-pull failure as
#198/#203/#205, occurring at container start before any project code runs.
Provenance
compare/260710d...145a987e5, the PR file list, and per-commit file attribution against the
body text. I read the script diffs; I did not execute any of the scripts/*.sh commands
locally, so every PASS in the ledger is unverified by me in both directions.
The one red check is external infrastructure, not this PRTracked in #207. Posting because this PR does edit the workflow that hosts the failing job, What is failing, verbatim
Why this PR's edit to
|
The evidence ledger describes a commit this PR is no longer onNot a vote. The artifacts that would justify a vote are pinned to a head that has The gap is ten commits, and one of them is yours
The commit that matters is your own Also in the unpinned range: Why this is not just bookkeepingThe body's provenance ledger is the mechanism this project uses to let a What would make this reviewable
Separately
|
## Canonical requirement Refs bytefolk/.github#32 - Canonical Issue URL: bytefolk/.github#32 - Consumed revision: R1 - No automatic close keywords: acknowledged Decision reference: the initial R1 Issue body. It explicitly records that local candidates preceded this prospective publication record; no retrospective approval is claimed. ## Requirement trace | REQ/AC IDs | Changed files / domain | Tests or review evidence | |---|---|---| | REQ-001 / AC-001 | 4 exact-pinned version annotations | Exact expected-byte replacement PASS | | REQ-002 / AC-002 | 2 files in bytefolk/mem | Repository inventory PASS; aggregate 7 repositories, 13 files, 21 lines | | REQ-003 / AC-003 | Existing workflow content and modes | Parsed YAML and comment-stripped bytes identical | | REQ-004 / AC-004 | Current-head CI and independent review | Local independent replay recorded in the canonical R1 Issue linked above; hosted CI collected on head `f464f686` (19 of 20 checks succeed, see Validation); independent human review requested and still pending | ## File domains `.github/workflows/bytefolk-scorecard.yml` (47); `.github/workflows/bytefolk-security.yml` (58, 65, 68). Prepared parent / merge base: `2986fe38175f54d99f15dd38a498708c6ecd88cd` PR base at publication: `87db0dfe0507be2190fe2fdcce0e267be8224f4d`. Since that baseline `main` advanced by six commits through `3c13f04e` (#162, #160, #165, #188, #158, #204) — not only `web/package-lock.json` as previously stated here. None of them touched `.github/workflows/`, so the F9 workflow blobs and the PR diff are unchanged. The reviewed commit and original parent are preserved. Head: `f464f68636adc6bb5295c3818aa6654c46a3caad` — `d2a9ec5` plus one non-forced `Merge branch 'main'` commit (`f464f686`) that brought the branch up to `3c13f04e` so it is no longer `BEHIND`. Verified: `git rev-parse d2a9ec5:.github/workflows/bytefolk-scorecard.yml` and `...:bytefolk-security.yml` return the same blobs (`2058126c`, `48a507e0`) as at `f464f686`, and `git diff main...f464f68` is still exactly these 2 files, `+4/-4`. The comment-only payload is therefore byte-identical to the reviewed commit and the equality proof above holds on the current head. ## Scope and non-goals Correct only `# v4.37.4` to `# v4.37.9` on CodeQL uses-lines pinned to `cdf488f595d80d6e07e03d4674febd5ab45fa938`. The [official tag object](https://api.github.com/repos/github/codeql-action/git/tags/a35ac6e6798d72df5475948b28efb89edc2e19ca) resolves to that existing pin. Action SHAs, permissions, triggers, steps, matrices, other pins, and runtime code are unchanged. ## Validation - Exact commands: `ruby evidence/verify.rb --baseline` and `ruby evidence/verify.rb --committed` from the retained review packet; `git diff --check 2986fe3 d2a9ec5` from this repository. - Observed counts/results: PASS 2/2 files and 4/4 replacements here; aggregate PASS 13/13 files and 21/21 replacements. Baseline intentionally exits 1 after detecting all 21 stale annotations; committed verification exits 0. - Check URLs: collected on head `f464f686` — 19 of 20 checks succeed. The single failure is [`HTTP, CLI and MCP lifecycle`](https://github.com/bytefolk/mem/actions/runs/34807101354/job/103861020551), whose log is `pull access denied for minio/minio` at ~13s: a container-image pull failure in an unrelated job. The same workflow was green on `main` at `3c13f04e`, and the identical failure is present on #198 and #199, so it is not caused by this comment-only change. Root-cause tracking is separate and open. The strict verifier checks the changed-file allowlist; exact old blobs and line inventory; complete expected-byte replacement; absence of stale target annotations; parsed YAML equality; comment-stripped byte equality and SHA-256 digests; whitespace and unchanged modes; one commit with the exact parent; and clean worktrees with no untracked files. All passed. The independent replay is recorded in canonical R1. The verifier and inventory are retained outside repository commits. | ID | REQ/AC | Observable acceptance criterion | Command or manual steps | Environment | Expected | Observed | Status | |---|---|---|---|---|---|---|---| | V1 | AC-001, AC-002, AC-003 | Exact annotations with executable YAML unchanged | `ruby evidence/verify.rb --committed` | Ruby 2.6.10, Psych 3.1.0, isolated review packet | Exact scoped replacements and equality | 2/2 files; 4/4 lines; all invariants pass | PASS | | V2 | AC-004 | Hosted checks on this exact head | Inspect this PR's checks at `f464f686` | GitHub Actions | Applicable checks succeed | 19 of 20 succeed; `HTTP, CLI and MCP lifecycle` fails on `pull access denied for minio/minio` (infra, unrelated job, also failing on #198/#199, green on `main`) | PARTIAL | ## Security and compatibility Documentation annotation only. No dependencies, permissions, credentials, data flows, or runtime behavior change. The diff and commit identity were inspected for public-safe content. No CHANGELOG entry or behavior-documentation update is needed because only explanatory comments change. ## Known limitations Runtime suites, build, coverage, and dependency audits were not rerun for this comment-only change; no runtime test result is claimed. Hosted CI is separate from local equality proof. Two limits now apply: (1) the strict verifier's `one commit with the exact parent` invariant describes the reviewed payload commit `d2a9ec5`, not the current branch shape, which carries two additional `Merge branch 'main'` commits; (2) this PR is **not merge-ready yet** — repository `AGENTS.md` step 6 requires passing CI *and* an approval from someone other than the author, and `HTTP, CLI and MCP lifecycle` is red on the unrelated `minio` pull, so the green-CI half is unmet until that infrastructure failure is fixed. ## Risk and rollback Low-risk annotation correction. Roll back through an ordinary revert of this single commit. There is no migration or release action. ## Product review handoff - Implementation/publication owner: @PeterGuy326 - Automated pre-review result: independent local replay recorded in R1; no human approval implied. - Human final review: PENDING; no human review requested by this publication. - Merge ledger owner: @PeterGuy326 - Product reviewer: @PeterGuy326 - Milestone or release packet: N/A: bounded documentation annotation maintenance - Merge, CI, release, and model judgment do not accept or close the Issue: acknowledged ## Maintenance update (2026-09-14, @waterbro-8) Records written by the maintainer account, not by the implementation owner: - `f464f686 Merge branch 'main'` was pushed to this head branch (non-forced, `main` at `3c13f04e` is an ancestor of the head) to clear the `BEHIND` state this PR's own body said blocked merging. No workflow file content changed: both blobs are identical to `d2a9ec5`. - The stale facts above were corrected in place: the recorded head SHA, the "Main advanced only `web/package-lock.json` in PR #192" claim, the `NOT VERIFIED` hosted-CI rows, and the "this is a draft, not merge-ready" note. - This PR was marked ready for review and an independent review was requested. The maintainer account that pushed the merge commit did **not** approve it: `AGENTS.md` step 6 requires an approval from someone other than the author, and a commit author on the head cannot supply that approval for their own push. `@PeterGuy326` remains implementation and merge-ledger owner. Co-authored-by: 勒布朗-詹姆斯 <2986253039@qq.com>
waterbro-8
left a comment
There was a problem hiding this comment.
Code review: approved
我逐条核对了改动,并且没有引用 PR 自述——结论全部来自当前 head 的代码和仓库现有内容。
一、最要命的那一问:会不会把现行版本校验打红?
这类收紧规则的改动,第一风险不是它自己写错,而是当前仓库已经不满足新规则。我按新逻辑在 main 上跑了一遍:
web/package.json:4与worker/pyproject.toml:3→ 当前版本0.1.1- CHANGELOG 的版本标题顺序:
## [0.1.1](116 行)→## [0.1.0](150 行) - 新增 awk 的语义是取第二个数字开头的标题 →
compare_base = 0.1.0 - 于是期望链接 =
[0.1.1]: https://github.com/bytefolk/mem/compare/v0.1.0...v0.1.1 - 仓库实际(441 行)=
[0.1.1]: https://github.com/bytefolk/mem/compare/v0.1.0...v0.1.1
逐字节相同。 前置版本存在时要求 compare、不存在时才允许 tag 形式,这条新规则对当前 head 是已经满足的,不需要连带改 CHANGELOG。
awk 的 if (seen++) 我也验了:第一次命中返回 0 不打印、seen 自增为 1;第二次命中返回 1 为真才打印并 exit。取到的确实是"紧邻的前一个版本",不是第一个、也不是最后一个。/^## \[[0-9]/ 同时把 ## [Unreleased] 排除了(U 不是数字)。
二、真正修掉的那个洞
require_absent_output 里的 -e 与 -L 是两回事,这是这条 PR 的实质:
[[ ! -e "${output}" && ! -L "${output}" ]] || die "checksum output path already exists"对一个悬空符号链接,-e 为假——只写 -e 的版本会放行它,然后 mv 顺着链接落到外部目录,把 manifest 写到资产树之外。加上 -L 才拦得住。测试里 dangling-symlink 这一例正是为此存在,并且它是先比对快照再看退出码的(原目录符号链接那个 bug 可能在 mv 已经写出去之后才失败,只看退出码会漏掉副作用)。
三、两处可移植性修正,都改在点子上
find -printf '%f\n'→find -exec basename {} \;:-printf是 GNU 独有,BSD find 没有。注释里提到+批量会让 GNU basename 拒收多个 operand,所以用\;逐条调用,这个细节是对的。wc -l→grep -c '':BSD 的wc -l < file输出带前导空格,[[ " 6" == 6 ]]判假。两个套件都改了,没有只改一处。
四、其余值得记一笔的
asset_listing="$(...)" || die:把 listing 先抓下来,避免进程替换吞掉find的退出状态,让一次工具失败伪装成"资产集合不符"这种误导性报错。[[ "${#actual_assets[@]}" -eq 0 ]]:空集合现在会失败,并且测试断言必须出现actual: <none>——空集合不再是"0 行 manifest 也算通过"。- 提交前第二次
require_absent_output:盖住了哈希期间才出现输出路径的窗口。测试用一个假sha256sum在被调用时植入符号链接,把这个窗口真正跑了一遍而不是只在注释里说。 - 断言 manifest 行数等于期望资产数:因为下游自校验用了
--ignore-missing,缺行本来会被静默容忍,所以在 staging 文件和期望集合都已知的这一刻补上断言是必要的。 - 测试目录名带空格(
assets with spaces、version fixture),并且symlink-file/directory/regular-file三例各自断言了原路径类型未被替换——不只是"命令失败了"。
五、我没有声称验证的事
我没在本机执行这些 shell(本机跑不了这条套件的完整环境)。以上是逐行读脚本 + 对当前仓库数据做静态比对得出的结论,不是运行时观测。合并前请以 CI 的 Validate Agent memory / CI 实际结果为准。
(本次为独立评审:我不是本 PR 作者,也不是其 head 的推送者。)
waterbro-8
left a comment
There was a problem hiding this comment.
Re-approving on the current head after the base-branch update (required so the most recent reviewable push is reviewed by someone other than the pusher). Assessment unchanged — see the review above.
Bindy-lbb
left a comment
There was a problem hiding this comment.
Mem PR #199 Review: LGTM (Approved) ✅
Key Review Highlights:
-
Changelog Comparison Link Validation (
scripts/validate_release_version.sh):- Strictly verifies that version comparison links in
CHANGELOG.mdcorrectly target the immediate predecessor (compare/v<predecessor>...v<version>). - For an initial release without a preceding version, only the exact release tag URL (
releases/tag/v<version>) is permitted. - Robustly guards against trailing path suffixes, mismatched comparison endpoints, or missing predecessors.
- Strictly verifies that version comparison links in
-
Atomic & Symlink-Safe Checksum Generation (
scripts/generate_release_checksums.sh):- Employs
mktemp "${output_file}.XXXXXX"within the asset directory to write manifests atomically, preventing symlink overwrite attacks and race conditions. - Robust handling for asset directories containing spaces.
- Replaces
wc -lwithgrep -c ''to ensure cross-platform compatibility across GNU and BSD coreutils.
- Employs
-
Release Guard Tests & CI:
- Added
scripts/test_release_checksum_output_safety.shand extendedtest_release_guards.shwith comprehensive negative and edge-case testing. - Enabled
workflow_dispatchinmemory-validation.yml. - All 20 GitHub CI checks have passed cleanly.
- Added
…) (#216) ## Requirement and scope Re-lands #157 onto current `main` as an organization branch. #157 was closed because the fork head could not carry CI, not because the work was rejected. Refs #151. Implementation owner on the issue is @waterbro-8; human review owner is @Bindy-lbb. Original implementation: @sun-970. ## Changes - Release workflow builds `memd`, `mem-migrate`, `mem-healthcheck`, and `mem` for linux/darwin amd64/arm64 in addition to `mem-mcp`. - Two checksum manifests: `mem-mcp-checksums.txt` (6) and `mem-checksums.txt` (16). The post-#199 output-path protections (no process-substitution find, no `wc -l`, refuse existing/late output symlinks, private mktemp staging) are kept and applied to both manifests. - `/v1/version` exposes distinct `version` / `revision` / `contract` fields; CLI `mem version` prints them and still redacts the server URL. - Docker image and DEPLOYMENT.md first-run notes from #157. ## Validation ledger | ID | Criterion | Command | Status | | --- | --- | --- | --- | | V1 | Checksum output safety | `bash scripts/test_release_checksum_output_safety.sh` | PASS | | V2 | Release guards | `bash scripts/test_release_guards.sh` | PASS | | V3 | Bash 3.2 helper compat | `bash scripts/test_release_helpers_compat.sh` | PASS | | V4 | `git diff --check` | local | PASS | | V5 | Go API/CLI tests | `make test-server` | NOT VERIFIED — host Go is 1.22.12, module requires 1.25.0 | | V6 | Built release binaries on six platforms | release workflow | NOT VERIFIED — no tag cut | | V7 | Client revision pin against a published memd | needs published artifact | NOT VERIFIED | No tag, GitHub Release, npm publish, merge, or issue closure is performed by this PR.
Tracking record and provenance
Refs #122 — bounded release-validation readiness, not publication or completion
of the release issue. Canonical draft successor to #170. Original author
sun-970and maintainer commits are preserved in ancestry. #170 remains openwith its original discussion and reviews; no original review is transferred
as an approval of this candidate.
fa2c30cc693bc0ae1e679e7d108d59aef1bd4007.260710d69a66f919520e5a4dccc3749335eb95fc.896aedb0069f688db3c46702147cf9ea7e015ba9has normalmerge parents, in order: source
fa2c30cc693bc0ae1e679e7d108d59aef1bd4007and actual canonical main
2986fe38175f54d99f15dd38a498708c6ecd88cd.5f1313f778ae2dc964c20d350b8829a365852100.unchanged
.github/workflows/bytefolk-security.ymland.github/workflows/bytefolk-scorecard.yml; source files remained exact atthat integration commit. The subsequent
260710dadds only the separatelyauthorized output-path safety fix and regressions described below.
11e02e21ef2c3dbd2dae26e4376872e54e78ecb5with its
cherry-pick -xtraceability. No original commit was rewritten.Summary and acceptance criteria
CHANGELOG comparison links must use the exact preceding version and release
endpoint. Missing predecessors fail closed; exact release-tag links remain
valid. GNU/Linux checksum enumeration must process each basename separately,
accept the correct six assets in a directory with spaces, reject an empty set
with an explicit diagnostic, and emit no manifest for invalid input.
An independent preflight then reproduced a separate unchanged-baseline gap:
an existing
mem-mcp-checksums.txtsymlink to a directory mademvpublishthe temporary manifest outside the asset directory. A later checksum failure
did not undo that write. This was NOT introduced by the basename fix and was
NOT fixed at original head
fa2c30cc. This successor now rejects all existingmanifest paths (including dangling symlinks) before hashing and immediately
before publication, preserving existing paths and external data. Staging still
uses randomized
mktemp, not a predictable filename.The canonical successor resolves the separate CI execution-path gate: main
requires three CodeQL language contexts, but the existing workflow skips fork
PRs. This same-repository candidate uses the existing allowed path without
editing security permissions, fork restrictions, required checks or tests.
Changed files against main:
CHANGELOG.md,scripts/generate_release_checksums.sh,scripts/test_release_guards.sh,scripts/validate_release_version.sh,scripts/test_release_checksum_output_safety.sh,web/package-lock.json. No securityworkflow differs from main.
Reproduction and attribution
On real GNU/Linux, base
7a194f1epasses the release guards, while pre-follow-up1624cf74fails with GNU basename'sextra operanderror becausefind -exec basename {} +batches paths. The fix invokes basename once per path with\;. The new comparison regression fails against the base wildcard validatorwith
wrong compare base v0.0.0: command unexpectedly succeeded.The earlier macOS
find -printffailure was not caused by the originalcomparison-link patch: its checksum script was byte-identical to base.
Public correction and evidence.
Do not confuse the Bash compatibility suite's find stub with actual GNU
semantics; the full guard suite uses real GNU find/basename/sha256sum.
Output-safety negative controls: the new focused regression fails on both
canonical main
2986fe38and pre-safety integration head896aedb0withsymlink-directory: output publication changed existing data or created an unexpected file.The fixed tree passes seven cases with path spaces: symlink-to-directory,
symlink-to-file, dangling symlink, existing directory, existing regular file,
an output symlink introduced during hashing, and a pre-existing template-shaped
temporary symlink. File-content snapshots verify external data and existing
outputs are preserved; the late-symlink case also verifies private staging
cleanup. This is bounded path-safety validation, not a claim of atomic defense
against a hostile process concurrently replacing paths after the final check;
release staging must remain controlled by the release job.
Validation ledger
Environment: isolated Linux aarch64, Linux 6.8, GNU find 4.9.0/coreutils 9.4,
Bash 5.2.21, Node 24.13.0/npm 11.6.2. The Node download is checksum-verified.
Fresh exact Git bundle clone, two CPUs, GOMAXPROCS=2 and GOFLAGS=-p=1.
git merge-base --is-ancestor fa2c30cc693bc0ae1e679e7d108d59aef1bd4007 HEADgit diff --stat 896aedb0069f688db3c46702147cf9ea7e015ba9 HEADbash scripts/test_release_guards.shbash scripts/test_release_checksum_output_safety.shbash scripts/test_release_helpers_compat.shbash scripts/test_validate_release_action_pins_compat.shbash scripts/validate_release_version.sh 0.1.1shellcheck scripts/generate_release_checksums.sh scripts/test_release_checksum_output_safety.sh scripts/test_release_guards.sh scripts/validate_release_version.shweb/:npm ci --registry=https://registry.npmjs.org --fetch-timeout=45000npm run audit --registry=https://registry.npmjs.orgnpm testnpm run lint/npm run typecheck/npm run buildgit diff --check 2986fe38175f54d99f15dd38a498708c6ecd88cd HEADTests, coverage and known limits
The source-head CI
and acceptance
passed; CodeQL was skipped there and did not satisfy its required contexts.
Those runs are source evidence, not the canonical successor's CI or review.
Coverage percentage was not remeasured. The new output-path safety regression
runs through the existing release-guard CI command; no job or check is removed.
Full stock-macOS release-guard portability is not claimed: existing BSD
wc -lpadding affects a row-count assertion. The full suite is validatedwith real GNU tools. The existing large-chunk build warning remains. Windows,
browser, Go/process and database acceptance use unchanged CI. No temporary
macOS Go executable is run; fixtures are disposable and create no real release.
Risk, rollback and review
Build/release-validation/dependency maintenance, no API/CLI/MCP authorization,
storage or migration contract change.
[Unreleased]documents the behavior.No custom repository secret is referenced by PR workflows; CodeQL uses its
existing security-events upload permission. Release/npm publication and
Scorecard are not triggered by these candidate branches. No tag, release,
original-PR closure, main merge, protection change or formal approval occurs.
Rollback is to leave this draft unmerged; no deployed behavior changes.
Draft pending exact-head required CI and independent review. The Owner relayed
an independent preflight PASS for the original comparison/enumeration delta;
that preflight found the baseline output-symlink gap and does not cover this
new safety commit. Fresh review of
260710dremains required. Original human-authored commits are retained; automatedassistance helped with maintainer remediation and validation evidence.