Skip to content

feat(state): add key-level restore ownership to agent manifests#6445

Merged
cv merged 41 commits into
mainfrom
feat/manifest-key-level-state-ownership
Jul 12, 2026
Merged

feat(state): add key-level restore ownership to agent manifests#6445
cv merged 41 commits into
mainfrom
feat/manifest-key-level-state-ownership

Conversation

@laitingsheng

@laitingsheng laitingsheng commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Agent manifests can now declare key-level restore ownership for mixed-ownership state files. Managed restore preserves only manifest-owned user preferences while the current target manifest remains authoritative for generated configuration. Deep Agents Code is migrated to this schema, and the restore path now fails closed on unsafe manifests, paths, TOML, filesystem races, and target/backup mismatches.

Related Issue

Resolves #6334

Changes

  • Add a strict, discriminated state_files restore schema for key-allowlist and openclaw-config strategies, including canonical relative-path validation and rejection of duplicate or ancestor-overlapping ownership declarations.
  • Require the current target manifest to authorize the backup agent, config directory, state-file path, strategy, and restore ownership before SSH or filesystem mutation.
  • Make managed key-level merge the default. Whole-file restore is available only through the explicit allowCustomImageWholeStateFileRestore capability for custom-image restore.
  • Read bounded backup TOML directly from Python stdin, parse with tomllib, create a private unpredictable O_EXCL stage, traverse parent directories without following symlinks, and revalidate current/stage metadata before atomic replacement.
  • Preserve all safe leading comments, preserve non-dictionary fresh ancestors instead of clobbering them, and keep fresh managed tables and headers authoritative.
  • Migrate the Deep Agents Code manifest and remove the agent-specific restore-policy callback.
  • Document managed key-level restore, target-manifest authority, and the custom-Dockerfile whole-file exception.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: maintainer-assisted review of the behavior at dd65850 passed all nine security categories; current head f9e4537 adds only a formatting-only blank-line deletion to satisfy the onboard.ts net-growth guardrail.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — 175 focused CLI assertions plus 71 affected integration assertions passed; the final phase/contract rerun passed 23/23. npm run typecheck:cli, npm run build:cli, npm run test-size:check, and git diff --check also passed.
  • Applicable broad gate passed — not applicable locally; targeted CLI/integration coverage exercised every changed restore path, and repository CI is running on the exact head.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only) — build passed with 0 errors and 2 pre-existing hidden-page warnings
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only) — no new pages

Signed-off-by: Tinson Lai tinsonl@nvidia.com
Signed-off-by: Charan Jagwani cjagwani@nvidia.com

Summary by CodeRabbit

  • New Features
    • Added manifest-driven, fine-grained state-file restore rules with typed user key allowlists and “freshness” requirements.
    • Custom Dockerfile sandboxes can restore whole state files during rebuilds when enabled.
  • Bug Fixes
    • Snapshot restore now fails closed for unknown, unsafe, stale, or conflicting state data, with stronger atomic replacement safeguards.
  • Documentation
    • Updated sandbox backup/restore guidance to reflect key-level ownership semantics, allowed preference preservation, and restore failure behavior.

Agent manifests can now declare per-key restore ownership for
mixed-ownership state files. A key-allowlist merge restores only
typed, bounded, or enum user keys and requires the declared fresh
tables and headers; a named openclaw-config strategy covers OpenClaw's
deep merge. Ownership is validated at manifest load time and read from
the live manifest during restore, so snapshot format is unchanged and
existing manifests keep whole-file behavior until they opt in.

The generic restore engine now dispatches on the manifest instead of
agent-specific conditionals. Migrates Deep Agents Code onto the
declarative schema and removes its local config-restore workaround, and
re-homes OpenClaw's merge behind the manifest marker.

Resolves #6334

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@laitingsheng laitingsheng self-assigned this Jul 8, 2026
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds manifest-declared state-file restore ownership, strict validation, key-allowlisted TOML merging, atomic replacement, and target-manifest-driven sandbox restore routing. Rebuild and snapshot flows propagate target-agent and custom-image context with expanded restore and safety tests.

Changes

Manifest contracts and validation

Layer / File(s) Summary
Restore ownership schema and parsing
src/lib/agent/*, agents/*/manifest.yaml
Manifests declare restore strategies, typed user keys, freshness requirements, and validated state-file paths.
Manifest validation coverage
src/lib/agent/*test.ts
Tests cover valid declarations, invalid constraints, unsafe paths, and overlapping keys.

Key-allowlist merge engine

Layer / File(s) Summary
TOML merge and atomic replacement
src/lib/state/key-allowlist-merge/*, src/lib/state/state-file-key-merge.ts
Embedded Python validates TOML, preserves required headers and tables, merges typed allowlisted keys, and atomically replaces the target file.
Merge behavior and safety tests
src/lib/state/state-file-key-merge-*.test.ts, src/lib/state/state-file-key-merge-test-fixture.ts
Tests cover deterministic output, rejected data, validation failures, header handling, link defenses, race detection, and staged replacement.

Manifest-driven sandbox restore

Layer / File(s) Summary
Restore orchestration and strategy dispatch
src/lib/state/sandbox.ts, src/lib/state/state-file-restore.ts
Restore validates target manifests and backup contracts, then dispatches each state file to its declared restore strategy.
Legacy policy removal and documentation
src/lib/state/openclaw-config-restore-input.*, docs/manage-sandboxes/*
Caller-supplied policy APIs are removed, and manifest-authoritative restore behavior is documented.

Rebuild and creation restore wiring

Layer / File(s) Summary
Target context propagation
src/lib/actions/sandbox/*, src/lib/onboard*, test/helpers/*
Rebuild and creation flows pass target agent type and custom-image capability into restore operations.
Forwarding and finalization tests
src/lib/actions/sandbox/*test.ts, src/lib/onboard/*test.ts
Tests verify custom-image whole-file restoration and standardized restore options.

Snapshot restore and reconciliation coverage

Layer / File(s) Summary
Snapshot restore fixtures and lifecycle tests
src/lib/actions/sandbox/snapshot-restore-*
Shared mocks and tests cover restore delegation, lifecycle locking, destination safety, gateway conflicts, observability replay, and OTLP reconciliation.
Related restore test adjustments
test/snapshot.test.ts, src/lib/actions/sandbox/snapshot-auto-create-failure.test.ts, src/lib/onboard/created-sandbox-failure.test.ts
Existing tests update registry setup, messaging mocks, and secret-scanner annotations.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5101: Updates the OpenClaw manifest state-file entry touched by this restore ownership change.
  • NVIDIA/NemoClaw#5174: Changes OpenClaw configuration merging in the restore path used by this manifest-driven flow.
  • NVIDIA/NemoClaw#5178: Adds fail-closed coverage for OpenClaw configuration restore behavior.

Suggested labels: security, area: sandbox

Suggested reviewers: jyaunches, cv, prekshivyas

Sequence Diagram(s)

sequenceDiagram
  participant SnapshotRestore
  participant SandboxRestore
  participant AgentManifest
  participant StateFileRestore
  participant RemoteSandbox
  SnapshotRestore->>SandboxRestore: restore backup for target sandbox
  SandboxRestore->>AgentManifest: load target state-file declarations
  AgentManifest-->>SandboxRestore: validated ownership and strategy
  SandboxRestore->>StateFileRestore: restore each declared state file
  StateFileRestore->>RemoteSandbox: merge or atomically replace state file
  RemoteSandbox-->>StateFileRestore: restore result
  StateFileRestore-->>SandboxRestore: per-file success or failure
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing key-level restore ownership in agent manifests.
Linked Issues check ✅ Passed The manifest schema, validation, migration, tests, and Deep Agents Code restore refactor all align with #6334's objectives.
Out of Scope Changes check ✅ Passed The changes shown are focused on manifest-driven restore ownership, validation, migration, docs, and tests, with no clear unrelated additions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/manifest-key-level-state-ownership

Comment @coderabbitai help to get the list of available commands.

@laitingsheng laitingsheng removed their assignment Jul 8, 2026
@github-code-quality

github-code-quality Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage remains at 96%, unchanged from the branch.

TypeScript / code-coverage/cli

The overall coverage in the branch remains at 79%, unchanged from the branch.

Show a code coverage summary of the most impacted files.
File a31b29b 10b2361 +/-
src/lib/actions...oy-execution.ts 89% 58% -31%
src/lib/actions...dbox/destroy.ts 87% 73% -14%
src/lib/onboard...er-gpu-patch.ts 87% 78% -9%
src/lib/state/o...oard-session.ts 81% 84% +3%
src/lib/sandbox/config.ts 58% 72% +14%
src/lib/onboard...host-forward.ts 45% 100% +55%
src/lib/agent/s...store-reader.ts 0% 88% +88%
src/lib/actions...test-fixture.ts 0% 90% +90%
src/lib/state/s...file-restore.ts 0% 97% +97%
src/lib/state/s...test-fixture.ts 0% 98% +98%

Updated July 12, 2026 00:18 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-6: Custom-image whole-file restore trusts user-controlled backup content; then add or justify PRA-T1.
Open items: 2 required · 6 warnings · 1 suggestion · 8 test follow-ups
Since last review: 0 prior items resolved · 9 still apply · 4 new items found

Action checklist

  • PRA-6 Fix: Custom-image whole-file restore trusts user-controlled backup content in src/lib/state/state-file-restore.ts:115
  • PRA-7 Fix: Partial restore failure retry convergence not tested end-to-end in src/lib/state/state-file-restore.ts:105
  • PRA-1 Resolve or justify: Onboarding monolith grows without extraction despite 7+ concurrent PR overlaps in src/lib/onboard.ts:1
  • PRA-2 Resolve or justify: Key-allowlist Python split across 5 modules increases cognitive load without documented flow in src/lib/state/key-allowlist-merge/python-script.ts:1
  • PRA-3 Resolve or justify: Dual authority between manifest and runtime for custom-image restore trust boundary in src/lib/state/state-file-restore.ts:115
  • PRA-4 Resolve or justify: PR fix(dcode): require Landlock enforcement #5812 (Landlock) merge coordination required for shared manifest/onboarding files in src/lib/agent/manifest-readers.ts:1
  • PRA-8 Resolve or justify: Host and in-sandbox runtime version agreement not tested after custom-image rebuild in src/lib/actions/sandbox/rebuild-pipeline.ts:222
  • PRA-9 Resolve or justify: Hermes E2E coverage missing for new key-allowlist restore reader in src/lib/agent/state-file-restore-reader.ts:1
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
  • PRA-T6 Add or justify test follow-up: Partial restore failure retry convergence not tested end-to-end
  • PRA-T7 Add or justify test follow-up: Host and in-sandbox runtime version agreement not tested after custom-image rebuild
  • PRA-T8 Add or justify test follow-up: Hermes E2E coverage missing for new key-allowlist restore reader
  • PRA-5 In-scope improvement: Key-allowlist Python modules could be consolidated or documented in src/lib/state/key-allowlist-merge/python-script.ts:1

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture src/lib/onboard.ts:1 Coordinate with PR #5812 author for merge order since both touch manifest-readers.ts, definition-types.ts, defs.ts, onboard.ts. Consider a stacked PR or rebase sequence. Verify onboard-resume and onboard-repair jobs pass after each merge. Extract cohesive helpers (FSM state machine, gateway routing logic, shield timer management) in a follow-up PR.
PRA-2 Resolve/justify architecture src/lib/state/key-allowlist-merge/python-script.ts:1 Add a top-of-file comment in python-script.ts explaining the concatenation order and all security-critical invariants. Consider a single-file script with section comments if the split is only for testability. If the split is necessary, add a README or module-index comment documenting the flow.
PRA-3 Resolve/justify scope src/lib/state/state-file-restore.ts:115 Make the custom-image exception explicit in the manifest schema: add allowWholeFileOnCustomImage: true to the restore block so the manifest is the single source of truth. Update rebuild-pipeline.ts to read this from the manifest rather than inferring from fromDockerfile.
PRA-4 Resolve/justify architecture src/lib/agent/manifest-readers.ts:1 Coordinate with PR #5812 author for merge order. Consider a stacked PR or rebase sequence. Verify onboard-resume, onboard-repair, and hermes-e2e jobs pass after each merge. Landlock enforcement may require manifest schema changes that affect restore ownership parsing.
PRA-5 Improvement architecture src/lib/state/key-allowlist-merge/python-script.ts:1 If the split is only for testability, consolidate into one script with section comments. If modularity is needed, add a module-index comment in python-script.ts documenting the concatenation order and all security-critical invariants.
PRA-6 Required security src/lib/state/state-file-restore.ts:115 Add an explicit manifest field (e.g., restore: { merge: key-allowlist, allowWholeFileOnCustomImage: true }) so the manifest is the single source of truth. Alternatively, document the trust assumption in manifest schema comments and add an adversarial test in the state-backup-restore job exercising custom-image restore with adversarial backup content.
PRA-7 Required tests src/lib/state/state-file-restore.ts:105 Add an E2E test in the state-backup-restore or onboard-repair job that injects a transient SSH failure during restoreRecreatedSandboxState, then retries the restore and verifies convergence without ghost resources or stale ports.
PRA-8 Resolve/justify tests src/lib/actions/sandbox/rebuild-pipeline.ts:222 Add a test in the upgrade-stale-sandbox job that performs a custom-image Deep Agents rebuild with key-allowlist restore and verifies host/in-sandbox version agreement.
PRA-9 Resolve/justify tests src/lib/agent/state-file-restore-reader.ts:1 Ensure the hermes-e2e required job runs in CI and exercises a Hermes sandbox rebuild with snapshot restore, verifying the state-file-restore-reader processes the Hermes manifest correctly. Add a targeted Hermes rebuild test case if the job doesn't already cover it.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-6 Required — Custom-image whole-file restore trusts user-controlled backup content

  • Location: src/lib/state/state-file-restore.ts:115
  • Category: security
  • Problem: When targetImageIsCustom=true (from fromDockerfile), state-file-restore.ts branches to whole-file restore without key-allowlist validation, trusting user-controlled backup content including executable hooks, unknown keys, and credential-like strings. This creates a sandbox escape vector where a compromised custom-image backup can restore arbitrary TOML that the managed path explicitly drops.
  • Impact: A malicious or compromised custom-image backup could restore executable Deep Agents hooks, provider credentials, or unknown runtime keys, bypassing the key-allowlist ownership model declared in the manifest. The manifest is not the single source of truth for restore behavior.
  • Required action: Add an explicit manifest field (e.g., restore: { merge: key-allowlist, allowWholeFileOnCustomImage: true }) so the manifest is the single source of truth. Alternatively, document the trust assumption in manifest schema comments and add an adversarial test in the state-backup-restore job exercising custom-image restore with adversarial backup content.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 where targetImageIsCustom=true is passed, and src/lib/state/state-file-restore.ts:115 where allowCustomImageWholeStateFileRestore branches to whole-file command.
  • Missing regression test: state-backup-restore E2E test: create custom-image Deep Agents sandbox, inject adversarial config.toml backup (executable hooks, oversized values, credential-like strings), run snapshot restore, verify restored config matches backup exactly (whole-file semantics) and no key-allowlist filtering occurs.
  • Done when: The required change is committed and verification passes: Check src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 where targetImageIsCustom=true is passed, and src/lib/state/state-file-restore.ts:115 where allowCustomImageWholeStateFileRestore branches to whole-file command.
  • Evidence: src/lib/state/state-file-restore.ts:105-120 src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 docs/manage-sandboxes/backup-restore.mdx:140-145

PRA-7 Required — Partial restore failure retry convergence not tested end-to-end

  • Location: src/lib/state/state-file-restore.ts:105
  • Category: tests
  • Problem: The restoreRecreatedSandboxState function can return partial success with failedDirs/failedFiles, but no E2E test injects a transient SSH failure during restore, retries the restore, and verifies: (a) no ghost sandbox/port, (b) final state matches successful restore, (c) no duplicate resources. This invariant is required by the riskPlan upgrade-rebuild and lifecycle-state families.
  • Impact: A transient failure during snapshot restore could leave ghost resources, stale ports, or duplicate state on retry. The invariants 'partial failure and retry converge without ghost resources or stale ports' (lifecycle-state) and 'failed mutations remain retryable without destructive cleanup' (upgrade-rebuild) lack automated verification in required jobs state-backup-restore and onboard-repair.
  • Required action: Add an E2E test in the state-backup-restore or onboard-repair job that injects a transient SSH failure during restoreRecreatedSandboxState, then retries the restore and verifies convergence without ghost resources or stale ports.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check src/lib/state/state-file-restore.ts:105 for the restore function. Search test/e2e/ and .github/workflows/ for existing state-backup-restore or onboard-repair job tests.
  • Missing regression test: E2E test: create sandbox, create snapshot, inject transient SSH failure during restore (e.g., network partition), retry restore, verify (a) no ghost sandbox/port, (b) final state matches successful restore, (c) no duplicate resources.
  • Done when: The required change is committed and verification passes: Check src/lib/state/state-file-restore.ts:105 for the restore function. Search test/e2e/ and .github/workflows/ for existing state-backup-restore or onboard-repair job tests.
  • Evidence: src/lib/state/state-file-restore.ts:105 riskPlan.requiredJobs includes state-backup-restore and onboard-repair riskPlan invariants: partial failure and retry converge without ghost resources or stale ports
Review findings by urgency: 2 required fixes, 6 items to resolve/justify, 1 in-scope improvement

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Onboarding monolith grows without extraction despite 7+ concurrent PR overlaps

  • Location: src/lib/onboard.ts:1
  • Category: architecture
  • Problem: src/lib/onboard.ts remains 4,885 lines with no extraction. PR fix(dcode): require Landlock enforcement #5812 (Landlock) and 6+ other open PRs modify the same files (manifest-readers.ts, definition-types.ts, defs.ts, onboard.ts, both manifests). Merge coordination is required but no stacked PR or rebase sequence is established.
  • Impact: Concurrent modifications to the onboarding monolith increase merge conflict risk, reduce reviewability, and make it harder to verify invariant preservation across PRs. The lifecycle-state and shared-agent risk families both depend on this file.
  • Recommended action: Coordinate with PR fix(dcode): require Landlock enforcement #5812 author for merge order since both touch manifest-readers.ts, definition-types.ts, defs.ts, onboard.ts. Consider a stacked PR or rebase sequence. Verify onboard-resume and onboard-repair jobs pass after each merge. Extract cohesive helpers (FSM state machine, gateway routing logic, shield timer management) in a follow-up PR.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check gh pr view 5812 --json files for overlapping files. Review onboard-resume and onboard-repair job definitions in .github/workflows/.
  • Missing regression test: Integration test that exercises onboarding FSM with Landlock enforcement enabled, verifying state convergence across resume/repair paths.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check gh pr view 5812 --json files for overlapping files. Review onboard-resume and onboard-repair job definitions in .github/workflows/.
  • Evidence: src/lib/onboard.ts:1 (4885 lines) openPrOverlaps includes PR fix(dcode): require Landlock enforcement #5812 with 6 sameFiles riskPlan families lifecycle-state and shared-agent both match onboard.ts

PRA-2 Resolve/justify — Key-allowlist Python split across 5 modules increases cognitive load without documented flow

  • Location: src/lib/state/key-allowlist-merge/python-script.ts:1
  • Category: architecture
  • Problem: The key-allowlist merge logic is split across python-config.ts, python-entrypoint.ts, python-ownership.ts, python-script.ts, python-serialization.ts (total ~480 lines). No top-of-file comment explains the concatenation order or all security-critical invariants.
  • Impact: Reviewers must mentally reconstruct the merge pipeline across 5 files. Security-critical invariants (e.g., key ownership precedence, TOML serialization safety, prototype pollution defense) are distributed without a single reference point.
  • Recommended action: Add a top-of-file comment in python-script.ts explaining the concatenation order and all security-critical invariants. Consider a single-file script with section comments if the split is only for testability. If the split is necessary, add a README or module-index comment documenting the flow.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read python-script.ts and verify it documents the module sequence and invariants. Check if a single-file alternative would be simpler.
  • Missing regression test: None required for documentation, but cross-runtime TOML parity test (PRA-11) would exercise the full pipeline.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read python-script.ts and verify it documents the module sequence and invariants. Check if a single-file alternative would be simpler.
  • Evidence: src/lib/state/key-allowlist-merge/python-script.ts:1 src/lib/state/key-allowlist-merge/python-config.ts:104 lines src/lib/state/key-allowlist-merge/python-ownership.ts:103 lines src/lib/state/key-allowlist-merge/python-serialization.ts:131 lines

PRA-3 Resolve/justify — Dual authority between manifest and runtime for custom-image restore trust boundary

  • Location: src/lib/state/state-file-restore.ts:115
  • Category: scope
  • Problem: The custom-image whole-file restore exception is inferred from fromDockerfile at runtime (rebuild-pipeline.ts:222-224) rather than declared in the agent manifest. The manifest declares restore: { merge: key-allowlist } for Deep Agents, but the runtime overrides this based on fromDockerfile.
  • Impact: The manifest is not the single source of truth for restore behavior. A custom-image sandbox created from a manifest declaring key-allowlist will silently get whole-file restore semantics, violating the declared policy. This creates a trust boundary where runtime state overrides manifest policy.
  • Recommended action: Make the custom-image exception explicit in the manifest schema: add allowWholeFileOnCustomImage: true to the restore block so the manifest is the single source of truth. Update rebuild-pipeline.ts to read this from the manifest rather than inferring from fromDockerfile.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Compare agents/langchain-deepagents-code/manifest.yaml restore block (merge: key-allowlist) with rebuild-pipeline.ts:222-224 where targetImageIsCustom overrides it.
  • Missing regression test: Test that a Deep Agents manifest with merge: key-allowlist but fromDockerfile set gets whole-file restore (current behavior) vs. test that manifest with allowWholeFileOnCustomImage: true gets whole-file restore (proposed behavior).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Compare agents/langchain-deepagents-code/manifest.yaml restore block (merge: key-allowlist) with rebuild-pipeline.ts:222-224 where targetImageIsCustom overrides it.
  • Evidence: agents/langchain-deepagents-code/manifest.yaml:20-35 (restore: merge: key-allowlist) src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 (targetImageIsCustom from fromDockerfile) src/lib/state/state-file-restore.ts:115 (allowCustomImageWholeStateFileRestore branch)

PRA-4 Resolve/justify — PR #5812 (Landlock) merge coordination required for shared manifest/onboarding files

  • Location: src/lib/agent/manifest-readers.ts:1
  • Category: architecture
  • Problem: PR fix(dcode): require Landlock enforcement #5812 modifies 6 identical files: agents/langchain-deepagents-code/manifest.yaml, agents/openclaw/manifest.yaml, src/lib/agent/definition-types.ts, src/lib/agent/defs.ts, src/lib/agent/manifest-readers.ts, src/lib/onboard.ts. Both PRs modify manifest schema (restore blocks vs. Landlock fields) and readers. No merge order or rebase sequence established.
  • Impact: Concurrent merges could cause semantic conflicts: Landlock may add new manifest fields that interact with restore ownership, or reader changes could conflict. Both PRs affect the lifecycle-state and shared-agent risk families.
  • Recommended action: Coordinate with PR fix(dcode): require Landlock enforcement #5812 author for merge order. Consider a stacked PR or rebase sequence. Verify onboard-resume, onboard-repair, and hermes-e2e jobs pass after each merge. Landlock enforcement may require manifest schema changes that affect restore ownership parsing.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check gh pr view 5812 --json files for exact overlapping files. Review both PRs' manifest schema changes for compatibility.
  • Missing regression test: Integration test exercising Landlock enforcement + key-allowlist restore on same sandbox rebuild.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check gh pr view 5812 --json files for exact overlapping files. Review both PRs' manifest schema changes for compatibility.
  • Evidence: openPrOverlaps shows PR fix(dcode): require Landlock enforcement #5812 with 6 sameFiles Both PRs modify manifest-readers.ts and definition-types.ts riskPlan families lifecycle-state and shared-agent both match these files

PRA-8 Resolve/justify — Host and in-sandbox runtime version agreement not tested after custom-image rebuild

  • Location: src/lib/actions/sandbox/rebuild-pipeline.ts:222
  • Category: tests
  • Problem: No test verifies that host and in-sandbox runtime versions agree after a custom-image rebuild with key-allowlist restore. The riskPlan upgrade-rebuild invariant 'host and in-sandbox runtime versions agree after mutation' lacks coverage for the new custom-image restore path.
  • Impact: A version mismatch after custom-image rebuild could leave the sandbox in an inconsistent state where the host expects one runtime version but the sandbox runs another, breaking subsequent operations.
  • Recommended action: Add a test in the upgrade-stale-sandbox job that performs a custom-image Deep Agents rebuild with key-allowlist restore and verifies host/in-sandbox version agreement.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check rebuild-pipeline.ts for version check logic. Search test/e2e/ for upgrade-stale-sandbox job tests covering custom-image rebuild.
  • Missing regression test: E2E test: create custom-image Deep Agents sandbox, trigger rebuild with key-allowlist restore, verify host and in-sandbox runtime versions agree after mutation.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check rebuild-pipeline.ts for version check logic. Search test/e2e/ for upgrade-stale-sandbox job tests covering custom-image rebuild.
  • Evidence: src/lib/actions/sandbox/rebuild-pipeline.ts:222 (targetImageIsCustom passed to restore) riskPlan.requiredJobs includes upgrade-stale-sandbox riskPlan invariant: host and in-sandbox runtime versions agree after mutation

PRA-9 Resolve/justify — Hermes E2E coverage missing for new key-allowlist restore reader

  • Location: src/lib/agent/state-file-restore-reader.ts:1
  • Category: tests
  • Problem: The new state-file-restore-reader.ts module parses restore ownership from agent manifests. The riskPlan declares hermes-e2e as a required job for the shared-agent family, but no evidence shows it exercises a Hermes sandbox rebuild with snapshot restore using the new reader with openclaw-config strategy.
  • Impact: If the restore reader has Hermes-specific parsing issues (e.g., openclaw-config vs key-allowlist strategy differences), they would not be caught before merge. The shared-agent invariant 'both supported agents become ready and complete a real turn' requires this coverage.
  • Recommended action: Ensure the hermes-e2e required job runs in CI and exercises a Hermes sandbox rebuild with snapshot restore, verifying the state-file-restore-reader processes the Hermes manifest correctly. Add a targeted Hermes rebuild test case if the job doesn't already cover it.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check .github/workflows/ for hermes-e2e job definition and whether it includes snapshot restore. Search test/e2e/ for Hermes rebuild tests.
  • Missing regression test: Hermes E2E test: create Hermes sandbox, create snapshot, trigger rebuild, verify restore reader processes openclaw-config merge strategy correctly and Hermes becomes ready.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check .github/workflows/ for hermes-e2e job definition and whether it includes snapshot restore. Search test/e2e/ for Hermes rebuild tests.
  • Evidence: src/lib/agent/state-file-restore-reader.ts:1 (new module) riskPlan.requiredJobs includes hermes-e2e for shared-agent family agents/openclaw/manifest.yaml declares restore: { merge: openclaw-config }

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

PRA-5 Improvement — Key-allowlist Python modules could be consolidated or documented

  • Location: src/lib/state/key-allowlist-merge/python-script.ts:1
  • Category: architecture
  • Problem: The 5-module split for key-allowlist merge increases cognitive load. A single script with clear section boundaries would be simpler to review and audit, or a module index documenting the flow.
  • Impact: Distributed security-critical logic across 5 files makes it harder to verify invariants (key ownership precedence, TOML serialization safety, prototype pollution defense) in a single review pass.
  • Suggested action: If the split is only for testability, consolidate into one script with section comments. If modularity is needed, add a module-index comment in python-script.ts documenting the concatenation order and all security-critical invariants.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check if python-script.ts imports the other 4 modules in sequence. Verify all security invariants are documented in one place.
  • Missing regression test: Cross-runtime TOML parity test would exercise the full pipeline regardless of module structure.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: src/lib/state/key-allowlist-merge/python-script.ts:1 src/lib/state/key-allowlist-merge/python-config.ts:104 lines src/lib/state/key-allowlist-merge/python-ownership.ts:103 lines src/lib/state/key-allowlist-merge/python-serialization.ts:131 lines
Simplification opportunities: 1 possible cut, net -200 lines possible

These are safe simplification checks only. Do not remove validation, security controls, data-loss prevention, or required tests.

  • PRA-5 shrink (src/lib/state/key-allowlist-merge/python-script.ts:1): 5 Python modules (python-config.ts, python-entrypoint.ts, python-ownership.ts, python-script.ts, python-serialization.ts) totaling ~480 lines for key-allowlist merge
    • Replacement: Single Python script with section comments, or documented module index with concatenation order and security invariants
    • Net: -200 lines
    • Safety boundary: Key-allowlist merge is security-critical; any consolidation must preserve all validation logic and test coverage
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Run the `full-e2e` E2E job for Shared agent abstractions must retain equivalent lifecycle behavior for OpenClaw and Hermes. Matched files: `src/lib/agent/definition-types.ts`, `src/lib/agent/defs.ts`, `src/lib/agent/manifest-readers.ts`, `src/lib/agent/state-file-restore-reader.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent invariants. 100+ unit/mock test blocks cover happy paths, error paths, policy reconciliation, and manifest validation. Required jobs (full-e2e, hermes-e2e, onboard-resume, onboard-repair, state-backup-restore, upgrade-stale-sandbox) declared in riskPlan but E2E coverage gaps exist for: (1) partial failure retry convergence, (2) version agreement after custom-image rebuild, (3) Hermes restore reader coverage.
  • PRA-T2 Runtime validation — E2E test in state-backup-restore or onboard-repair job: inject transient SSH failure during restoreRecreatedSandboxState, retry restore, verify convergence without ghost resources or stale ports (covers F-008). Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent invariants. 100+ unit/mock test blocks cover happy paths, error paths, policy reconciliation, and manifest validation. Required jobs (full-e2e, hermes-e2e, onboard-resume, onboard-repair, state-backup-restore, upgrade-stale-sandbox) declared in riskPlan but E2E coverage gaps exist for: (1) partial failure retry convergence, (2) version agreement after custom-image rebuild, (3) Hermes restore reader coverage.
  • PRA-T3 Runtime validation — Run the `hermes-e2e` E2E job for Shared agent abstractions must retain equivalent lifecycle behavior for OpenClaw and Hermes. Matched files: `src/lib/agent/definition-types.ts`, `src/lib/agent/defs.ts`, `src/lib/agent/manifest-readers.ts`, `src/lib/agent/state-file-restore-reader.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent invariants. 100+ unit/mock test blocks cover happy paths, error paths, policy reconciliation, and manifest validation. Required jobs (full-e2e, hermes-e2e, onboard-resume, onboard-repair, state-backup-restore, upgrade-stale-sandbox) declared in riskPlan but E2E coverage gaps exist for: (1) partial failure retry convergence, (2) version agreement after custom-image rebuild, (3) Hermes restore reader coverage.
  • PRA-T4 Runtime validation — E2E test in upgrade-stale-sandbox job: custom-image Deep Agents rebuild with key-allowlist restore, verify host/in-sandbox runtime version agreement (covers F-009). Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent invariants. 100+ unit/mock test blocks cover happy paths, error paths, policy reconciliation, and manifest validation. Required jobs (full-e2e, hermes-e2e, onboard-resume, onboard-repair, state-backup-restore, upgrade-stale-sandbox) declared in riskPlan but E2E coverage gaps exist for: (1) partial failure retry convergence, (2) version agreement after custom-image rebuild, (3) Hermes restore reader coverage.
  • PRA-T5 Runtime validation — Run the `onboard-repair` E2E job for Onboarding and sandbox state must converge across persisted metadata, reported status, and the live runtime. Matched files: `src/lib/actions/sandbox/rebuild-pipeline.ts`, `src/lib/actions/sandbox/rebuild-restore-phase.ts`, `src/lib/actions/sandbox/snapshot-restore-test-fixture.ts`, `src/lib/onboard.ts`, `src/lib/onboard/created-sandbox-finalization.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent invariants. 100+ unit/mock test blocks cover happy paths, error paths, policy reconciliation, and manifest validation. Required jobs (full-e2e, hermes-e2e, onboard-resume, onboard-repair, state-backup-restore, upgrade-stale-sandbox) declared in riskPlan but E2E coverage gaps exist for: (1) partial failure retry convergence, (2) version agreement after custom-image rebuild, (3) Hermes restore reader coverage.
  • PRA-T6 Partial restore failure retry convergence not tested end-to-end — Add an E2E test in the state-backup-restore or onboard-repair job that injects a transient SSH failure during restoreRecreatedSandboxState, then retries the restore and verifies convergence without ghost resources or stale ports.
  • PRA-T7 Host and in-sandbox runtime version agreement not tested after custom-image rebuild — Add a test in the upgrade-stale-sandbox job that performs a custom-image Deep Agents rebuild with key-allowlist restore and verifies host/in-sandbox version agreement.
  • PRA-T8 Hermes E2E coverage missing for new key-allowlist restore reader — Ensure the hermes-e2e required job runs in CI and exercises a Hermes sandbox rebuild with snapshot restore, verifying the state-file-restore-reader processes the Hermes manifest correctly. Add a targeted Hermes rebuild test case if the job doesn't already cover it.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Onboarding monolith grows without extraction despite 7+ concurrent PR overlaps

  • Location: src/lib/onboard.ts:1
  • Category: architecture
  • Problem: src/lib/onboard.ts remains 4,885 lines with no extraction. PR fix(dcode): require Landlock enforcement #5812 (Landlock) and 6+ other open PRs modify the same files (manifest-readers.ts, definition-types.ts, defs.ts, onboard.ts, both manifests). Merge coordination is required but no stacked PR or rebase sequence is established.
  • Impact: Concurrent modifications to the onboarding monolith increase merge conflict risk, reduce reviewability, and make it harder to verify invariant preservation across PRs. The lifecycle-state and shared-agent risk families both depend on this file.
  • Recommended action: Coordinate with PR fix(dcode): require Landlock enforcement #5812 author for merge order since both touch manifest-readers.ts, definition-types.ts, defs.ts, onboard.ts. Consider a stacked PR or rebase sequence. Verify onboard-resume and onboard-repair jobs pass after each merge. Extract cohesive helpers (FSM state machine, gateway routing logic, shield timer management) in a follow-up PR.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check gh pr view 5812 --json files for overlapping files. Review onboard-resume and onboard-repair job definitions in .github/workflows/.
  • Missing regression test: Integration test that exercises onboarding FSM with Landlock enforcement enabled, verifying state convergence across resume/repair paths.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check gh pr view 5812 --json files for overlapping files. Review onboard-resume and onboard-repair job definitions in .github/workflows/.
  • Evidence: src/lib/onboard.ts:1 (4885 lines) openPrOverlaps includes PR fix(dcode): require Landlock enforcement #5812 with 6 sameFiles riskPlan families lifecycle-state and shared-agent both match onboard.ts

PRA-2 Resolve/justify — Key-allowlist Python split across 5 modules increases cognitive load without documented flow

  • Location: src/lib/state/key-allowlist-merge/python-script.ts:1
  • Category: architecture
  • Problem: The key-allowlist merge logic is split across python-config.ts, python-entrypoint.ts, python-ownership.ts, python-script.ts, python-serialization.ts (total ~480 lines). No top-of-file comment explains the concatenation order or all security-critical invariants.
  • Impact: Reviewers must mentally reconstruct the merge pipeline across 5 files. Security-critical invariants (e.g., key ownership precedence, TOML serialization safety, prototype pollution defense) are distributed without a single reference point.
  • Recommended action: Add a top-of-file comment in python-script.ts explaining the concatenation order and all security-critical invariants. Consider a single-file script with section comments if the split is only for testability. If the split is necessary, add a README or module-index comment documenting the flow.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read python-script.ts and verify it documents the module sequence and invariants. Check if a single-file alternative would be simpler.
  • Missing regression test: None required for documentation, but cross-runtime TOML parity test (PRA-11) would exercise the full pipeline.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read python-script.ts and verify it documents the module sequence and invariants. Check if a single-file alternative would be simpler.
  • Evidence: src/lib/state/key-allowlist-merge/python-script.ts:1 src/lib/state/key-allowlist-merge/python-config.ts:104 lines src/lib/state/key-allowlist-merge/python-ownership.ts:103 lines src/lib/state/key-allowlist-merge/python-serialization.ts:131 lines

PRA-3 Resolve/justify — Dual authority between manifest and runtime for custom-image restore trust boundary

  • Location: src/lib/state/state-file-restore.ts:115
  • Category: scope
  • Problem: The custom-image whole-file restore exception is inferred from fromDockerfile at runtime (rebuild-pipeline.ts:222-224) rather than declared in the agent manifest. The manifest declares restore: { merge: key-allowlist } for Deep Agents, but the runtime overrides this based on fromDockerfile.
  • Impact: The manifest is not the single source of truth for restore behavior. A custom-image sandbox created from a manifest declaring key-allowlist will silently get whole-file restore semantics, violating the declared policy. This creates a trust boundary where runtime state overrides manifest policy.
  • Recommended action: Make the custom-image exception explicit in the manifest schema: add allowWholeFileOnCustomImage: true to the restore block so the manifest is the single source of truth. Update rebuild-pipeline.ts to read this from the manifest rather than inferring from fromDockerfile.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Compare agents/langchain-deepagents-code/manifest.yaml restore block (merge: key-allowlist) with rebuild-pipeline.ts:222-224 where targetImageIsCustom overrides it.
  • Missing regression test: Test that a Deep Agents manifest with merge: key-allowlist but fromDockerfile set gets whole-file restore (current behavior) vs. test that manifest with allowWholeFileOnCustomImage: true gets whole-file restore (proposed behavior).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Compare agents/langchain-deepagents-code/manifest.yaml restore block (merge: key-allowlist) with rebuild-pipeline.ts:222-224 where targetImageIsCustom overrides it.
  • Evidence: agents/langchain-deepagents-code/manifest.yaml:20-35 (restore: merge: key-allowlist) src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 (targetImageIsCustom from fromDockerfile) src/lib/state/state-file-restore.ts:115 (allowCustomImageWholeStateFileRestore branch)

PRA-4 Resolve/justify — PR #5812 (Landlock) merge coordination required for shared manifest/onboarding files

  • Location: src/lib/agent/manifest-readers.ts:1
  • Category: architecture
  • Problem: PR fix(dcode): require Landlock enforcement #5812 modifies 6 identical files: agents/langchain-deepagents-code/manifest.yaml, agents/openclaw/manifest.yaml, src/lib/agent/definition-types.ts, src/lib/agent/defs.ts, src/lib/agent/manifest-readers.ts, src/lib/onboard.ts. Both PRs modify manifest schema (restore blocks vs. Landlock fields) and readers. No merge order or rebase sequence established.
  • Impact: Concurrent merges could cause semantic conflicts: Landlock may add new manifest fields that interact with restore ownership, or reader changes could conflict. Both PRs affect the lifecycle-state and shared-agent risk families.
  • Recommended action: Coordinate with PR fix(dcode): require Landlock enforcement #5812 author for merge order. Consider a stacked PR or rebase sequence. Verify onboard-resume, onboard-repair, and hermes-e2e jobs pass after each merge. Landlock enforcement may require manifest schema changes that affect restore ownership parsing.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check gh pr view 5812 --json files for exact overlapping files. Review both PRs' manifest schema changes for compatibility.
  • Missing regression test: Integration test exercising Landlock enforcement + key-allowlist restore on same sandbox rebuild.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check gh pr view 5812 --json files for exact overlapping files. Review both PRs' manifest schema changes for compatibility.
  • Evidence: openPrOverlaps shows PR fix(dcode): require Landlock enforcement #5812 with 6 sameFiles Both PRs modify manifest-readers.ts and definition-types.ts riskPlan families lifecycle-state and shared-agent both match these files

PRA-5 Improvement — Key-allowlist Python modules could be consolidated or documented

  • Location: src/lib/state/key-allowlist-merge/python-script.ts:1
  • Category: architecture
  • Problem: The 5-module split for key-allowlist merge increases cognitive load. A single script with clear section boundaries would be simpler to review and audit, or a module index documenting the flow.
  • Impact: Distributed security-critical logic across 5 files makes it harder to verify invariants (key ownership precedence, TOML serialization safety, prototype pollution defense) in a single review pass.
  • Suggested action: If the split is only for testability, consolidate into one script with section comments. If modularity is needed, add a module-index comment in python-script.ts documenting the concatenation order and all security-critical invariants.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check if python-script.ts imports the other 4 modules in sequence. Verify all security invariants are documented in one place.
  • Missing regression test: Cross-runtime TOML parity test would exercise the full pipeline regardless of module structure.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: src/lib/state/key-allowlist-merge/python-script.ts:1 src/lib/state/key-allowlist-merge/python-config.ts:104 lines src/lib/state/key-allowlist-merge/python-ownership.ts:103 lines src/lib/state/key-allowlist-merge/python-serialization.ts:131 lines

PRA-6 Required — Custom-image whole-file restore trusts user-controlled backup content

  • Location: src/lib/state/state-file-restore.ts:115
  • Category: security
  • Problem: When targetImageIsCustom=true (from fromDockerfile), state-file-restore.ts branches to whole-file restore without key-allowlist validation, trusting user-controlled backup content including executable hooks, unknown keys, and credential-like strings. This creates a sandbox escape vector where a compromised custom-image backup can restore arbitrary TOML that the managed path explicitly drops.
  • Impact: A malicious or compromised custom-image backup could restore executable Deep Agents hooks, provider credentials, or unknown runtime keys, bypassing the key-allowlist ownership model declared in the manifest. The manifest is not the single source of truth for restore behavior.
  • Required action: Add an explicit manifest field (e.g., restore: { merge: key-allowlist, allowWholeFileOnCustomImage: true }) so the manifest is the single source of truth. Alternatively, document the trust assumption in manifest schema comments and add an adversarial test in the state-backup-restore job exercising custom-image restore with adversarial backup content.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 where targetImageIsCustom=true is passed, and src/lib/state/state-file-restore.ts:115 where allowCustomImageWholeStateFileRestore branches to whole-file command.
  • Missing regression test: state-backup-restore E2E test: create custom-image Deep Agents sandbox, inject adversarial config.toml backup (executable hooks, oversized values, credential-like strings), run snapshot restore, verify restored config matches backup exactly (whole-file semantics) and no key-allowlist filtering occurs.
  • Done when: The required change is committed and verification passes: Check src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 where targetImageIsCustom=true is passed, and src/lib/state/state-file-restore.ts:115 where allowCustomImageWholeStateFileRestore branches to whole-file command.
  • Evidence: src/lib/state/state-file-restore.ts:105-120 src/lib/actions/sandbox/rebuild-pipeline.ts:222-224 docs/manage-sandboxes/backup-restore.mdx:140-145

PRA-7 Required — Partial restore failure retry convergence not tested end-to-end

  • Location: src/lib/state/state-file-restore.ts:105
  • Category: tests
  • Problem: The restoreRecreatedSandboxState function can return partial success with failedDirs/failedFiles, but no E2E test injects a transient SSH failure during restore, retries the restore, and verifies: (a) no ghost sandbox/port, (b) final state matches successful restore, (c) no duplicate resources. This invariant is required by the riskPlan upgrade-rebuild and lifecycle-state families.
  • Impact: A transient failure during snapshot restore could leave ghost resources, stale ports, or duplicate state on retry. The invariants 'partial failure and retry converge without ghost resources or stale ports' (lifecycle-state) and 'failed mutations remain retryable without destructive cleanup' (upgrade-rebuild) lack automated verification in required jobs state-backup-restore and onboard-repair.
  • Required action: Add an E2E test in the state-backup-restore or onboard-repair job that injects a transient SSH failure during restoreRecreatedSandboxState, then retries the restore and verifies convergence without ghost resources or stale ports.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check src/lib/state/state-file-restore.ts:105 for the restore function. Search test/e2e/ and .github/workflows/ for existing state-backup-restore or onboard-repair job tests.
  • Missing regression test: E2E test: create sandbox, create snapshot, inject transient SSH failure during restore (e.g., network partition), retry restore, verify (a) no ghost sandbox/port, (b) final state matches successful restore, (c) no duplicate resources.
  • Done when: The required change is committed and verification passes: Check src/lib/state/state-file-restore.ts:105 for the restore function. Search test/e2e/ and .github/workflows/ for existing state-backup-restore or onboard-repair job tests.
  • Evidence: src/lib/state/state-file-restore.ts:105 riskPlan.requiredJobs includes state-backup-restore and onboard-repair riskPlan invariants: partial failure and retry converge without ghost resources or stale ports

PRA-8 Resolve/justify — Host and in-sandbox runtime version agreement not tested after custom-image rebuild

  • Location: src/lib/actions/sandbox/rebuild-pipeline.ts:222
  • Category: tests
  • Problem: No test verifies that host and in-sandbox runtime versions agree after a custom-image rebuild with key-allowlist restore. The riskPlan upgrade-rebuild invariant 'host and in-sandbox runtime versions agree after mutation' lacks coverage for the new custom-image restore path.
  • Impact: A version mismatch after custom-image rebuild could leave the sandbox in an inconsistent state where the host expects one runtime version but the sandbox runs another, breaking subsequent operations.
  • Recommended action: Add a test in the upgrade-stale-sandbox job that performs a custom-image Deep Agents rebuild with key-allowlist restore and verifies host/in-sandbox version agreement.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check rebuild-pipeline.ts for version check logic. Search test/e2e/ for upgrade-stale-sandbox job tests covering custom-image rebuild.
  • Missing regression test: E2E test: create custom-image Deep Agents sandbox, trigger rebuild with key-allowlist restore, verify host and in-sandbox runtime versions agree after mutation.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check rebuild-pipeline.ts for version check logic. Search test/e2e/ for upgrade-stale-sandbox job tests covering custom-image rebuild.
  • Evidence: src/lib/actions/sandbox/rebuild-pipeline.ts:222 (targetImageIsCustom passed to restore) riskPlan.requiredJobs includes upgrade-stale-sandbox riskPlan invariant: host and in-sandbox runtime versions agree after mutation

PRA-9 Resolve/justify — Hermes E2E coverage missing for new key-allowlist restore reader

  • Location: src/lib/agent/state-file-restore-reader.ts:1
  • Category: tests
  • Problem: The new state-file-restore-reader.ts module parses restore ownership from agent manifests. The riskPlan declares hermes-e2e as a required job for the shared-agent family, but no evidence shows it exercises a Hermes sandbox rebuild with snapshot restore using the new reader with openclaw-config strategy.
  • Impact: If the restore reader has Hermes-specific parsing issues (e.g., openclaw-config vs key-allowlist strategy differences), they would not be caught before merge. The shared-agent invariant 'both supported agents become ready and complete a real turn' requires this coverage.
  • Recommended action: Ensure the hermes-e2e required job runs in CI and exercises a Hermes sandbox rebuild with snapshot restore, verifying the state-file-restore-reader processes the Hermes manifest correctly. Add a targeted Hermes rebuild test case if the job doesn't already cover it.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check .github/workflows/ for hermes-e2e job definition and whether it includes snapshot restore. Search test/e2e/ for Hermes rebuild tests.
  • Missing regression test: Hermes E2E test: create Hermes sandbox, create snapshot, trigger rebuild, verify restore reader processes openclaw-config merge strategy correctly and Hermes becomes ready.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check .github/workflows/ for hermes-e2e job definition and whether it includes snapshot restore. Search test/e2e/ for Hermes rebuild tests.
  • Evidence: src/lib/agent/state-file-restore-reader.ts:1 (new module) riskPlan.requiredJobs includes hermes-e2e for shared-agent family agents/openclaw/manifest.yaml declares restore: { merge: openclaw-config }

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

Merge posture: No blocking advisor findings
Primary next action: No advisor follow-up required beyond maintainer review.
Findings: 0 required · 0 warnings · 0 optional suggestions
Since last review: 1 prior item resolved · 0 still apply · 0 new items found

Workflow run details

This is an automated review. Required findings need action before merge. Warnings and optional suggestions do not require a response or follow-up. A human maintainer makes the final merge decision.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: credential-sanitization, security-posture, full-e2e, hermes-e2e, onboard-repair, onboard-resume, state-backup-restore, upgrade-stale-sandbox, cloud-onboard, snapshot-commands
Optional E2E: sandbox-rebuild, ubuntu-repo-cloud-langchain-deepagents-code

Dispatch hint: cloud-onboard,credential-sanitization,full-e2e,hermes-e2e,onboard-repair,onboard-resume,security-posture,snapshot-commands,state-backup-restore,upgrade-stale-sandbox

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • credential-sanitization: Required by deterministic risk plan for credential/security-boundary changes; validates that snapshot/rebuild/onboard flows do not leak or revive credentials.
  • security-posture: Required by deterministic risk plan for security-boundary changes; validates fail-closed sandbox posture across OpenClaw and Hermes live sandboxes.
  • full-e2e: Required by deterministic risk plan for shared agent abstraction and manifest-reader changes; validates OpenClaw live onboarding, readiness, inference, credentials, and runtime behavior.
  • hermes-e2e: Required by deterministic risk plan for shared agent abstraction changes; validates Hermes live onboarding and runtime behavior is not broken by shared manifest/state-file restore changes.
  • onboard-repair: Required by deterministic risk plan for lifecycle-state changes and by the onboarding resume/repair rule for onboarding finalization/state transition changes.
  • onboard-resume: Required by deterministic risk plan for lifecycle-state changes and by the onboarding resume/repair rule for onboarding finalization/state transition changes.
  • state-backup-restore: Required by deterministic risk plan for state backup/restore and manifest-defined durable state-file behavior.
  • upgrade-stale-sandbox: Required by deterministic risk plan for upgrade/rebuild restore changes; validates state preservation and retryability across a stale sandbox upgrade.
  • cloud-onboard: src/lib/onboard.ts and created-sandbox finalization changes can affect full hosted onboarding after sandbox creation, restore, route validation, and registry publication.
  • snapshot-commands: State-file restore ownership, snapshot restore lifecycle, and observability policy reconciliation changes affect the real snapshot create/list/restore user flow.

Optional E2E

  • sandbox-rebuild: Adjacent confidence for the direct sandbox rebuild command after rebuild restore target-agent/custom-image option forwarding changes.
  • ubuntu-repo-cloud-langchain-deepagents-code: Adjacent typed live target for Deep Agents manifest/state-file restore ownership changes; useful if capacity allows because this PR changes Deep Agents config.toml restore rules.

New E2E recommendations

  • managed-state-file-restore-ownership (high): Existing live jobs cover broad backup/restore and snapshot flows, but there is no clearly dedicated live E2E that mutates Deep Agents config.toml allowlisted and non-allowlisted keys, rebuilds/restores, then proves fresh inference route tables/headers win while only user-owned keys survive.
    • Suggested test: Add a Deep Agents managed state-file restore ownership E2E covering key-allowlist merge, malformed config failure, and no whole-file fallback on managed images.
  • custom-image-state-file-restore (medium): This PR introduces an explicit custom-image whole-state-file restore capability, but current live recommendations rely mostly on unit tests for the managed-vs-custom image split.
    • Suggested test: Add a custom-Dockerfile snapshot/rebuild restore E2E proving whole-file restore is allowed only for custom Deep Agents targets and rejected for managed targets.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: cloud-onboard,credential-sanitization,full-e2e,hermes-e2e,onboard-repair,onboard-resume,security-posture,snapshot-commands,state-backup-restore,upgrade-stale-sandbox

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: full-e2e, hermes-e2e, onboard-repair, onboard-resume, state-backup-restore, upgrade-stale-sandbox
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=full-e2e
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-e2e
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=state-backup-restore
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=upgrade-stale-sandbox

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • full-e2e: Shared agent abstractions must retain equivalent lifecycle behavior for OpenClaw and Hermes.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=full-e2e
  • hermes-e2e: Shared agent abstractions must retain equivalent lifecycle behavior for OpenClaw and Hermes.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-e2e
  • onboard-repair: Onboarding and sandbox state must converge across persisted metadata, reported status, and the live runtime.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair
  • onboard-resume: Onboarding and sandbox state must converge across persisted metadata, reported status, and the live runtime.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • state-backup-restore: Upgrade, rebuild, snapshot, and restore operations must preserve user state while replacing stale runtime state.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=state-backup-restore
  • upgrade-stale-sandbox: Upgrade, rebuild, snapshot, and restore operations must preserve user state while replacing stale runtime state.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=upgrade-stale-sandbox

Optional E2E targets

  • None.

Relevant changed files

  • agents/langchain-deepagents-code/manifest.yaml
  • agents/openclaw/manifest.yaml
  • src/lib/actions/sandbox/rebuild-pipeline.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.ts
  • src/lib/agent/definition-types.ts
  • src/lib/agent/defs.ts
  • src/lib/agent/manifest-readers.ts
  • src/lib/agent/state-file-restore-reader.ts
  • src/lib/onboard.ts
  • src/lib/onboard/created-sandbox-finalization.ts
  • src/lib/state/dcode-config-restore-input.ts
  • src/lib/state/key-allowlist-merge/python-config.ts
  • src/lib/state/key-allowlist-merge/python-entrypoint.ts
  • src/lib/state/key-allowlist-merge/python-ownership.ts
  • src/lib/state/key-allowlist-merge/python-script.ts
  • src/lib/state/key-allowlist-merge/python-serialization.ts
  • src/lib/state/openclaw-config-restore-input.ts
  • src/lib/state/sandbox.ts
  • src/lib/state/state-file-key-merge.ts
  • src/lib/state/state-file-restore-policy.ts
  • src/lib/state/state-file-restore.ts
  • src/lib/actions/sandbox/snapshot-restore-test-fixture.ts
  • src/lib/state/state-file-key-merge-test-fixture.ts

@coderabbitai coderabbitai 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.

Actionable comments posted: 5

🧹 Nitpick comments (3)
src/lib/state/state-file-key-merge.test.ts (2)

300-321: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Prefer behavioral coverage for the generated restore command.

This test locks on command substrings and embedded source details, but does not prove the command safely stages, replaces, or rejects unsafe paths. Consider making the Python executable injectable for tests and running the generated command against temp files.

As per path instructions, tests should prefer observable outcomes through the public boundary over source-text assertions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/state/state-file-key-merge.test.ts` around lines 300 - 321, The test
for buildKeyAllowlistMergeRestoreCommand is too implementation-focused, since it
asserts command substrings and embedded source text instead of observable
restore behavior. Update the coverage to exercise the public boundary by making
the Python executable used by buildKeyAllowlistMergeRestoreCommand injectable
for tests, then run the generated restore command against temp files to verify
it stages, replaces, and rejects unsafe paths correctly. Keep the assertions
centered on the outcomes of buildKeyAllowlistMergeRestoreCommand rather than
checking internal command fragments or KEY_ALLOWLIST_MERGE_PYTHON source
details.

Source: Path instructions


21-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Avoid replacing the TOML boundary with JSON-backed fakes.

The wrapper executes the merge algorithm, but not production TOML parsing/serialization. Use real TOML fixtures with the actual tomllib/tomli_w path where possible, so malformed TOML, TOML numeric forms, and emitted TOML are covered.

As per path instructions, tests should prefer observable behavior and flag broad mocks that bypass the behavior under test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/state/state-file-key-merge.test.ts` around lines 21 - 50, The test
wrapper currently fakes tomllib and tomli_w with JSON-backed modules, which
bypasses the real TOML behavior under test. Update the state-file merge tests in
state-file-key-merge.test.ts to use real TOML fixtures and the actual
tomllib/tomli_w path where possible, so the merge logic is exercised against
genuine TOML parsing, malformed TOML, numeric forms, and emitted TOML; keep the
wrapper focused on running the script rather than replacing
serialization/parsing semantics.

Source: Path instructions

src/lib/agent/definition-types.ts (1)

46-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Encode restore ownership as a discriminated union.

The exported interface currently permits invalid combinations like merge: "openclaw-config" with userKeys, or merge: "key-allowlist" without userKeys. Encoding the parser invariants in the type keeps downstream restore dispatch harder to misuse.

Suggested type tightening
-export interface StateFileRestoreOwnership {
-  merge: StateFileRestoreMerge;
-  userKeys?: readonly StateFileUserKey[];
-  requireFreshTables?: readonly string[];
-  requireFreshHeaders?: readonly StateFileFreshHeader[];
-}
+export type StateFileRestoreOwnership =
+  | {
+      merge: "openclaw-config";
+      userKeys?: never;
+      requireFreshTables?: never;
+      requireFreshHeaders?: never;
+    }
+  | {
+      merge: "key-allowlist";
+      userKeys: readonly StateFileUserKey[];
+      requireFreshTables?: readonly string[];
+      requireFreshHeaders?: readonly StateFileFreshHeader[];
+    };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/agent/definition-types.ts` around lines 46 - 51, Update
StateFileRestoreOwnership in definition-types.ts to a discriminated union keyed
by merge so the parser invariants are encoded in the type. Keep the existing
StateFileRestoreMerge symbol as the discriminator, but split the current
interface into branch types so the key-allowlist shape requires userKeys and the
openclaw-config shape forbids it, while preserving requireFreshTables and
requireFreshHeaders only where valid. Make sure any downstream references to
StateFileRestoreOwnership continue to compile against the new union.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/agent/defs.test.ts`:
- Around line 529-734: The new behavior-oriented test titles in defs.test.ts are
missing the required local issue suffix; update each added it(...) description
to end with the linked issue reference in the final "(`#1234`)" form. Keep the
existing test intent the same, and only adjust the titles for the affected
restore-related cases so they follow the project’s test naming convention.

In `@src/lib/agent/manifest-readers.ts`:
- Around line 140-210: The `readStateFileUserKey` parser currently accepts
`values`, `min/max`, and `max_length` but silently ignores any other properties
on `raw`, which lets typos in `restore` and `user_keys[]` records pass
unnoticed. Add a fail-closed unknown-field check in `readStateFileUserKey` (and
the related restore-schema reader referenced by this path) by validating the
allowed keys for each `type` and throwing on any extra property such as
misspelled `requireFreshTables` or `maxLength`, so only explicitly supported
fields are accepted.

In `@src/lib/state/sandbox.ts`:
- Around line 876-880: The restore flow in sandbox.ts is failing open when
`loadAgent()` throws, because the `agent` load in the ownership restore path
swallows every error and returns an empty ownership map. Update the restore
logic around `loadAgent`, `restore ownership`, and the downstream restore
decision near the wholesale-restore fallback so that manifest load/validation
failures are treated as state-file restore failures, not as unmanaged restores;
this should fail closed and prevent managed files from bypassing the key
allowlist validation.

In `@src/lib/state/state-file-key-merge.ts`:
- Around line 108-136: The validation helper value_allowed currently lets
non-finite numbers through and uses loose equality for enum matching. Update
value_allowed in state-file-key-merge so the number branch explicitly rejects
NaN and infinities before applying min/max checks, and make the enum branch
require strict membership against the allowed values without allowing
boolean/integer coercion. Keep the fix localized to value_allowed and any
restore path that depends on it.
- Around line 278-280: Reject unsafe state-file paths before building the
restore command in state-file-key-merge logic. In the code that composes
`destination` from `normalizedDir` and `spec.path`, add a local `path.posix`
validation or parsing-time rejection so absolute paths and any `..` segments are
refused before concatenation. Keep the fix near the restore-command assembly
that uses `shellQuote`, and ensure `stateFileKeyMergeSpec`/`state_files`
handling cannot resolve outside the intended `dir`.

---

Nitpick comments:
In `@src/lib/agent/definition-types.ts`:
- Around line 46-51: Update StateFileRestoreOwnership in definition-types.ts to
a discriminated union keyed by merge so the parser invariants are encoded in the
type. Keep the existing StateFileRestoreMerge symbol as the discriminator, but
split the current interface into branch types so the key-allowlist shape
requires userKeys and the openclaw-config shape forbids it, while preserving
requireFreshTables and requireFreshHeaders only where valid. Make sure any
downstream references to StateFileRestoreOwnership continue to compile against
the new union.

In `@src/lib/state/state-file-key-merge.test.ts`:
- Around line 300-321: The test for buildKeyAllowlistMergeRestoreCommand is too
implementation-focused, since it asserts command substrings and embedded source
text instead of observable restore behavior. Update the coverage to exercise the
public boundary by making the Python executable used by
buildKeyAllowlistMergeRestoreCommand injectable for tests, then run the
generated restore command against temp files to verify it stages, replaces, and
rejects unsafe paths correctly. Keep the assertions centered on the outcomes of
buildKeyAllowlistMergeRestoreCommand rather than checking internal command
fragments or KEY_ALLOWLIST_MERGE_PYTHON source details.
- Around line 21-50: The test wrapper currently fakes tomllib and tomli_w with
JSON-backed modules, which bypasses the real TOML behavior under test. Update
the state-file merge tests in state-file-key-merge.test.ts to use real TOML
fixtures and the actual tomllib/tomli_w path where possible, so the merge logic
is exercised against genuine TOML parsing, malformed TOML, numeric forms, and
emitted TOML; keep the wrapper focused on running the script rather than
replacing serialization/parsing semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 120f5162-3224-49e2-8cef-4df049d98759

📥 Commits

Reviewing files that changed from the base of the PR and between be3e7cc and 004846e.

📒 Files selected for processing (16)
  • agents/langchain-deepagents-code/manifest.yaml
  • agents/openclaw/manifest.yaml
  • src/lib/agent/definition-types.ts
  • src/lib/agent/defs.test.ts
  • src/lib/agent/defs.ts
  • src/lib/agent/manifest-readers.ts
  • src/lib/onboard/created-sandbox-finalization.test.ts
  • src/lib/onboard/created-sandbox-finalization.ts
  • src/lib/state/dcode-config-restore-input.test.ts
  • src/lib/state/dcode-config-restore-input.ts
  • src/lib/state/openclaw-config-restore-input.test.ts
  • src/lib/state/openclaw-config-restore-input.ts
  • src/lib/state/sandbox.ts
  • src/lib/state/state-file-key-merge.test.ts
  • src/lib/state/state-file-key-merge.ts
  • src/lib/state/state-file-restore-policy.ts
💤 Files with no reviewable changes (4)
  • src/lib/state/state-file-restore-policy.ts
  • src/lib/state/dcode-config-restore-input.test.ts
  • src/lib/state/dcode-config-restore-input.ts
  • src/lib/state/openclaw-config-restore-input.ts

Comment thread src/lib/agent/defs.test.ts Outdated
Comment thread src/lib/agent/manifest-readers.ts Outdated
Comment thread src/lib/state/sandbox.ts Outdated
Comment thread src/lib/state/state-file-key-merge.ts Outdated
Comment thread src/lib/state/state-file-key-merge.ts
@laitingsheng laitingsheng added the feature PR adds or expands user-visible functionality label Jul 8, 2026
…uild and snapshot restore

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
…s own module

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
…st merge

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/actions/sandbox/snapshot-restore.test.ts`:
- Around line 446-490: Add test coverage for the positive
applyManagedStateFileRestore path in the snapshot restore flow. In this
`it.each` case inside `runSandboxSnapshot`, assert the `restoreSandboxStateMock`
call includes `applyManagedStateFileRestore: true` when the source sandbox uses
the DCode agent (`langchain-deepagents-code`) and the clone target matches the
no-Dockerfile scenario that should flip `usesManagedDcodeIdentity` to true.
Update the existing restore assertions in this test block to verify the full
options passed to `restoreSandboxStateMock`, not just the `false` branch.

In `@src/lib/agent/state-file-restore-reader.test.ts`:
- Around line 20-27: The cleanup in afterEach for tempAgentDirs currently
introduces an if guard, which violates the test-file guardrail. Update the
afterEach logic in state-file-restore-reader.test.ts to remove the conditional
by restructuring the loop so it only processes defined entries from
tempAgentDirs, while preserving the recursive fs.rmSync cleanup behavior. Use
the existing afterEach and tempAgentDirs symbols to locate and adjust the
teardown code.

In `@src/lib/agent/state-file-restore-reader.ts`:
- Around line 182-212: In readStateFileFreshHeaders, add the same strict object
validation used elsewhere in the manifest parser so require_fresh_headers
entries reject unknown keys before reading fields. Also stop defaulting match
via readString(raw, "match") ?? "exact"; instead require match to be either
absent or an explicit string value, and throw if it is present but not a string
or not one of the allowed values. Keep the existing array and value checks, but
make the object path consistent with restore/user_keys validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: eda4fae1-da0b-4011-880d-6b8bf196262c

📥 Commits

Reviewing files that changed from the base of the PR and between 004846e and a25f9ed.

📒 Files selected for processing (18)
  • agents/langchain-deepagents-code/manifest.yaml
  • src/lib/actions/sandbox/rebuild-dcode-recovery.test.ts
  • src/lib/actions/sandbox/rebuild-local-provider-recreate.test.ts
  • src/lib/actions/sandbox/rebuild-pipeline.ts
  • src/lib/actions/sandbox/rebuild-prepared-recovery.test.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.test.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.ts
  • src/lib/actions/sandbox/snapshot-restore.test.ts
  • src/lib/actions/sandbox/snapshot.test.ts
  • src/lib/actions/sandbox/snapshot.ts
  • src/lib/agent/defs.test.ts
  • src/lib/agent/manifest-readers.ts
  • src/lib/agent/state-file-restore-reader.test.ts
  • src/lib/agent/state-file-restore-reader.ts
  • src/lib/state/sandbox.ts
  • src/lib/state/state-file-key-merge.ts
  • test/helpers/rebuild-flow-lifecycle-cases.ts
  • test/helpers/rebuild-flow-recovery-cases.ts
💤 Files with no reviewable changes (1)
  • src/lib/agent/defs.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/actions/sandbox/rebuild-prepared-recovery.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • agents/langchain-deepagents-code/manifest.yaml
  • src/lib/state/state-file-key-merge.ts
  • src/lib/state/sandbox.ts

Comment thread src/lib/actions/sandbox/snapshot-restore.test.ts Outdated
Comment thread src/lib/agent/state-file-restore-reader.test.ts
Comment thread src/lib/agent/state-file-restore-reader.ts

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
src/lib/onboard/created-sandbox-finalization.test.ts (1)

218-234: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting a shared default-deps builder for these tests.

Several tests in this file construct near-identical deps objects (discoverFreshOpenClawImagePluginInstalls, restoreRecreatedSandboxState, getDcodeSelectionDrift, register, note, error, exitProcess), differing only in a couple of overrides. A small factory (e.g., makeFinalizationDeps(overrides)) would reduce duplication and make future flag additions (like applyManagedStateFileRestore) easier to thread consistently across tests.

Also applies to: 359-396, 440-476, 478-527, 529-575

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard/created-sandbox-finalization.test.ts` around lines 218 - 234,
Several tests in created-sandbox-finalization.test.ts are duplicating almost the
same deps setup, so extract a shared default-deps factory such as
makeFinalizationDeps(overrides) and use it in the affected test cases. Move the
common pieces from the existing deps objects used around
restoreRecreatedSandboxState, discoverFreshOpenClawImagePluginInstalls,
getDcodeSelectionDrift, register, note, error, and exitProcess into that helper,
then pass only per-test overrides so new flags like applyManagedStateFileRestore
stay consistent everywhere.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/lib/onboard/created-sandbox-finalization.test.ts`:
- Around line 218-234: Several tests in created-sandbox-finalization.test.ts are
duplicating almost the same deps setup, so extract a shared default-deps factory
such as makeFinalizationDeps(overrides) and use it in the affected test cases.
Move the common pieces from the existing deps objects used around
restoreRecreatedSandboxState, discoverFreshOpenClawImagePluginInstalls,
getDcodeSelectionDrift, register, note, error, and exitProcess into that helper,
then pass only per-test overrides so new flags like applyManagedStateFileRestore
stay consistent everywhere.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 61b00ddf-1a65-4c7e-905d-8112817466fe

📥 Commits

Reviewing files that changed from the base of the PR and between a25f9ed and 44a248c.

📒 Files selected for processing (16)
  • agents/langchain-deepagents-code/manifest.yaml
  • src/lib/actions/sandbox/rebuild-dcode-recovery.test.ts
  • src/lib/actions/sandbox/rebuild-local-provider-recreate.test.ts
  • src/lib/actions/sandbox/rebuild-pipeline.ts
  • src/lib/actions/sandbox/rebuild-prepared-recovery.test.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.test.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.ts
  • src/lib/actions/sandbox/snapshot-restore.test.ts
  • src/lib/actions/sandbox/snapshot.ts
  • src/lib/agent/defs.test.ts
  • src/lib/agent/state-file-restore-reader.test.ts
  • src/lib/onboard/created-sandbox-finalization.test.ts
  • src/lib/onboard/created-sandbox-finalization.ts
  • src/lib/state/openclaw-config-restore-input.test.ts
  • src/lib/state/openclaw-config-restore-input.ts
  • src/lib/state/sandbox.ts
💤 Files with no reviewable changes (3)
  • src/lib/state/openclaw-config-restore-input.test.ts
  • src/lib/state/openclaw-config-restore-input.ts
  • src/lib/state/sandbox.ts
✅ Files skipped from review due to trivial changes (2)
  • src/lib/actions/sandbox/rebuild-dcode-recovery.test.ts
  • src/lib/actions/sandbox/rebuild-prepared-recovery.test.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/lib/actions/sandbox/rebuild-pipeline.ts
  • agents/langchain-deepagents-code/manifest.yaml
  • src/lib/actions/sandbox/rebuild-local-provider-recreate.test.ts
  • src/lib/actions/sandbox/snapshot.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.ts
  • src/lib/agent/defs.test.ts
  • src/lib/onboard/created-sandbox-finalization.ts
  • src/lib/agent/state-file-restore-reader.test.ts
  • src/lib/actions/sandbox/rebuild-restore-phase.test.ts
  • src/lib/actions/sandbox/snapshot-restore.test.ts

… match

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
…d config

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
…n snapshot restore

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
…hip lookup

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@laitingsheng laitingsheng added the v0.0.79 Release target label Jul 9, 2026
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29129384871
Workflow ref: feat/manifest-key-level-state-ownership
Requested targets: (default — all supported)
Requested jobs: full-e2e,hermes-e2e,onboard-repair,onboard-resume,state-backup-restore,upgrade-stale-sandbox,cloud-onboard,snapshot-commands
Summary: 7 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
cloud-onboard ✅ success
full-e2e ❌ failure
hermes-e2e ✅ success
onboard-repair ✅ success
onboard-resume ✅ success
snapshot-commands ✅ success
state-backup-restore ✅ success
upgrade-stale-sandbox ✅ success

Failed jobs: full-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29129667043
Workflow ref: feat/manifest-key-level-state-ownership
Requested targets: (default — all supported)
Requested jobs: full-e2e
Summary: 0 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
full-e2e ❌ failure

Failed jobs: full-e2e. Check run artifacts for logs.

@cjagwani cjagwani requested a review from cv July 10, 2026 23:16
@cjagwani cjagwani removed their assignment Jul 10, 2026
@prekshivyas prekshivyas added v0.0.81 Release target and removed v0.0.80 Release target labels Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29130111510
Workflow ref: feat/manifest-key-level-state-ownership
Requested targets: (default — all supported)
Requested jobs: full-e2e
Summary: 0 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
full-e2e ❌ failure

Failed jobs: full-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29140856250
Workflow ref: feat/manifest-key-level-state-ownership
Requested targets: (default — all supported)
Requested jobs: (default — all default-enabled free-standing jobs; explicit-only jobs openshell-gateway-auth-contract, mcp-bridge-dev, hermes-gpu-startup, sandbox-rlimits-connect, and jetson-nvmap-gpu are skipped unless selected)
Summary: 68 passed, 3 failed, 0 cancelled, 5 skipped

Job Result
agent-turn-latency ✅ success
bedrock-runtime-compatible-anthropic ✅ success
brave-search ✅ success
channels-add-remove ✅ success
channels-stop-start ✅ success
cloud-inference ✅ success
cloud-onboard ✅ success
common-egress-agent ✅ success
concurrent-gateway-ports ✅ success
credential-migration ✅ success
credential-sanitization ✅ success
cron-preflight-inference-local ✅ success
device-auth-health ✅ success
diagnostics ✅ success
docs-validation ✅ success
double-onboard ✅ success
full-e2e ✅ success
gateway-drift-preflight ✅ success
gateway-guard-recovery ✅ success
gateway-health-honest ✅ success
generate-matrix ✅ success
gpu-double-onboard ✅ success
gpu-e2e ✅ success
hermes-dashboard ✅ success
hermes-discord ✅ success
hermes-e2e ✅ success
hermes-gpu-startup ⏭️ skipped
hermes-inference-switch ✅ success
hermes-shields-config ✅ success
hermes-slack ✅ success
inference-routing ✅ success
issue-2478-crash-loop-recovery ✅ success
issue-4434-tui-unreachable-inference ✅ success
issue-4462-scope-upgrade-approval ✅ success
jetson-nvmap-gpu ⏭️ skipped
kimi-inference-compat ✅ success
launchable-smoke ✅ success
live ✅ success
mcp-bridge ❌ failure
mcp-bridge-dev ⏭️ skipped
messaging-compatible-endpoint ✅ success
messaging-providers ✅ success
model-router-provider-routed-inference ✅ success
network-policy ✅ success
ollama-auth-proxy ✅ success
onboard-negative-paths ✅ success
onboard-repair ✅ success
onboard-resume ✅ success
openclaw-discord-pairing ✅ success
openclaw-inference-switch ✅ success
openclaw-plugin-runtime-exdev ✅ success
openclaw-skill-cli ✅ success
openclaw-slack-pairing ✅ success
openclaw-tui-chat-correlation ✅ success
openshell-gateway-auth-contract ⏭️ skipped
openshell-gateway-upgrade ❌ failure
openshell-version-pin ✅ success
overlayfs-autofix ✅ success
rebuild-hermes ❌ failure
rebuild-hermes-stale-base ✅ success
rebuild-openclaw ✅ success
sandbox-operations ✅ success
sandbox-rebuild ✅ success
sandbox-rlimits-connect ⏭️ skipped
sandbox-survival ✅ success
security-posture ✅ success
sessions-agents-cli ✅ success
shields-config ✅ success
skill-agent ✅ success
snapshot-commands ✅ success
spark-install ✅ success
state-backup-restore ✅ success
telegram-injection ✅ success
token-rotation ✅ success
tunnel-lifecycle ✅ success
upgrade-stale-sandbox ✅ success

Explicit-only jobs skipped: openshell-gateway-auth-contract (default dispatch excludes the resource-heavy OpenShell auth-contract probe unless selected; validate with jobs=openshell-gateway-auth-contract or targets=openshell-gateway-auth-contract), mcp-bridge-dev (default dispatch excludes moving OpenShell dev artifacts unless explicitly selected; validate with jobs=mcp-bridge-dev or targets=mcp-bridge-dev), hermes-gpu-startup (default dispatch excludes this explicit-only job unless selected; validate with jobs=hermes-gpu-startup or targets=hermes-gpu-startup), sandbox-rlimits-connect (default dispatch excludes the destructive rlimit fork/connect probe unless selected; validate with jobs=sandbox-rlimits-connect or targets=sandbox-rlimits-connect), jetson-nvmap-gpu (default dispatch excludes Jetson; explicit dispatch requires allow_jetson_runner_queue=true after confirming an online Jetson runner because queued jobs do not honor timeout-minutes before assignment; validate with jobs=jetson-nvmap-gpu or targets=jetson-nvmap-gpu).

Failed jobs: mcp-bridge, openshell-gateway-upgrade, rebuild-hermes. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29143011000
Workflow ref: feat/manifest-key-level-state-ownership
Requested targets: (default — all supported)
Requested jobs: mcp-bridge,rebuild-hermes,openshell-gateway-upgrade
Summary: 2 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
mcp-bridge ✅ success
openshell-gateway-upgrade ✅ success
rebuild-hermes ❌ failure

Failed jobs: rebuild-hermes. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ❌ Some jobs failed

Run: 29143776167
Workflow ref: feat/manifest-key-level-state-ownership
Requested targets: (default — all supported)
Requested jobs: rebuild-hermes
Summary: 0 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
rebuild-hermes ❌ failure

Failed jobs: rebuild-hermes. Check run artifacts for logs.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Current-head re-review passed at b2725d5. The prior HOLD items are resolved: current main is integrated, real TOML and filesystem race/symlink/inode-swap paths are covered, managed ownership and the custom-image trust exception are explicit and documented, required exact-head E2Es passed, all commits are Verified, and the formal GPT gate returned merge_as_is with no findings. Nemotron’s transient retry-convergence scenario is worthwhile follow-up coverage rather than evidence of a product defect; the custom-image boundary is intentional and tested. The lone cancel-superseded failure is a run-pagination tooling error, not a code/test failure.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested tests passed

Run: 29173513546
Workflow ref: feat/manifest-key-level-state-ownership
Requested targets: (default — all supported)
Requested test IDs: credential-sanitization,security-posture,full-e2e,hermes-e2e,onboard-repair,onboard-resume,state-backup-restore,upgrade-stale-sandbox,cloud-onboard,snapshot-commands
Summary: 10 passed, 0 failed, 0 cancelled, 0 skipped, 0 unknown

Test Result
cloud-onboard ✅ success
credential-sanitization ✅ success
full-e2e ✅ success
hermes-e2e ✅ success
onboard-repair ✅ success
onboard-resume ✅ success
security-posture ✅ success
snapshot-commands ✅ success
state-backup-restore ✅ success
upgrade-stale-sandbox ✅ success

@cv cv dismissed cjagwani’s stale review July 12, 2026 00:29

Dismissed after current-commit re-review: main is synced, key-level ownership and safe TOML merge/race handling are covered, documentation is complete, ChatGPT auth state is now excluded from managed snapshots, all 51 ordinary checks and trusted advisors are green, and the full ten-target live matrix passed.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved current PR commit 10b2361 after the ChatGPT auth-state exclusion, focused 68-test regression suite, 52 green checks, clean advisor recommendation, and all 10 required live E2E targets passed in run 29173513546.

@cv cv merged commit b9b8d2a into main Jul 12, 2026
128 checks passed
@cv cv deleted the feat/manifest-key-level-state-ownership branch July 12, 2026 00:31
@cv cv mentioned this pull request Jul 12, 2026
21 tasks
cv added a commit that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Release-prep documentation for v0.0.81 now summarizes user-facing
changes merged since v0.0.80.
It also closes the Hermes dashboard-profile backup gap and distinguishes
direct blueprint-runner actions from public host CLI commands.

## Changes

- Add the `v0.0.81` section to `docs/about/release-notes.mdx` with links
to the detailed user guides.
- Document that Hermes rebuilds preserve `.hermes/dashboard-home/`,
including Dashboard `MEMORY.md` and `USER.md`.
- Update Hermes manual backup and restore examples to transfer those two
profile files without copying generated configuration or the
secret-bearing dashboard `.env`.
- Explain the new per-item backup failure causes.
- Clarify that migration snapshot retention fragments are direct-runner
arguments and are not exposed by the host `nemoclaw` CLI.

### Source summary

- #6445 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Summarize manifest-owned
key-level restore and current-config authority.
- #6617 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Record the fail-closed
`/proc` fallback used to verify an idle Deep Agents runtime before
snapshot creation.
- #6685 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Document Hermes Web
Dashboard profile persistence and safe manual transfer.
- #6649 -> `docs/about/release-notes.mdx`: Summarize host-validated
loopback compatible-endpoint routing through the sandbox gateway.
- #6643 -> `docs/about/release-notes.mdx`: Summarize automatic
`max_completion_tokens` handling for GPT-5 and o-series models.
- #6661 -> `docs/about/release-notes.mdx`: Summarize bounded connection
reuse for eligible provider-validation probes.
- #6704 -> `docs/about/release-notes.mdx`: Record that direct blueprint
apply stops instead of persisting incomplete state after provider or
inference setup fails.
- #6677 -> `docs/about/release-notes.mdx`: Summarize transactional
recovery for legacy Docker containers whose managed supervisor
disappeared after restart.
- #6625 -> `docs/about/release-notes.mdx`: Record Hermes managed-startup
persistence across direct Docker restarts.
- #6597 -> `docs/about/release-notes.mdx`: Record final-sandbox gateway
cleanup on macOS.
- #6680 -> `docs/about/release-notes.mdx`: Summarize managed Deep Agents
first-run and process-tree cleanup improvements.
- #6647 -> `docs/about/release-notes.mdx`: Record fail-closed validation
for the managed Deep Agents fetch CA bundle.
- #6645 -> `docs/about/release-notes.mdx`: Summarize WhatsApp loopback
pairing and trusted npm plugin provenance.
- #6673 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document stopped-sandbox
backup remediation.
- #6631 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document per-item backup
failure causes.
- #6620 -> `docs/about/release-notes.mdx`: Record the
created-but-not-ready sandbox lifecycle receipt.
- #6664 -> `docs/about/release-notes.mdx`: Record prompt-aware
onboarding progress output.
- #6598 -> `docs/about/release-notes.mdx`: Summarize stale replay-result
invalidation during resumed onboarding.
- #6593 -> `docs/about/release-notes.mdx`: Summarize contextual OpenClaw
audit findings for managed dashboard compatibility settings.
- #6650 -> `docs/about/release-notes.mdx`: Record redaction of
token-shaped URL query values.
- #6638 -> `docs/about/release-notes.mdx`: Record the exact-path MCP
`DELETE` policy recipe for session termination.
- #5453 -> `docs/reference/host-files-and-state.mdx`: Clarify that
snapshot retention actions belong to direct runner integrations and are
not standalone host CLI commands.

### Skipped from docs-skip

- #6633 matched the `openclaw-sandbox-permissive.yaml` path in
`docs/.docs-skip` and produced no documentation in this update.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [x] Doc only (includes code sample changes)

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: This is a documentation-only
release-prep update; behavior is protected by the merged source PRs, and
the documentation build validates the changed examples and routes.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — tests are not applicable for this
documentation-only change; `npm run docs` completed successfully.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not run for this
documentation-only change.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — 0
errors; two existing Fern warnings remain.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new pages.

---
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Documentation**
- Added release notes for v0.0.81 covering state preservation, inference
setup, sandbox recovery, session setup, pairing, diagnostics, and
security policy updates.
- Expanded backup and restore guidance to include dashboard profile
files and clarify files that must not be copied.
- Added dashboard profile persistence details to workspace and rebuild
documentation.
- Clarified snapshot retention guidance and the distinction between host
CLI capabilities and direct runner actions.
  - Added more detailed backup failure reporting information.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…IA#6445)

<!-- markdownlint-disable MD041 -->
## Summary

Agent manifests can now declare key-level restore ownership for
mixed-ownership state files. Managed restore preserves only
manifest-owned user preferences while the current target manifest
remains authoritative for generated configuration. Deep Agents Code is
migrated to this schema, and the restore path now fails closed on unsafe
manifests, paths, TOML, filesystem races, and target/backup mismatches.

## Related Issue

Resolves NVIDIA#6334

## Changes

- Add a strict, discriminated state_files restore schema for
key-allowlist and openclaw-config strategies, including canonical
relative-path validation and rejection of duplicate or
ancestor-overlapping ownership declarations.
- Require the current target manifest to authorize the backup agent,
config directory, state-file path, strategy, and restore ownership
before SSH or filesystem mutation.
- Make managed key-level merge the default. Whole-file restore is
available only through the explicit
allowCustomImageWholeStateFileRestore capability for custom-image
restore.
- Read bounded backup TOML directly from Python stdin, parse with
tomllib, create a private unpredictable O_EXCL stage, traverse parent
directories without following symlinks, and revalidate current/stage
metadata before atomic replacement.
- Preserve all safe leading comments, preserve non-dictionary fresh
ancestors instead of clobbering them, and keep fresh managed tables and
headers authoritative.
- Migrate the Deep Agents Code manifest and remove the agent-specific
restore-policy callback.
- Document managed key-level restore, target-manifest authority, and the
custom-Dockerfile whole-file exception.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [x] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: maintainer-assisted
review of the behavior at dd65850
passed all nine security categories; current head
f9e4537 adds only a formatting-only
blank-line deletion to satisfy the onboard.ts net-growth guardrail.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as Verified in GitHub
- [x] Normal pre-commit, commit-msg, and pre-push hooks passed, or npm
run check:diff passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — 175 focused CLI assertions plus 71
affected integration assertions passed; the final phase/contract rerun
passed 23/23. npm run typecheck:cli, npm run build:cli, npm run
test-size:check, and git diff --check also passed.
- [ ] Applicable broad gate passed — not applicable locally; targeted
CLI/integration coverage exercised every changed restore path, and
repository CI is running on the exact head.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] npm run docs builds without warnings (doc changes only) — build
passed with 0 errors and 2 pre-existing hidden-page warnings
- [x] Doc pages follow the style guide (doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new pages

---
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added manifest-driven, fine-grained state-file restore rules with
typed user key allowlists and “freshness” requirements.
* Custom Dockerfile sandboxes can restore whole state files during
rebuilds when enabled.
* **Bug Fixes**
* Snapshot restore now fails closed for unknown, unsafe, stale, or
conflicting state data, with stronger atomic replacement safeguards.
* **Documentation**
* Updated sandbox backup/restore guidance to reflect key-level ownership
semantics, allowed preference preservation, and restore failure
behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Release-prep documentation for v0.0.81 now summarizes user-facing
changes merged since v0.0.80.
It also closes the Hermes dashboard-profile backup gap and distinguishes
direct blueprint-runner actions from public host CLI commands.

## Changes

- Add the `v0.0.81` section to `docs/about/release-notes.mdx` with links
to the detailed user guides.
- Document that Hermes rebuilds preserve `.hermes/dashboard-home/`,
including Dashboard `MEMORY.md` and `USER.md`.
- Update Hermes manual backup and restore examples to transfer those two
profile files without copying generated configuration or the
secret-bearing dashboard `.env`.
- Explain the new per-item backup failure causes.
- Clarify that migration snapshot retention fragments are direct-runner
arguments and are not exposed by the host `nemoclaw` CLI.

### Source summary

- NVIDIA#6445 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Summarize manifest-owned
key-level restore and current-config authority.
- NVIDIA#6617 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Record the fail-closed
`/proc` fallback used to verify an idle Deep Agents runtime before
snapshot creation.
- NVIDIA#6685 -> `docs/about/release-notes.mdx`,
`docs/manage-sandboxes/backup-restore.mdx`, and
`docs/manage-sandboxes/workspace-files.mdx`: Document Hermes Web
Dashboard profile persistence and safe manual transfer.
- NVIDIA#6649 -> `docs/about/release-notes.mdx`: Summarize host-validated
loopback compatible-endpoint routing through the sandbox gateway.
- NVIDIA#6643 -> `docs/about/release-notes.mdx`: Summarize automatic
`max_completion_tokens` handling for GPT-5 and o-series models.
- NVIDIA#6661 -> `docs/about/release-notes.mdx`: Summarize bounded connection
reuse for eligible provider-validation probes.
- NVIDIA#6704 -> `docs/about/release-notes.mdx`: Record that direct blueprint
apply stops instead of persisting incomplete state after provider or
inference setup fails.
- NVIDIA#6677 -> `docs/about/release-notes.mdx`: Summarize transactional
recovery for legacy Docker containers whose managed supervisor
disappeared after restart.
- NVIDIA#6625 -> `docs/about/release-notes.mdx`: Record Hermes managed-startup
persistence across direct Docker restarts.
- NVIDIA#6597 -> `docs/about/release-notes.mdx`: Record final-sandbox gateway
cleanup on macOS.
- NVIDIA#6680 -> `docs/about/release-notes.mdx`: Summarize managed Deep Agents
first-run and process-tree cleanup improvements.
- NVIDIA#6647 -> `docs/about/release-notes.mdx`: Record fail-closed validation
for the managed Deep Agents fetch CA bundle.
- NVIDIA#6645 -> `docs/about/release-notes.mdx`: Summarize WhatsApp loopback
pairing and trusted npm plugin provenance.
- NVIDIA#6673 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document stopped-sandbox
backup remediation.
- NVIDIA#6631 -> `docs/about/release-notes.mdx` and
`docs/manage-sandboxes/backup-restore.mdx`: Document per-item backup
failure causes.
- NVIDIA#6620 -> `docs/about/release-notes.mdx`: Record the
created-but-not-ready sandbox lifecycle receipt.
- NVIDIA#6664 -> `docs/about/release-notes.mdx`: Record prompt-aware
onboarding progress output.
- NVIDIA#6598 -> `docs/about/release-notes.mdx`: Summarize stale replay-result
invalidation during resumed onboarding.
- NVIDIA#6593 -> `docs/about/release-notes.mdx`: Summarize contextual OpenClaw
audit findings for managed dashboard compatibility settings.
- NVIDIA#6650 -> `docs/about/release-notes.mdx`: Record redaction of
token-shaped URL query values.
- NVIDIA#6638 -> `docs/about/release-notes.mdx`: Record the exact-path MCP
`DELETE` policy recipe for session termination.
- NVIDIA#5453 -> `docs/reference/host-files-and-state.mdx`: Clarify that
snapshot retention actions belong to direct runner integrations and are
not standalone host CLI commands.

### Skipped from docs-skip

- NVIDIA#6633 matched the `openclaw-sandbox-permissive.yaml` path in
`docs/.docs-skip` and produced no documentation in this update.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [x] Doc only (includes code sample changes)

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: This is a documentation-only
release-prep update; behavior is protected by the merged source PRs, and
the documentation build validates the changed examples and routes.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — tests are not applicable for this
documentation-only change; `npm run docs` completed successfully.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: not run for this
documentation-only change.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — 0
errors; two existing Fern warnings remain.
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)
— no new pages.

---
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Documentation**
- Added release notes for v0.0.81 covering state preservation, inference
setup, sandbox recovery, session setup, pairing, diagnostics, and
security policy updates.
- Expanded backup and restore guidance to include dashboard profile
files and clarify files that must not be copied.
- Added dashboard profile persistence details to workspace and rebuild
documentation.
- Clarified snapshot retention guidance and the distinction between host
CLI capabilities and direct runner actions.
  - Added more detailed backup failure reporting information.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature PR adds or expands user-visible functionality v0.0.81 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add key-level state ownership to agent manifests

5 participants