Skip to content

feat(runtime): add transactional Podman bootstrap preparation - #8055

Open
ericksoa wants to merge 20 commits into
feat/podman-bootstrap-authorityfrom
feat/podman-bootstrap-journal
Open

feat(runtime): add transactional Podman bootstrap preparation#8055
ericksoa wants to merge 20 commits into
feat/podman-bootstrap-authorityfrom
feat/podman-bootstrap-journal

Conversation

@ericksoa

@ericksoa ericksoa commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Add the dormant transactional preparation boundary for native Podman bootstrap. The new internal path durably owns a stopped replacement and its Podman-managed state volume, preserves the exact original until commit, and provides exact pre-commit rollback without activating Podman runtime selection.

Related Issue

Related to #7744.

Changes

  • Add a private, canonical phase journal that binds one bootstrap identity to the exact engine authority, stopped watcher lease, original container, managed state volume, replacement intent, and rollback decision. A durable journal is required because container and volume creation have lost-acknowledgement and process-crash windows; podman-bootstrap-journal.test.ts covers canonical storage, monotonic phases, decision recovery, and fail-closed parsing.
  • Add a stopped-replacement primitive that creates one deterministic labelled local volume at /var/lib/nemoclaw, transports environment values only through a private temporary file, creates one final-labelled replacement, and proves the exact volume, mount, image, startup arguments, environment, and stopped identity. Direct central orchestration is insufficient because the later image-owned all-agent transaction must share state with no-exec helper containers; podman-bootstrap-replacement.test.ts covers the exact command, inspection, secret, collision, and mount-shadow boundaries.
  • Add exact original-stop and pre-commit rollback primitives. Rollback durably commits to compensation, reconciles one lost replacement acknowledgement, removes only the proven stopped replacement and owned volume, restores the exact original, and retains the watcher lease for its caller.
  • Record the inert lifecycle and deferred activation boundary in src/lib/onboard/lifecycle-contracts.md.

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: This slice is internal and unregistered; the internal lifecycle contract map records its ownership and deferred activation boundary.
  • 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-directed inert slice in [Epic] Support native Podman with buildless managed onboarding #7744; exact engine, watcher, volume, secret-transport, container, and rollback boundaries have focused characterization coverage.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: src/lib/onboard/lifecycle-contracts.md; the explanatory text in src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.ts, podman-bootstrap-journal.test.ts, podman-bootstrap-replacement.ts, and podman-bootstrap-replacement.test.ts; and the refreshed test/runtime-provider-source-shape.test.ts inventory were independently reviewed against WRITING.md and the controlled word list. The review clarified that creation requests relabel=shared while inspection proves a writable mount with no reported private Z relabel, and distinguishes volume labels from container labels. No findings remain, and git diff --check passed. The append-only parent refresh to 4b4fcef76 preserves the exact reviewed slice diff and changes no reviewed documentation.
  • Agent: Codex Desktop
  • Qualification carry-forward: Exact head e724196 on base fb1e210 preserves the byte-identical previously reviewed slice diff (stable patch ID 86881068f19dfb1d5be7c6b0e38ec3a1b48f8cdb; binary diff SHA-256 74b8e9d7d4150209776bc525e961a7c79ae34215c586f82a3689b9425d518abb), and its source and documentation tree is unchanged from reviewed head 9cb9e34.

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit:
  • Station profile/scenario:
  • Result:
  • Supporting evidence:

Verification

  • Qualification-only exact head/base: e724196 / fb1e210; signed-DCO append-only cascade, stable-patch proof, byte-identical slice diff, final-tree equality, and normal pre-push hooks passed.
  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: npx vitest run --project cli src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.test.ts src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts (28 tests passed); npx vitest run --project integration test/runtime-provider-source-shape.test.ts (2 tests passed); CLI and plugin builds plus CLI typecheck and exact-base pre-push passed.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • 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)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Aaron Erickson aerickson@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added a managed Podman bootstrap replacement workflow that prepares and verifies a stopped replacement while preserving the original until validation completes.
    • Added durable journaling for bootstrap progress, recovery decisions, and rollback.
    • Added safeguards for identity, ownership, permissions, authority, and resource conflicts.
    • Added deterministic staging and state-volume handling with secure temporary configuration files.
  • Bug Fixes

    • Improved fail-closed rollback and recovery when bootstrap state is ambiguous, changed, interrupted, or cannot be safely reconciled.

ericksoa added 12 commits August 1, 2026 02:19
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa self-assigned this Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a durable Podman bootstrap journal and a dormant replacement transaction. The workflow validates identities, ownership, authority, and runtime state; creates a stopped replacement; stops only the exact original; and supports authorized rollback with filesystem-backed recovery.

Changes

Podman bootstrap replacement

Layer / File(s) Summary
Journal contract and durable storage
src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.ts, src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.test.ts
Adds canonical journal contracts, strict validation, private durable storage, ordered phase transitions, rollback decision recovery, atomic writes, and cleanup tests.
Replacement validation and Podman observation
src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts, src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts
Adds bounded plan normalization, authority binding, deterministic resource naming, secure environment-file handling, and stable validation of volumes and containers.
Preparation, exact stop, and rollback
src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts, src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts, src/lib/onboard/lifecycle-contracts.md, test/runtime-provider-source-shape.test.ts
Adds stopped replacement preparation, exact-original stop sequencing, rollback cleanup and restart behavior, recovery and fail-closed tests, and the dormant lifecycle contract.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#7969: Extends dormant managed-startup transaction patterns with Podman-specific journaling and replacement operations.
  • NVIDIA/NemoClaw#7990: Introduces the runtime-provider lifecycle and authority model extended by this Podman workflow.

Suggested labels: area: onboarding, feature, platform: container, area: security, v0.0.100

Suggested reviewers: jyaunches, cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the transactional Podman bootstrap preparation added by the pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/podman-bootstrap-journal

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

@github-code-quality

github-code-quality Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit e724196 in the feat/podman-bootstra... branch remains at 96%, unchanged from commit d47ffe5 in the feat/podman-bootstra... branch.

TypeScript / code-coverage/cli

The overall coverage in commit e724196 in the feat/podman-bootstra... branch is 80%. The coverage in commit d47ffe5 in the feat/podman-bootstra... branch is 81%.

Show a code coverage summary of the most impacted files.
File feat/podman-bootstra... d47ffe5 feat/podman-bootstra... e724196 +/-
src/lib/onboard...trap/adapter.ts 0% 63% +63%
src/lib/onboard...strap/docker.ts 0% 64% +64%
src/lib/onboard...atcher-lease.ts 0% 75% +75%
src/lib/onboard...cker-journal.ts 0% 83% +83%
src/lib/onboard...der/snapshot.ts 0% 83% +83%
src/lib/onboard...one-rebinder.ts 0% 83% +83%
src/lib/onboard...trap-journal.ts 0% 86% +86%
src/lib/actions...ne-providers.ts 0% 86% +86%
src/lib/onboard...-replacement.ts 0% 87% +87%
src/lib/onboard...test-fixture.ts 0% 96% +96%

Updated August 01, 2026 13:59 UTC

@ericksoa

ericksoa commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / low confidence
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions
Status: Partial review preserved 1 canonical finding(s) before the advisor stopped.

Model lanes

  • GPT-5.6 Terra (primary): Failed after a partial review · low confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed

Second-opinion E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: onboard-repair, onboard-resume, cloud-onboard

1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Restrict isolation-sensitive Podman runtime arguments

  • Location: src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts:337
  • Category: security
  • Problem: The replacement plan passes runtimeArgs to `podman container create` after rejecting only a partial denylist. It still accepts isolation-sensitive flags such as `--cap-add`, `--device`, `--pid=host`, `--userns=host`, and `--security-opt`, so a future plan producer can create a replacement with privileges beyond the held workload or sandbox policy.
  • Impact: An untrusted or incorrectly validated plan producer could weaken the replacement container's isolation before the exact identity and rollback checks run.
  • Recommendation: Use an explicit allowlist for runtime arguments, or derive each isolation-sensitive option from the held workload and require an exact match before `container create`.
  • Verification: Inspect `runtimeArguments` and `createArgs`; confirm every accepted argument cannot change privileges, namespaces, devices, security options, identity, mounts, environment, entrypoint, or image selection.
  • Test coverage: Add parameterized tests that pass capability, device, host-PID, host-user-namespace, and security-opt flags and verify failure occurs before journal creation or any Podman command.
  • Evidence: src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts:337-363 rejects a partial denylist before returning runtime arguments. src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts:742-766 appends `plan.runtimeArgs` directly to `podman container create`. src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts covers `--name` and mount rejection but has no denial cases for capabilities, devices, namespaces, or `--security-opt`.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@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: 7

🧹 Nitpick comments (4)
src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.ts (1)

559-572: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Verify the durable read-back in recordOriginalStopped.

recordStateVolume (Lines 525-529) and recordReplacement (Lines 553-556) both re-read the journal and compare it with sameJournal before they return. recordOriginalStopped writes and then returns the in-memory updated value. The original-stopped phase is the boundary that records that the exact original container is stopped, so it carries the same durability requirement as the two preceding transitions. Apply the same read-back so the store contract stays uniform.

♻️ Proposed read-back for `recordOriginalStopped`
       const updated = normalizePodmanBootstrapJournal({ ...current, phase: "original-stopped" });
       atomicWrite(directory, target, serializePodmanBootstrapJournal(updated), false);
-      return updated;
+      const persisted = load(bootstrapIdentity);
+      if (!persisted || !sameJournal(persisted, updated)) {
+        fail("original stop boundary was not durably re-readable");
+      }
+      return persisted;
     },
🤖 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/managed-bootstrap/podman-bootstrap-journal.ts` around lines
559 - 572, Update recordOriginalStopped to re-read the journal from durable
storage after atomicWrite, compare the read-back with updated using the existing
sameJournal validation, and return the verified persisted value instead of the
in-memory object. Preserve the existing phase checks and idempotent current
return behavior.
src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts (2)

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

Do not recompute the production naming formula in the test.

Lines 49-51 rebuild the staging name and the state-volume name with the same expression that stagingName and stateVolumeName use in podman-bootstrap-replacement.ts (Lines 346-363). The assertions at Lines 352-353 then compare the result against that recomputation. If the production suffix changes, both sides change together and the test still passes, so it cannot detect a naming regression.

Use literal expected names so the deterministic naming contract is pinned.

♻️ Proposed literal name expectations
-const STAGING_NAME = `${ORIGINAL_NAME}-nemoclaw-bootstrap-${BOOTSTRAP_IDENTITY.slice(0, 12)}`;
-const STATE_VOLUME_NAME = `${ORIGINAL_NAME}-nemoclaw-state-${BOOTSTRAP_IDENTITY.slice(0, 12)}`;
+const STAGING_NAME = "openshell-sandbox-alpha-nemoclaw-bootstrap-111111111111";
+const STATE_VOLUME_NAME = "openshell-sandbox-alpha-nemoclaw-state-111111111111";

As per path instructions: "Flag copied production algorithms, broad mocks that bypass the behavior under test, and conditionals that make a test pass without exercising its claim."

🤖 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/managed-bootstrap/podman-bootstrap-replacement.test.ts`
around lines 49 - 51, Replace the computed STAGING_NAME and STATE_VOLUME_NAME
constants in the test with literal expected names derived from the current
deterministic naming contract. Keep STATE_VOLUME_MOUNTPOINT based on the literal
state-volume name, so the assertions test production output without duplicating
the naming formula used by podman-bootstrap-replacement.ts.

Source: Path instructions


574-613: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for two fail-closed branches on the critical path.

The suite covers ambiguity and engine-authority mismatch. Two adjacent guards have no test:

  • stopExactPodmanBootstrapOriginal rejects a prepared value whose replacementStateVolumeMountpoint or replacementSpecFingerprint diverges from the journal (Lines 1020-1028 of podman-bootstrap-replacement.ts). Pass a mutated prepared and assert "does not match the durable journal", and assert that the original still runs.
  • rollbackPodmanBootstrapBeforeCommit fails when the journal recorded a mountpoint but the state volume is gone (Line 1087). Set harness.stateVolume = null after a successful prepare, then assert "recorded state volume disappeared before rollback".

Both guards protect the boundary at which the original container is stopped, so a regression in either is silent today.

Do you want me to write both test cases?

🤖 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/managed-bootstrap/podman-bootstrap-replacement.test.ts`
around lines 574 - 613, Add tests for the two uncovered fail-closed guards:
mutate the prepared replacementStateVolumeMountpoint or
replacementSpecFingerprint before calling stopExactPodmanBootstrapOriginal,
assert “does not match the durable journal,” and verify the original remains
running; separately, after successful prepare, set harness.stateVolume to null,
call rollbackPodmanBootstrapBeforeCommit, assert “recorded state volume
disappeared before rollback,” and preserve the journal assertions relevant to
rollback authorization.
src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts (1)

933-943: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Cover or remove the candidate.Id ?? candidate.ID fallback.

Line 936 accepts two spellings of the Podman container ls --format json identity field. The coding guidelines prohibit compatibility layers without a current requirement, and they ask for the current consumer and a protecting test. The harness in podman-bootstrap-replacement.test.ts emits only Id (Line 289), so the ID branch has no coverage.

If a supported Podman version emits ID, add a test that exercises that branch. If no supported version emits ID, read Id only.

Line 940 also contains dead logic. ids.length > 1 already fails, so new Set(ids).size !== ids.length can never be reached.

As per coding guidelines: "Do not add configuration, fallback, migration, compatibility, or extension layers without a current requirement; identify the current consumer and protecting 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/onboard/managed-bootstrap/podman-bootstrap-replacement.ts` around
lines 933 - 943, Update the staging discovery mapping in the replacement flow to
read only the currently supported Podman identity field, Id, unless a supported
version requires ID; if so, add a protecting test that emits ID. Remove the
unreachable duplicate-identity Set check and retain the existing single-identity
validation through ids.length > 1.

Source: Coding guidelines

🤖 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/onboard/lifecycle-contracts.md`:
- Around line 167-177: Update the rollback requirement around
stopExactPodmanBootstrapOriginal so the caller invokes
rollbackPodmanBootstrapBeforeCommit only when the thrown
PodmanBootstrapPreparationError has rollbackRequired set. Preserve the
no-rollback path for pre-mutation validation failures where no journal exists.

In `@src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts`:
- Around line 405-414: Update the test around the first prepare call to capture
and assert on its thrown Podman create failure, rather than invoking prepare
again with the same journal state. Ensure the assertion verifies the thrown
error does not contain either credential string, and use an assertion pattern
that fails if prepare returns normally; preserve the existing status and
journal-phase checks.
- Around line 196-292: Refactor PodmanHarness.capture to remove its conditional
chain and dispatch commands through a table keyed by the first two arguments.
Move each existing branch into named private helper methods, preserving all fake
behavior and return values, and route unknown commands through a single
unsupported helper that throws the existing Unexpected Podman command error.

In `@src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts`:
- Around line 240-254: Update the key comparator in exactStringMap to use
deterministic code-unit ordering instead of localeCompare, ensuring
canonicalLabels and the resulting persisted fingerprints remain identical across
locales and ICU environments.
- Around line 301-314: Update assertMountDoesNotShadowState to recognize the
dest destination alias, preserve the full destination value after the first “=”
when parsing mount entries, and reject specifications that lack a recognized
destination key instead of returning. Keep pathsOverlap validation applied to
every recognized destination so nested overlaps with
PODMAN_BOOTSTRAP_STATE_DIRECTORY are rejected.
- Around line 602-623: Update the state-volume validation around modeTokens so
Mounts[].Mode is treated as non-authoritative: remove the requirement for
modeTokens to contain “z” while preserving rejection of “Z”, “ro”, and readonly
options. Add coverage for a valid mount with an empty Mode value.
- Around line 665-699: Update the environment validation in the inspect
comparison to compare validated Config.Env entries by variable name rather than
array order. Replace the sameArray check for environment with the existing
validated key-based map comparison, while preserving the current handling of
--unsetenv-all and --http-proxy=false and leaving entrypoint, command, and
supervisor comparisons unchanged.

---

Nitpick comments:
In `@src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.ts`:
- Around line 559-572: Update recordOriginalStopped to re-read the journal from
durable storage after atomicWrite, compare the read-back with updated using the
existing sameJournal validation, and return the verified persisted value instead
of the in-memory object. Preserve the existing phase checks and idempotent
current return behavior.

In `@src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts`:
- Around line 49-51: Replace the computed STAGING_NAME and STATE_VOLUME_NAME
constants in the test with literal expected names derived from the current
deterministic naming contract. Keep STATE_VOLUME_MOUNTPOINT based on the literal
state-volume name, so the assertions test production output without duplicating
the naming formula used by podman-bootstrap-replacement.ts.
- Around line 574-613: Add tests for the two uncovered fail-closed guards:
mutate the prepared replacementStateVolumeMountpoint or
replacementSpecFingerprint before calling stopExactPodmanBootstrapOriginal,
assert “does not match the durable journal,” and verify the original remains
running; separately, after successful prepare, set harness.stateVolume to null,
call rollbackPodmanBootstrapBeforeCommit, assert “recorded state volume
disappeared before rollback,” and preserve the journal assertions relevant to
rollback authorization.

In `@src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts`:
- Around line 933-943: Update the staging discovery mapping in the replacement
flow to read only the currently supported Podman identity field, Id, unless a
supported version requires ID; if so, add a protecting test that emits ID.
Remove the unreachable duplicate-identity Set check and retain the existing
single-identity validation through ids.length > 1.
🪄 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: bd154581-9c2f-40d9-b0c3-0dfccc97d4c6

📥 Commits

Reviewing files that changed from the base of the PR and between d7eb1f5 and 3d2efa1.

📒 Files selected for processing (5)
  • src/lib/onboard/lifecycle-contracts.md
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.test.ts
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.ts
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts

Comment thread src/lib/onboard/lifecycle-contracts.md
Comment thread src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts Outdated
Comment thread src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts
Comment thread src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts
Comment thread src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts
Comment thread src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa

ericksoa commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 1

🤖 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/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts`:
- Around line 503-519: Update the fixture in the “recognizes the Podman dest
alias without truncating its value” test to use a destination whose prefix
before the second “=” matches the protected directory while the complete
destination does not overlap it, so truncation would cause rejection. Keep the
existing prepareStoppedPodmanBootstrapReplacement call and replacement-created
assertion.
🪄 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: ceaba696-e2e5-4cae-8744-c087ee00c9cb

📥 Commits

Reviewing files that changed from the base of the PR and between 3d2efa1 and c992dd3.

📒 Files selected for processing (5)
  • src/lib/onboard/lifecycle-contracts.md
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.ts
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.test.ts
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts
  • test/runtime-provider-source-shape.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/onboard/lifecycle-contracts.md
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-journal.ts
  • src/lib/onboard/managed-bootstrap/podman-bootstrap-replacement.ts

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa

ericksoa commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ericksoa ericksoa added area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: security Security controls, permissions, secrets, or hardening feature PR adds or expands user-visible functionality platform: container Affects Docker, containerd, Podman, or images v0.0.101 labels Aug 1, 2026
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@github-actions github-actions Bot added v0.0.102 Release target and removed v0.0.101 labels Aug 3, 2026

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

Comment — reviewed exact head e724196. The transactional Podman bootstrap preparation is safe to merge and I found no blocking defect. Non-blocking fast follow: replace the partial runtimeArgs denylist with an activation-time allowlist before this dormant provider is registered, so boundary-changing flags such as --cap-add, --device, --pid=host, --userns=host, and --security-opt cannot slip through. Also add a lost-ack rollback test where volume removal succeeds but receipt publication fails, to pin reconciliation rather than repeated mutation.

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

Reviewed commit e724196652 in bottom-up stack order. This PR depends on root PR #8052, which is not approval-ready. The branch is behind that parent and its build, typecheck, CI, and E2E checks fail. Review remains blocked until the parent is reconstructed or repaired, this branch is restacked on the accepted parent commit, and current CI, security, and documentation evidence passes for the resulting commit. No approval is granted for the current branch.

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

Labels

area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow area: security Security controls, permissions, secrets, or hardening feature PR adds or expands user-visible functionality platform: container Affects Docker, containerd, Podman, or images v0.0.102 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants