sdk(P1.6): client-side head tracking — your SDK is a fork detector
Completes the verification chain (P1.2 -> P1.1 -> P1.3 -> P1.6). The client remembers the last accepted (seq_no, event_hash) per stream and checks every new receipt links forward; if the server rewinds a sequence number or presents a divergent lineage, log_event / log_events raise AttestoForkDetected (Go: *ForkDetectedError) and the stored head is NOT advanced. The customer's own machine becomes the fork detector — no trust in any Attesto-side check. - Python: HeadStore protocol + FileHeadStore (~/.attesto/heads.json, atomic, 0600, default) + MemoryHeadStore; wired into sync and async v2 clients; head_store=None disables. - TypeScript: HeadStore + MemoryHeadStore (default, edge-safe); Node-only FileHeadStore kept in a separate module (@attesto/sdk/heads-file) so the core bundle imports no node:fs; headStore: null disables. - Go: HeadStore interface + MemoryHeadStore (default) + NewFileHeadStore; WithHeadStore option; WithHeadStore(nil) disables. Same forward/rewind/divergence/gap semantics across all three (unit-tested: in-order advance, forged-rewind fork, divergent-next fork, forward-gap accept, file-store restart persistence). Existing v2 client tests pin head_store=None (they replay overlapping seq). READMEs gain a "Your SDK is a witness" section. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
17
README.md
17
README.md
@@ -112,6 +112,23 @@ comp := attesto.VerifyCompleteness(events, 5, 8) // no event
|
||||
numbers must be gap-free and each event's `prev_event_hash` must chain to the
|
||||
previous event's `event_hash`.
|
||||
|
||||
## Your SDK is a witness
|
||||
|
||||
The client remembers the last accepted `(seqNo, eventHash)` per stream and checks
|
||||
every new receipt links forward. If the server ever rewinds a sequence number or
|
||||
presents a divergent lineage, `LogEvent` / `LogEvents` return a
|
||||
`*ForkDetectedError` and the stored head is not advanced. The default store is
|
||||
in-memory; use a file store for fork detection across process invocations, or
|
||||
disable it.
|
||||
|
||||
```go
|
||||
// Persist across CLI invocations (atomic, 0600 at ~/.attesto/heads.json):
|
||||
client, _ := attesto.NewClient(apiKey, attesto.WithHeadStore(attesto.NewFileHeadStore("")))
|
||||
|
||||
// Disable fork detection:
|
||||
client, _ = attesto.NewClient(apiKey, attesto.WithHeadStore(nil))
|
||||
```
|
||||
|
||||
## Operator and Admin Endpoints
|
||||
|
||||
System-key clients are created with `attesto.NewClient`. Tenant/operator
|
||||
|
||||
Reference in New Issue
Block a user