@@ -16,7 +16,7 @@ use std::time::Duration;
1616
1717use clap:: { CommandFactory , Parser , Subcommand , ValueEnum } ;
1818use openshell_prover:: containment:: {
19- CheckOptions , CheckResult , CheckScope , ContainmentPolicy , Counterexample , parse_policy_str,
19+ CheckCoverage , CheckOptions , CheckResult , ContainmentPolicy , Counterexample , parse_policy_str,
2020} ;
2121use serde:: Serialize ;
2222
@@ -62,7 +62,7 @@ struct Envelope<'a> {
6262 schema_version : u32 ,
6363 prover_version : & ' static str ,
6464 check : & ' static str ,
65- scope : Option < ScopeJson < ' a > > ,
65+ coverage : Option < CoverageJson < ' a > > ,
6666 result : & ' static str ,
6767 exit_code : u8 ,
6868 inputs : InputsJson ,
@@ -72,9 +72,7 @@ struct Envelope<'a> {
7272}
7373
7474#[ derive( Debug , Serialize ) ]
75- struct ScopeJson < ' a > {
76- model_version : & ' a str ,
77- policy_version : u32 ,
75+ struct CoverageJson < ' a > {
7876 domains : Vec < & ' a str > ,
7977}
8078
@@ -87,6 +85,15 @@ struct InputsJson {
8785#[ derive( Debug , Serialize ) ]
8886#[ serde( tag = "domain" , rename_all = "snake_case" ) ]
8987enum CounterexampleJson < ' a > {
88+ Process {
89+ field : & ' a str ,
90+ boundary : & ' a str ,
91+ candidate : & ' a str ,
92+ } ,
93+ Landlock {
94+ boundary : & ' a str ,
95+ candidate : & ' a str ,
96+ } ,
9097 Filesystem {
9198 access : & ' a str ,
9299 path : & ' a str ,
@@ -96,6 +103,8 @@ enum CounterexampleJson<'a> {
96103 ancestor_binary : Option < & ' a str > ,
97104 binary_identity_required : bool ,
98105 host : & ' a str ,
106+ destination_ip : String ,
107+ trusted_gateway : bool ,
99108 port : u16 ,
100109 protocol : & ' a str ,
101110 method : Option < & ' a str > ,
@@ -284,7 +293,7 @@ fn render_input_error(
284293 schema_version : 1 ,
285294 prover_version : env ! ( "CARGO_PKG_VERSION" ) ,
286295 check : "boundary" ,
287- scope : None ,
296+ coverage : None ,
288297 result : "error" ,
289298 exit_code : 2 ,
290299 inputs,
@@ -308,18 +317,20 @@ fn render_cancelled(output: OutputFormat, inputs: InputsJson) -> Result<u8, Stri
308317}
309318
310319fn result_envelope ( result : & CheckResult , inputs : InputsJson ) -> Result < Envelope < ' _ > , String > {
311- let ( scope, result_name, exit_code, counterexample, reason_code, reason) = match result {
312- CheckResult :: Within ( evidence) => ( evidence. scope ( ) , "within_boundary" , 0 , None , None , None ) ,
320+ let ( coverage, result_name, exit_code, counterexample, reason_code, reason) = match result {
321+ CheckResult :: Within ( evidence) => {
322+ ( evidence. coverage ( ) , "within_boundary" , 0 , None , None , None )
323+ }
313324 CheckResult :: Exceeds ( evidence) => (
314- evidence. scope ( ) ,
325+ evidence. coverage ( ) ,
315326 "exceeds_boundary" ,
316327 1 ,
317328 Some ( counterexample_json ( evidence. counterexample ( ) ) ?) ,
318329 None ,
319330 None ,
320331 ) ,
321332 CheckResult :: Unsupported ( evidence) => (
322- evidence. scope ( ) ,
333+ evidence. coverage ( ) ,
323334 "unsupported" ,
324335 3 ,
325336 None ,
@@ -334,7 +345,7 @@ fn result_envelope(result: &CheckResult, inputs: InputsJson) -> Result<Envelope<
334345 3
335346 } ;
336347 (
337- evidence. scope ( ) ,
348+ evidence. coverage ( ) ,
338349 "inconclusive" ,
339350 exit_code,
340351 None ,
@@ -347,7 +358,7 @@ fn result_envelope(result: &CheckResult, inputs: InputsJson) -> Result<Envelope<
347358 schema_version : 1 ,
348359 prover_version : env ! ( "CARGO_PKG_VERSION" ) ,
349360 check : "boundary" ,
350- scope : Some ( scope_json ( scope ) ) ,
361+ coverage : Some ( coverage_json ( coverage ) ) ,
351362 result : result_name,
352363 exit_code,
353364 inputs,
@@ -357,16 +368,36 @@ fn result_envelope(result: &CheckResult, inputs: InputsJson) -> Result<Envelope<
357368 } )
358369}
359370
360- fn scope_json ( scope : & CheckScope ) -> ScopeJson < ' _ > {
361- ScopeJson {
362- model_version : scope. model_version ,
363- policy_version : scope. policy_version ,
364- domains : scope. domains . iter ( ) . map ( |domain| domain. as_str ( ) ) . collect ( ) ,
371+ fn coverage_json ( coverage : & CheckCoverage ) -> CoverageJson < ' _ > {
372+ CoverageJson {
373+ domains : coverage
374+ . domains
375+ . iter ( )
376+ . map ( |domain| domain. as_str ( ) )
377+ . collect ( ) ,
365378 }
366379}
367380
368381fn counterexample_json ( counterexample : & Counterexample ) -> Result < CounterexampleJson < ' _ > , String > {
369382 let converted = match counterexample {
383+ Counterexample :: Process {
384+ field,
385+ boundary,
386+ candidate,
387+ ..
388+ } => CounterexampleJson :: Process {
389+ field,
390+ boundary,
391+ candidate,
392+ } ,
393+ Counterexample :: Landlock {
394+ boundary,
395+ candidate,
396+ ..
397+ } => CounterexampleJson :: Landlock {
398+ boundary,
399+ candidate,
400+ } ,
370401 Counterexample :: Filesystem { access, path, .. } => CounterexampleJson :: Filesystem {
371402 access : access. as_str ( ) ,
372403 path,
@@ -376,6 +407,8 @@ fn counterexample_json(counterexample: &Counterexample) -> Result<Counterexample
376407 ancestor_binary,
377408 binary_identity_required,
378409 host,
410+ destination_ip,
411+ trusted_gateway,
379412 port,
380413 protocol,
381414 method,
@@ -386,6 +419,8 @@ fn counterexample_json(counterexample: &Counterexample) -> Result<Counterexample
386419 ancestor_binary : ancestor_binary. as_deref ( ) ,
387420 binary_identity_required : * binary_identity_required,
388421 host,
422+ destination_ip : destination_ip. to_string ( ) ,
423+ trusted_gateway : * trusted_gateway,
389424 port : * port,
390425 protocol : protocol. as_str ( ) ,
391426 method : method. as_deref ( ) ,
@@ -412,18 +447,14 @@ fn render(output: OutputFormat, envelope: &Envelope<'_>) -> Result<(), String> {
412447fn render_text ( mut writer : impl Write , envelope : & Envelope < ' _ > ) -> Result < ( ) , String > {
413448 writeln ! ( writer, "result: {}" , envelope. result)
414449 . map_err ( |error| format ! ( "failed to write output: {error}" ) ) ?;
415- if let Some ( scope) = & envelope. scope {
416- writeln ! (
417- writer,
418- "scope: model={} policy={} domains={}" ,
419- escape_terminal( scope. model_version) ,
420- scope. policy_version,
421- scope. domains. join( "," )
422- )
423- . map_err ( |error| format ! ( "failed to write output: {error}" ) ) ?;
450+ if let Some ( coverage) = & envelope. coverage {
451+ writeln ! ( writer, "coverage: domains={}" , coverage. domains. join( "," ) )
452+ . map_err ( |error| format ! ( "failed to write output: {error}" ) ) ?;
424453 }
425454 if let Some ( counterexample) = & envelope. counterexample {
426455 match counterexample {
456+ CounterexampleJson :: Process { field, boundary, candidate } => writeln ! ( writer, "counterexample: process {} boundary={} candidate={}" , escape_terminal( field) , escape_terminal( boundary) , escape_terminal( candidate) ) ,
457+ CounterexampleJson :: Landlock { boundary, candidate } => writeln ! ( writer, "counterexample: landlock boundary={} candidate={}" , escape_terminal( boundary) , escape_terminal( candidate) ) ,
427458 CounterexampleJson :: Filesystem { access, path } => writeln ! (
428459 writer,
429460 "counterexample: filesystem {access} {}" ,
@@ -434,18 +465,22 @@ fn render_text(mut writer: impl Write, envelope: &Envelope<'_>) -> Result<(), St
434465 ancestor_binary,
435466 binary_identity_required,
436467 host,
468+ destination_ip,
469+ trusted_gateway,
437470 port,
438471 protocol,
439472 method,
440473 path,
441474 } => writeln ! (
442475 writer,
443- "counterexample: network binary={} ancestor_binary={} binary_identity_required={} host={}:{} protocol={} method={} path={}" ,
476+ "counterexample: network binary={} ancestor_binary={} binary_identity_required={} host={}:{} destination_ip={} trusted_gateway={} protocol={} method={} path={}" ,
444477 binary. map_or( "-" . to_owned( ) , escape_terminal) ,
445478 ancestor_binary. map_or( "-" . to_owned( ) , escape_terminal) ,
446479 binary_identity_required,
447480 escape_terminal( host) ,
448481 port,
482+ destination_ip,
483+ trusted_gateway,
449484 escape_terminal( protocol) ,
450485 method. map_or( "-" . to_owned( ) , escape_terminal) ,
451486 path. map_or( "-" . to_owned( ) , escape_terminal) ,
@@ -557,7 +592,7 @@ mod tests {
557592 schema_version : 1 ,
558593 prover_version : env ! ( "CARGO_PKG_VERSION" ) ,
559594 check : "boundary" ,
560- scope : None ,
595+ coverage : None ,
561596 result : "within_boundary" ,
562597 exit_code : 0 ,
563598 inputs : InputsJson {
0 commit comments