fix(cog-person-count): emit real signed manifest from CLI (ADR-159 A4)
cmd_manifest emitted a null skeleton (binary_sha256: null) while the real signed manifest existed on disk at cog/artifacts/manifests/<arch>/manifest.json. - New manifest module include_str!-embeds the real signed manifests (x86_64 + arm), selected by build target arch. - cmd_manifest parses-then-emits the embedded signed manifest, mirroring cog-pose-estimation manifest_roundtrips. CLI now reports the real binary_sha256, weights_sha256, Ed25519 signature, and honest build_metadata (training_class1_accuracy = 0.343). Failing-on-old test: manifest::tests::embedded_manifest_has_non_null_binary_sha256 (+ embedded_manifest_is_signed, embedded_manifest_id_matches_cog). Verified end-to-end: cog-person-count manifest -> non-null sha256. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
2400216920
commit
6b5fd3cf25
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
pub mod fusion;
|
||||
pub mod inference;
|
||||
pub mod manifest;
|
||||
pub mod publisher;
|
||||
pub mod runtime;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ use cog_person_count::{
|
|||
publisher, COG_ID, COG_VERSION,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Parser)]
|
||||
|
|
@ -83,19 +82,11 @@ fn cmd_version() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
|
||||
fn cmd_manifest() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"id": COG_ID,
|
||||
"version": COG_VERSION,
|
||||
"binary_url": Value::Null,
|
||||
"binary_bytes": Value::Null,
|
||||
"binary_sha256": Value::Null,
|
||||
"binary_signature": Value::Null,
|
||||
"installed_at": Value::Null,
|
||||
"status": Value::Null,
|
||||
}))?
|
||||
);
|
||||
// Emit the real, signed manifest embedded at compile time (ADR-159 §A4) —
|
||||
// not the old hollow null skeleton. Parse-then-emit so a malformed embedded
|
||||
// artifact fails loudly and the output is canonical JSON.
|
||||
let spec = cog_person_count::manifest::embedded_manifest_value()?;
|
||||
println!("{}", serde_json::to_string_pretty(&spec)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
//! Embedded signed cog manifest (ADR-100 §"manifest.json", ADR-159 §A4).
|
||||
//!
|
||||
//! The `cog-person-count manifest` subcommand emits the **real, signed**
|
||||
//! manifest the release pipeline produced — byte-for-byte the artifact served
|
||||
//! from GCS, with a real `binary_sha256`, `weights_sha256`, Ed25519
|
||||
//! `binary_signature`, and honest `build_metadata` (e.g. `training_class1_accuracy
|
||||
//! = 0.343`, not inflated). The previous implementation printed a hollow
|
||||
//! skeleton with `binary_sha256: null`, which made the CLI look unsigned even
|
||||
//! though the signed manifest existed on disk.
|
||||
//!
|
||||
//! The matching manifest for the build's target arch is selected via `cfg!`.
|
||||
|
||||
/// Real signed manifest for `x86_64-unknown-linux-gnu`.
|
||||
pub const MANIFEST_X86_64: &str =
|
||||
include_str!("../cog/artifacts/manifests/x86_64/manifest.json");
|
||||
|
||||
/// Real signed manifest for `aarch64`/`arm` (the Seed appliance).
|
||||
pub const MANIFEST_ARM: &str = include_str!("../cog/artifacts/manifests/arm/manifest.json");
|
||||
|
||||
/// The embedded signed manifest matching the build's target arch.
|
||||
pub fn embedded_manifest_str() -> &'static str {
|
||||
if cfg!(any(target_arch = "aarch64", target_arch = "arm")) {
|
||||
MANIFEST_ARM
|
||||
} else {
|
||||
MANIFEST_X86_64
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the embedded manifest into canonical JSON. Returns an error if the
|
||||
/// embedded artifact is malformed (so the CLI fails loudly rather than printing
|
||||
/// garbage).
|
||||
pub fn embedded_manifest_value() -> Result<serde_json::Value, serde_json::Error> {
|
||||
serde_json::from_str(embedded_manifest_str())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// ADR-159 §A4 — the embedded manifest the CLI emits must carry a real
|
||||
/// `binary_sha256` (the field the old hollow `cmd_manifest` left null).
|
||||
#[test]
|
||||
fn embedded_manifest_has_non_null_binary_sha256() {
|
||||
let v = embedded_manifest_value().expect("embedded manifest parses");
|
||||
let sha = v.get("binary_sha256").and_then(|s| s.as_str());
|
||||
assert!(
|
||||
sha.is_some(),
|
||||
"embedded manifest must have a non-null binary_sha256 (got {:?})",
|
||||
v.get("binary_sha256")
|
||||
);
|
||||
let sha = sha.unwrap();
|
||||
assert_eq!(sha.len(), 64, "binary_sha256 must be a 32-byte hex digest");
|
||||
assert!(
|
||||
sha.chars().all(|c| c.is_ascii_hexdigit()),
|
||||
"binary_sha256 must be hex"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_manifest_is_signed() {
|
||||
let v = embedded_manifest_value().expect("parse");
|
||||
assert!(
|
||||
v.get("binary_signature").and_then(|s| s.as_str()).is_some(),
|
||||
"embedded manifest must carry an Ed25519 binary_signature"
|
||||
);
|
||||
assert_eq!(
|
||||
v.get("sig_algo").and_then(|s| s.as_str()),
|
||||
Some("Ed25519")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_manifest_id_matches_cog() {
|
||||
let v = embedded_manifest_value().expect("parse");
|
||||
assert_eq!(v.get("id").and_then(|s| s.as_str()), Some(crate::COG_ID));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue