| Crates.io | logline-core |
| lib.rs | logline-core |
| version | 0.1.1 |
| created_at | 2026-01-08 17:49:20.215368+00 |
| updated_at | 2026-01-09 13:40:28.944967+00 |
| description | The Conceptual Atom of Verifiable Action — LogLine Protocol implementation |
| homepage | https://logline.foundation |
| repository | https://github.com/LogLine-Foundation/logline-core |
| max_upload_size | |
| id | 2030780 |
| size | 73,221 |
The Conceptual Atom of Verifiable Action — Paper I §3 (9-field tuple, lifecycle, invariants, Ghost Records)
logline-core implementa o átomo básico do LogLine Protocol:
who, did, this, when, confirmed_by, if_ok, if_doubt, if_not, status)DRAFT → PENDING → COMMITTED ou GHOSTif_ok, if_doubt, if_notSigner/Signature + bytes determinísticos (placeholder v0.1)--no-default-features (usa apenas alloc)[dependencies]
logline-core = "0.1"
std (default) — ergonomia com stdserde — Serialize/Deserialize para todas as estruturasSem std:
cargo build --no-default-features --features serde
use logline_core::*;
struct NoopSigner;
impl Signer for NoopSigner {
fn sign(&self, msg: &[u8]) -> Result<Signature, SignError> {
Ok(Signature { alg: "none".into(), bytes: msg.to_vec() })
}
}
fn main() {
let signer = NoopSigner;
// Paper I: "nada acontece sem estar assinado" — attempt já nasce assinado
let draft = LogLine::builder()
.who("did:ubl:alice")
.did(Verb::Approve)
.this(Payload::Text("purchase:123".into()))
.when(1_735_671_234) // unix ns (canônico: ISO8601 na serialização JSON✯Atomic)
.if_ok(Outcome { label: "approved".into(), effects: vec!["emit_receipt".into()] })
.if_doubt(Escalation { label: "manual_review".into(), route_to: "auditor".into() })
.if_not(FailureHandling { label: "rejected".into(), action: "notify".into() })
.build_draft().unwrap();
// Paper I: assinar antes de freeze (attempt já nasce assinado)
let signed = draft.sign(&signer).unwrap();
let pending = signed.freeze().unwrap();
// Paper I: commit requer assinatura obrigatória
let committed = pending.commit(&signer).unwrap();
assert!(matches!(committed.status, Status::Committed));
}
| Campo | Tipo | Notas |
|---|---|---|
who |
String |
DID futuro (ex.: did:ubl:...) |
did |
Verb |
Transfer, Deploy, Approve, ou Custom |
this |
Payload |
None | Text | Bytes |
when |
u64 |
Timestamp unix (ns) |
confirmed_by |
Option<String> |
Identidade de confirmação (opcional) |
if_ok |
Outcome |
Consequência positiva (obrigatória) |
if_doubt |
Escalation |
Rota de dúvida (obrigatória) |
if_not |
FailureHandling |
Tratamento de falha (obrigatório) |
status |
Status |
Draft | Pending | Committed | Ghost |
Invariants (checadas em build_draft() e verify_invariants()):
who não vaziowhen > 0if_ok, if_doubt, if_not sempre presentes e não vaziosDRAFT --freeze()--> PENDING --commit()--> COMMITTED
\
\--abandon()------------------> GHOST
Committed → Ghost é proibido.abandon(reason) produz GhostRecord com forense opcional.sign() assina DRAFT/PENDING antes de commitcommit() requer signer obrigatório (não mais opcional)abandon_signed() permite abandon assinado (attempt já nasce assinado)Signer/Signature expostosto_signable_bytes() com ordem fixa (v0.1 placeholder)ed25519-dalek + canonicidade JSON✯Atomicno_stdA crate é no_std-compatible: desative std e ela usa apenas alloc.
examples/simple_commit.rs — create → freeze → commitexamples/ghost_record.rs — draft → abandon → ghostRode:
cargo run --example simple_commit
cargo run --example ghost_record
Criterion (dev-only):
cargo bench
cargo test
cargo test --features serde
Esta implementação está alinhada com Paper I (The LogLine Protocol — The Conceptual Atom of Verifiable Action):
✅ 9-field tuple rígido — especificação completa implementada
✅ Lifecycle determinístico — DRAFT → PENDING → COMMITTED | GHOST com enforcement
✅ Consequence invariants — if_ok, if_doubt, if_not obrigatórios
✅ Ghost Records — trilha forense para intents abandonadas
✅ Assinatura obrigatória — Paper I: "nada acontece sem estar assinado"
✅ VerbRegistry — validação de verbos contra ALLOWED_ACTIONS (Paper I §3.1)
✅ Payload tipado — suporte a Payload::Json com feature serde (Paper I: JSON estrito)
✅ Tempo canônico — when como unix-ns interno; ISO8601 na serialização canônica (Paper I §3.1)
Notas de implementação:
confirmed_by: obrigatório para ações L3+ (regra de runtime/policy)to_signable_bytes(): placeholder v0.1 (ordem fixa); JSON✯Atomic canônico em json-atomic (v0.3.0)Rust stable 1.75+ (alvo). PRs para suportar versões anteriores são bem-vindos.
to_signable_bytes() estável (separadores ASCII, doc do formato); docs.rs melhoradased25519 (opcional) com ed25519-dalek; Signature realjson-atomic (crate irmã) para bytes canônicos JSON✯Atomic + prova de assinaturaPayload::Map (serde) opcionalContribuições são bem-vindas! Veja CONTRIBUTING.md para detalhes.
Relatos de vulnerabilidades devem seguir SECURITY.md.
Criptografia & canônica: json_atomic — o átomo criptográfico (Paper II): canonicalização JSON✯Atomic, BLAKE3 CID e DV25-Seal (Ed25519) para Signed Facts imutáveis.
MIT — veja LICENSE.