refactor(onboard): persist messagingPlan in session for resume#4901
Conversation
Stores the compiled SandboxMessagingPlan in the onboard session so that resume runs can restore the plan to env without re-running enrollment hooks (token paste, QR pairing). Fixes the gap where the registry entry lost its `messaging` field on rebuild because the plan was only held in a process env var that didn't survive across process restarts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughPersist compiled SandboxMessagingPlan across sandbox runs: add parsing and session fields, propagate plan through update inputs, expose env read/write and registry accessor, wire helpers into handleSandboxState, stage plans during rebuild, and add tests for restore and persistence behavior. ChangesMessaging Plan Persistence
Sequence Diagram(s)sequenceDiagram
participant CLI as Onboard CLI
participant Handler as handleSandboxState
participant Env as MessagingSetupApplier
participant Registry as registry.getSandbox
participant Session as SessionStore
CLI->>Handler: start or resume sandbox
Handler->>Session: read current.messagingPlan
alt resume with recorded channels
Handler->>Env: readMessagingPlanFromEnv()
Env-->>Handler: env plan|null
alt env plan present
Handler->>Session: persist current.messagingPlan = env plan
else env plan missing
Handler->>Registry: getRegistrySandboxMessagingPlan(sandboxName)
Registry-->>Handler: registry plan|null
alt registry plan present
Handler->>Env: writePlanToEnv(registry plan)
Handler->>Session: persist current.messagingPlan = registry plan
else
Handler->>Session: persist current.messagingPlan = null
end
end
else no recorded channels
Handler->>Env: setupMessagingChannels()
Handler->>Env: readMessagingPlanFromEnv()
Env-->>Handler: env plan|null
Handler->>Session: persist current.messagingPlan = env plan|null
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
E2E Advisor RecommendationRequired E2E: Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
E2E Scenario Advisor RecommendationRequired scenario E2E: Dispatch required scenario E2E:
Full scenario advisor summaryE2E Scenario AdvisorBase: Required scenario E2E
Optional scenario E2E
Relevant changed files
|
…el-setup Exports readMessagingPlanFromEnv and writePlanToEnv from messaging-channel-setup.ts (which already owns MessagingSetupApplier) to keep src/lib/onboard.ts from growing. Collapses the one-name messaging-channel-setup require into a single line to free headroom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
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.ts`:
- Around line 6502-6503: The file exceeded growth budget by +2 lines; keep the
MessagingSetupApplier wiring but reduce lines: replace the two separate
arrow-wrapper properties (readMessagingPlanFromEnv: () =>
MessagingSetupApplier.readPlanFromEnv(), writePlanToEnv: (plan) =>
MessagingSetupApplier.writePlanToEnv(plan)) by a more compact form and remove
one additional non-functional line nearby (e.g., an extra blank line or
redundant comment) so you eliminate at least two lines total; ensure you
reference MessagingSetupApplier.readPlanFromEnv and
MessagingSetupApplier.writePlanToEnv exactly so behavior is preserved.
🪄 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: ff77f7f1-f35a-4224-938a-c5962d173b7a
📒 Files selected for processing (5)
src/lib/onboard.tssrc/lib/onboard/machine/handlers/sandbox.test.tssrc/lib/onboard/machine/handlers/sandbox.tssrc/lib/onboard/session-updates.tssrc/lib/state/onboard-session.ts
PR Review AdvisorFindings: 2 needs attention, 9 worth checking, 0 nice ideas Review findings🛠️ Needs attention
🔎 Worth checking
🌱 Nice ideas
Consider writing more tests for
Since last review detailsCurrent findings:
This is an automated advisory review. A human maintainer must make the final merge decision. |
…an persistence - Extract parseSandboxMessagingPlan to messaging-plan-session.ts to keep onboard-session.ts growth under the monolith threshold - Guard plan restoration with sandbox-name + agent identity check so stale plans from renamed sandboxes or agent switches are not reused - Add three behavior assertions in sandbox.test.ts: fresh setup persists env plan to session; matching plan is restored to env on non-interactive resume; mismatched sandbox name skips restoration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Addressed the PR advisor findings in 9a4ed8e: Needs attention → fixed
Worth checking → fixed
E2E triggered: https://github.com/NVIDIA/NemoClaw/actions/runs/27084551984 |
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/machine/handlers/sandbox.ts (1)
270-298:⚠️ Potential issue | 🟠 Major | ⚡ Quick winGuard mismatch path skips plan recompilation.
At Line 278-280, the comment says stale plans should go through the normal setup path, but when
planMatchesCurrentis false the code just continues withrecordedMessagingChannelsand leavesmessagingPlannull. This can recreate the “missing messaging state on createSandbox” path for stale-plan resumes.Suggested fix
- if (recordedMessagingChannels) { + let shouldSetupMessaging = !recordedMessagingChannels; + if (recordedMessagingChannels) { selectedMessagingChannels = recordedMessagingChannels; if (selectedMessagingChannels.length > 0) { deps.note(` [non-interactive] Reusing messaging channel configuration: ${selectedMessagingChannels.join(", ")}`); @@ if (planMatchesCurrent && storedPlan != null) { deps.writePlanToEnv(storedPlan); messagingPlan = storedPlan; + } else { + shouldSetupMessaging = true; } } - } else { + } + if (shouldSetupMessaging) { const existing = sandboxName ? deps.getSandboxMessagingChannels(sandboxName) ?? session?.messagingChannels ?? null : session?.messagingChannels ?? null; selectedMessagingChannels = await deps.setupMessagingChannels(agent, existing, sandboxName); messagingPlan = deps.readMessagingPlanFromEnv(); }🤖 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/machine/handlers/sandbox.ts` around lines 270 - 298, The current branch reuses recordedMessagingChannels but if planMatchesCurrent is false it leaves messagingPlan null and skips the normal setup path; instead when recordedMessagingChannels exists but planMatchesCurrent is false you should treat it like the "no recorded" case: call deps.setupMessagingChannels(agent, existing, sandboxName) to obtain selectedMessagingChannels and then set messagingPlan = deps.readMessagingPlanFromEnv(); only call deps.writePlanToEnv(storedPlan) when planMatchesCurrent is true. Update the logic around recordedMessagingChannels / planMatchesCurrent (using variables recordedMessagingChannels, selectedMessagingChannels, messagingPlan, storedPlan, planMatchesCurrent and methods deps.setupMessagingChannels, deps.readMessagingPlanFromEnv, deps.writePlanToEnv) so stale plans are recompiled via the normal setup path.
🧹 Nitpick comments (1)
src/lib/onboard/machine/handlers/sandbox.test.ts (1)
351-373: ⚡ Quick winAdd coverage for the agent-identity mismatch guard.
The new handler guard checks both
sandboxNameandagentidentity, but the new tests only assert sandbox-name mismatch. Add an agent-mismatch case so the second branch is protected from regressions.🤖 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/machine/handlers/sandbox.test.ts` around lines 351 - 373, The tests cover sandbox-name mismatch but not the agent-identity mismatch guard in handleSandboxState; add a new test similar to the "does not restore plan to env when sandbox name does not match" case that keeps sandboxName equal but sets the plan's agent identity (via makeMinimalPlan or the session.messagingPlan) to a different agent than the provided session or resume input, mock getRecordedMessagingChannelsForResume and writePlanToEnv as in the other tests, call handleSandboxState with resume: true and the matching sandboxName, and assert writePlanToEnv was not called to ensure the agent-identity guard is exercised.
🤖 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/machine/handlers/sandbox.ts`:
- Around line 270-298: The current branch reuses recordedMessagingChannels but
if planMatchesCurrent is false it leaves messagingPlan null and skips the normal
setup path; instead when recordedMessagingChannels exists but planMatchesCurrent
is false you should treat it like the "no recorded" case: call
deps.setupMessagingChannels(agent, existing, sandboxName) to obtain
selectedMessagingChannels and then set messagingPlan =
deps.readMessagingPlanFromEnv(); only call deps.writePlanToEnv(storedPlan) when
planMatchesCurrent is true. Update the logic around recordedMessagingChannels /
planMatchesCurrent (using variables recordedMessagingChannels,
selectedMessagingChannels, messagingPlan, storedPlan, planMatchesCurrent and
methods deps.setupMessagingChannels, deps.readMessagingPlanFromEnv,
deps.writePlanToEnv) so stale plans are recompiled via the normal setup path.
---
Nitpick comments:
In `@src/lib/onboard/machine/handlers/sandbox.test.ts`:
- Around line 351-373: The tests cover sandbox-name mismatch but not the
agent-identity mismatch guard in handleSandboxState; add a new test similar to
the "does not restore plan to env when sandbox name does not match" case that
keeps sandboxName equal but sets the plan's agent identity (via makeMinimalPlan
or the session.messagingPlan) to a different agent than the provided session or
resume input, mock getRecordedMessagingChannelsForResume and writePlanToEnv as
in the other tests, call handleSandboxState with resume: true and the matching
sandboxName, and assert writePlanToEnv was not called to ensure the
agent-identity guard is exercised.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: d4dbd24a-3cb7-4bd4-ad7a-facb49a8af1b
📒 Files selected for processing (4)
src/lib/onboard/machine/handlers/sandbox.test.tssrc/lib/onboard/machine/handlers/sandbox.tssrc/lib/onboard/messaging-plan-session.tssrc/lib/state/onboard-session.ts
✅ Files skipped from review due to trivial changes (1)
- src/lib/onboard/messaging-plan-session.ts
|
Waiting for E2E confirm |
…tive resume rebuild.ts stages an authoritative plan from the registry (which reflects post-stop/-start channel mutations) before calling onboard --resume. Previously, the session plan restoration was unconditionally overwriting that staged plan, causing stopped channels to reappear as active after rebuild. Now the handler checks the env first: if a plan is already staged (rebuild path), it is used as-is. The session plan is only restored when the env is empty, covering the plain process-restart resume case this PR was originally targeting. Also adds a test asserting the rebuild-path preference. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Selective E2E Results — ❌ Some jobs failedRun: 27085364196
|
Selective E2E Results — ❌ Some jobs failedRun: 27085645605
|
- On non-interactive resume, restore plan from registry (always current after stop/start/add/remove) instead of stale session snapshot; env-first priority preserved so rebuild.ts staging still wins - In rebuild.ts, persist the staged plan to the session alongside messagingChannels/disabledChannels/messagingChannelConfig so the session is fully consistent during the rebuild window - Add getChannelsFromPlan, getDisabledChannelsFromPlan, and getMessagingChannelConfigFromPlan helpers in messaging-plan-session.ts so the next PR can replace the three individual session fields with plan-derived reads - Move MessagingHostStateApplier re-export to messaging-channel-setup and getRegistrySandboxMessagingPlan helper to keep onboard.ts net-neutral Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.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/messaging-plan-session.ts (1)
7-26:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHarden
parseSandboxMessagingPlanelement-level validation at the boundary.Line 14–21 only verifies arrays exist, but not element shapes. A malformed persisted session payload can pass this parser and later break helpers (e.g., missing
channelIdor non-arrayinputs), causing incorrect restored state or runtime failure.Suggested fix (validate minimal nested shape before accepting)
export function parseSandboxMessagingPlan(value: unknown): SandboxMessagingPlan | null { if ( !isObject(value) || value.schemaVersion !== 1 || typeof value.sandboxName !== "string" || typeof value.agent !== "string" || typeof value.workflow !== "string" || !Array.isArray(value.channels) || !Array.isArray(value.disabledChannels) || !Array.isArray(value.credentialBindings) || !isObject(value.networkPolicy) || !Array.isArray(value.agentRender) || !Array.isArray(value.buildSteps) || !Array.isArray(value.stateUpdates) || - !Array.isArray(value.healthChecks) + !Array.isArray(value.healthChecks) || + !value.channels.every( + (c) => + isObject(c) && + typeof c.channelId === "string" && + Array.isArray(c.inputs), + ) || + !value.disabledChannels.every((c) => typeof c === "string") ) { return null; } return value as unknown as SandboxMessagingPlan; }🤖 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/messaging-plan-session.ts` around lines 7 - 26, The parser parseSandboxMessagingPlan currently only checks that several properties are arrays/objects but not the shape of their elements; update the function to validate minimal nested shapes for each collection before returning the cast: ensure channels entries contain a string channelId and an array inputs (and that each input has required fields like id/type as appropriate), disabledChannels entries are strings (or objects with channelId), credentialBindings entries include string keys and credentialId, agentRender and buildSteps are arrays of the expected primitive/object shape (e.g., renderId/string or object with name/type), stateUpdates entries have required fields (e.g., key and value types), and healthChecks entries include required fields (e.g., id/string and enabled boolean); if any element fails its shape check, return null. Locate and update parseSandboxMessagingPlan to add these per-item guards (using isObject/type checks and Array.isArray on nested arrays) so the final return value can safely be cast to SandboxMessagingPlan.
🧹 Nitpick comments (3)
src/lib/onboard.ts (1)
6499-6501: Run the onboarding E2E matrix for this dependency wiring change.Since this updates
handleSandboxStatedependencies in onboarding core, run the recommendedsrc/lib/onboard.tsE2E jobs before merge.As per coding guidelines, changes in
src/lib/onboard.tsshould be validated with the listed onboarding E2E workflows (e.g.,cloud-e2e,sandbox-operations-e2e,rebuild-openclaw-e2e,channels-stop-start-e2e, and related jobs).🤖 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.ts` around lines 6499 - 6501, This change updates dependencies used by handleSandboxState in src/lib/onboard.ts (notably readMessagingPlanFromEnv, writePlanToEnv, and getRegistrySandboxMessagingPlan); before merging, run the onboarding E2E matrix (cloud-e2e, sandbox-operations-e2e, rebuild-openclaw-e2e, channels-stop-start-e2e and related onboarding jobs) to validate the new wiring and ensure no regressions in sandbox onboarding flows.Source: Coding guidelines
src/lib/onboard/machine/handlers/sandbox.test.ts (2)
369-386: 💤 Low valueConsider making the two plans distinguishable for test clarity.
Both
registryPlanandrebuiltPlanare created with identical arguments (makeMinimalPlan("my-assistant")), making their content indistinguishable. While the test is functionally correct—the assertion on line 384 (expect(writePlanToEnv).not.toHaveBeenCalled()) definitively proves the env path was taken—using different sandbox names or agents would make the test intent clearer and guard against logic changes that might accidentally swap the plans.📋 Suggested improvement
- const registryPlan = makeMinimalPlan("my-assistant"); - const rebuiltPlan = makeMinimalPlan("my-assistant"); + const registryPlan = makeMinimalPlan("my-assistant", "openclaw"); + const rebuiltPlan = makeMinimalPlan("my-assistant", "hermes");🤖 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/machine/handlers/sandbox.test.ts` around lines 369 - 386, The two plans used in the test are identical which reduces clarity; change how registryPlan and rebuiltPlan are constructed so they are distinguishable (e.g., call makeMinimalPlan with different sandbox names or different agent identifiers) and keep the rest of the test intact; update the variables registryPlan and rebuiltPlan (used by readMessagingPlanFromEnv and getRegistrySandboxMessagingPlan in createDeps) so that when handleSandboxState is invoked you can clearly assert getSession().messagingPlan equals rebuiltPlan and that writePlanToEnv was not called.
352-367: 💤 Low valueConsider adding session state assertions for completeness.
Test "restores registry plan to env..." (lines 352-367) verifies that
writePlanToEnvis called but doesn't assert that the plan is also persisted tosession.messagingPlan. Similarly, test "does not restore plan to env..." (lines 388-402) could verify thatsession.messagingPlanremainsnullwhen no registry entry exists. The runtime code (context snippet 2, line 305) always updatescurrent.messagingPlan, so adding these assertions would strengthen coverage and make the tests more complete.📋 Suggested additions
For test starting at line 352:
await handleSandboxState({ ...baseOptions(deps, session), resume: true, sandboxName: "my-assistant" }); expect(writePlanToEnv).toHaveBeenCalledWith(registryPlan); + expect(getSession().messagingPlan).toEqual(registryPlan); });For test starting at line 388:
await handleSandboxState({ ...baseOptions(deps, session), resume: true, sandboxName: "my-assistant" }); expect(writePlanToEnv).not.toHaveBeenCalled(); + expect(getSession().messagingPlan).toBeNull(); });Note: You'll need to capture
getSessionfromcreateDepsin the test at line 388 (similar to line 375).Also applies to: 388-402
🤖 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/machine/handlers/sandbox.test.ts` around lines 352 - 367, Add assertions to these tests to verify session.messagingPlan is updated or left null: after calling handleSandboxState in the "restores registry plan to env on non-interactive resume..." test assert that the session object passed into handleSandboxState has its messagingPlan set to registryPlan (in addition to expecting writePlanToEnv). In the "does not restore plan to env..." test capture the same session (use the session returned from createDeps/getSession or the local session variable) and assert session.messagingPlan remains null after handleSandboxState when readMessagingPlanFromEnv returns null and there is no registry entry. Reference handleSandboxState, writePlanToEnv, session.messagingPlan, createDeps/getSession when locating where to add the assertions.
🤖 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/messaging-plan-session.ts`:
- Around line 7-26: The parser parseSandboxMessagingPlan currently only checks
that several properties are arrays/objects but not the shape of their elements;
update the function to validate minimal nested shapes for each collection before
returning the cast: ensure channels entries contain a string channelId and an
array inputs (and that each input has required fields like id/type as
appropriate), disabledChannels entries are strings (or objects with channelId),
credentialBindings entries include string keys and credentialId, agentRender and
buildSteps are arrays of the expected primitive/object shape (e.g.,
renderId/string or object with name/type), stateUpdates entries have required
fields (e.g., key and value types), and healthChecks entries include required
fields (e.g., id/string and enabled boolean); if any element fails its shape
check, return null. Locate and update parseSandboxMessagingPlan to add these
per-item guards (using isObject/type checks and Array.isArray on nested arrays)
so the final return value can safely be cast to SandboxMessagingPlan.
---
Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 6499-6501: This change updates dependencies used by
handleSandboxState in src/lib/onboard.ts (notably readMessagingPlanFromEnv,
writePlanToEnv, and getRegistrySandboxMessagingPlan); before merging, run the
onboarding E2E matrix (cloud-e2e, sandbox-operations-e2e, rebuild-openclaw-e2e,
channels-stop-start-e2e and related onboarding jobs) to validate the new wiring
and ensure no regressions in sandbox onboarding flows.
In `@src/lib/onboard/machine/handlers/sandbox.test.ts`:
- Around line 369-386: The two plans used in the test are identical which
reduces clarity; change how registryPlan and rebuiltPlan are constructed so they
are distinguishable (e.g., call makeMinimalPlan with different sandbox names or
different agent identifiers) and keep the rest of the test intact; update the
variables registryPlan and rebuiltPlan (used by readMessagingPlanFromEnv and
getRegistrySandboxMessagingPlan in createDeps) so that when handleSandboxState
is invoked you can clearly assert getSession().messagingPlan equals rebuiltPlan
and that writePlanToEnv was not called.
- Around line 352-367: Add assertions to these tests to verify
session.messagingPlan is updated or left null: after calling handleSandboxState
in the "restores registry plan to env on non-interactive resume..." test assert
that the session object passed into handleSandboxState has its messagingPlan set
to registryPlan (in addition to expecting writePlanToEnv). In the "does not
restore plan to env..." test capture the same session (use the session returned
from createDeps/getSession or the local session variable) and assert
session.messagingPlan remains null after handleSandboxState when
readMessagingPlanFromEnv returns null and there is no registry entry. Reference
handleSandboxState, writePlanToEnv, session.messagingPlan, createDeps/getSession
when locating where to add the assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 1e37ed83-b2a8-43e8-8ac6-d3b86d8a7dee
📒 Files selected for processing (6)
src/lib/actions/sandbox/rebuild.tssrc/lib/onboard.tssrc/lib/onboard/machine/handlers/sandbox.test.tssrc/lib/onboard/machine/handlers/sandbox.tssrc/lib/onboard/messaging-channel-setup.tssrc/lib/onboard/messaging-plan-session.ts
Selective E2E Results — ✅ All requested jobs passedRun: 27088189131
|
Move messaging policy application into src/lib/messaging/applier/ and replace channel-list-based preset computation with plan.networkPolicy.presets throughout the policy selection, resume, and sandbox create flows. - Add getPolicyPresetsFromPlan helper to messaging-plan-session - Move pruneDisabledMessagingPolicyPresets to messaging/applier/policy-presets; delete merged/computed functions superseded by the compiled plan - Replace enabledChannels/disabledChannels with messagingPolicyPresets in SetupPolicySelectionOptions, SetupPresetSuggestionOptions, and preparePolicyPresetResumeSelection; stale-preset detection now uses ALL_MESSAGING_POLICY_PRESET_NAMES diff against plan presets - Remove selectedMessagingChannels, mergePolicyMessagingChannels, and getActiveSandbox from handlePoliciesState; handler now accepts a single messagingPolicyPresets: string[] derived from the session plan - Wire getPolicyPresetsFromPlan into onboard.ts handlePoliciesState call and prepareInitialSandboxCreatePolicy sandbox create policy - Update rebuild.ts import to new applier location Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…esets" This reverts commit 12d5e96.
Selective E2E Results — ✅ All requested jobs passedRun: 27091050083
|
Summary
Persists the compiled
SandboxMessagingPlanin the onboard session so that--resumeruns carry the full channel plan across process restarts without re-reading from env or registry. EstablishesmessagingPlanas the canonical session field for channel state, with helpers to derivemessagingChannels,disabledChannels, andmessagingChannelConfigfrom it.Related Issue
Closes #4902
Changes
messaging-channel-setup.ts— move plan env helpers (writePlanToEnv,readMessagingPlanFromEnv) here from onboard.tsmessaging-plan-session.ts— addgetChannelsFromPlan,getDisabledChannelsFromPlan,getMessagingChannelConfigFromPlanderivation helpers andparseSandboxMessagingPlanfor env deserializationhandlers/sandbox.ts— persistmessagingPlanto session after sandbox step; restore plan from env or registry on non-interactive resume with plan identity guardonboard-session.ts— addmessagingPlan: SandboxMessagingPlan | nulltoSessionandSessionUpdatesType of Change
Verification
npx prek run --all-filespassesnpm testpassesnpm run docsbuilds without warnings (doc changes only)Signed-off-by: San Dang sdang@nvidia.com