Skip to content

fix(release): contain installer artifact restores#103608

Merged
vincentkoc merged 1 commit into
mainfrom
codex/fix-installer-package-path-guard
Jul 10, 2026
Merged

fix(release): contain installer artifact restores#103608
vincentkoc merged 1 commit into
mainfrom
codex/fix-installer-package-path-guard

Conversation

@steipete

@steipete steipete commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Related: #103552
Follow-up to #103556

What Problem This Solves

Fixes an issue where installer release smoke could restore prebuilt package artifacts through candidate-owned package path aliases.

Why This Change Was Made

The trusted harness now resolves the restore root once, requires the bundled AI package owner paths to remain inside that root, and rejects linked intermediate package directories before Docker or filesystem side effects. Artifact install and rollback reuse those validated physical paths.

User Impact

Release validation now fails closed before modifying build artifacts when a candidate checkout does not provide normal package directories. Normal installer and Bun package smoke behavior is unchanged.

Evidence

  • Blacksmith Testbox through Crabbox tbx_01kx5nyaw5vg1e15mx40cd8jv6 / Actions run 29083395122: pnpm test test/scripts/test-install-sh-docker.test.ts (63/63 passed)
  • Same Testbox: targeted oxfmt --check passed
  • Same Testbox: pnpm check:changed tooling lane passed
  • Same Testbox, immutable harness 8ebe7753772d600b4037b9a389e8ee7662077332 plus frozen candidate 811ddd96180583bae00001f71971419182ae0520: full installer smoke passed, including package integrity, fresh install/runtime load, 2026.6.11 to 2026.7.1-beta.3 update/doctor/runtime load, freshness policy, and non-root installers (4m0.5s, exit 0)
  • Exact-head hosted CI: run 29083902332 completed successfully (55 jobs, no failures or pending jobs)
  • Repository autoreview on commit 8ebe7753772d: no accepted/actionable findings
  • Regression fixtures cover both intermediate path aliases, preserve the external sentinel and existing root artifact, and prove Docker is never invoked

AI-assisted; maintainer-reviewed proof and exact CI will remain attached to this PR.

@steipete
steipete requested a review from a team July 10, 2026 09:41
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts docker Docker and sandbox tooling size: S maintainer Maintainer-authored PR labels Jul 10, 2026
@steipete

steipete commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Pre-land proof for exact head 8ebe7753772d600b4037b9a389e8ee7662077332:

  • Blacksmith Testbox through Crabbox tbx_01kx5nyaw5vg1e15mx40cd8jv6 / Actions 29083395122: focused installer tooling tests passed (63/63), targeted formatting passed, and check:changed passed.
  • Immutable full installer smoke used this PR head as the trusted harness and frozen candidate 811ddd96180583bae00001f71971419182ae0520: package integrity, fresh install/runtime load, 2026.6.11 to 2026.7.1-beta.3 update/doctor/runtime load, freshness policy, and non-root installers all passed (4m0.5s, exit 0).
  • Exact-head hosted CI run 29083902332 completed successfully: 55 jobs, no failures or pending jobs.
  • Fresh commit autoreview reported no accepted/actionable findings.
  • openclaw-secops and openclaw-release-managers reviews are requested and remain the only owner-review waits.

@steipete
steipete requested review from a team, joshavant and vincentkoc July 10, 2026 09:55
@steipete

Copy link
Copy Markdown
Contributor Author

@vincentkoc @joshavant could one of you provide the human owner review for both the release-packaging and secops trust-boundary concerns here? You are members of both requested teams, so one approval from either of you covers both gates. Exact-head CI, immutable installer smoke, native prepare, and the focused security regressions are all green in the proof above.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 10, 2026
@clawsweeper

clawsweeper Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 10, 2026, 8:03 AM ET / 12:03 UTC.

Summary
The PR resolves trusted physical restore paths, rejects symlinked packages or packages/ai owners before side effects, reuses validated paths for rollback, and adds regression fixtures for both escapes.

PR surface: Tests +43, Other +26. Total +69 across 2 files.

Reproducibility: yes. from source inspection: the pre-fix helper follows candidate-owned packages and packages/ai components during trusted artifact moves, and the added fixtures deterministically model both escape paths. This read-only review did not execute the fixture itself.

Review metrics: none identified.

Root-cause cluster
Relationship: canonical
Canonical: #103608
Summary: This PR is the canonical item for the candidate-owned package-path containment flaw; the linked merged work concerns the preceding incomplete artifact-restore bug.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Obtain release/secops confirmation of the lifecycle trust invariant.
  • Refresh against current main and rerun focused plus immutable installer-smoke proof on the final head.

Risk before merge

  • [P1] The pathname checks depend on the documented trusted-workflow invariant that no candidate-controlled process can mutate the checkout between validation and restore; release/secops owners have not yet confirmed that invariant publicly.
  • [P1] The branch is behind current main, so the strong existing proof should be refreshed on the final integrated head even though the computed three-way merge is clean.

Maintainer options:

  1. Confirm invariant and merge final head (recommended)
    Release/secops confirms the no-concurrent-candidate-process assumption, then the focused and immutable installer-smoke proof is rerun on the integrated head.
  2. Pause for race-resistant containment
    If any candidate-controlled process can overlap restoration, pause and redesign the filesystem operation before landing.

Next step before merge

  • [P2] The remaining action is protected release/secops trust-boundary approval and refreshed final-head proof, not an automated code repair.

Maintainer decision needed

  • Question: Can release/secops owners confirm that every caller performs artifact restoration before any candidate-controlled process can mutate the checkout?
  • Rationale: The patch intentionally uses pathname validation under a documented trusted-harness lifecycle invariant rather than race-resistant filesystem handles, so only the workflow owners can confirm the security boundary.
  • Likely owner: vincentkoc — He introduced the shared restore lifecycle and is best positioned to verify its ordering across both installer-smoke callers.
  • Options:
    • Approve and refresh proof (recommended): Confirm the lifecycle invariant, integrate current main, and rerun the focused tests plus immutable installer smoke before merge.
    • Require stronger containment: If candidate mutation can overlap restoration, replace pathname validation with a race-resistant filesystem containment design.

Security
Needs attention: The patch strengthens the filesystem boundary without adding dependencies or permissions, but owner confirmation of its no-concurrent-mutation invariant remains required.

Review details

Best possible solution:

Keep the centralized physical-path validation and rollback design, obtain release/secops confirmation of its lifecycle invariant, then rerun focused and immutable installer smoke on the final integrated head.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: the pre-fix helper follows candidate-owned packages and packages/ai components during trusted artifact moves, and the added fixtures deterministically model both escape paths. This read-only review did not execute the fixture itself.

Is this the best way to solve the issue?

Yes, conditionally: validating once inside the existing shared restore helper and reusing those physical paths for swaps and rollback is the narrowest maintainable fix, provided workflow owners confirm the no-concurrency invariant.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 13819996adca.

Label changes

Label changes:

  • add P2: This is bounded release-validation hardening with important but limited direct user blast radius.
  • add merge-risk: 🚨 security-boundary: Merge safety depends on the trusted release workflow preventing candidate-controlled path mutation after validation.
  • add proof: sufficient: Contributor real behavior proof is sufficient. Exact-head Testbox results and an immutable full installer smoke demonstrate the after-fix package-integrity, fresh-install, update, doctor, freshness, and non-root paths with an observed successful result.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): Exact-head Testbox results and an immutable full installer smoke demonstrate the after-fix package-integrity, fresh-install, update, doctor, freshness, and non-root paths with an observed successful result.

Label justifications:

  • P2: This is bounded release-validation hardening with important but limited direct user blast radius.
  • merge-risk: 🚨 security-boundary: Merge safety depends on the trusted release workflow preventing candidate-controlled path mutation after validation.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): Exact-head Testbox results and an immutable full installer smoke demonstrate the after-fix package-integrity, fresh-install, update, doctor, freshness, and non-root paths with an observed successful result.
  • proof: sufficient: Contributor real behavior proof is sufficient. Exact-head Testbox results and an immutable full installer smoke demonstrate the after-fix package-integrity, fresh-install, update, doctor, freshness, and non-root paths with an observed successful result.
Evidence reviewed

PR surface:

Tests +43, Other +26. Total +69 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 1 56 13 +43
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 41 15 +26
Total 2 97 28 +69

Security concerns:

  • [medium] Confirm the no-concurrent-candidate-process invariant — scripts/lib/docker-e2e-package.sh:214
    The guard resolves and validates pathnames once, then later performs pathname-based moves; this is safe only if candidate-controlled code cannot mutate those directories concurrently, as the new comment asserts.
    Confidence: 0.9

What I checked:

  • Current-main behavior: Current main still detects and swaps the bundled AI artifact through $ROOT_DIR/packages/ai, so a candidate-owned intermediate symlink can redirect trusted restore operations. (scripts/lib/docker-e2e-package.sh:208, 13819996adca)
  • Containment implementation: The branch resolves the restore root physically, rejects linked package owners, proves the AI package remains below the root, and completes these checks before Docker creation or filesystem swaps. (scripts/lib/docker-e2e-package.sh:210, 8ebe7753772d)
  • Regression coverage: The added fixtures exercise both a symlinked packages directory and a symlinked packages/ai directory, verify external data remains unchanged, and prove Docker is not invoked. (test/scripts/test-install-sh-docker.test.ts:530, 8ebe7753772d)
  • Real behavior proof: The PR supplies exact-head focused Testbox results, successful hosted CI, and an immutable full installer smoke covering package integrity, fresh install, stable-to-candidate update, doctor, freshness policy, and non-root installers. (8ebe7753772d)
  • Clean current-main integration: A read-only three-way merge calculation against current main completed without conflicts; main-side drift in the touched test file is unrelated build-identity coverage. (test/scripts/test-install-sh-docker.test.ts:636, 13819996adca)
  • Feature provenance: The shared root-and-AI artifact restore helper was introduced by the merged installer-smoke repair, and this branch is a distinct containment follow-up rather than duplicate work already on main. (scripts/lib/docker-e2e-package.sh:155, 8755077fe45b)

Likely related people:

  • vincentkoc: Authored and merged the preceding installer-smoke repair that introduced the shared artifact restore lifecycle this PR hardens. (role: introduced behavior; confidence: high; commits: 0a7de77e44f5, e92771a1c2d3, 8755077fe45b; files: scripts/lib/docker-e2e-package.sh, scripts/docker/install-sh-smoke/run.sh, scripts/e2e/bun-global-install-smoke.sh)
  • steipete: Contributed prior merged installer-smoke hardening, including the loadability check in the preceding repair, and has repeated history in the affected install-smoke tests. (role: recent area contributor; confidence: high; commits: 3118589702f4, 6709589117ce, ec3bbae49b14; files: scripts/lib/docker-e2e-package.sh, test/scripts/test-install-sh-docker.test.ts, scripts/check-openclaw-package-tarball.mjs)
  • joshavant: The PR discussion explicitly requests his combined release-packaging and secops trust-boundary review, making him a likely approval owner for the remaining gate. (role: requested owner reviewer; confidence: medium; files: scripts/lib/docker-e2e-package.sh)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@vincentkoc vincentkoc self-assigned this Jul 10, 2026
@vincentkoc
vincentkoc merged commit 5635d74 into main Jul 10, 2026
153 of 163 checks passed
@vincentkoc
vincentkoc deleted the codex/fix-installer-package-path-guard branch July 10, 2026 15:27
@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docker Docker and sandbox tooling maintainer Maintainer-authored PR merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts size: S status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants