11// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22// SPDX-License-Identifier: Apache-2.0
33
4+ import { createHash } from "node:crypto" ;
45import { createRequire } from "node:module" ;
56import { afterEach , describe , expect , it , vi } from "vitest" ;
67
8+ import { managedStartupE2eProfile } from "../../../scripts/checks/generate-managed-startup-profile-fixture.mts" ;
79import {
810 serializedHostLocalInferenceReceipt ,
911 serializedLlamaCppHostLocalInferenceReceipt ,
1012} from "../../../test/helpers/host-local-inference-receipt" ;
13+ import type { SandboxWorkloadReceipt } from "../state/registry/types" ;
1114import { createSandboxHostLocalInferenceProvenance } from "../state/registry/host-local-inference" ;
15+ import {
16+ MANAGED_IMAGE_CAPABILITY_CONTRACT_VERSION ,
17+ MANAGED_IMAGE_REPOSITORIES ,
18+ MANAGED_IMAGE_STARTUP_PROFILE_CONTRACT_VERSION ,
19+ type ManagedImageAgent ,
20+ } from "./managed-image/contract" ;
21+ import { encodeManagedStartupProfile } from "./managed-startup/profile" ;
1222
1323const requireDist = createRequire ( import . meta. url ) ;
1424const onboardSession = requireDist ( "../state/onboard-session.js" ) ;
@@ -31,7 +41,103 @@ const runtimeFields = {
3141 openshellVersion : "0.1.2" ,
3242} ;
3343
44+ function managedWorkloadReceipt (
45+ agent : ManagedImageAgent ,
46+ ) : Extract < SandboxWorkloadReceipt , { readonly kind : "managed-image" } > {
47+ const encodedProfile = encodeManagedStartupProfile ( managedStartupE2eProfile ( agent ) ) ;
48+ const digest = agent === "openclaw" ? "a" : "b" ;
49+ return {
50+ schemaVersion : 1 ,
51+ kind : "managed-image" ,
52+ reference : `${ MANAGED_IMAGE_REPOSITORIES [ agent ] } @sha256:${ digest . repeat ( 64 ) } ` ,
53+ platform : "linux/amd64" ,
54+ release : "v0.0.100" ,
55+ sourceRevision : "d" . repeat ( 40 ) ,
56+ sourceCohort : "ghrun-9356-1" ,
57+ capabilityContractVersion : MANAGED_IMAGE_CAPABILITY_CONTRACT_VERSION ,
58+ startupProfileContractVersion : MANAGED_IMAGE_STARTUP_PROFILE_CONTRACT_VERSION ,
59+ encodedProfile,
60+ startupProfileSha256 : createHash ( "sha256" ) . update ( encodedProfile , "utf8" ) . digest ( "hex" ) ,
61+ credentialProxyReplayRequired : false ,
62+ shared : true ,
63+ } ;
64+ }
65+
66+ function createdRegistryEntryInput (
67+ overrides : Partial < Parameters < typeof buildCreatedSandboxRegistryEntry > [ 0 ] > = { } ,
68+ ) : Parameters < typeof buildCreatedSandboxRegistryEntry > [ 0 ] {
69+ return {
70+ sandboxName : "demo" ,
71+ inferenceSelection : {
72+ model : "llama" ,
73+ provider : "openai-compatible" ,
74+ endpointUrl : null ,
75+ credentialEnv : null ,
76+ preferredInferenceApi : null ,
77+ compatibleEndpointReasoning : null ,
78+ compatibleEndpointReasoningEffort : null ,
79+ nimContainer : null ,
80+ } ,
81+ runtimeFields,
82+ agent : null ,
83+ agentVersionKnown : true ,
84+ imageTag : null ,
85+ appliedPolicies : [ ] ,
86+ plannedMessagingState : undefined ,
87+ hermesToolGateways : [ ] ,
88+ hermesDashboardState : { enabled : false , config : null } ,
89+ dashboardPort : 18789 ,
90+ gatewayName : "nemoclaw" ,
91+ gatewayPort : 8080 ,
92+ ...overrides ,
93+ } ;
94+ }
95+
3496describe ( "buildCreatedSandboxRegistryEntry" , ( ) => {
97+ it ( "records explicit OpenClaw identity for a managed workload receipt (#9356)" , ( ) => {
98+ const workload = managedWorkloadReceipt ( "openclaw" ) ;
99+ const entry = buildCreatedSandboxRegistryEntry (
100+ createdRegistryEntryInput ( { imageTag : workload . reference , workload } ) ,
101+ ) ;
102+ const authority = requireDist (
103+ "./workload/authority.ts" ,
104+ ) as typeof import ( "./workload/authority" ) ;
105+
106+ expect ( entry . agent ) . toBe ( "openclaw" ) ;
107+ expect ( authority . readManagedWorkloadAuthority ( entry ) ?. agent ) . toBe ( "openclaw" ) ;
108+ } ) ;
109+
110+ it ( "keeps the legacy OpenClaw registry identity for a custom image (#9356)" , ( ) => {
111+ const entry = buildCreatedSandboxRegistryEntry (
112+ createdRegistryEntryInput ( {
113+ agentVersionKnown : false ,
114+ fromDockerfile : "/tmp/Dockerfile.custom" ,
115+ imageTag : "custom-openclaw:latest" ,
116+ workload : {
117+ schemaVersion : 1 ,
118+ kind : "legacy-dockerfile" ,
119+ reference : "custom-openclaw:latest" ,
120+ shared : false ,
121+ } ,
122+ } ) ,
123+ ) ;
124+
125+ expect ( entry . agent ) . toBeNull ( ) ;
126+ } ) ;
127+
128+ it ( "rejects a managed receipt for a different agent before registry mutation (#9356)" , ( ) => {
129+ const workload = managedWorkloadReceipt ( "hermes" ) ;
130+ const registerSandbox = vi . fn ( ) ;
131+
132+ expect ( ( ) =>
133+ registerCreatedSandbox ( {
134+ ...createdRegistryEntryInput ( { imageTag : workload . reference , workload } ) ,
135+ registerSandbox,
136+ } ) ,
137+ ) . toThrow ( / a g e n t i d e n t i t y d o e s n o t m a t c h i t s m a n a g e d w o r k l o a d r e c e i p t / u) ;
138+ expect ( registerSandbox ) . not . toHaveBeenCalled ( ) ;
139+ } ) ;
140+
35141 it ( "copies matching session profile provenance into the durable registry (#8246)" , ( ) => {
36142 const provenance = {
37143 schemaVersion : 1 ,
0 commit comments