Fix backup verifier for root-relative hardlink targets#89328
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 2, 2026, 1:02 AM ET / 05:02 UTC. Summary PR surface: Source +6, Tests +33. Total +39 across 2 files. Reproducibility: yes. Source inspection shows current main rejects a hardlink target that is relative to the archive payload/root, and the PR adds a synthetic tar fixture that exercises that exact path. Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrow verifier compatibility fix if maintainer review and CI stay clean, while keeping the linked report open for separate live reproduction or repair of the backup-create temp archive failure. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main rejects a hardlink target that is relative to the archive payload/root, and the PR adds a synthetic tar fixture that exercises that exact path. Is this the best way to solve the issue? Yes for the verifier compatibility bug. The hardlink target validator is the narrow owner of this invariant; backup creation already dereferences hardlinks, so changing create logic would not address older archives. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 16808524cbd3. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +6, Tests +33. Total +39 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Follow-up to openclaw#89328. node-tar records a deduplicated hardlink's linkpath as the cwd-relative source path (e.g. .openclaw/state/db), so prepending only the archive-root segment still misses the real <root>/payload/posix/... target and older backups keep failing verify. node-tar dedupes only files under a shared cwd, so the target is <ancestor-of-link>/<linkpath>: walk the link entry's ancestor dirs and require an exact entry match. This also covers the root-relative shape openclaw#89328 added and avoids a loose suffix scan that let an unrelated same-named file mask a dropped/corrupt target.
Follow-up to openclaw#89328. node-tar records a deduplicated hardlink's linkpath as the cwd-relative source path (e.g. .openclaw/state/db), so prepending only the archive-root segment still misses the real <root>/payload/posix/... target and older backups keep failing verify. node-tar dedupes only files under a shared cwd, so the target is <ancestor-of-link>/<linkpath>: walk the link entry's ancestor dirs and require an exact entry match. This also covers the root-relative shape openclaw#89328 added and avoids a loose suffix scan that let an unrelated same-named file mask a dropped/corrupt target.
Follow-up to openclaw#89328. node-tar records a deduplicated hardlink's linkpath as the cwd-relative source path (e.g. .openclaw/state/db), so prepending only the archive-root segment still misses the real <root>/payload/posix/... target and older backups keep failing verify. node-tar dedupes only files under a shared cwd, so the target is <ancestor-of-link>/<linkpath>: walk the link entry's ancestor dirs and require an exact entry match. This also covers the root-relative shape openclaw#89328 added and avoids a loose suffix scan that let an unrelated same-named file mask a dropped/corrupt target.
Summary
Refs #89257
AI-assisted: yes, prepared with Codex and checked with
codex reviewbefore submission.Verification
node scripts/run-vitest.mjs src/commands/backup-verify.test.ts src/infra/backup-create.test.ts src/commands/backup.create-verify.test.ts src/commands/backup.atomic.test.ts src/cli/program/register.backup.test.tsgit diff --check -- src/commands/backup-verify.ts src/commands/backup-verify.test.tspnpm buildcodex review --base origin/mainReal behavior proof
Behavior addressed:
backup verifynow accepts older backup archives whose internal hardlink targets are recorded relative to the archive payload/root, while preserving rejection for unsafe or missing hardlink targets.Real environment tested: Source checkout on the PR branch, using a synthetic backup archive that matches the reported older internal hardlink shape. Release-branch reproduction of the verifier failure was confirmed separately before the fix.
Exact steps or command run after this patch:
node scripts/run-vitest.mjs src/commands/backup-verify.test.ts src/infra/backup-create.test.ts src/commands/backup.create-verify.test.ts src/commands/backup.atomic.test.ts src/cli/program/register.backup.test.tsgit diff --check -- src/commands/backup-verify.ts src/commands/backup-verify.test.tspnpm buildcodex review --base origin/mainEvidence after fix: Focused backup tests passed, build passed, Codex review reported no actionable regressions, and the disposable create/verify smoke printed
Archive verification: passedwith no.tmpfiles listed.Observed result after fix: The new verifier regression accepts the older internal hardlink target shape, while existing unsafe and missing hardlink target tests continue to pass.
What was not tested: Full
pnpm check && pnpm test; the reporter's actual archive; the reportedbackup create --verifyexit-13 temp archive failure; applying this fix torelease/2026.5.28.