| 1040 | |
| 1041 | #[test] |
| 1042 | fn program_trace_serializes_with_stable_schema() { |
| 1043 | let result = ProgramResult { |
| 1044 | program_name: "program_code_search".to_string(), |
| 1045 | success: true, |
| 1046 | summary: "done".to_string(), |
| 1047 | steps: vec![ProgramStepResult { |
| 1048 | tool_name: "grep".to_string(), |
| 1049 | label: Some("search_code".to_string()), |
| 1050 | success: true, |
| 1051 | output: "match".to_string(), |
| 1052 | metadata: Some(serde_json::json!({ "exit_code": 0 })), |
| 1053 | }], |
| 1054 | }; |
| 1055 | |
| 1056 | let step_trace = ProgramTraceStep::from_result( |
| 1057 | 0, |
| 1058 | &result.steps[0], |
| 1059 | true, |
| 1060 | Some(ProgramTraceArtifact { |
| 1061 | artifact_id: "artifact-1".to_string(), |
| 1062 | artifact_uri: "artifact://tool-output/artifact-1".to_string(), |
| 1063 | original_bytes: 100, |
| 1064 | shown_bytes: 10, |
| 1065 | }), |
| 1066 | ); |
| 1067 | let trace = ProgramTrace::from_result(&result, vec![step_trace]); |
| 1068 | let value = trace.to_value(); |
| 1069 | |
| 1070 | assert_eq!(value["schema"], PROGRAM_TRACE_SCHEMA); |
| 1071 | assert_eq!(value["type"], "program_execution"); |
| 1072 | assert_eq!(value["program_name"], "program_code_search"); |
| 1073 | assert_eq!(value["step_count"], 1); |
| 1074 | assert_eq!(value["failed_steps"], 0); |
| 1075 | assert_eq!(value["steps"][0]["label"], "search_code"); |
| 1076 | assert_eq!(value["steps"][0]["output_bytes"], 5); |
| 1077 | assert_eq!(value["steps"][0]["metadata"]["exit_code"], 0); |
| 1078 | assert_eq!( |
| 1079 | value["steps"][0]["artifact"]["artifact_uri"], |
| 1080 | "artifact://tool-output/artifact-1" |
| 1081 | ); |
| 1082 | } |
| 1083 | |
| 1084 | #[test] |
| 1085 | fn program_verification_hints_include_program_contract() { |