Auditor drill: OpenRouter lane sweep + warren Gitea repoint (post-PR11 polish) #14
@@ -2,9 +2,11 @@
|
|||||||
//!
|
//!
|
||||||
//! Specification: docs/specs/SUBJECT_MANIFESTS_ON_CATALOGD.md §5 Step 8.
|
//! Specification: docs/specs/SUBJECT_MANIFESTS_ON_CATALOGD.md §5 Step 8.
|
||||||
//!
|
//!
|
||||||
//! This binary is consumed by scripts/cutover/parity/subject_audit_parity.sh
|
//! This binary is consumed by the Go-repo's
|
||||||
//! (which lives in /home/profit/golangLAKEHOUSE/scripts/cutover/parity/).
|
//! scripts/cutover/parity/subject_audit_parity.sh.
|
||||||
//! Its Go counterpart is at golangLAKEHOUSE/scripts/cutover/parity/subject_audit_helper/main.go.
|
//! Go counterpart: scripts/cutover/parity/subject_audit_helper/main.go
|
||||||
|
//! (in the Go repo). Both helpers are kept in lockstep by the parity
|
||||||
|
//! script's byte-equality assertions — change one, change both.
|
||||||
//!
|
//!
|
||||||
//! Both helpers MUST produce byte-identical output for the same inputs.
|
//! Both helpers MUST produce byte-identical output for the same inputs.
|
||||||
//! Divergence here is a parity break — a SubjectManifest written by Rust
|
//! Divergence here is a parity break — a SubjectManifest written by Rust
|
||||||
@@ -88,6 +90,15 @@ fn deterministic_key() -> Vec<u8> {
|
|||||||
(0u8..32).collect()
|
(0u8..32).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Print to stderr + exit(2). Never returns. Used in place of `.expect()`
|
||||||
|
/// on argv / file reads so failures produce a clean usage error rather
|
||||||
|
/// than a Rust panic backtrace that the parity script would mistake
|
||||||
|
/// for a parity break.
|
||||||
|
fn die(msg: &str) -> ! {
|
||||||
|
eprintln!("error: {msg}");
|
||||||
|
std::process::exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct KnownAnswerOut {
|
struct KnownAnswerOut {
|
||||||
mode: &'static str,
|
mode: &'static str,
|
||||||
@@ -141,6 +152,10 @@ async fn main() {
|
|||||||
let mut audit_path: Option<PathBuf> = None;
|
let mut audit_path: Option<PathBuf> = None;
|
||||||
let mut key_path: Option<PathBuf> = None;
|
let mut key_path: Option<PathBuf> = None;
|
||||||
|
|
||||||
|
// Argv parsing fails via stderr+exit, never via panic. The parity
|
||||||
|
// script captures stdout for byte-comparison; a Rust panic backtrace
|
||||||
|
// would land in stdout (the script merges 2>&1) and read as a parity
|
||||||
|
// break instead of a usage error. (Caught 2026-05-03 opus scrum WARN.)
|
||||||
let mut i = 1;
|
let mut i = 1;
|
||||||
while i < argv.len() {
|
while i < argv.len() {
|
||||||
match argv[i].as_str() {
|
match argv[i].as_str() {
|
||||||
@@ -149,13 +164,13 @@ async fn main() {
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
"--verify" => {
|
"--verify" => {
|
||||||
audit_path = Some(PathBuf::from(
|
let p = argv.get(i + 1).unwrap_or_else(|| die("--verify needs a path"));
|
||||||
argv.get(i + 1).expect("--verify needs path"),
|
audit_path = Some(PathBuf::from(p));
|
||||||
));
|
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
"--key" => {
|
"--key" => {
|
||||||
key_path = Some(PathBuf::from(argv.get(i + 1).expect("--key needs path")));
|
let p = argv.get(i + 1).unwrap_or_else(|| die("--key needs a path"));
|
||||||
|
key_path = Some(PathBuf::from(p));
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
"-h" | "--help" => {
|
"-h" | "--help" => {
|
||||||
@@ -175,15 +190,15 @@ async fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let audit_path = audit_path.expect("need --known-answer OR --verify ... --key ...");
|
let audit_path = audit_path.unwrap_or_else(|| die("need --known-answer OR --verify <path> --key <path>"));
|
||||||
let key_path = key_path.expect("--verify also needs --key");
|
let key_path = key_path.unwrap_or_else(|| die("--verify also needs --key"));
|
||||||
|
|
||||||
let key = std::fs::read(&key_path).expect("read key file");
|
let key = std::fs::read(&key_path).unwrap_or_else(|e| die(&format!("read key file: {e}")));
|
||||||
let candidate_id = audit_path
|
let candidate_id = audit_path
|
||||||
.file_name()
|
.file_name()
|
||||||
.and_then(|s| s.to_str())
|
.and_then(|s| s.to_str())
|
||||||
.and_then(|s| s.strip_suffix(".audit.jsonl"))
|
.and_then(|s| s.strip_suffix(".audit.jsonl"))
|
||||||
.expect("audit log path must end with <candidate_id>.audit.jsonl")
|
.unwrap_or_else(|| die("audit log path must end with <candidate_id>.audit.jsonl"))
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
// Stand up an in-memory object store, seed it with the audit log
|
// Stand up an in-memory object store, seed it with the audit log
|
||||||
|
|||||||
Reference in New Issue
Block a user