Skip to content

fix(backup): support managed config and credentials links - #136343

Merged
obviyus merged 9 commits into
openclaw:mainfrom
vsumner:codex/backup-declared-absolute-symlinks
Sep 3, 2026
Merged

fix(backup): support managed config and credentials links#136343
obviyus merged 9 commits into
openclaw:mainfrom
vsumner:codex/backup-declared-absolute-symlinks

Conversation

@vsumner

@vsumner vsumner commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Closes #136326

What Problem This Solves

Native backup creation failed when the active config file or credentials directory was an absolute symbolic link to a Nix-managed path outside the state directory.

Root Cause

Backup planning used lexical state containment for credentials, so it could omit the external canonical asset. Archive creation then passed absolute first-hop link targets to the portable archive guard, which correctly rejected them.

Fix

  • Decide config and credentials coverage from their canonical paths while preserving active files inside volatile state roots.
  • Resolve absolute link chains to their final declared asset before writing a portable relative archive link.
  • Keep the existing archive guard unchanged for undeclared, dangling, and escaping links.
  • Document the managed-link archive contract.

Evidence

  • Current main failed native backup create --verify --json for direct and chained managed config links before publishing an archive.
  • Exact-head tests passed: 108 backup-create tests and 64 backup verify/restore tests, with 1 platform-specific skip.
  • Exact-head changed checks passed, including formatting, type checks, lint, dependency guards, architecture guards, and dead-export checks.
  • A fresh secretless Linux container created, verified, and restored direct and chained config and credentials links through the native CLI.
  • The restored links were relative, resolved inside the restore target, and exposed the original managed content.
  • Native undeclared, dangling, and escaping link probes still failed before archive publication.

Collaboration

Thanks @vsumner for the original repair and real Nix reproduction. Thanks @NianJiuZst for identifying and validating the chained-link case.

@clawsweeper

clawsweeper Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: S labels Sep 2, 2026
@vsumner
vsumner marked this pull request as ready for review September 2, 2026 13:57
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T14:05:30.443188Z 3b084a8 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3b084a844e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/infra/backup-create.ts Outdated
@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Sep 2, 2026
@clawsweeper

clawsweeper Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Codex review: blocked before merge. Reviewed September 3, 2026, 12:58 PM ET / 16:58 UTC.

ClawSweeper review

What this changes

The PR includes configured config and credentials symlink targets as backup assets, then rewrites eligible absolute links to portable archive-relative links.

Regression provenance

Possible regression — suspected (reviewed change). No predecessor PR is attributed.

Merge readiness

Blocked before merge - 3 items remain

Keep open: this PR directly owns the still-open backup bug and no introduced correctness defect was found. Current fetched main and the installed tar source were unavailable in this offline, blobless checkout, so this review does not claim a final merge-ready comparison.

Priority: P1
Reviewed head: 043014d1c11115ba8c6418c546ea7f6772f9be20

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The patch has focused owner-boundary coverage and a reported native CLI archive/verify/restore result, with remaining reviewer limitations around fetched main and the installed tar source.
Proof confidence 🐚 platinum hermit (4/6) Sufficient (terminal): The PR body reports a fresh secretless Linux native CLI run that created, verified, and restored direct and chained managed config and credentials links; the changed archive-owner tests independently assert portable relative links, restored content, and continued rejection of unsafe links. The repository has also marked this exact PR proof sufficient.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): The PR body reports a fresh secretless Linux native CLI run that created, verified, and restored direct and chained managed config and credentials links; the changed archive-owner tests independently assert portable relative links, restored content, and continued rejection of unsafe links. The repository has also marked this exact PR proof sufficient.
Evidence reviewed 8 items Planner preserves both ownership views: The planner records lexical and canonical config/credentials paths, then separately selects configured symlink paths so the archive retains the portable in-state link while the resolved target supplies content.
Archive exception remains asset-bound: The writer resolves an absolute link only when its final target is contained by a declared asset, then routes the result through the existing archive symlink validator.
Verification enforces the same boundary: Verification validates every symbolic link against the manifest asset paths before restore can extract the archive.
Findings None None.
Security None None.

How this fits together

The backup CLI plans state, configuration, credentials, and workspace assets before serializing them into a portable archive. Archive verification and restore consume that same manifest, so selection and symlink validation must enforce the same containment boundary.

flowchart LR
A[Configured config and credentials] --> B[Backup asset planner]
B --> C[Declared archive assets]
C --> D[Archive writer]
D --> E[Portable relative links]
E --> F[Verification and restore]
Loading

Before merge

  • Resolve merge risk (P1) - This intentionally changes compatibility: configured absolute config or credentials links that previously failed can now archive when their resolved target is declared. The manifest-contained-target condition must remain the sole exception to the absolute-link rejection rule.
  • Resolve merge risk (P1) - The review environment could not inspect the fetched current-main tree or tar@7.5.22 implementation because network access failed and node_modules is absent; maintainers should retain normal exact-head CI and current-main checks before merge.
  • Resolve review confidence - ClawSweeper must reach high confidence before merge readiness is known.
Agent review details

Security

None.

PR surface

Source +48, Tests +221, Docs 0. Total +269 across 8 files.

View PR surface stats
Area Files Added Removed Net
Source 3 71 23 +48
Tests 4 239 18 +221
Docs 1 1 1 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 8 311 42 +269

Review metrics

Metric Value Why it matters
Production versus test delta production +71/-23 (net +48); tests +239/-18 (net +221); docs +1/-1 The added production logic implements the paired lexical-link and resolved-target ownership boundary; the larger test delta covers archive creation, verification, restore, volatile paths, and native CLI behavior.
Archive-link contract 1 eligibility case added Previously rejected absolute configured links become portable only when their real target is manifest-declared, which is the compatibility surface maintainers need to accept.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #136326
Summary: This PR is the active candidate fix for the reported managed-config symlink backup failure.

Members:

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

Merge-risk options

Maintainer options:

  1. Accept the declared-asset compatibility contract (recommended)
    Merge only with the documented rule that an absolute configured link is portable when its resolved target is inside a manifest-declared asset.
  2. Pause for a different archive policy
    Keep rejecting every absolute link if maintainers do not want backups to restore managed config and credential links portably.

Technical review

Best possible solution:

Keep one manifest-owned symlink flow: archive the resolved configured asset and lexical configured link, rewrite only a resolved target inside a declared asset, and verify that same invariant before restore.

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

Yes. The linked report provides a concrete v2026.8.2 Linux symlink layout, and the added owner-boundary tests construct direct and chained config/credentials links through create, verify, and restore; this reviewer could not rerun them in the read-only dependency-less checkout.

Is this the best way to solve the issue?

Yes. The patch keeps the existing fail-closed archive guard and makes the exception at the manifest ownership boundary; broadly accepting absolute links would lose that containment guarantee.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1b6eea93c861.

Labels

Label justifications:

  • P1: Affected Nix-managed installations cannot create a verified native backup until this repair lands.
  • merge-risk: 🚨 compatibility: The PR intentionally changes archive behavior for existing configured absolute symlinks that previously failed closed.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body reports a fresh secretless Linux native CLI run that created, verified, and restored direct and chained managed config and credentials links; the changed archive-owner tests independently assert portable relative links, restored content, and continued rejection of unsafe links. The repository has also marked this exact PR proof sufficient.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body reports a fresh secretless Linux native CLI run that created, verified, and restored direct and chained managed config and credentials links; the changed archive-owner tests independently assert portable relative links, restored content, and continued rejection of unsafe links. The repository has also marked this exact PR proof sufficient.

Evidence

What I checked:

  • Planner preserves both ownership views: The planner records lexical and canonical config/credentials paths, then separately selects configured symlink paths so the archive retains the portable in-state link while the resolved target supplies content. (src/commands/backup-shared.ts:197, 043014d1c111)
  • Archive exception remains asset-bound: The writer resolves an absolute link only when its final target is contained by a declared asset, then routes the result through the existing archive symlink validator. (src/infra/backup-create.ts:346, 043014d1c111)
  • Verification enforces the same boundary: Verification validates every symbolic link against the manifest asset paths before restore can extract the archive. (src/commands/backup-verify.ts:645, 043014d1c111)
  • Boundary regression coverage: The table-driven test covers direct and chained config/credentials links, volatile configured paths, archive verification, restore, relative link output, and excluded neighbors. (src/infra/backup-create.test.ts:3101, 043014d1c111)
  • Native CLI coverage: The process test exercises backup create with an absolute managed config link and asserts verified JSON output plus the retained lexical state entry. (src/cli/help-exit.process.test.ts:435, 043014d1c111)
  • Documented archive contract: The CLI documentation now describes the narrow declared-asset exception while retaining rejection for other absolute, backslash, and escaping links. Public docs: docs/cli/backup.md. (docs/cli/backup.md:311, 043014d1c111)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • Vincent Koc: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (8 earlier review cycles)
  • reviewed 2026-09-02T14:14:53.573Z sha 3b084a8 :: needs real behavior proof before merge. :: [P2] Canonicalize chained absolute link targets | [P3] Document the declared absolute-link rewrite
  • reviewed 2026-09-02T15:28:10.132Z sha 4970988 :: needs real behavior proof before merge. :: [P2] Canonicalize chained absolute link targets | [P3] Document the declared-asset symlink rewrite
  • reviewed 2026-09-02T18:54:12.505Z sha 78cba81 :: needs real behavior proof before merge. :: none
  • reviewed 2026-09-02T19:11:52.109Z sha 78cba81 :: needs maintainer review before merge. :: none
  • reviewed 2026-09-02T20:56:50.859Z sha ea61cb7 :: needs maintainer review before merge. :: none
  • reviewed 2026-09-03T06:38:53.372Z sha 7208757 :: blocked before merge. :: [P1] Preserve managed links under volatile active paths
  • reviewed 2026-09-03T07:09:32.461Z sha 7208757 :: blocked before merge. :: [P1] Preserve managed links under volatile active paths
  • reviewed 2026-09-03T08:06:26.571Z sha 5f18aed :: blocked before merge. :: none

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. label Sep 2, 2026
@vsumner
vsumner force-pushed the codex/backup-declared-absolute-symlinks branch from 4970988 to 78cba81 Compare September 2, 2026 18:40
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation and removed extensions: codex labels Sep 2, 2026
@vsumner

vsumner commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@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: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Sep 2, 2026
@vsumner
vsumner force-pushed the codex/backup-declared-absolute-symlinks branch from 78cba81 to ea61cb7 Compare September 2, 2026 19:38
@vsumner

vsumner commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@obviyus obviyus changed the title fix(backup): support Nix-managed config symlinks fix(backup): support managed config and credentials links Sep 3, 2026
@clawsweeper clawsweeper Bot added P1 High-priority user-facing bug, regression, or broken workflow. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Sep 3, 2026
@obviyus

obviyus commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Sep 3, 2026
@openclaw-barnacle openclaw-barnacle Bot added the cli CLI command changes label Sep 3, 2026
@obviyus
obviyus merged commit 0aa9ae9 into openclaw:main Sep 3, 2026
206 checks passed
@obviyus

obviyus commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Thanks @vsumner!

Proof: Native backup CLI created, verified, and restored managed config and credentials links through the portable archive path.

  • Bug: A declared config or credentials link to a managed absolute path made backup creation fail before it published an archive.
  • Fix: Backup now archives the declared target and restores the configured link as a portable relative link.
Before After
Managed absolute links failed backup creation Managed links create, verify, and restore successfully

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Sep 4, 2026
…36343)

Closes openclaw#136326

## What Problem This Solves

Native backup creation failed when the active config file or credentials directory was an absolute symbolic link to a Nix-managed path outside the state directory.

## Root Cause

Backup planning used lexical state containment for credentials, so it could omit the external canonical asset. Archive creation then passed absolute first-hop link targets to the portable archive guard, which correctly rejected them.

## Fix

- Decide config and credentials coverage from their canonical paths while preserving active files inside volatile state roots.
- Resolve absolute link chains to their final declared asset before writing a portable relative archive link.
- Keep the existing archive guard unchanged for undeclared, dangling, and escaping links.
- Document the managed-link archive contract.

## Evidence

- Current `main` failed native `backup create --verify --json` for direct and chained managed config links before publishing an archive.
- Exact-head tests passed: 108 backup-create tests and 64 backup verify/restore tests, with 1 platform-specific skip.
- Exact-head changed checks passed, including formatting, type checks, lint, dependency guards, architecture guards, and dead-export checks.
- A fresh secretless Linux container created, verified, and restored direct and chained config and credentials links through the native CLI.
- The restored links were relative, resolved inside the restore target, and exposed the original managed content.
- Native undeclared, dangling, and escaping link probes still failed before archive publication.

## Collaboration

Thanks @vsumner for the original repair and real Nix reproduction. Thanks @NianJiuZst for identifying and validating the chained-link case.

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
180Sai pushed a commit to 180Sai/openclaw that referenced this pull request Sep 5, 2026
…36343)

Closes openclaw#136326

## What Problem This Solves

Native backup creation failed when the active config file or credentials directory was an absolute symbolic link to a Nix-managed path outside the state directory.

## Root Cause

Backup planning used lexical state containment for credentials, so it could omit the external canonical asset. Archive creation then passed absolute first-hop link targets to the portable archive guard, which correctly rejected them.

## Fix

- Decide config and credentials coverage from their canonical paths while preserving active files inside volatile state roots.
- Resolve absolute link chains to their final declared asset before writing a portable relative archive link.
- Keep the existing archive guard unchanged for undeclared, dangling, and escaping links.
- Document the managed-link archive contract.

## Evidence

- Current `main` failed native `backup create --verify --json` for direct and chained managed config links before publishing an archive.
- Exact-head tests passed: 108 backup-create tests and 64 backup verify/restore tests, with 1 platform-specific skip.
- Exact-head changed checks passed, including formatting, type checks, lint, dependency guards, architecture guards, and dead-export checks.
- A fresh secretless Linux container created, verified, and restored direct and chained config and credentials links through the native CLI.
- The restored links were relative, resolved inside the restore target, and exposed the original managed content.
- Native undeclared, dangling, and escaping link probes still failed before archive publication.

## Collaboration

Thanks @vsumner for the original repair and real Nix reproduction. Thanks @NianJiuZst for identifying and validating the chained-link case.

Co-authored-by: NianJiuZst <180004567+NianJiuZst@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes commands Command implementations docs Improvements or additions to documentation merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: backup fails for Nix-managed absolute config symlink

2 participants