Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
3ea754c
refactor(cli): route buffered exec through adapter
rsliter Sep 4, 2026
f9b939d
merge: refresh canonical main
rsliter Sep 4, 2026
f751809
fix(sandbox): harden buffered exec migration
rsliter Sep 5, 2026
b070c24
merge(main): refresh buffered exec PR
rsliter Sep 5, 2026
50ecd5d
fix: harden buffered exec readiness follow-up
rsliter Sep 7, 2026
4a7ee12
merge: refresh main for issue 10991
rsliter Sep 7, 2026
cb63218
test: update N1x finalization executor fixture
rsliter Sep 7, 2026
f2c3a67
fix: honor final rebuild permission verification
rsliter Sep 7, 2026
4f19896
merge: integrate main into buffered exec
rsliter Sep 7, 2026
7624e2c
merge: integrate latest main into buffered exec
rsliter Sep 7, 2026
7fb76b1
fix: contain rejected gateway diagnostics
rsliter Sep 7, 2026
a16f1ac
merge: integrate typed provider lifecycle
rsliter Sep 7, 2026
68e3479
chore: refresh sandbox observer architecture budget
rsliter Sep 7, 2026
1c02f19
test: preserve connect diagnostic environment
rsliter Sep 7, 2026
077d576
merge: refresh main for issue 10991
rsliter Sep 8, 2026
e13b0d6
fix(cli): route session list through buffered executor
rsliter Sep 8, 2026
98f77b4
refactor(cli): centralize OpenShell process lifecycle
rsliter Sep 8, 2026
6018c8e
merge: refresh main for PR 11089
rsliter Sep 8, 2026
15f4c68
fix(cli): avoid empty stdin lifecycle race
rsliter Sep 8, 2026
63f1d92
merge: refresh main for PR 11089
rsliter Sep 8, 2026
17fc541
test(hermes): restore API port fixture prerequisite
rsliter Sep 8, 2026
3e3651b
fix(cli): preserve async spawn failures
rsliter Sep 8, 2026
b2b7710
merge: refresh main for PR 11089
rsliter Sep 8, 2026
a324c31
merge: refresh main for PR 11089
rsliter Sep 8, 2026
746afc6
merge: resolve conflicts with main
github-actions[bot] Sep 8, 2026
c296df6
fix(cli): preserve safe sandbox exec fallback
rsliter Sep 8, 2026
9adfd90
Merge remote-tracking branch 'origin/main' into codex/10991-buffered-…
rsliter Sep 8, 2026
6a02869
Merge remote-tracking branch 'origin/codex/10991-buffered-exec-pr' in…
rsliter Sep 8, 2026
1ea5b47
fix(cli): block buffered helper re-exports
rsliter Sep 9, 2026
4e34cf6
fix(cli): complete buffered helper export guard
rsliter Sep 9, 2026
dde688a
Merge remote-tracking branch 'refs/remotes/origin/main' into codex/10…
rsliter Sep 9, 2026
c4fb27f
Merge remote-tracking branch 'refs/remotes/origin/main' into codex/10…
rsliter Sep 9, 2026
fb9d306
Merge remote-tracking branch 'refs/remotes/origin/main' into codex/10…
rsliter Sep 9, 2026
a1be013
test(cli): isolate supervisor relaunch port state
rsliter Sep 9, 2026
23b952b
Merge remote-tracking branch 'origin/main' into codex/10991-buffered-…
rsliter Sep 9, 2026
e240f24
fix(ci): avoid backtracking in export guard
rsliter Sep 9, 2026
ab41e95
Merge remote-tracking branch 'origin/main' into codex/10991-buffered-…
rsliter Sep 9, 2026
30e3f5b
Merge remote-tracking branch 'origin/main' into codex/10991-buffered-…
rsliter Sep 9, 2026
b0ad3c1
fix(onboard): await sandbox config sync
rsliter Sep 9, 2026
c7d6e67
Merge remote-tracking branch 'refs/remotes/origin/main' into HEAD
rsliter Sep 9, 2026
024369f
Merge remote-tracking branch 'refs/remotes/origin/main' into HEAD
rsliter Sep 9, 2026
4181aed
test(onboard): await resumed identity probes
rsliter Sep 9, 2026
1719601
Merge remote-tracking branch 'refs/remotes/origin/main' into HEAD
rsliter Sep 9, 2026
8769dd6
Merge remote-tracking branch 'refs/remotes/origin/main' into HEAD
rsliter Sep 9, 2026
c4e1606
Merge remote-tracking branch 'refs/remotes/origin/main' into HEAD
rsliter Sep 9, 2026
7b66f3d
merge: resolve conflicts with main
github-actions[bot] Sep 9, 2026
0bdd4af
fix(onboard): preserve buffered smoke after main refresh
rsliter Sep 9, 2026
24d3aab
docs: clarify channel cleanup transport order
rsliter Sep 9, 2026
0ddf9cf
Merge branch 'main' into codex/10991-buffered-exec-pr
rsliter Sep 9, 2026
fb5979c
fix(recovery): make supervisor finalization single-flight
rsliter Sep 9, 2026
e6a9c75
Merge branch 'main' into codex/10991-buffered-exec-pr
rsliter Sep 9, 2026
a52d048
fix(ci): repair inherited main regressions
rsliter Sep 9, 2026
73f7596
docs(sandbox): correct channel cleanup order
rsliter Sep 9, 2026
805f933
fix(cli): inject sessions command executor
rsliter Sep 9, 2026
9ee57e3
Merge remote-tracking branch 'origin/main' into codex/10991-buffered-…
rsliter Sep 9, 2026
568e096
Merge remote-tracking branch 'origin/main' into codex/10991-buffered-…
rsliter Sep 9, 2026
eb2a2ed
merge: resolve conflicts with main
github-actions[bot] Sep 9, 2026
bdd41f9
Merge remote-tracking branch 'origin/main' into codex/10991-monitor-head
rsliter Sep 9, 2026
09e386d
fix(ci): reconcile source architecture limits
rsliter Sep 9, 2026
1b7744b
merge: resolve conflicts with main
github-actions[bot] Sep 9, 2026
957dfc5
ci: trigger checks after conflict resolution
rsliter Sep 9, 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
17 changes: 10 additions & 7 deletions ci/source-architecture-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"src/lib/adapters/openshell/client.ts": 21,
"src/lib/adapters/openshell/command-argv.ts": 23,
"src/lib/adapters/openshell/resolve.ts": 25,
"src/lib/adapters/openshell/runtime.ts": 53,
"src/lib/adapters/openshell/runtime.ts": 50,
"src/lib/adapters/openshell/sandbox-observer.ts": 29,
"src/lib/adapters/openshell/timeouts.ts": 33,
"src/lib/agent/defs.ts": 32,
"src/lib/cli/branding.ts": 80,
Expand All @@ -30,32 +31,34 @@
"src/lib/state/onboard-session.ts": 35,
"src/lib/state/registry.ts": 96,
"src/lib/state/state-root.ts": 21,
"src/lib/subprocess-env.ts": 22,
"src/lib/subprocess-env.ts": 24,
"src/lib/validation.ts": 24
}
},
"fanOut": {
"defaultMax": 20,
"maxByFile": {
"src/lib/actions/inference-set.ts": 31,
"src/lib/actions/sandbox/connect.ts": 42,
"src/lib/actions/sandbox/connect.ts": 43,
"src/lib/actions/sandbox/destroy.ts": 28,
"src/lib/actions/sandbox/doctor.ts": 27,
"src/lib/actions/sandbox/doctor.ts": 28,
"src/lib/actions/sandbox/gateway-state.ts": 21,
"src/lib/actions/sandbox/status-snapshot.ts": 19,
"src/lib/actions/sandbox/policy-channel.ts": 30,
"src/lib/actions/sandbox/process-recovery.ts": 20,
"src/lib/actions/sandbox/process-recovery.ts": 22,
"src/lib/actions/sandbox/rebuild-pipeline.ts": 30,
"src/lib/actions/sandbox/snapshot.ts": 37,
"src/lib/actions/uninstall/run-plan.ts": 25,
"src/lib/inference/local.ts": 22,
"src/lib/inference/onboard-probes.ts": 21,
"src/lib/inference/vllm.ts": 20,
"src/lib/onboard.ts": 191,
"src/lib/onboard.ts": 192,
"src/lib/onboard/sandbox-gpu-create-run-attempt.ts": 21,
"src/lib/onboard/machine/handlers/sandbox.ts": 21,
"src/lib/policy/index.ts": 22,
"src/lib/sandbox/config.ts": 19,
"src/lib/state/sandbox.ts": 21
"src/lib/state/sandbox.ts": 21,
"scripts/checks/run-managed-image-openshell-e2e.ts": 21
}
},
"allowedCycles": [],
Expand Down
83 changes: 81 additions & 2 deletions scripts/checks/layer-import-boundaries.mts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ const MANAGED_STATE_ROOT_PROVIDER_MODULES = [
"src/lib/onboard/managed-bootstrap/docker.ts",
"src/lib/onboard/managed-bootstrap/podman-runtime.ts",
] as const;
const LEGACY_BUFFERED_EXEC_HELPER = "src/lib/actions/sandbox/exec.ts";
const INTERACTIVE_EXEC_HELPER_IMPORTERS = new Set([
"src/lib/actions/sandbox/agent/passthrough-json.ts",
"src/lib/actions/sandbox/agent/passthrough.ts",
"src/lib/actions/sandbox/launch.ts",
"src/lib/actions/sandbox/sessions/passthrough.ts",
]);
const MANAGED_AGENT_IDS = new Set(["openclaw", "hermes", "langchain-deepagents-code", "pi"]);

function toRepoPath(absPath: string): string {
Expand Down Expand Up @@ -379,6 +386,66 @@ function checkNoBinLibShimImport(
}
}

function checkBufferedExecHelperImport(
absPath: string,
repoPath: string,
sourceFile: ts.SourceFile,
violations: Violation[],
): void {
if (repoPath === LEGACY_BUFFERED_EXEC_HELPER || INTERACTIVE_EXEC_HELPER_IMPORTERS.has(repoPath)) {
return;
}
const namespaceImports = new Set<string>();
for (const statement of sourceFile.statements) {
if (
!ts.isImportDeclaration(statement) ||
!ts.isStringLiteralLike(statement.moduleSpecifier) ||
resolveInternalImport(absPath, statement.moduleSpecifier.text) !== LEGACY_BUFFERED_EXEC_HELPER
) {
continue;
}
const bindings = statement.importClause?.namedBindings;
if (bindings && ts.isNamedImports(bindings)) {
for (const binding of bindings.elements) {
if ((binding.propertyName?.text ?? binding.name.text) !== "buildOpenshellExecArgs")
continue;
const pos = position(sourceFile, binding);
addViolation(
violations,
repoPath,
pos.line,
pos.column,
"buffered-exec-uses-async-executor",
"buffered sandbox execution must use the async command executor instead of buildOpenshellExecArgs",
);
}
} else if (bindings && ts.isNamespaceImport(bindings)) {
namespaceImports.add(bindings.name.text);
}
}
if (namespaceImports.size === 0) return;
const visit = (node: ts.Node): void => {
if (
ts.isPropertyAccessExpression(node) &&
ts.isIdentifier(node.expression) &&
namespaceImports.has(node.expression.text) &&
node.name.text === "buildOpenshellExecArgs"
) {
const pos = position(sourceFile, node);
addViolation(
violations,
repoPath,
pos.line,
pos.column,
"buffered-exec-uses-async-executor",
"buffered sandbox execution must use the async command executor instead of buildOpenshellExecArgs",
);
}
ts.forEachChild(node, visit);
};
visit(sourceFile);
}

function checkMessagingManifestFile(
absPath: string,
repoPath: string,
Expand Down Expand Up @@ -506,11 +573,23 @@ export function findLayerImportBoundaryViolations(root = SRC_ROOT): Violation[]
const messagingManifestFile = isMessagingManifestFile(repoPath);
const commandFile = isCommandFile(repoPath);
const source = readFileSync(absPath, "utf8");
if (!domainFile && !actionFile && !adapterFile && !messagingManifestFile && !commandFile) {
checkNoBinLibShimImport(absPath, repoPath, collectPreprocessedImportRefs(source), violations);
const preprocessedImports = collectPreprocessedImportRefs(source);
const importsBufferedExecHelper =
repoPath !== LEGACY_BUFFERED_EXEC_HELPER &&
!INTERACTIVE_EXEC_HELPER_IMPORTERS.has(repoPath) &&
preprocessedImports.some(
(ref) => resolveInternalImport(absPath, ref.specifier) === LEGACY_BUFFERED_EXEC_HELPER,
);
const layerFile =
domainFile || actionFile || adapterFile || messagingManifestFile || commandFile;
if (!layerFile && !importsBufferedExecHelper) {
checkNoBinLibShimImport(absPath, repoPath, preprocessedImports, violations);
continue;
}
const sourceFile = sourceFileFor(absPath, source);
if (importsBufferedExecHelper) {
checkBufferedExecHelperImport(absPath, repoPath, sourceFile, violations);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
}
const imports = collectImportRefs(sourceFile);
checkNoBinLibShimImport(absPath, repoPath, imports, violations);
if (domainFile) {
Expand Down
17 changes: 10 additions & 7 deletions scripts/checks/run-managed-image-openshell-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { resolveAgent } from "../../src/lib/agent/onboard.ts";
import { parseOpenShellSandboxId } from "../../src/lib/adapters/openshell/sandbox-identity.ts";
import { createCliOpenShellSandboxCommandExecutor } from "../../src/lib/adapters/openshell/sandbox-command-cli.ts";
import { createCliOpenShellSandboxObserverFromRunner } from "../../src/lib/adapters/openshell/sandbox-observer-cli.ts";
import { isValidName, NAME_ALLOWED_FORMAT } from "../../src/lib/name-validation.ts";
import {
Expand Down Expand Up @@ -67,6 +68,7 @@ import {
// and profile policy remains in managed-image-protected-runtime-contract.ts.

const MANAGED_AGENTS = new Set<ShippedManagedImageAgent>(SHIPPED_MANAGED_IMAGE_AGENTS);
const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
const MODEL = "nvidia/nemotron-3-ultra-550b-a55b";
const GATEWAY_NAME = "nemoclaw";
const GATEWAY_PORT = 8080;
Expand Down Expand Up @@ -367,12 +369,7 @@ export function parseManagedImageOpenShellE2eInputs(argv: readonly string[]): In
}

export function managedImageOpenShellBasePolicyPath(agent: ShippedManagedImageAgent): string {
return path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
"..",
"..",
...MANAGED_AGENT_BASE_POLICIES[agent],
);
return path.resolve(REPOSITORY_ROOT, ...MANAGED_AGENT_BASE_POLICIES[agent]);
}

export interface ManagedImageCommandResult {
Expand Down Expand Up @@ -784,8 +781,10 @@ function assertProtectedLocalInference(
export function failureInjectingAdapter(
onboard: OnboardModule,
stateRoot: string,
commandExecutor = createCliOpenShellSandboxCommandExecutor({ hostCwd: REPOSITORY_ROOT }),
): ManagedBootstrapAdapter {
const adapter = createDockerManagedBootstrapAdapter({
commandExecutor,
runCaptureOpenshell: onboard.runCaptureOpenshell,
runOpenshell: onboard.runOpenshell,
sleep: onboard.sleepSeconds,
Expand Down Expand Up @@ -1139,6 +1138,9 @@ async function run<T extends ManagedImageOpenShellE2eLocalInferenceEvidence = ne
detail: null,
at: new Date().toISOString(),
});
const commandExecutor = createCliOpenShellSandboxCommandExecutor({
hostCwd: REPOSITORY_ROOT,
});
let flow: Awaited<ReturnType<typeof runSandboxGpuCreateFlow>> | null = null;
try {
flow = await runSandboxGpuCreateFlow(
Expand Down Expand Up @@ -1179,6 +1181,7 @@ async function run<T extends ManagedImageOpenShellE2eLocalInferenceEvidence = ne
...startupPlan,
},
{
commandExecutor,
runOpenshell: onboard.runOpenshell,
runCaptureOpenshell: onboard.runCaptureOpenshell,
sandboxObserver: createCliOpenShellSandboxObserverFromRunner(onboard.runOpenshell),
Expand All @@ -1188,7 +1191,7 @@ async function run<T extends ManagedImageOpenShellE2eLocalInferenceEvidence = ne
...(input.failureInjection
? {
createManagedBootstrapAdapter: (stateRoot: string) =>
failureInjectingAdapter(onboard!, stateRoot),
failureInjectingAdapter(onboard!, stateRoot, commandExecutor),
}
: {}),
},
Expand Down
2 changes: 1 addition & 1 deletion src/commands/sandbox/gateway/restart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class GatewayRestartCliCommand extends NemoClawCommand {

public async run(): Promise<void> {
const { args, flags } = await this.parse(GatewayRestartCliCommand);
const result = restartSandboxGateway(args.sandboxName, { quiet: flags.quiet === true });
const result = await restartSandboxGateway(args.sandboxName, { quiet: flags.quiet === true });
if (!result.ok) {
this.setExitCode(1);
}
Expand Down
Loading
Loading