feat(onboard): add managed bootstrap image runtime - #8045
Conversation
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>
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>
Preserve the exact reviewed tree while moving the stacked base to merged PR3.3. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Preserve the exact reviewed tree while moving the stacked base to restacked PR3.4a. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Preserve the exact reviewed tree while moving the stacked base to restacked PR3.4b. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Carry the reviewed PR3.4b slice unchanged onto the CodeRabbit feedback fix for PR3.4a. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Carry the reviewed PR3.5 slice unchanged onto the CodeRabbit feedback restack through PR3.4b. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Carry the reviewed PR3.4b slice unchanged onto the serialized PR3.4a transaction contract. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Carry the reviewed PR3.5 slice unchanged onto the serialized PR3.4a transaction contract. The review patch remains unchanged through PR3.4b. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Restack PR3.4b without changing its review patch. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Restack PR3.5 without changing its review patch. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Keep managed-startup activation independent from the dormant managed-bootstrap composition, and prove exact attempt identity, success ordering, failure behavior, and both bootstrap CLI modes. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/lib/onboard/managed-startup-image-runtime.test.ts (3)
704-732: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSplit the CLI leg into its own test.
The title claims two behaviors: completion is published only after application, and attempt identity is preserved. Lines 704-731 add a third behavior, which is CLI logging for
--apply-bootstrap-fileand--verify-bootstrap-completion. Line 704 also calls the mockedfs.unlinkSyncdirectly to reset state between the two legs.Move lines 704-731 into a separate
itthat seeds its own filesystem. The reset at line 704 then disappears, and a CLI regression names the CLI behavior instead of the publish-ordering behavior.🤖 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-startup-image-runtime.test.ts` around lines 704 - 732, Split the CLI logging assertions around mainManagedBootstrapImageRuntime into a separate it test that initializes its own filesystem state and validates both --apply-bootstrap-file and --verify-bootstrap-completion logs. Remove the direct fs.unlinkSync reset from the existing publish-ordering/attempt-identity test, leaving that test focused only on its claimed behavior.
734-776: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winAdd coverage for envelope metadata rejection.
This test covers one failure mode, which is a rejecting coordinator.
consumeManagedBootstrapEnvelopeinsrc/lib/onboard/managed-bootstrap/image-runtime.tslines 89-96 also rejects an envelope that is not root:root mode 0400 with one link. That check is the trust boundary for the request file, and the seeded map already carries amode, so the case is cheap to express.Add a case that seeds the request file with mode
0o444and asserts that the call rejects and that the request file is not consumed. Also add a case with a mismatchedbootstrapIdentityto cover the identity check at lines 98-104.🤖 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-startup-image-runtime.test.ts` around lines 734 - 776, Add test coverage for envelope metadata validation alongside the existing rejecting-coordinator test: seed the request file with mode 0o444 and assert applyManagedBootstrapEnvelope rejects without consuming the request, then add a separate case with a mismatched bootstrapIdentity and the same non-consumption assertion. Reuse the existing managed profile, filesystem setup, and request envelope helpers while targeting the metadata checks in consumeManagedBootstrapEnvelope.Source: Path instructions
634-635: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the exported bootstrap path constants in both test setups. Import
MANAGED_BOOTSTRAP_REQUEST_FILEandMANAGED_BOOTSTRAP_COMPLETION_FILE, then use them instead of the repeated literals at lines 634-635 and 739-740. The CLI entry point defaults to these constants, so one source prevents fixture paths from drifting.🤖 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-startup-image-runtime.test.ts` around lines 634 - 635, Update both test setups in managed-startup-image-runtime.test.ts to import and use the exported MANAGED_BOOTSTRAP_REQUEST_FILE and MANAGED_BOOTSTRAP_COMPLETION_FILE constants instead of hardcoded path literals. Apply this at both fixture definitions around lines 634-635 and 739-740, preserving the existing test behavior.
🤖 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/image-runtime.ts`:
- Around line 179-185: Update the --verify-bootstrap-completion branch to retain
the completion record returned by verifyManagedBootstrapImageCompletion and
include its transactionPending value in the verification log, matching the apply
log’s pending-state reporting. Update the corresponding assertion in
managed-startup-image-runtime.test.ts to expect the expanded message.
- Around line 105-118: Update applyManagedBootstrapEnvelope and the
consumeManagedBootstrapEnvelope flow so the bootstrap request remains available
until applyManagedStartupRootRequest completes successfully. Preserve or
re-stage the consumed envelope when application throws, allowing a subsequent
invocation to retry; retain the existing cleanup behavior after success. Add
coverage for an interrupted application followed by a successful retry.
---
Nitpick comments:
In `@src/lib/onboard/managed-startup-image-runtime.test.ts`:
- Around line 704-732: Split the CLI logging assertions around
mainManagedBootstrapImageRuntime into a separate it test that initializes its
own filesystem state and validates both --apply-bootstrap-file and
--verify-bootstrap-completion logs. Remove the direct fs.unlinkSync reset from
the existing publish-ordering/attempt-identity test, leaving that test focused
only on its claimed behavior.
- Around line 734-776: Add test coverage for envelope metadata validation
alongside the existing rejecting-coordinator test: seed the request file with
mode 0o444 and assert applyManagedBootstrapEnvelope rejects without consuming
the request, then add a separate case with a mismatched bootstrapIdentity and
the same non-consumption assertion. Reuse the existing managed profile,
filesystem setup, and request envelope helpers while targeting the metadata
checks in consumeManagedBootstrapEnvelope.
- Around line 634-635: Update both test setups in
managed-startup-image-runtime.test.ts to import and use the exported
MANAGED_BOOTSTRAP_REQUEST_FILE and MANAGED_BOOTSTRAP_COMPLETION_FILE constants
instead of hardcoded path literals. Apply this at both fixture definitions
around lines 634-635 and 739-740, preserving the existing test behavior.
🪄 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: 81885d26-b680-449d-803e-cdac2eb6ad7e
📒 Files selected for processing (7)
src/lib/onboard/managed-bootstrap/README.mdsrc/lib/onboard/managed-bootstrap/image-runtime.tssrc/lib/onboard/managed-bootstrap/index.tssrc/lib/onboard/managed-startup-bootstrap-image-runtime.test.tssrc/lib/onboard/managed-startup-image-runtime.test.tssrc/lib/onboard/managed-startup/image-runtime.tstest/runtime-provider-source-shape.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/lib/onboard/managed-startup-bootstrap-image-runtime.test.ts
- src/lib/onboard/managed-bootstrap/README.md
Linearize the fake-filesystem cleanup path and document the exact composed entrypoint that future image packaging must install. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/onboard/managed-startup-image-runtime.test.ts (1)
527-529: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueModel pending temporary-file cleanup in the fake filesystem.
unlinkSync(temporary)runs after atomic-write failure, but the mock only deletes committed files. Remove pending entries before falling back todeleteExistingFile; the production catch preserves the primary failure, so the current mock does not mask it.🤖 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-startup-image-runtime.test.ts` around lines 527 - 529, Update the vi.spyOn(fs, "unlinkSync") mock in the test to remove the provided temporary path from the fake filesystem’s pending entries before calling deleteExistingFile(String(target)). Preserve the existing committed-file cleanup fallback and ensure atomic-write failure cleanup mirrors production behavior without masking the primary error.Source: Path instructions
🤖 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/managed-startup-image-runtime.test.ts`:
- Around line 527-529: Update the vi.spyOn(fs, "unlinkSync") mock in the test to
remove the provided temporary path from the fake filesystem’s pending entries
before calling deleteExistingFile(String(target)). Preserve the existing
committed-file cleanup fallback and ensure atomic-write failure cleanup mirrors
production behavior without masking the primary error.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 280fbcd6-935e-40a0-a68c-262e9b3e35c2
📒 Files selected for processing (2)
src/lib/onboard/managed-bootstrap/README.mdsrc/lib/onboard/managed-startup-image-runtime.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/onboard/managed-bootstrap/README.md
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Keep the exact protected request available until application and completion publication both succeed, so an interrupted bootstrap can retry safely. Report pending shared-state completion during verification. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib/onboard/managed-bootstrap/image-runtime.ts (1)
108-130: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winBind request cleanup to the validated file.
readManagedBootstrapEnvelopevalidates one file, butapplyManagedBootstrapEnvelopecloses it before theawaitand then unlinksrequestFileby pathname. A replacement can therefore be deleted. Serialize access or revalidate the same file identity before cleanup. Add tests for default and injectedrequestFilepaths.🤖 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/image-runtime.ts` around lines 108 - 130, Update applyManagedBootstrapEnvelope so cleanup remains bound to the request file validated by readManagedBootstrapEnvelope across the await, preventing a replacement at requestFile from being deleted; serialize access or revalidate the file identity before fs.unlinkSync. Add coverage for both the default requestFile and an injected requestFile path.Source: Path instructions
🤖 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.
Outside diff comments:
In `@src/lib/onboard/managed-bootstrap/image-runtime.ts`:
- Around line 108-130: Update applyManagedBootstrapEnvelope so cleanup remains
bound to the request file validated by readManagedBootstrapEnvelope across the
await, preventing a replacement at requestFile from being deleted; serialize
access or revalidate the file identity before fs.unlinkSync. Add coverage for
both the default requestFile and an injected requestFile path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: de0b2078-bc1c-4525-8414-a2a3dc9fe3f6
📒 Files selected for processing (5)
src/lib/onboard/managed-bootstrap/README.mdsrc/lib/onboard/managed-bootstrap/image-runtime.tssrc/lib/onboard/managed-bootstrap/index.tssrc/lib/onboard/managed-startup-bootstrap-image-runtime.test.tssrc/lib/onboard/managed-startup-image-runtime.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/lib/onboard/managed-bootstrap/index.ts
- src/lib/onboard/managed-startup-bootstrap-image-runtime.test.ts
- src/lib/onboard/managed-startup-image-runtime.test.ts
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Retain and revalidate the exact root-owned request file identity before completion publication and immediately before removal. Fail closed without deleting a replacement or publishing a false completion. Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
🧹 Nitpick comments (7)
src/lib/onboard/managed-startup-image-runtime.test.ts (2)
1197-1206: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAssert one failure mode for the pre-claim replacement.
The regular expression accepts two different rejection reasons. The test passes whether the runtime detects the identity mismatch or the pre-claim change. That hides a change in which check fires first. The rename observer replaces the request exactly at the claim rename, so the expected failure is deterministic. Assert that single message, and keep the
recoverManagedBootstrapEnvelopeClaimassertion on Line 1204 as the identity check.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-startup-image-runtime.test.ts` around lines 1197 - 1206, The applyManagedBootstrapEnvelope assertion in the pre-claim replacement test must require the deterministic “changed before its atomic claim” rejection instead of accepting either message; keep the separate recoverManagedBootstrapEnvelopeClaim assertion for “identity does not match” unchanged.Source: Path instructions
550-568: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake
openSyncreject reads of missing files.The mock only raises
ENOENTforMANAGED_STARTUP_RUNTIME_ENV_FILEandMANAGED_STARTUP_COMPLETION_FILE. For any other absent path,allocateDescriptorreturns a descriptor, and the failure surfaces later infstatSync. ProductionreadStableFilewraps only theopenSynccall and reportscould not safely open <target>; it does not wrapfstatSync. A test that exercises a missing request or claim file therefore observes a rawENOENTinstead of the production error text.Gate the behavior on the create flag so writes still work.
♻️ Proposed mock fidelity fix
- vi.spyOn(fs, "openSync").mockImplementation(((target: fs.PathLike, _flags, mode) => { + vi.spyOn(fs, "openSync").mockImplementation(((target: fs.PathLike, flags, mode) => { const resolved = String(target); + const creating = + typeof flags === "number" && (flags & fs.constants.O_CREAT) === fs.constants.O_CREAT; const descriptor = - (resolved === MANAGED_STARTUP_RUNTIME_ENV_FILE || - resolved === MANAGED_STARTUP_COMPLETION_FILE) && - !files.has(resolved) + !creating && !files.has(resolved) && !directories.has(resolved) ? missing() : allocateDescriptor(resolved, typeof mode === "number" ? mode : 0o600);🤖 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-startup-image-runtime.test.ts` around lines 550 - 568, Update the openSync mock in the managed startup runtime tests to throw the missing-file error for every absent path when the requested flags do not permit creation, while preserving descriptor allocation for create-mode writes. Keep existing special handling and descriptor snapshots unchanged for present files, and ensure missing request or claim reads fail at openSync so readStableFile produces its expected error.src/lib/onboard/managed-bootstrap/README.md (1)
193-199: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the redundant qualifier.
Line 194 says "the same exact attempt". Use "the same attempt". The rest of the paragraph matches the implemented claim protocol.
✏️ Proposed change
-completion publication so the same exact attempt can retry after interruption; +completion publication so the same attempt can retry after interruption;🤖 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/README.md` around lines 193 - 199, In the managed-bootstrap README paragraph, update the phrase “the same exact attempt” to “the same attempt” while leaving the rest of the claim protocol description unchanged.Source: Linters/SAST tools
src/lib/onboard/managed-bootstrap/image-runtime.ts (2)
99-132: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReuse
isProtectedManagedBootstrapFilefor the snapshot metadata check.Lines 108-115 repeat the ownership, link-count, and mode rules that
isProtectedManagedBootstrapFilealready encodes at lines 181-189. One helper keeps both paths in agreement if the protected-file rule changes.♻️ Proposed refactor
- if ( - stat.nlink !== 1n || - stat.uid !== 0n || - stat.gid !== 0n || - Number(stat.mode & 0o777n) !== 0o400 - ) { + if (!isProtectedManagedBootstrapFile(stat)) { fail("managed bootstrap envelope must be root:root mode 0400 with one link"); }
readStableRegularFileSnapshotalready proves the target is a regular file, so the addedisFile()check does not change behavior.🤖 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/image-runtime.ts` around lines 99 - 132, Update readManagedBootstrapEnvelopeSnapshot to reuse isProtectedManagedBootstrapFile for validating the snapshot stat metadata instead of duplicating the nlink, uid, gid, and mode checks. Preserve the existing failure message and identity validation behavior.
154-179: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueCompose the two stat-comparison helpers.
sameClaimedManagedBootstrapFilerepeats every field ofsameStableManagedBootstrapFileexceptctimeNs. Express the stable check as the claimed check plusctimeNsequality. This removes the risk that a future field is added to only one helper.♻️ Proposed refactor
function sameStableManagedBootstrapFile(left: fs.BigIntStats, right: fs.BigIntStats): boolean { - return ( - left.dev === right.dev && - left.ino === right.ino && - left.mode === right.mode && - left.nlink === right.nlink && - left.uid === right.uid && - left.gid === right.gid && - left.size === right.size && - left.mtimeNs === right.mtimeNs && - left.ctimeNs === right.ctimeNs - ); + return sameClaimedManagedBootstrapFile(left, right) && left.ctimeNs === right.ctimeNs; }🤖 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/image-runtime.ts` around lines 154 - 179, Refactor sameStableManagedBootstrapFile to reuse sameClaimedManagedBootstrapFile for all shared stat comparisons, then additionally require matching ctimeNs. Remove the duplicated field checks while preserving both helpers’ existing comparison behavior.test/managed-bootstrap-trampoline.test.ts (1)
766-777: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert that the restart invoked claim recovery.
The mock node command at lines 652-653 removes both the request and the claim on every invocation. So the assertions at lines 770-772 pass even if the trampoline never runs
--recover-bootstrap-claimon the restart. Add a count assertion on the recovery trace line. This makes the recovered-claim claim in the test title observable.💚 Proposed change
lines = fs.readFileSync(trace, "utf8").trim().split("\n"); + expect(lines.filter((line) => line.includes("--recover-bootstrap-claim"))).toHaveLength(2); expect(lines.filter((line) => line.includes("--apply-bootstrap-file"))).toHaveLength(2);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 `@test/managed-bootstrap-trampoline.test.ts` around lines 766 - 777, Extend the assertions in the restart scenario to verify the recovery path was invoked, using the existing trace lines collected in lines. Add a count assertion for the --recover-bootstrap-claim invocation alongside the existing --apply-bootstrap-file, supervisor, and startup assertions, so the test observes claim recovery rather than relying only on filesystem cleanup.Source: Path instructions
ci/test-file-size-budget.json (1)
7-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffSplit the bootstrap cases before adding more lines.
The checker treats
legacyMaxLinesas both a maximum and a ratchet. Since the file is exactly 1874 lines, any line-count change fails CI unless the budget changes with it.🤖 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 `@ci/test-file-size-budget.json` at line 7, Split the bootstrap test cases in managed-startup-image-runtime.test.ts into a separate test file before adding further lines, then update ci/test-file-size-budget.json so each resulting file has an appropriate legacyMaxLines budget and no file remains ratcheted at the exact 1874-line limit.
🤖 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 `@ci/test-file-size-budget.json`:
- Line 7: Split the bootstrap test cases in
managed-startup-image-runtime.test.ts into a separate test file before adding
further lines, then update ci/test-file-size-budget.json so each resulting file
has an appropriate legacyMaxLines budget and no file remains ratcheted at the
exact 1874-line limit.
In `@src/lib/onboard/managed-bootstrap/image-runtime.ts`:
- Around line 99-132: Update readManagedBootstrapEnvelopeSnapshot to reuse
isProtectedManagedBootstrapFile for validating the snapshot stat metadata
instead of duplicating the nlink, uid, gid, and mode checks. Preserve the
existing failure message and identity validation behavior.
- Around line 154-179: Refactor sameStableManagedBootstrapFile to reuse
sameClaimedManagedBootstrapFile for all shared stat comparisons, then
additionally require matching ctimeNs. Remove the duplicated field checks while
preserving both helpers’ existing comparison behavior.
In `@src/lib/onboard/managed-bootstrap/README.md`:
- Around line 193-199: In the managed-bootstrap README paragraph, update the
phrase “the same exact attempt” to “the same attempt” while leaving the rest of
the claim protocol description unchanged.
In `@src/lib/onboard/managed-startup-image-runtime.test.ts`:
- Around line 1197-1206: The applyManagedBootstrapEnvelope assertion in the
pre-claim replacement test must require the deterministic “changed before its
atomic claim” rejection instead of accepting either message; keep the separate
recoverManagedBootstrapEnvelopeClaim assertion for “identity does not match”
unchanged.
- Around line 550-568: Update the openSync mock in the managed startup runtime
tests to throw the missing-file error for every absent path when the requested
flags do not permit creation, while preserving descriptor allocation for
create-mode writes. Keep existing special handling and descriptor snapshots
unchanged for present files, and ensure missing request or claim reads fail at
openSync so readStableFile produces its expected error.
In `@test/managed-bootstrap-trampoline.test.ts`:
- Around line 766-777: Extend the assertions in the restart scenario to verify
the recovery path was invoked, using the existing trace lines collected in
lines. Add a count assertion for the --recover-bootstrap-claim invocation
alongside the existing --apply-bootstrap-file, supervisor, and startup
assertions, so the test observes claim recovery rather than relying only on
filesystem cleanup.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: cefbf62d-7fc1-4cb1-9fd0-990690a1d067
📒 Files selected for processing (8)
ci/test-file-size-budget.jsonscripts/managed-bootstrap-trampoline.shsrc/lib/onboard/managed-bootstrap/README.mdsrc/lib/onboard/managed-bootstrap/image-runtime.tssrc/lib/onboard/managed-bootstrap/index.tssrc/lib/onboard/managed-startup-bootstrap-image-runtime.test.tssrc/lib/onboard/managed-startup-image-runtime.test.tstest/managed-bootstrap-trampoline.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/lib/onboard/managed-bootstrap/index.ts
- src/lib/onboard/managed-startup-bootstrap-image-runtime.test.ts
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Package the dormant managed-bootstrap boundary into the OpenClaw, Hermes, and LangChain Deep Agents Code images and qualify exact managed-image artifacts for amd64 and arm64. Production runtime selection remains unsupported, so this slice does not advertise or activate buildless or Podman support. ## Related Issue Part of #7744. ## Changes - Compile and package the native bootstrap entrypoint, composed image runtime, startup hold, and complete inert capability union in all three supported agent images. - Preserve each agent startup, application environment, corporate-CA, dashboard, messaging, and plugin behavior behind the dormant image-owned handoff. - Build and directly exercise exact OpenClaw, Hermes, and DCode amd64 artifacts on pull requests. - Publish amd64 and arm64 variants only after the matching all-agent validation and attestation evidence succeeds. - Add bounded, sanitized managed-image failure diagnostics and exact publication-evidence verification. - Keep central orchestration provider-neutral and production activation unavailable. ## Type of Change - [ ] 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: The reconstruction preserves the previously audited publication source while adapting it to the merged #8045 ownership model. Exact-head CodeRabbit is green with zero unresolved threads, and the published advisor assessment reports no blocking findings. - [x] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: `PR review advisor (GPT-5.6 Terra)` and `PR review advisor (Nemotron 3 Ultra)` are accepted as mechanical service failures on [exact-head attempt 2](https://github.com/NVIDIA/NemoClaw/actions/runs/30888817498/attempts/2): Terra rejected an invalid service-generated `max_output_tokens=1`, while Nemotron returned no required analysis. The exact-head publisher reports 0 blockers, 0 warnings, 0 suggestions, and no follow-up needed; the primary advisor passed on the immediately preceding implementation head in [run 30883374986](https://github.com/NVIDIA/NemoClaw/actions/runs/30883374986). No code follow-up issue is warranted. ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: `src/lib/onboard/managed-bootstrap/README.md` documents the all-agent image-packaging boundary and explicitly keeps production onboarding inert. The exact-head qualification corrections change only private image construction and direct-E2E boundaries; public `docs/` remain unchanged because this slice does not activate a user-visible runtime surface. - Agent: Codex Desktop <!-- docs-review-head-sha: 4af85d6 --> <!-- docs-review-agents-blob-sha: 3dd7c24 --> ## DGX Station Hardware Evidence - [ ] Tested on DGX Station - Tested commit: - Station profile/scenario: - Result: - Supporting evidence: ## Verification - Exact public head: `4af85d6f86a9db6ff201f75f31f94e75987a7410`. - Append-only repair: contaminated source head `6a1b8443a` is preserved at `backup/podman-stack/pr8047-contaminated-6a1b8443`; reviewed clean source `d656863ea` is preserved at `backup/podman-stack/pr8047-clean-d656863e`. - The qualification ancestry preserves the independently reviewed clean implementation. Exact-head corrections stage the canonical bootstrap envelope through root docker exec stdin, align SLSA dependency verification with BuildKit output, keep the fixed all-agent capability inventory independently asserted, and prove non-GHCR identity rejection occurs before any registry tool can run. The append-only public history incorporates current `main` at `453b5df0a0cd17e1f898c333a6c1583d96f51096`; the exact-head tree is `4a3b61ec6a731babdcf01f19e469be7e00aff551`, and the independently reviewed pre-correction clean source remains preserved at its backup ref. - Current GitHub diff versus the PR base: 72 files, +5,966/-397; no Podman lifecycle or provider implementation files. - Changed integration set: 29 files, 491 passing tests, 48 expected skips. - Changed CLI set: 3 files, 68 passing tests. - Focused exact-head remediation set: 3 suites, 126 passing tests. - Composed managed-bootstrap runtime bundles successfully; shell boundaries parse; local no-added-test-conditionals, test-size, source-shape, repository, Biome, hadolint, shellcheck, secret-scan, signed-DCO, and pre-push gates pass. - [x] PR description includes a Signed-off-by line and every new reconstruction commit is signed; GitHub verification is checked on the pushed head. - [x] Normal pre-commit, commit-msg, and pre-push hooks passed. - [x] Targeted behavior tests pass for the current change set. - [x] Applicable broad gate passed — exact-head CI, all-agent managed-image builds, CodeQL, CodeRabbit, and the published advisor assessment pass; all 22 executed jobs for the 17 protected E2E selections passed with no skips or pending tests. - [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) - [ ] 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> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added managed startup support across OpenClaw, Hermes, and LangChain Deep Agents Code. * Added configurable runtime identity and bundled capability support. * Added amd64 and arm64 image validation with direct startup checks. * **Bug Fixes** * Prevented unsupported integrations from activating unexpectedly. * Improved certificate handling, environment cleanup, permissions, and startup reliability. * **Chores** * Strengthened image publication verification, diagnostics, run isolation, and promotion safeguards. * Expanded validation for security, configuration, attestations, and image integrity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
Add the dormant image-owned managed-bootstrap runtime for OpenClaw, Hermes, and
LangChain Deep Agents Code. It authenticates the canonical envelope, atomically
moves that exact inode into a root-private retry claim, applies the root request,
publishes identity-bound completion, and consumes only the authenticated claim.
A newer canonical request is preserved. This slice does not package, advertise,
or activate buildless support.
Related Issue
Part of #7744.
Changes
verification CLI modes without importing managed-bootstrap from the neutral
managed-startup layer.
root-owned claim parents, and a root-private mode-0700 adjacent claim.
a newly staged canonical request, and fail closed before application if the
claim cannot be made.
rename, and reconcile the exact two-link state left by interruption during
exclusive restoration without overwriting a later canonical request.
completion-publication, and cleanup interruption; resume it idempotently.
succeeds, then delegate shared completion and runtime-environment verification.
the native trampoline for every supported agent before supervisor resume.
bootstrap-unsupported and current images do not package this entrypoint.
keep branch-heavy fake-FS setup in a 429-line non-test helper so no legacy
size or conditional-growth
allowance is required.
documentation, and advisor dispositions.
Type of Change
Quality Gates
onboarding, inference, runner, sandbox, or messaging)
reviewer/approval link/justification: two independent exact-tree audits cover
atomic claim ownership, descriptor identity, replacement preservation,
protected-parent validation, crash recovery, completion ordering, all-agent
trampoline behavior, provider neutrality, and inert activation.
name, approval link, and follow-up issue: the maintainer explicitly waived the
known npm advisory and its consequential same-repository E2E blockage for this
stack because that advisory is handled on a separate security stream. No other
check is waived.
Documentation Writer Review
docs-updatedsrc/lib/onboard/managed-bootstrap/README.mdwas checked against theexact claim runtime, trampoline, tests, provider registry, production image
packaging, and source-shape contract. It documents atomic private-claim retry
authority, preservation of a newer canonical request, post-rename crash
restoration, fail-closed rename,
one-way managed-bootstrap-to-managed-startup composition, delegated shared
completion verification, Node-owned state transitions, and inert activation.
No published
docs/change is needed while the capability remains unpackagedand provider-unsupported.
DGX Station Hardware Evidence
Verification
Exact public head:
9c67a9a2a0f98c34508305360671a8a9c7a4bec5.Exact head tree:
c615ee677c9a8bab4eebcbda57f97224da69eb09.Exact PR base used by the current workflow dispatch:
878430aebebcc5e584be3bef6685997d039c213a.Direct base-to-head scope: 11 files,
+2675/-575.Stable patch ID:
2ca3949b0dd55275a70bd86fd3a8d9b2118b2bc5.Binary diff SHA-256:
68d73166b4ac0dd62e7d12c7bab09a1b3be775082c544c211d3ed929f010ed78.Focused five-file runtime/source-shape verification: 94 passed; 9 Linux-only
tests skipped on the macOS host. The exact runtime suite passes 46 of 46.
The largest changed test file is 1,291 lines; branch-heavy fake-FS setup is in
a 429-line non-test helper. The trusted base-to-head evaluators report zero size
violations and
0 -> 0conditional growth for all five changed test files.CLI build and typecheck, repository architecture checks, source-shape and
test-size guards, Biome, Markdown lint, ShellCheck, diff checks, commit hooks,
and pre-push hooks pass locally.
The append-only history preserves every former public head.
9c67a9a2ahassole parent
30b61ca5c; that GitHub update commit retains856a021b3as itsfirst parent and the exact workflow base as its second. No remote history was
rewritten.
GitHub verifies the exact head signature and DCO. Exact-head CI, advisors,
CodeRabbit, and protected E2E are running.
All seven findings in CodeRabbit review
4850036066are addressed. The priorNemotron size warning and Terra post-rename replacement race are fixed;
dependency direction, delegated verification, Node-owned state transitions,
and fail-closed recovery behavior are explicit in the README and independently
audited.
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
Applicable broad gate passed — exact-head CI is running
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)
Stack
9c67a9a2a, targetingmain.review batches to pay one qualification cycle per batch. Buildless and Podman
support remain disabled until the complete all-agent, multiarch, GPU/local-
inference, recovery, installer, and protected-E2E gates in [Epic] Support native Podman with buildless managed onboarding #7744 pass.
Signed-off-by: Aaron Erickson aerickson@nvidia.com