//! A narrated end-to-end walkthrough of jacquard against in-memory adapters.
//!
//! Two organisations, one shared registry, no network, no persistence, no
//! real git. Run it with:
//!
//! ```text
//! cargo run -p jac-demo
//! ```
//!
//! The story: a repo evolves with AI-assisted commits, an agent proposes a
//! design decision, the gate blocks promotion until a human attests, the
//! registry notices another team weaving the same cloth and introduces them,
//! and the whole thing round-trips to plain git without losing provenance.
use anyhow::Result;
use jac_core::{
AgentId, Author, DecisionId, FixedClock, HumanId, HumanIdentity, OrgId, Provenance, RepoPath,
Timestamp,
};
use jac_decision::{Decision, DecisionScope, RationaleFamily, Statement};
use jac_gate::Verdict;
use jac_git::{FakeGit, GitInterop as _};
use jac_object::{MemoryObjectStore, ObjectStore as _, snapshot_id};
use jac_rendezvous::{MemoryRegistry, Publication, PublishedSketch, Registry as _};
use jac_repo::{MemoryRefStore, RefName, Repo};
use jac_sketch::Similarity;
type DemoRepo = Repo<MemoryObjectStore, MemoryRefStore, jac_decision::MemoryLedger, FixedClock>;
/// Everything the scenes share.
#[derive(Debug)]
struct Stage {
ada: HumanIdentity,
loom_bot: AgentId,
meridian: OrgId,
halcyon: OrgId,
registry: MemoryRegistry,
repo: DemoRepo,
other: DemoRepo,
main_ref: RefName,
feature: RefName,
}
fn new_repo(start_ms: i64) -> DemoRepo {
Repo::new(
MemoryObjectStore::new(),
MemoryRefStore::new(),
jac_decision::MemoryLedger::new(),
FixedClock::new(Timestamp::from_millis(start_ms)),
)
}
fn scene(n: usize, title: &str) {
println!("\n── scene {n} ─ {title}");
}
fn say(text: &str) {
println!(" {text}");
}
fn main() -> Result<()> {
println!("jacquard — a narrated walkthrough (in-memory, no network, no git)");
let mut stage = cast()?;
let decision = weave(&mut stage)?;
gate(&mut stage, decision)?;
rendezvous(&mut stage, decision)?;
bridge(&mut stage)?;
epilogue();
println!("\ndone: the books balance.\n");
Ok(())
}
/// Scene 1: the cast.
fn cast() -> Result<Stage> {
scene(1, "the cast");
say("Meridian Systems: Ada (a person) and loom-bot (an agent).");
say("Halcyon Works: an unrelated team, in another repo entirely.");
say("Between them: one rendezvous registry, holding digests and nothing else.");
Ok(Stage {
ada: HumanIdentity {
id: HumanId::new(1)?,
display_name: "Ada".to_owned(),
},
loom_bot: AgentId::new(2)?,
meridian: OrgId::new(10)?,
halcyon: OrgId::new(20)?,
registry: MemoryRegistry::new(),
repo: new_repo(1_000),
other: new_repo(1_000),
main_ref: RefName::parse("main")?,
feature: RefName::parse("feature/backoff")?,
})
}
/// Scenes 2–4: commits with provenance, and a proposed decision.
fn weave(s: &mut Stage) -> Result<DecisionId> {
scene(2, "Ada lays down the auth module");
s.repo.clock_mut().advance(60_000);
let first = s.repo.commit(
&s.main_ref,
&[(
"src/auth/login.rs",
b"pub fn login(user: &str, token: &str) -> Result<Session, AuthError> { /* ... */ }"
.as_slice(),
)],
Author::Human(s.ada.id),
Provenance::Human,
"auth: initial login flow",
)?;
say(&format!("committed {} (provenance: human)", first.short()));
scene(
3,
"loom-bot adds a retry layer — and provenance is identity",
);
s.repo.clock_mut().advance(60_000);
let base = s
.repo
.head(&s.main_ref)
.ok_or_else(|| anyhow::anyhow!("main is bound"))?;
let files: &[(&str, &[u8])] = &[
(
"src/auth/login.rs",
b"pub fn login(user: &str, token: &str) -> Result<Session, AuthError> { /* ... */ }",
),
(
"src/auth/backoff.rs",
b"pub fn retry(op: impl Fn() -> Outcome) -> Outcome { /* exponential backoff; 401/403 are terminal */ }",
),
];
s.repo.branch(&s.feature, base);
let agent_snapshot = s.repo.commit(
&s.feature,
files,
Author::Agent(s.loom_bot),
Provenance::Agent,
"auth: retry with exponential backoff",
)?;
say(&format!(
"committed {} (provenance: agent)",
agent_snapshot.short()
));
// The same tree, relabelled human, is a *different* snapshot:
let stored = s.repo.store().snapshot(agent_snapshot)?.clone();
let mut relabelled = stored.clone();
relabelled.provenance = Provenance::Human;
say("the same tree relabelled `human` would be a different object entirely:");
say(&format!(
" as committed (agent): {}",
snapshot_id(&stored).short()
));
say(&format!(
" relabelled (human): {}",
snapshot_id(&relabelled).short()
));
say("provenance is inside the content address; it cannot be quietly rewritten.");
scene(4, "loom-bot proposes the governing decision");
s.repo.clock_mut().advance(30_000);
let decision_at = s.repo.now();
let decision = s.repo.propose_decision(Decision {
title: "auth retry fails closed on 401/403".to_owned(),
rationale: "On 401 and 403 responses the retry layer fails closed. Exponential \
backoff applies to transient network errors only. Cached credentials \
are never reused for an unauthorized request."
.to_owned(),
families: vec![
RationaleFamily::Constraints,
RationaleFamily::ConfidenceRisk,
],
proposed_by: Author::Agent(s.loom_bot),
scope: DecisionScope {
path_prefixes: vec![RepoPath::parse("src/auth")?],
},
at: decision_at,
});
say(&format!("decision proposed: {}", decision.short()));
say("drafted by the agent from the diff — an interview it would conduct with");
say("the author in the full system. proposed_by says `agent`, honestly.");
say("state: UNSETTLED. no human has put their name to it.");
Ok(decision)
}
/// Scenes 5–7: blocked, attested, admitted.
fn gate(s: &mut Stage, decision: DecisionId) -> Result<()> {
scene(
5,
"promotion is blocked — the work parks, nobody is punished",
);
let verdict = s.repo.promote(&s.feature, &s.main_ref)?;
match &verdict {
Verdict::Blocked { unsettled, .. } => {
say("promote(feature/backoff → main):");
say(&format!(
" BLOCKED — {} unsettled decision(s) govern the blast radius:",
unsettled.len()
));
for id in unsettled {
say(&format!(" {}", id.short()));
}
say("the branch is parked, the decision is surfaced, and a human is routed");
say("to it. attestation is recognised, never policed.");
}
other_verdict => say(&format!("unexpected verdict: {other_verdict:?}")),
}
scene(6, "Ada walks the change and answers in her own words");
s.repo.clock_mut().advance(240_000);
s.repo.attest(
decision,
&s.ada,
Statement::new(
"I traced the 401 path by hand: the retry loop treats it as terminal and \
surfaces the error instead of replaying stale credentials. The backoff \
bound is what I'd have picked. I'd revisit if we ever add token refresh \
inside the retry.",
)?,
)?;
say("Ada's attestation is her verbatim account — a few sentences only a read");
say("can produce. It is a separate object from the agent-drafted rationale;");
say("human-said and machine-synthesized are never conflated.");
say("state: SETTLED. This transition exists in exactly one place in the code —");
say("DecisionRecord::<Unsettled>::attest — and the compiler proves an agent");
say("cannot reach it.");
scene(7, "the same promotion, admitted");
let verdict = s.repo.promote(&s.feature, &s.main_ref)?;
match &verdict {
Verdict::Admitted { decisions_checked } => {
say(&format!(
"promote(feature/backoff → main): ADMITTED — {decisions_checked} settled \
decision(s) checked."
));
say("honest scope: the gate proves a human attested every governing decision.");
say("it does not prove the decision is *good* — that stays a human question.");
}
other_verdict => say(&format!("unexpected verdict: {other_verdict:?}")),
}
Ok(())
}
/// Scenes 8–9: publish sketches; another org's similar work surfaces.
fn rendezvous(s: &mut Stage, decision: DecisionId) -> Result<()> {
scene(8, "Meridian publishes sketches — and only sketches");
let head = s
.repo
.head(&s.main_ref)
.ok_or_else(|| anyhow::anyhow!("main is bound"))?;
let content_sketch = s.repo.sketch_snapshot(head)?;
let decision_sketch = s.repo.sketch_decision(decision)?;
let at = s.repo.now();
s.registry.publish(Publication {
org: s.meridian,
sketch: PublishedSketch::Content(content_sketch),
at,
});
s.registry.publish(Publication {
org: s.meridian,
sketch: PublishedSketch::Decision(decision_sketch),
at,
});
say("what left the org, in its entirety:");
for p in s.registry.publications() {
say(&format!(
" {} sketch from {}: 64 u64 lane minima + a timestamp",
p.sketch.kind(),
p.org
));
}
say("no file names, no source text, no decision prose. the registry cannot");
say("hold content: its crate cannot even name those types, and its API only");
say("accepts DigestSafe values. both facts are checked by the build.");
scene(9, "Halcyon, independently, has the same problem");
s.other.clock_mut().advance(90_000);
let their_at = s.other.now();
let their_decision = s.other.propose_decision(Decision {
title: "retry layer: authentication errors are terminal".to_owned(),
rationale: "The retry layer fails closed on 401 and 403 responses. Exponential \
backoff is for transient network errors only. A request that was \
unauthorized is never replayed with cached credentials."
.to_owned(),
families: vec![RationaleFamily::Constraints],
proposed_by: Author::Agent(AgentId::new(7)?),
scope: DecisionScope {
path_prefixes: vec![RepoPath::parse("lib/net/retry")?],
},
at: their_at,
});
let their_sketch = s.other.sketch_decision(their_decision)?;
s.registry.publish(Publication {
org: s.halcyon,
sketch: PublishedSketch::Decision(their_sketch),
at: their_at,
});
let probe = PublishedSketch::Decision(s.other.sketch_decision(their_decision)?);
let matches = s
.registry
.find_similar(&probe, Similarity::from_permille(150), s.halcyon);
say("Halcyon publishes its own decision sketch and probes the board:");
for m in &matches {
say(&format!(
" match: {} has similar work (decision sketch, similarity {})",
m.org, m.similarity
));
}
let introduction = s.registry.broker(s.halcyon, s.meridian, their_at);
say(&format!(
"introduction brokered: token {} for {} ↔ {}",
introduction.token, introduction.parties.0, introduction.parties.1
));
say("two teams solving the same problem now know about each other — and the");
say("registry never held a line of either team's content. the conversation");
say("happens between the humans, outside the system.");
Ok(())
}
/// Scene 10: the round trip to plain git.
fn bridge(s: &mut Stage) -> Result<()> {
scene(10, "the same history, as plain git");
let head = s
.repo
.head(&s.main_ref)
.ok_or_else(|| anyhow::anyhow!("main is bound"))?;
let mut bridge = FakeGit::new();
let image = bridge.export(head, s.repo.store())?;
say("exported the head snapshot as a git commit image. its trailers:");
for (key, value) in &image.trailers {
say(&format!(" {key}: {value}"));
}
let reimported = bridge.import(&image, s.repo.store_mut())?;
say(&format!(
"import(export(snapshot)) == snapshot: {}",
if reimported == head {
"IDENTICAL"
} else {
"MISMATCH"
}
));
say("provenance rides in ordinary git trailers, so a jacquard repo remains a");
say("clonable git repo — and anything that already crawls the repo (search,");
say("blame tooling, a knowledge platform) indexes decisions for free.");
Ok(())
}
/// Scene 11: the claims table.
fn epilogue() {
scene(11, "what was proven, and by which mechanism");
say("claim mechanism");
say("──────────────────────────────────────── ───────────────────────────────");
say("provenance can't be edited after the fact it is inside the content address");
say("an agent cannot attest no constructor accepts one (compile_fail)");
say("Settled requires an attestation typestate; no other producing path");
say("unproven work does not promote Verdict::default() is Blocked");
say("the registry cannot hold content dep graph + DigestSafe bound");
say("git round-trip keeps provenance trailer test: ids identical");
say("");
say("and what was NOT proven, said plainly:");
say(" - provenance is self-reported at creation (signing is future work)");
say(" - HumanIdentity is not authentication (also future work)");
say(" - the gate binds declared scopes only; ungoverned paths admit freely");
}