66 listSpans ,
77 resetSpans ,
88} from "@corpos/core" ;
9+ import { buildApp } from "@corpos/api" ;
910import { eq } from "drizzle-orm" ;
1011import fs from "node:fs" ;
1112import path from "node:path" ;
@@ -19,6 +20,8 @@ function cell(id, ok, detail = "") {
1920 if ( ! ok ) throw new Error ( `${ id } failed: ${ detail } ` ) ;
2021}
2122
23+ const DANGEROUS_TOOL_RE = / \b ( s h e l l | e v a l | e x e c | s p a w n | c h i l d _ p r o c e s s | b a s h | p o w e r s h e l l | o s \. s y s t e m ) \b / i;
24+
2225// ASI02 / gateway bypass
2326const bypass = await company . gateway . invoke (
2427 "evil.shell" ,
@@ -37,13 +40,17 @@ cell(
3740 "unknown tool" ,
3841) ;
3942
40- // ASI05 attestation — no shell/eval tools
41- const aibomPath = path . resolve ( "docs/aibom.json" ) ;
42- const aibom = JSON . parse ( fs . readFileSync ( aibomPath , "utf8" ) ) ;
43+ // ASI05 — live tool registry scan (not AIBOM self-attestation alone)
44+ const registered = company . gateway . list ( ) ;
45+ const dangerousLive = registered . filter (
46+ ( t ) => DANGEROUS_TOOL_RE . test ( t . name ) || DANGEROUS_TOOL_RE . test ( t . description ?? "" ) ,
47+ ) ;
4348cell (
4449 "ASI05" ,
45- Array . isArray ( aibom . dangerous_tools_registered ) && aibom . dangerous_tools_registered . length === 0 ,
46- "no dangerous tools" ,
50+ registered . length > 0 && dangerousLive . length === 0 ,
51+ dangerousLive . length
52+ ? `dangerous tools: ${ dangerousLive . map ( ( t ) => t . name ) . join ( "," ) } `
53+ : "no shell/eval tools in live registry" ,
4754) ;
4855
4956// ASI03 three-layer privilege expansion
@@ -127,6 +134,8 @@ cell("ASI01", untrusted, "KB marked untrusted");
127134cell ( "ASI06" , untrusted , "context poisoning boundary" ) ;
128135
129136// ASI04 AIBOM
137+ const aibomPath = path . resolve ( "docs/aibom.json" ) ;
138+ const aibom = JSON . parse ( fs . readFileSync ( aibomPath , "utf8" ) ) ;
130139cell ( "ASI04" , Boolean ( aibom . policyBundleHash ) && Array . isArray ( aibom . mcp_servers ) , "aibom" ) ;
131140
132141// ASI07 handoff envelope via deny missing originator
@@ -153,10 +162,35 @@ const email = await company.gateway.invoke(
153162) ;
154163cell ( "ASI09" , email . decision . effect === "approve" && Boolean ( email . decision . approvalId ) , "HITL" ) ;
155164
156- // Auth shared mode
165+ // AUTH — exercise real requireAuth via HTTP on /api/kill (shared mode)
166+ const prevMode = process . env . CORPOS_MODE ;
167+ const prevToken = process . env . DASHBOARD_API_TOKEN ;
157168process . env . CORPOS_MODE = "shared" ;
158169process . env . DASHBOARD_API_TOKEN = "secret" ;
159- cell ( "AUTH" , `Bearer ${ process . env . DASHBOARD_API_TOKEN } ` === "Bearer secret" , "token" ) ;
170+ const app = buildApp ( company , "simulation" ) ;
171+ const unauth = await app . request ( "/api/kill" , {
172+ method : "POST" ,
173+ headers : { "content-type" : "application/json" } ,
174+ body : JSON . stringify ( { killed : true } ) ,
175+ } ) ;
176+ const authed = await app . request ( "/api/kill" , {
177+ method : "POST" ,
178+ headers : {
179+ "content-type" : "application/json" ,
180+ authorization : "Bearer secret" ,
181+ } ,
182+ body : JSON . stringify ( { killed : false } ) ,
183+ } ) ;
184+ if ( prevMode === undefined ) delete process . env . CORPOS_MODE ;
185+ else process . env . CORPOS_MODE = prevMode ;
186+ if ( prevToken === undefined ) delete process . env . DASHBOARD_API_TOKEN ;
187+ else process . env . DASHBOARD_API_TOKEN = prevToken ;
188+ const authedBody = await authed . json ( ) ;
189+ cell (
190+ "AUTH" ,
191+ unauth . status === 401 && authed . status === 200 && authedBody . killed === false ,
192+ `unauth=${ unauth . status } authed=${ authed . status } ` ,
193+ ) ;
160194
161195// Audit forge
162196await company . audit . append ( "a" , { n : 1 } ) ;
@@ -173,9 +207,13 @@ const { resolveProvider } = await import("@corpos/core");
173207const resolved = resolveProvider ( process . env ) ;
174208cell ( "HEALTH" , resolved . mode === "simulation" , "no live without allow" ) ;
175209
176- // OTel spans emitted on gateway
177- void listSpans ( ) ;
178- cell ( "OTEL" , true , "span buffer available" ) ;
210+ // OTel — require recorded spans from prior gateway invokes
211+ const spans = listSpans ( ) ;
212+ cell (
213+ "OTEL" ,
214+ spans . some ( ( s ) => s . operation === "execute_tool" || s . operation === "invoke_agent" ) ,
215+ `spans=${ spans . length } ` ,
216+ ) ;
179217
180218company . close ( ) ;
181219console . log ( "adversarial: ok" ) ;
0 commit comments