feat(0094b): content-id surface + Tier-1 stability — aura graph introspect --content-id (iter 2)
Completes #158 acceptance (acc 1 + acc 3) on top of iteration 1's reproduction: - acc 1: `aura graph introspect --content-id` reads an op-script and prints the content id of its canonical blueprint — the SHA256 (hex) of the same blueprint_to_json bytes `graph build` emits. Extracted the single `content_id` primitive shared by this surface AND topology_hash, so the two command paths (this surface / hashing a `graph build` output) agree by construction. Verified live: both e2be81b2… for the SMA-cross op-script. Deterministic + distinguishes topologies; a malformed op-list fails cleanly (exit 2, no partial hash). - acc 3: a Tier-1 optional field the blueprint does not use is tolerated by the loader (#156) and absent from the canonical omit-defaults form, so the content id is unchanged (content_id_is_stable_across_a_tolerated_tier1_field); plus content-id stability across the serialize -> reload -> re-serialize store round-trip (#164), the property reproduction rests on. Finding (documented, filed forward): an op-script and the Rust `stage1_signal` builder produce DIFFERENT canonical forms — the composite debug-name ("graph" vs "stage1_signal"), a named vs unnamed Sub, and an unbound vs bound Bias.scale — so they are different topologies by the byte definition and get different content ids. Content-addressing keys on the canonical form, which currently includes the composite debug-name (a non-load-bearing symbol, invariant 11). Whether the content id should exclude the debug-name (a topology-canonical form distinct from the byte-canonical form, which would also change the shipped cycle-0092 topology_hash values) is a forward design question, not this cycle. Verified: full workspace suite green (51 suites); clippy -D warnings clean. refs #158
This commit is contained in:
@@ -208,8 +208,29 @@ pub fn introspect_cmd(rest: &[&str]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
["--content-id"] => {
|
||||
// the content id (#158) of the op-list's canonical blueprint: SHA256 (hex)
|
||||
// of the same `blueprint_to_json` bytes `graph build` emits, via the one
|
||||
// shared `crate::content_id` primitive `topology_hash` also uses — so this
|
||||
// surface and hashing a `graph build` output agree by construction.
|
||||
use std::io::Read;
|
||||
let mut doc = String::new();
|
||||
if let Err(e) = std::io::stdin().read_to_string(&mut doc) {
|
||||
eprintln!("aura: reading stdin: {e}");
|
||||
std::process::exit(2);
|
||||
}
|
||||
match build_from_str(&doc) {
|
||||
Ok(json) => println!("{}", crate::content_id(&json)),
|
||||
Err(m) => {
|
||||
eprintln!("aura: {m}");
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
eprintln!("aura: usage: aura graph introspect --vocabulary | --node <T> | --unwired");
|
||||
eprintln!(
|
||||
"aura: usage: aura graph introspect --vocabulary | --node <T> | --unwired | --content-id"
|
||||
);
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user