@@ -177,11 +177,20 @@ pub const Reader = struct {
177177// ============================================================================
178178
179179/// Map PREMIS MIME type to a Lithoglyph bofig_evidence evidence_type value.
180+ /// Covers all 15 evidence types defined in the Lithoglyph OpenAPI spec:
181+ /// court_filing, deposition, testimony, flight_log, financial_record,
182+ /// communication, photograph, video, official_statistics, news_report,
183+ /// document, dataset, interview, affidavit, subpoena, other.
184+ ///
185+ /// MIME-only detection is inherently limited — many types (deposition,
186+ /// testimony, affidavit, subpoena, flight_log) share the same MIME as
187+ /// generic documents. Callers should override via investigation context
188+ /// or NER stage output when available.
180189fn detectEvidenceType (mime : []const u8 ) []const u8 {
181190 if (mime .len == 0 ) return "document" ;
182191
183- // PDF documents — could be court filings, depositions, or general documents.
184- // Default to "document"; the caller can override based on investigation context.
192+ // PDF documents — default to "court_filing" as the most common
193+ // investigative PDF type; callers override via context.
185194 if (std .mem .startsWith (u8 , mime , "application/pdf" )) return "court_filing" ;
186195
187196 // Images
@@ -190,21 +199,33 @@ fn detectEvidenceType(mime: []const u8) []const u8 {
190199 // Video
191200 if (std .mem .startsWith (u8 , mime , "video/" )) return "video" ;
192201
193- // Audio (depositions, interviews)
202+ // Audio (depositions, interviews, testimony recordings )
194203 if (std .mem .startsWith (u8 , mime , "audio/" )) return "interview" ;
195204
196- // Spreadsheets / CSV — likely financial records
205+ // Spreadsheets / CSV — financial records or datasets
197206 if (std .mem .startsWith (u8 , mime , "text/csv" ) or
198207 std .mem .startsWith (u8 , mime , "application/vnd.ms-excel" ) or
199208 std .mem .startsWith (u8 , mime , "application/vnd.openxmlformats-officedocument.spreadsheetml" ))
200209 {
201210 return "financial_record" ;
202211 }
203212
204- // Plain text / HTML
213+ // Structured data formats — datasets
214+ if (std .mem .startsWith (u8 , mime , "application/json" ) or
215+ std .mem .startsWith (u8 , mime , "application/xml" ) or
216+ std .mem .startsWith (u8 , mime , "text/xml" ) or
217+ std .mem .startsWith (u8 , mime , "application/vnd.openxmlformats-officedocument.presentationml" ))
218+ {
219+ return "dataset" ;
220+ }
221+
222+ // HTML — news reports or general documents
223+ if (std .mem .eql (u8 , mime , "text/html" )) return "news_report" ;
224+
225+ // Plain text
205226 if (std .mem .startsWith (u8 , mime , "text/" )) return "document" ;
206227
207- // Email
228+ // Email / messaging
208229 if (std .mem .startsWith (u8 , mime , "message/" )) return "communication" ;
209230
210231 return "document" ;
@@ -479,13 +500,15 @@ pub fn stageResultsToJson(
479500 w .print ("\" legal_statute_refs\" :{d}" , .{legal_statutes }) catch return null ;
480501 w .writeAll ("}," ) catch return null ;
481502
482- // PROMPT scores
483- w .print ("\" prompt_provenance\" :{d}," , .{prompt .provenance }) catch return null ;
484- w .print ("\" prompt_replicability\" :{d}," , .{prompt .replicability }) catch return null ;
485- w .print ("\" prompt_objective\" :{d}," , .{prompt .objective }) catch return null ;
486- w .print ("\" prompt_methodology\" :{d}," , .{prompt .methodology }) catch return null ;
487- w .print ("\" prompt_publication\" :{d}," , .{prompt .publication }) catch return null ;
488- w .print ("\" prompt_transparency\" :{d}," , .{prompt .transparency }) catch return null ;
503+ // PROMPT scores — nested object matching Lithoglyph PromptScoresInput schema
504+ w .writeAll ("\" promptScores\" :{" ) catch return null ;
505+ w .print ("\" provenance\" :{d}," , .{prompt .provenance }) catch return null ;
506+ w .print ("\" replicability\" :{d}," , .{prompt .replicability }) catch return null ;
507+ w .print ("\" objective\" :{d}," , .{prompt .objective }) catch return null ;
508+ w .print ("\" methodology\" :{d}," , .{prompt .methodology }) catch return null ;
509+ w .print ("\" publication\" :{d}," , .{prompt .publication }) catch return null ;
510+ w .print ("\" transparency\" :{d}" , .{prompt .transparency }) catch return null ;
511+ w .writeAll ("}," ) catch return null ;
489512
490513 // Sensitivity defaults to public for automated ingestion.
491514 writeJsonString (w , "sensitivity_level" , "public" ) catch return null ;
@@ -588,6 +611,13 @@ test "detectEvidenceType maps MIME types correctly" {
588611 try std .testing .expectEqualStrings ("communication" , detectEvidenceType ("message/rfc822" ));
589612 try std .testing .expectEqualStrings ("document" , detectEvidenceType ("" ));
590613 try std .testing .expectEqualStrings ("document" , detectEvidenceType ("application/octet-stream" ));
614+
615+ // New evidence type coverage
616+ try std .testing .expectEqualStrings ("dataset" , detectEvidenceType ("application/json" ));
617+ try std .testing .expectEqualStrings ("dataset" , detectEvidenceType ("application/xml" ));
618+ try std .testing .expectEqualStrings ("dataset" , detectEvidenceType ("text/xml" ));
619+ try std .testing .expectEqualStrings ("news_report" , detectEvidenceType ("text/html" ));
620+ try std .testing .expectEqualStrings ("financial_record" , detectEvidenceType ("application/vnd.ms-excel" ));
591621}
592622
593623test "computePromptScores basic scoring" {
0 commit comments