Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
dc08a1c
refactor(onboard): declare resume compatibility states
cv Jun 23, 2026
6c6812f
refactor(onboard): remove resume flag from live slices
cv Jun 23, 2026
07543b8
test(onboard): cover undeclared resume slice states
cv Jun 23, 2026
df75e11
Merge branch 'refactor/onboard-fsm-compat-states' into refactor/onboa…
cv Jun 23, 2026
7c45f1f
Merge remote-tracking branch 'origin/main' into refactor/onboard-fsm-…
cv Jun 23, 2026
21d17d1
refactor(onboard): inline compatibility result sequences
cv Jun 23, 2026
6ac7170
refactor(onboard): drop unused record-only runner
cv Jun 23, 2026
233ebc2
refactor(onboard): trim runtime boundary recorders
cv Jun 23, 2026
88364bd
refactor(onboard): default boundary steps to record-only
cv Jun 23, 2026
599e71f
test(onboard): assert default boundary record-only behavior
cv Jun 23, 2026
aeadb9e
test(onboard): avoid conditional growth in boundary harness
cv Jun 23, 2026
5f615b8
refactor(onboard): default runtime steps to record-only
cv Jun 23, 2026
0472db4
refactor(onboard): name legacy step machine mutation
cv Jun 23, 2026
eacd305
test(onboard): freeze shared step mutation options
cv Jun 23, 2026
8a3286e
test(onboard): make legacy step mutation explicit
cv Jun 23, 2026
6ae8561
test(onboard): address legacy step default coverage
cv Jun 23, 2026
116e2f9
Merge remote-tracking branch 'origin/main' into refactor/onboard-fsm-…
cv Jun 23, 2026
efec88b
Merge branch 'refactor/onboard-fsm-live-slice-inputs' into refactor/o…
cv Jun 23, 2026
1b70dce
Merge branch 'refactor/onboard-fsm-compat-result-loop' into refactor/…
cv Jun 23, 2026
3d404fa
Merge branch 'refactor/onboard-fsm-drop-record-only-runner' into refa…
cv Jun 23, 2026
febe3f1
Merge branch 'refactor/onboard-fsm-trim-recorders' into refactor/onbo…
cv Jun 23, 2026
d2da211
Merge branch 'refactor/onboard-fsm-record-only-boundary' into refacto…
cv Jun 23, 2026
22e8748
Merge branch 'refactor/onboard-fsm-runtime-record-only' into refactor…
cv Jun 23, 2026
bc45cea
Merge branch 'refactor/onboard-fsm-name-legacy-step-mutation' into te…
cv Jun 23, 2026
3c9351a
test(onboard): cover fresh slice entry strict paths
cv Jun 23, 2026
571a10b
Merge branch 'main' into refactor/onboard-fsm-live-slice-inputs
cv Jun 23, 2026
b091692
Merge branch 'refactor/onboard-fsm-live-slice-inputs' into refactor/o…
cv Jun 23, 2026
2799f21
refactor(onboard): default session steps to record-only
cv Jun 24, 2026
d219bb5
merge(onboard): sync PR #5647 with base branch
cv Jun 24, 2026
abf3178
merge(onboard): sync PR #5648 with base branch
cv Jun 24, 2026
9c626cb
merge(onboard): sync PR #5678 with base branch
cv Jun 24, 2026
ebd7ed9
merge(onboard): sync PR #5687 with base branch
cv Jun 24, 2026
fd777ad
merge(onboard): sync PR #5689 with base branch
cv Jun 24, 2026
0e20868
merge(onboard): sync PR #5692 with base branch
cv Jun 24, 2026
4c4be0b
refactor(onboard): move exit failure marking out of entrypoint
cv Jun 24, 2026
8fad47b
fix(onboard): reject stale record-only state results
cv Jun 24, 2026
b8b7e13
merge(onboard): sync PR #5701 with base branch
cv Jun 24, 2026
48b8e53
merge(onboard): integrate remote PR #5701 updates
cv Jun 24, 2026
2e5a31d
test(onboard): keep exit failure tests linear
cv Jun 24, 2026
6a24dbc
test(onboard): avoid conditional growth in exit failure tests
cv Jun 24, 2026
d376911
Merge remote-tracking branch 'origin/refactor/onboard-fsm-session-rec…
cv Jun 24, 2026
80e4176
test(onboard): move legacy step helper coverage
cv Jun 24, 2026
e298886
merge(onboard): sync PR #5701 with updated base
cv Jun 24, 2026
2697e76
merge(onboard): integrate remote PR #5701 updates
cv Jun 24, 2026
bf6b796
test(onboard): align no-options step helper coverage
cv Jun 24, 2026
75c899b
test(onboard): align no-options step helper coverage after remote sync
cv Jun 24, 2026
9065f9b
test(onboard): cover terminal cleanup callers
cv Jun 24, 2026
a92e9b8
test(onboard): keep rebuild flow harness linear
cv Jun 24, 2026
9026886
test(onboard): pin onboard exit registration
cv Jun 24, 2026
432110b
refactor(onboard): move exit registration helper
cv Jun 24, 2026
cdde4fb
test(onboard): cover production exit registration
cv Jun 24, 2026
3ce8a72
fix(onboard): guard completed exit sessions
cv Jun 24, 2026
308932f
test(onboard): move record-only stale result coverage
cv Jun 24, 2026
2fb808f
merge(onboard): sync record-only stale coverage
cv Jun 24, 2026
b9da71e
Merge remote-tracking branch 'origin/main' into test/onboard-explicit…
cv Jun 24, 2026
9101fb1
Merge remote-tracking branch 'origin/test/onboard-explicit-legacy-ste…
cv Jun 24, 2026
00f03a2
Merge remote-tracking branch 'origin/refactor/onboard-fsm-session-rec…
cv Jun 24, 2026
4a5cd39
Merge remote-tracking branch 'origin/main' into refactor/onboard-fsm-…
cv Jun 24, 2026
a5610fe
Merge remote-tracking branch 'origin/refactor/onboard-fsm-session-rec…
cv Jun 24, 2026
e361220
test(onboard): trim step mutation fixtures
cv Jun 24, 2026
f6c79f6
Merge remote-tracking branch 'origin/refactor/onboard-fsm-session-rec…
cv Jun 24, 2026
2029c34
Merge branch 'main' into test/onboard-record-only-boundary-stale-results
cv Jun 24, 2026
fe4699f
refactor(onboard): clarify compatibility bridge comments (#5709)
cv Jun 24, 2026
decb592
refactor(onboard): apply strict step results directly (#5710)
cv Jun 24, 2026
c0003d3
docs(onboard): clarify resume compatibility sources
cv Jun 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions src/lib/onboard/machine/core-flow-phases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,19 @@ export async function runCoreOnboardFlowSlice<Context extends OnboardFlowContext
resume: boolean;
recordStateResult(result: OnboardStateResult): Promise<unknown>;
}): Promise<OnboardMachineRunnerResult<Context>> {
// Compatibility bridge for live resume repair while legacy step helpers and
// OnboardRuntimeBoundary compatibility replay can leave the durable machine
// snapshot already downstream of this slice. The tolerated downstream family
// includes sandbox branch states and the final slice handoff states: openclaw,
// agent_setup, policies, finalizing, and post_verify. Resume still needs to
// re-run provider and sandbox repair/backstop checks before policy or final
// verification handling observes the session. This PR does not fix the
// broader persistence contract because those repairs are not strict FSM states
// yet. Remove this fallback once resume repairs are strict FSM states, or once
// direct legacy step helpers no longer write session.machine.
// Compatibility bridge for live resume repair when durable machine snapshots
// are already downstream of this slice even though provider/sandbox
// repair/backstop checks must still re-run. Those ahead-state snapshots can
// come from legacy/test step mutation that explicitly opts into
// `updateMachine === true` or from repaired-resume replay of persisted
// sessions. This slice cannot eliminate that source locally because the
// repair/backstop checks are still modeled as imperative resume work rather
// than strict FSM recovery states. The tolerated downstream family includes
// sandbox branch states and the final slice handoff states: openclaw,
// agent_setup, policies, finalizing, and post_verify. Phase tests cover
// ahead-state resume and terminal-state rejection; remove this fallback once
// those checks are strict FSM recovery states and legacy machine step mutation
// is gone.
return runLiveOnboardFlowSlice({
context: options.context,
runtime: options.runtime,
Expand Down
24 changes: 12 additions & 12 deletions src/lib/onboard/machine/final-flow-phases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,18 +159,18 @@ export async function runFinalOnboardFlowSlice<Context extends OnboardFlowContex
afterPoliciesResultApplied?(): void;
onContextUpdated?(context: Context): void;
}): Promise<void> {
// Keep resume and ahead-state sessions on the compatibility path for now.
// The persisted invalid states for this slice are "policies", "finalizing",
// and "post_verify": a previous run may have advanced `session.machine`
// there via legacy step helpers, but resume still needs to re-run branch
// setup/readiness, policy reconciliation, and final verification. Those
// legacy helpers remain a second machine snapshot writer in
// OnboardRuntimeBoundary/recordStateResultWithStepCompatibility, so this
// slice cannot make those persisted states impossible at the source without
// changing the broader step persistence contract. Remove this fallback once
// final-phase repair checks are first-class resumable FSM states, or once
// legacy step helpers no longer advance `session.machine` and handler FSM
// results are the sole transition source.
// Compatibility bridge for live resume repair when durable machine snapshots
// are already downstream of this slice even though branch setup/readiness,
// policy reconciliation, and final verification must still re-run. Those
// ahead-state snapshots can come from legacy/test step mutation that
// explicitly opts into `updateMachine === true` or from repaired-resume replay
// of persisted sessions. This slice cannot eliminate that source locally
// because final-phase repair checks are still modeled as imperative resume
// work rather than strict FSM recovery states. The tolerated downstream states
// are "policies", "finalizing", and "post_verify". Phase tests cover
// ahead-state resume and terminal-state rejection; remove this fallback once
// final-phase repair checks are first-class FSM recovery states and legacy
// machine step mutation is gone.
await runLiveOnboardFlowSlice({
context: options.context,
runtime: withAfterPoliciesResultApplied(options.runtime, options.afterPoliciesResultApplied),
Expand Down
24 changes: 13 additions & 11 deletions src/lib/onboard/machine/initial-flow-phases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,19 @@ export async function runInitialOnboardFlowSlice<Context extends OnboardFlowCont
resume: boolean;
recordStateResult(result: OnboardStateResult): Promise<unknown>;
}): Promise<OnboardMachineRunnerResult<Context>> {
// Compatibility bridge for live resume repair while legacy step helpers and
// OnboardRuntimeBoundary compatibility replay can leave the durable machine
// snapshot already downstream of this slice. The tolerated downstream family
// is every nonterminal state after the initial slice: inference, sandbox,
// openclaw/agent_setup, policies, finalizing, and post_verify. Resume still
// needs to re-run preflight/gateway host backstops before later provider,
// sandbox, policy, or verification handling observes the session. This PR
// does not fix the broader persistence contract because strict FSM repair
// states must preserve those safety checks first. Remove this fallback once
// resume repairs are strict FSM states, or once direct legacy step helpers no
// longer write session.machine.
// Compatibility bridge for live resume repair when durable machine snapshots
// are already downstream of this slice even though preflight/gateway host
// backstops must still re-run. Those ahead-state snapshots can come from
// legacy/test step mutation that explicitly opts into `updateMachine === true`
// or from repaired-resume replay of persisted sessions. This slice cannot
// eliminate that source locally because the host backstop checks are still
// modeled as imperative resume work rather than strict FSM recovery states.
// The tolerated downstream family is every nonterminal state after the initial
// slice: inference, sandbox, openclaw/agent_setup, policies, finalizing, and
// post_verify. Phase tests cover ahead-state resume and terminal-state
// rejection; remove this fallback once those repair/backstop checks are
// modeled as strict FSM recovery states and legacy machine step mutation is
// gone.
return runLiveOnboardFlowSlice({
context: options.context,
runtime: options.runtime,
Expand Down
34 changes: 33 additions & 1 deletion src/lib/onboard/runtime-boundary-record-only.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";

import {
createSession,
Expand Down Expand Up @@ -115,6 +115,38 @@ describe("OnboardRuntimeBoundary record-only step/result pairing", () => {
]);
});

it("applies validated step completion results directly without compatibility diagnostics", async () => {
const { boundary, events } = createRuntimeHarness();
const compatibilitySpy = vi
.spyOn(boundary, "recordStateResultWithStepCompatibility")
.mockRejectedValue(new Error("compatibility bridge should not be used"));

try {
await boundary.recordStateResult(advanceTo("preflight"));
const completed = await boundary.recordStepCompleteWithStateResult(
"preflight",
{ sandboxName: "strict-path-sb" },
advanceTo("gateway", { metadata: { state: "preflight" } }),
);

expect(completed).toMatchObject({
sandboxName: "strict-path-sb",
machine: { state: "gateway", revision: 2 },
steps: { preflight: { status: "complete" } },
});
expect(compatibilitySpy).not.toHaveBeenCalled();
expect(events.map((event) => event.type)).toEqual([
"state.exited",
"state.entered",
"state.exited",
"state.entered",
]);
expect(events.some((event) => event.type === "state.result.skipped")).toBe(false);
} finally {
compatibilitySpy.mockRestore();
}
});

it("pairs record-only step failure with an explicit failure result", async () => {
const { boundary, events } = createRuntimeHarness();

Expand Down
11 changes: 5 additions & 6 deletions src/lib/onboard/runtime-boundary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export class OnboardRuntimeBoundary {
): Promise<Session> {
await this.assertStateResultWillApply(result);
await this.getRuntime().markStepCompleteRecordOnly(stepName, updates);
return this.recordStateResultWithStepCompatibility(result);
return this.recordStateResult(result);
}

async recordStepFailedWithStateResult(
Expand All @@ -190,15 +190,14 @@ export class OnboardRuntimeBoundary {

/**
* Compatibility bridge for two named stale-result sources:
* 1. legacy/test boundaries configured with `updateMachine === true`, where
* step helpers still advance `session.machine` before handler results;
* 1. legacy/test boundaries explicitly configured with `updateMachine === true`;
* 2. live flow-slice replay for repaired resume or persisted ahead-state
* sessions, where safety checks must re-run even when the durable machine
* snapshot is already downstream.
*
* Default production record-only paths reject stale transition results before
* applying them. Skipped compatible results must stay metadata-only so stale
* results cannot become a context source. Remove this bridge once resume
* Default record-only paths reject stale transition results before applying
* them. Skipped compatible results must stay metadata-only so stale results
* cannot become a context source. Remove this bridge once resume
* repair/ahead-state replay is represented by first-class FSM recovery states
* and no boundary opts into legacy machine step mutation.
*/
Expand Down