Skip to content

Commit 3eec80b

Browse files
committed
feat(federation): establish graph engine foundation
1 parent b89dc2d commit 3eec80b

11 files changed

Lines changed: 5689 additions & 132 deletions

File tree

‎rust/decided/tests/cli.rs‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,46 @@ fn run(args: &[&str]) -> Output {
3535
.expect("run decided")
3636
}
3737

38+
#[test]
39+
fn corpus_digest_version_two_is_explicit_and_keeps_v1_as_the_default() {
40+
let root = empty_scratch_root("digest-v2");
41+
fs::create_dir_all(root.join(".decided")).unwrap();
42+
fs::create_dir_all(root.join("decisions")).unwrap();
43+
fs::write(
44+
root.join(".decided/config.yaml"),
45+
"repository_key: STD\ncorpus:\n source: acme/standards\n",
46+
)
47+
.unwrap();
48+
fs::write(root.join("decisions/policy.md"), "policy\n").unwrap();
49+
let root_text = root.to_string_lossy().into_owned();
50+
51+
let v1 = run(&[
52+
"corpus",
53+
"digest",
54+
"--root",
55+
&root_text,
56+
"--corpus",
57+
"decisions",
58+
]);
59+
assert!(v1.status.success(), "{}", String::from_utf8_lossy(&v1.stderr));
60+
assert!(String::from_utf8_lossy(&v1.stdout).starts_with("sha256:"));
61+
62+
let v2 = run(&[
63+
"corpus",
64+
"digest",
65+
"--version",
66+
"2",
67+
"--root",
68+
&root_text,
69+
"--corpus",
70+
"decisions",
71+
]);
72+
assert!(v2.status.success(), "{}", String::from_utf8_lossy(&v2.stderr));
73+
assert!(String::from_utf8_lossy(&v2.stdout).starts_with("sha256-v2:"));
74+
75+
fs::remove_dir_all(root).unwrap();
76+
}
77+
3878
fn empty_scratch_root(label: &str) -> PathBuf {
3979
let root = std::env::temp_dir().join(format!("asdecided-cli-{label}-{}", scratch_suffix()));
4080
fs::create_dir_all(&root).expect("create empty CLI scratch repository");

‎rust/rac-engine/src/cli.rs‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ fn run_dispatch(args: &[String]) -> u8 {
185185
let order_aware = matches!(
186186
first.as_str(),
187187
"mcp-stats" | "telemetry" | "usage" | "skill" | "hook" | "eval" | "init" | "quickstart"
188-
| "migrate" | "watchkeeper"
188+
| "migrate" | "watchkeeper" | "corpus"
189189
);
190190
if !order_aware {
191191
if rest.iter().any(|a| a.as_str() == "--version") {
@@ -287,6 +287,7 @@ fn run_corpus(rest: &[&String]) -> u8 {
287287
let mut action: Option<String> = None;
288288
let mut root: Option<String> = None;
289289
let mut corpus: Option<String> = None;
290+
let mut version: u32 = 1;
290291
let mut extras: Vec<String> = Vec::new();
291292
let mut positional_only = false;
292293

@@ -324,6 +325,18 @@ fn run_corpus(rest: &[&String]) -> u8 {
324325
Err(code) => return code,
325326
}
326327
}
328+
other if other == "--version" || other.starts_with("--version=") => {
329+
match take_opt_value(prog, "--version", other, rest, &mut i) {
330+
Ok(value) if value == "2" => version = 2,
331+
Ok(value) => {
332+
return argparse_error(
333+
prog,
334+
&format!("argument --version: invalid choice: '{value}' (choose from '2')"),
335+
)
336+
}
337+
Err(code) => return code,
338+
}
339+
}
327340
other => extras.push(other.to_string()),
328341
}
329342
i += 1;
@@ -351,6 +364,7 @@ fn run_corpus(rest: &[&String]) -> u8 {
351364
cmd_corpus_digest(&CorpusDigestArgs {
352365
root: root.expect("checked above"),
353366
corpus: corpus.expect("checked above"),
367+
version,
354368
}) as u8
355369
}
356370

‎rust/rac-engine/src/commands.rs‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,15 +2899,23 @@ pub fn cmd_rename(args: &RenameArgs) -> i32 {
28992899
pub struct CorpusDigestArgs {
29002900
pub root: String,
29012901
pub corpus: String,
2902+
pub version: u32,
29022903
}
29032904

29042905
/// Read-only operator calculation for the canonical parent corpus pin. The
29052906
/// implementation consumes only local bytes below `root` and cannot write,
29062907
/// fetch, refresh, or repin anything.
29072908
pub fn cmd_corpus_digest(args: &CorpusDigestArgs) -> i32 {
2908-
match crate::federation::calculate_parent_digest(&args.root, &args.corpus) {
2909-
Ok(result) => {
2910-
emit(result.digest);
2909+
let result = if args.version == 2 {
2910+
crate::federation::calculate_parent_digest_v2(&args.root, &args.corpus)
2911+
.map(|result| result.digest)
2912+
} else {
2913+
crate::federation::calculate_parent_digest(&args.root, &args.corpus)
2914+
.map(|result| result.digest)
2915+
};
2916+
match result {
2917+
Ok(digest) => {
2918+
emit(digest);
29112919
EXIT_OK
29122920
}
29132921
Err(error) => {

0 commit comments

Comments
 (0)