Four precision primitives for multi-day, multi-agent runs.
- jouleclaw-contract: ValidationContract / Assertion / Feature /
Evidence / verify() -> ContractVerdict. Authored before code,
lives independently of implementation. Typed coverage matrix
with per-assertion rollup; must-have gaps block ship.
- jouleclaw-graph: RunEvent::HandoffRecorded variant +
WorkerHandoffEvent + HandoffCommand (BLAKE3 over NUL-joined
argv). Forces every agent to write down what happened; hash
chain protects against post-hoc edits.
- jouleclaw-mission: three-role Mission { contract, run,
evidence } with async Worker trait. Orchestrator authors,
Worker does, Validator judges. Serial-by-default dispatch;
validate() is a pure function of (contract, evidence).
- jouleclaw-hydra-client: ValueReport companion to CallReport.
Tracks closure rate (delivered / attempted) per call;
mean_closure_rate aggregates across a run. The activity-vs-
value gap closed at the dispatch layer.
Spec gains normative sections 16 (contract) / 17 (handoff) /
18 (mission) / 19 (value report). Vocab v1.jsonld + v1.ttl +
v1.shapes.ttl extended with the new classes, enumerations,
properties, and SHACL shapes.
Drive-by: jouleclaw-stack had jouleclaw-prov as a dev-dep while
using it in library code; promoted to [dependencies].
Tests: contract 17/17, graph 40/40 (+2 new), mission 6/6,
hydra-client 20/20 (+4 new). Two runnable examples
(missions_pass, three_role_demo).
Co-Authored-By: Claude Opus 4.7 <[email protected]>
75 lines
2.3 KiB
Rust
75 lines
2.3 KiB
Rust
//! End-to-end: build a small contract, run the verifier against
|
||
//! synthetic evidence, print the verdict.
|
||
|
||
use jouleclaw_contract::{
|
||
verify, Acceptance, Assertion, AssertionCheck, Evidence, EvidenceItem, Feature,
|
||
Priority, ValidationContract,
|
||
};
|
||
|
||
fn main() {
|
||
let assertions = vec![
|
||
Assertion {
|
||
id: "A-001".into(),
|
||
title: "All cargo tests pass".into(),
|
||
rationale: "Workspace `cargo test` exits 0".into(),
|
||
priority: Priority::MustHave,
|
||
check: AssertionCheck::Command {
|
||
command_hash: "test".into(),
|
||
expected_exit: 0,
|
||
},
|
||
},
|
||
Assertion {
|
||
id: "A-002".into(),
|
||
title: "Run journal written".into(),
|
||
rationale: "Receipt stream produced".into(),
|
||
priority: Priority::MustHave,
|
||
check: AssertionCheck::Artifact {
|
||
path: "receipts/run.jsonl".into(),
|
||
expected_hash: None,
|
||
},
|
||
},
|
||
];
|
||
let features = vec![
|
||
Feature {
|
||
id: "F-001".into(),
|
||
title: "Cascade dispatch".into(),
|
||
description: String::new(),
|
||
claims: vec!["A-001".into()],
|
||
},
|
||
Feature {
|
||
id: "F-002".into(),
|
||
title: "Receipt stream".into(),
|
||
description: String::new(),
|
||
claims: vec!["A-002".into()],
|
||
},
|
||
];
|
||
|
||
let contract = ValidationContract::seal(
|
||
"Cascade + receipts demo",
|
||
"did:key:zSample",
|
||
assertions,
|
||
features,
|
||
Acceptance::default(),
|
||
)
|
||
.expect("contract seals");
|
||
|
||
let mut evidence = Evidence::new();
|
||
evidence.push(EvidenceItem::CommandRun {
|
||
command_hash: "test".into(),
|
||
exit_code: 0,
|
||
});
|
||
evidence.push(EvidenceItem::ArtifactPresent {
|
||
path: "receipts/run.jsonl".into(),
|
||
hash: "cafebabe".into(),
|
||
});
|
||
|
||
let verdict = verify(&contract, &evidence);
|
||
println!("contract: {}", contract.content_hash_hex());
|
||
println!("verdict: passed={} — {}", verdict.passed, verdict.summary);
|
||
println!(
|
||
"coverage: {} cells across {} assertion(s) × {} feature(s)",
|
||
verdict.coverage.cells.len(),
|
||
verdict.coverage.assertion_ids.len(),
|
||
verdict.coverage.feature_ids.len()
|
||
);
|
||
}
|