[package]
name = "license-registry"
template = "basic"
[settle-graft]
gate-chain = [
"sig-verify-schnorr",
"manifest-verify",
]
[rbac-graft]
admins = ["~0xa2c1..."]
[registry-graft]
[log-graft]
[batch-graft]
:: five grafts. one command composes them.
:: nockup graft inject --apply hoon/app/app.hoon
:: app.hoon — the only Hoon you write.
:: five domain causes, ~5 lines each.
++ issue-license
|= [holder=@ux terms=@t]
^- (list effect)
?> (is-admin src.bowl)
=/ id=@ud (next-id registry)
:: registry-graft remembers; log-graft trails;
:: settle-graft commits the merkle root.
:~ [%registry-put id holder terms]
[%log-append %license-issued id]
[%settle-note id (commit terms)]
==// main.rs — typed Rust at every seam.
// No noun construction. No drift surprises.
use vesl_core::{Mint, build_issue_license_poke, PokeOutcome};
use vesl_test::Harness;
#[tokio::main]
async fn main() -> Result<()> {
let app = vesl_hull::serve("out.jam").await?;
let holder = pubkey_from_hex("0xa2c1...");
let poke = build_issue_license_poke(holder, b"v1: MIT");
match app.poke(SystemWire.to_wire(), poke).await? {
PokeOutcome::Accepted { effects } => print_effects(effects),
PokeOutcome::Rejected { reason } => eprintln!("deny: {reason}"),
PokeOutcome::Crashed { error } => panic!("{error}"),
}
Ok(())
}// GET /status — build provenance at the HTTP layer.
{
"hull_id": "license-registry",
"notes_settled": 1247,
"settlement_mode": "merkle-schnorr",
"gate": "sig-verify-schnorr ∘ manifest-verify",
"grafts": ["settle", "rbac", "registry", "log", "batch"],
"manifest_shas": {
"settle": "sha256:7f3a...e1b2",
"rbac": "sha256:c801...44ab",
"registry": "sha256:9d2c...77f4",
"log": "sha256:1e6f...3d09",
"batch": "sha256:b4a1...5c20"
}
}
// grep manifest_shas against `nockup graft inject` output.
// what you composed is what you're running.