Documentation
¶
Overview ¶
package: ranke / archive type: logic job: an immutable Ranke-Archive snapshot RA_k = (𝒰, k); reads claims and branches through the head claim, delegating closure ops to the Universe limits: advances nothing — writes go through the Sequencer (-> sequencer); closure traversal belongs to the Universe (-> universe)
package: ranke / claim type: logic job: the Claim type and the concrete claim with its methods limits: the Contributor extension lives in claim_type_contributor.go; construction/signing in claim_builder.go; helpers in claim_helpers.go; codec in codec.go
package: ranke / claim type: logic job: AssembleClaim — rebuild a Claim from its parsed components + id, without CBOR and without signing (the field-oriented sibling of DecodeClaim, for non-CBOR cache backends) limits: reconstructs a cache view, not a self-verifiable claim — it has no canonical bytes, so it cannot be structurally verified; a cache is checked by comparison to the authoritative layer (-> verify.go)
package: ranke / claim type: logic job: ClaimBuilder — assembles, validates, attributes, and signs a claim into an immutable Claim limits: pure construction helpers live in claim_helpers.go; signing primitives in sign.go
package: ranke / claim type: logic job: pure helpers for claim construction — type parsing, pubkey resolution, edge checks limits: no I/O or signing; the builder that calls them is in claim_builder.go
package: ranke / claim_type_branch type: logic job: the Branch view over a contribution/branch edge — a named pointer into an archive's branch table limits: the branch-table logic (materialising the diff chain) lives in the Archive (-> archive); a Branch only navigates the subgraph its edge references
package: ranke / claim_type_contributor type: logic job: the Contributor extension of Claim — a contribution/contributor claim, plus a session-scoped signing key limits: the base Claim + concrete claim live in claim.go; construction/signing in claim_builder.go
package: ranke / codec type: io job: canonical CBOR (de)serialization of the claim record — S(v) with its edges inlined, which is what an envelope carries as payload, and what DecodeClaim reads back out of one limits: persists nothing (-> universe, adapter); the envelope around the record, and the signature over it, are codec_envelope.go's; content integrity lives in content.go
package: ranke / codec_envelope type: crypto job: the claim envelope (`V-ENV`) — a COSE_Sign1 over S(v), which the Universe stores under id(v) = H(S(env(v))) limits: the record it wraps is codec.go's, and this says nothing about its shape; resolves no contributor key (-> verify)
package: ranke / codec_wire type: io job: the contribution codec — a CBOR sequence (RFC 8742) opening with the branches it touches, then claims under their id and externalized content under its hash limits: the record level only; the claim and node records it carries are codec.go's, and admitting them into an archive is the Sequencer's (-> sequencer, contribution)
package: ranke / contribution type: logic job: the contribution contract — the staged → verified → mergable advance of a Ranke-Archive (RA_k → RA_k') limits: the contract plus the shared wire drain; opening, verifying and merging a contribution are a Sequencer's (-> adapter/sequencer/dev, adapter/sequencer/concurrent)
package: ranke / deletion type: logic job: the planned-deletion sweep — remove the bytes of every claim whose delete_by has fallen due, leaving the gap the citing edges already explain (`R-DPLANNED`) limits: the planned form only; a requested deletion is the Sequencer's to carry out (`R-DREQUEST`). Removes bytes through the Universe port and rewrites no id
package: ranke / edge type: data job: the Edge directed-reference type, its filters, and the closed edge type vocabulary limits: does not build claims (-> claim) or serialize edges (-> codec)
package: ranke / taxonomy type: logic job: the edge-type vocabulary (§4.8) — the closed class set, the subtypes the ADT defines, and their compact aliases — with enumeration/validation helpers limits: vocabulary only; edge construction and matching live elsewhere (-> edge, filter)
package: ranke / taxonomy type: logic job: EDTF Level 1 parsing for `dated` (`V-DATED`), including its own date-and-time form, and the millisecond span/midpoint `R-QTEMPORAL`'s `compare: temporal` reads off it — an instant shares the same axis as a zero-width span limits: Level 1 only: no sets, no individual-component qualification, no exponential years
package: ranke / taxonomy type: logic job: the encoding (MIME media-type) vocabulary — the closed top-level class set with compact aliases, well-known subtype aliases with two-way resolution, the class constructors, and named constants for the popular media types limits: vocabulary + alias resolution only; the codec applies the aliases into the canonical bytes and the node holds the value (-> codec, node)
package: ranke / errors type: data job: centralized package error sentinels — one static error per fixed condition limits: no fmt.Errorf anywhere in the package — dynamic errors compose via wrap/withDetail/wrapDetail over these sentinels
package: ranke / taxonomy type: logic job: field-name/value size caps and the well-known field-name constants, enforced at claim/edge construction limits: reference-impl caps (the paper leaves them open); the codec/verifier never reject an already-stored record (-> claim_builder)
package: ranke / filter type: logic job: the Filter contract and the built-in edge filters (by field value, by type) that Claim.Edges applies, AND-combined limits: selection only; edge and claim construction live elsewhere (-> edge, claim)
package: ranke / graph type: logic job: a Ranke-Graph handle RG ⊆ 𝒰 — stages claims into a Universe under the atomic-creation rule, tracks open heads, consolidates limits: claims live in the Universe (-> universe); does not bind graphs to branches (-> archive); verification lives in verify.go
package: ranke / history type: logic job: the History contract — persists the archive head-id timeline k₀…kₙ (append + read-back) — plus SpliceHistory, the graft a tagging pass uses to update it limits: interface only; concrete timeline stores live in adapters (-> adapter/history)
package: ranke / history type: logic job: HistoryItem — one immutable entry in the head-id timeline (head id, height, append time) plus its constructor and getters limits: a value type; the timeline it belongs to is History (-> history)
package: ranke / id type: crypto job: the content-addressed Id type — a multihash with parsing and equality limits: does not sign or verify ids (-> sign); does not verify content bytes (-> content)
package: ranke / node type: data job: the Node structural component of a claim, plus the closed node/encoding type vocabularies limits: does not build nodes (-> claim) or serialize them (-> serialize)
package: ranke / taxonomy type: logic job: the node-type vocabulary (§4.8) — the closed class set, the subtypes the ADT defines, and their compact aliases — with enumeration/validation helpers limits: vocabulary only; node construction and content live elsewhere (-> node)
package: ranke / query type: data job: the declarative read AST (RQL — the paper's §Filtered Reads) and its result/stream shapes limits: types only; the reference executor is DefaultQuery (-> query_default.go)
package: ranke / query_codec type: io job: the RQL wire codec — a Query to and from the canonical JSON that ranke-graph's rql.schema.json fixes, plus the shape checks a query must pass before an engine sees it limits: shape only; which claims a read returns is the executor's (-> query_default)
package: ranke / query type: logic job: `R-QCONTENT` — how many bytes of inline content an encoded claim carries, read off Output.Content and spent by the codec across the claim's content sequence limits: inline content only, per §Content the bytes a record holds; external content stays in the Universe, which is what lets content in full be S(v) (`R-QCANON`)
package: ranke / query type: logic job: DefaultQuery — the reference RQL executor a byte-store Universe delegates to: a forward-closure walk (reverse via closure inversion) with filter/order/limit/shape limits: performance-ignorant; a graph-native backend overrides with a native lowering (-> adapter/storage/neo4j)
package: ranke / query type: logic job: fill QueryResult's Encoded fields per Output.Detail and Encoding — the serialized claim as CBOR or JSON, or the stored envelope copied out under its own tag limits: serialisation only; which claims a read returns is the executor's (-> query_default, adapter/storage/neo4j)
package: ranke / query_report type: logic job: the RQL execution report — a structured event log a query collects across the call chain when Execution.Report is set limits: a passive collector carried in ctx; a nil collector (report off) makes every log a no-op
package: ranke / query walk type: logic job: the reference RQL traversal — walk a Select's Path from its root (forward, and reverse via a built closure-inversion index), returning the reached set and each claim's canonical route limits: reachability only; filter/order/limit/shape live in query_default.go. Route ties break on the (created_at, id) total order so a path shape is byte-identical to a Cypher lowering
package: ranke / sequencer type: logic job: the Sequencer contract — the sole writer of a Ranke-Archive: hands out read snapshots and advances the head by merging contributions limits: interfaces only; the naive concrete implementation is a write-path mechanism (-> adapter/sequencer_mechanism)
package: ranke / sign type: crypto job: multikey pubkey framing (`V-SIGN`) plus Ed25519 key encoding and PEM loading limits: signs and verifies nothing — a claim's signature lives in its envelope (-> envelope); supports only Ed25519 today
package: ranke / taxonomy type: logic job: `V-TIME` for the optional timestamp fields — delete_by, pubkey_valid_from, pubkey_expires_after — refused wherever a claim arrives, by decode and by assemble; created_at is a record slot decodeNode already parses limits: no verifyRules entry, since the closure verifier decodes every claim it walks and would reach a rule that can never fire; an ABSENT field is no violation, only a present unparsable one
package: ranke / universe type: io job: the 𝒰 interface — a content-addressed bag of claims and content with bulk get/put/has, copy, and single-item wrappers limits: defines the contract only; concrete backends live under adapter/; does no validation (-> graph, content)
package: ranke / universe_default type: logic job: the reference Default* implementations a Universe delegates to — diff materialisation, closure membership/lookup, and copy walkers — all in terms of the public Universe API limits: called by Universe implementations (byte-store adapters delegate here; a graph-native backend may override with native queries); does no storage of its own
package: ranke / tagger type: logic job: TagArchive — descend an archive's branch-table spine and stamp every branch's closure with each member claim's .node.Height() limits: optional (gated by Capabilities.Tags); tags are read off the claims (GetClaims injects them) and written through the Universe's bulk SetClaimsTags — this file holds no backend I/O of its own
package: ranke / universe_memory type: io job: NewMemoryUniverse — a naive in-process Universe storing canonical CBOR in maps, decoded on read: the Graph's nil-Universe fallback and the reference Universe for tests limits: ephemeral; correctness over speed (decodes per read, no caching); closure/copy via the Default* helpers; persistent/graph-native backends live under adapter/
package: ranke / taxonomy type: logic job: list of field names and special values (taxonomy) in context of Universe (storage layer) limits: names only; the tagger logic lives in universe_default_tagger.go,
package: ranke / verify type: logic job: the configurable closure verifier — §5.10 per-claim integrity + authenticity over a graph, archive, or branch closure, as a live progress run limits: does not fetch content bytes unless asked (WithExternalContent); does not persist or advance anything (-> universe, sequencer)
package: ranke / content type: crypto job: storage-agnostic content integrity (§5.10) — verify bytes against a hash+size, whole or streamed limits: does not store or fetch content (-> universe); does not hash claim records (-> hash)
package: ranke / verify type: logic job: `R-DEXPIRY`'s second sentence — the contribution/expiry edge that moves the end of a contributor's key window, resolved once per contributor per run limits: finds the edge, never applies the window (-> verify for the comparison)
package: ranke / verify type: logic job: the per-claim rules re-derived from a claim's direct references — `V-HEIGHT` height and `V-MONO` created_at, which the closure walk makes transitive limits: judges one claim against its references only (-> verify for the walk and the registry)
package: ranke / verify type: logic job: the live handle on a verification — a Failure list and a progress count safe to read while the closure walk runs, plus the Wait that blocks until it is done limits: holds no rules and walks nothing; the walk and the rule registry are verify.go's
package: ranke / verify type: logic job: the per-claim rules read off a claim's own shape — `V-TYPE` type classes, `V-REL` relation_direction, `V-EORDER` the inlined edge order, `R-DREQUEST` a delete mark's target limits: needs no Universe read and no reference resolution, so it judges a record that arrived as bytes or through AssembleClaim as readily as one this library built
Index ¶
- Constants
- Variables
- func AdmitCreatedAt(c Claim, base time.Time) error
- func BranchTagKey(branch string) string
- func CheckDeletable(class NodeClass, sub string, fields map[string]string) error
- func DecodePublicKey(b []byte) (multicodec.Code, crypto.PublicKey, error)
- func DefaultClaimsInBranches(ctx context.Context, u Universe, branches map[string]Id, ids []Id) ([]bool, error)
- func DefaultCopyClaims(ctx context.Context, dst, src Universe, ids []Id, opts ...CopyOption) error
- func DefaultCopyContents(ctx context.Context, dst, src Universe, refs []ContentRef, opts ...CopyOption) error
- func DefaultGetClaimHeights(ctx context.Context, u Universe, ids []Id) ([]uint64, error)
- func DefaultSync(ctx context.Context, dst, src Universe, id Id) <-chan SyncResult
- func DefaultTag(ctx context.Context, u Universe, head Id) error
- func DrainWire(ctx context.Context, c Contribution, u Universe, wr *WireReader) error
- func EncodePublicKey(pub crypto.PublicKey) ([]byte, error)
- func EncodeQuery(q Query) ([]byte, error)
- func EncodeResults(results []QueryResult, out Output) error
- func EncodingApplication(sub string) string
- func EncodingAudio(sub string) string
- func EncodingExample(sub string) string
- func EncodingFont(sub string) string
- func EncodingImage(sub string) string
- func EncodingMessage(sub string) string
- func EncodingModel(sub string) string
- func EncodingMultipart(sub string) string
- func EncodingText(sub string) string
- func EncodingVideo(sub string) string
- func GetClaimHeight(ctx context.Context, u Universe, id Id) (uint64, error)
- func GetTag(ctx context.Context, u Universe, id Id, tag string) (found bool, value string, err error)
- func HasClaim(ctx context.Context, u Universe, id Id) (bool, error)
- func HasContent(ctx context.Context, u Universe, id Id) (bool, error)
- func HeightOf(refs ...Claim) uint64
- func Hops(n int) *int
- func InClosure(ctx context.Context, u Universe, branch string, heads []Id, id Id) (bool, error)
- func IsTextEncoding(encoding string) bool
- func LoadEd25519PrivateKeyPEM(path string) (ed25519.PrivateKey, error)
- func LoadEd25519PublicKeyPEM(path string) (ed25519.PublicKey, error)
- func MarshalCBOR(v any) ([]byte, error)
- func NewVerifyingReader(src io.ReadCloser, hash Id, size uint64) (io.ReadCloser, error)
- func PutClaim(ctx context.Context, u Universe, c Claim) error
- func PutContent(ctx context.Context, u Universe, id Id, content []byte) error
- func ReportEnabled(ctx context.Context, level ReportLevel) bool
- func ReportEvent(ctx context.Context, engine, op string, level ReportLevel, detail string, ...)
- func SyncedNow(id Id) <-chan SyncResult
- func TemporalMidpointMs(s string) (int64, bool)
- func TypeDerivation(sub string) string
- func TypeEntity(sub string) string
- func TypeRelation(sub string) string
- func TypeSource(sub string) string
- func ValidateQuery(q Query) error
- func VerifyContent(hash Id, size uint64, data []byte) error
- func WantsDelta(opts ...GetOption) bool
- func WithDetail(sentinel error, detail string) error
- func WithReport(ctx context.Context, level ReportLevel) (context.Context, func() []QueryEvent)
- func Wrap(sentinel, cause error) error
- func WrapDetail(sentinel error, detail string, cause error) error
- type Archive
- type Branch
- type Capabilities
- type Claim
- func AssembleClaim(parts ClaimParts) (Claim, error)
- func DecodeClaim(id Id, b []byte) (Claim, error)
- func DefaultMaterialize(ctx context.Context, u Universe, claims []Claim, opts ...GetOption) ([]Claim, error)
- func GetClaim(ctx context.Context, u Universe, id Id, opts ...GetOption) (Claim, error)
- func GetFromClosure(ctx context.Context, u Universe, branch string, heads []Id, id Id) (Claim, error)
- type ClaimBuilder
- func (b ClaimBuilder) AllowInvalid() ClaimBuilder
- func (b ClaimBuilder) Sign(signingKey ...crypto.Signer) (Claim, error)
- func (b ClaimBuilder) WithAutoHeight(ctx context.Context, u Universe) ClaimBuilder
- func (b ClaimBuilder) WithContributor(c Contributor) ClaimBuilder
- func (b ClaimBuilder) WithCreatedAt(t time.Time) ClaimBuilder
- func (b ClaimBuilder) WithDated(t time.Time) ClaimBuilder
- func (b ClaimBuilder) WithDatedEDTF(d string) ClaimBuilder
- func (b ClaimBuilder) WithDiff(id Id) ClaimBuilder
- func (b ClaimBuilder) WithEdges(edges ...Edge) ClaimBuilder
- func (b ClaimBuilder) WithEncoding(e string) ClaimBuilder
- func (b ClaimBuilder) WithExternalContent(hash Id, size uint64) ClaimBuilder
- func (b ClaimBuilder) WithField(key, value string) ClaimBuilder
- func (b ClaimBuilder) WithHeight(h uint64) ClaimBuilder
- func (b ClaimBuilder) WithInlineContent(c []byte) ClaimBuilder
- func (b ClaimBuilder) WithSigningKey(k crypto.Signer) ClaimBuilder
- func (b ClaimBuilder) WithType(t string) ClaimBuilder
- type ClaimParts
- type Collation
- type Comparison
- type Constraints
- type ContentBlob
- type ContentKind
- type ContentRef
- type Contribution
- type ContributionOption
- type Contributor
- type CopyConfig
- type CopyOption
- type CopyProgress
- type Detail
- type Direction
- type Edge
- type EdgeClass
- type EdgeConfig
- type EdgeFilterFieldValue
- type EdgeFilterType
- type EdgeFilterTypes
- type EdgeParts
- type EdgeSubtype
- type EncodingClass
- type EncodingSubtype
- type Execution
- type Failure
- type Field
- type Filter
- type Form
- type GetOption
- type Graph
- type HeightCache
- type History
- type HistoryItem
- type Id
- type Keypair
- type Limit
- type MergableContribution
- type Node
- type NodeClass
- type NodeSubtype
- type OrderKey
- type Output
- type OutputContent
- type Overflow
- type PathStep
- type Query
- type QueryEvent
- type QueryReport
- type QueryResult
- type Receipt
- type RelationDirection
- type ReportLevel
- type ResultEncoding
- type ResultKind
- type ResultStream
- type Scope
- type Select
- type Sequencer
- type Shape
- type SortDir
- type StorageTier
- type SweepResult
- type SyncResult
- type TagArchiveOptions
- type Universe
- type VerificationRun
- type VerifiedContribution
- type VerifyOption
- func WithCreatedAfter(t time.Time) VerifyOption
- func WithExternalContent() VerifyOption
- func WithMaxClaims(n int) VerifyOption
- func WithMaxDepth(n int) VerifyOption
- func WithOnError(fn func(Failure)) VerifyOption
- func WithSkipRules(names ...string) VerifyOption
- func WithStopAfter(n int) VerifyOption
- func WithTrusted(fn func(Id) bool) VerifyOption
- type VerifyRule
- type Where
- type WireConstraints
- type WireKind
- type WireReader
- type WireRecord
- type WireWriter
Constants ¶
const ( EdgeTypeContributor = string(EdgeClassContribution) + "/" + string(EdgeSubtypeContributor) EdgeTypeHead = string(EdgeClassContribution) + "/" + string(EdgeSubtypeHead) EdgeTypeBranches = string(EdgeClassContribution) + "/" + string(EdgeSubtypeBranches) EdgeTypeBranch = string(EdgeClassContribution) + "/" + string(EdgeSubtypeBranch) EdgeTypePrune = string(EdgeClassContribution) + "/" + string(EdgeSubtypePrune) EdgeTypeDiff = string(EdgeClassContribution) + "/" + string(EdgeSubtypeDiff) EdgeTypeDelete = string(EdgeClassContribution) + "/" + string(EdgeSubtypeDelete) EdgeTypeExpiry = string(EdgeClassContribution) + "/" + string(EdgeSubtypeExpiry) )
Closed contribution/* edge type strings, for EdgeConfig.Type — each combined from its class and subtype constants. Branch and Prune are edge-only — no claim counterpart.
const ( EncodingJSON = "application/json" EncodingJSONLD = "application/ld+json" EncodingXML = "application/xml" EncodingXHTML = "application/xhtml+xml" EncodingPDF = "application/pdf" EncodingOctetStream = "application/octet-stream" EncodingWebManifest = "application/manifest+json" EncodingRTF = "application/rtf" // Archives / compression. EncodingZIP = "application/zip" EncodingGZIP = "application/gzip" EncodingTAR = "application/x-tar" EncodingBzip2 = "application/x-bzip2" Encoding7Z = "application/x-7z-compressed" EncodingRAR = "application/vnd.rar" EncodingJAR = "application/java-archive" EncodingEPUB = "application/epub+zip" // Office / OpenDocument. EncodingMSWord = "application/msword" EncodingMSExcel = "application/vnd.ms-excel" EncodingMSPowerPoint = "application/vnd.ms-powerpoint" EncodingDOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" EncodingXLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" EncodingPPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation" EncodingODT = "application/vnd.oasis.opendocument.text" EncodingODS = "application/vnd.oasis.opendocument.spreadsheet" EncodingODP = "application/vnd.oasis.opendocument.presentation" )
Application media types (application/*): structured data, documents, archives.
const ( EncodingPlain = "text/plain" EncodingHTML = "text/html" EncodingCSS = "text/css" EncodingJavaScript = "text/javascript" EncodingCSV = "text/csv" EncodingMarkdown = "text/markdown" EncodingCalendar = "text/calendar" )
Text media types (text/*).
const ( EncodingPNG = "image/png" EncodingAPNG = "image/apng" EncodingJPEG = "image/jpeg" EncodingGIF = "image/gif" EncodingWebP = "image/webp" EncodingAVIF = "image/avif" EncodingSVG = "image/svg+xml" EncodingBMP = "image/bmp" EncodingTIFF = "image/tiff" EncodingICO = "image/vnd.microsoft.icon" )
Image media types (image/*).
const ( EncodingMP3 = "audio/mpeg" EncodingAAC = "audio/aac" EncodingWAV = "audio/wav" EncodingOggAudio = "audio/ogg" EncodingWebmAudio = "audio/webm" EncodingMIDI = "audio/midi" )
Audio media types (audio/*).
const ( EncodingMP4 = "video/mp4" EncodingMPEG = "video/mpeg" EncodingWebmVideo = "video/webm" EncodingOggVideo = "video/ogg" EncodingAVI = "video/x-msvideo" EncodingMP2T = "video/mp2t" Encoding3GP = "video/3gpp" )
Video media types (video/*).
const ( EncodingWOFF = "font/woff" EncodingWOFF2 = "font/woff2" EncodingTTF = "font/ttf" EncodingOTF = "font/otf" )
Font media types (font/*).
const ( FieldName = "name" FieldNameAlias = "n" FieldEdges = "edges" FieldEdgesAlias = "e" FieldContent = "content" FieldContentAlias = "c" FieldContentSize = "content_size" FieldContentSizeAlias = "s" FieldContentHash = "content_hash" FieldContentHashAlias = "h" FieldHeight = "height" FieldHeightAlias = "H" // FieldEdgesDiffOmit lists, on a diff claim, names of inherited edges to drop when // materialising, one per line — only named edges inherit. Overwrite/add is // re-stating the edge. FieldEdgesDiffOmit = "edges_diff_omit" FieldEdgesDiffOmitAlias = "E" // FieldFieldsDiffOmit is the node-field analogue: newline-separated names. FieldFieldsDiffOmit = "fields_diff_omit" FieldFieldsDiffOmitAlias = "F" // FieldPubkeyValidFrom and FieldPubkeyExpiresAfter bound a contributor key's // validity (RFC 3339, paper 2 §Contributor Keys): a claim it signed is dated // within the closed window they describe. Either may stand alone. FieldPubkeyValidFrom = "pubkey_valid_from" FieldPubkeyValidFromAlias = "v" FieldPubkeyExpiresAfter = "pubkey_expires_after" FieldPubkeyExpiresAfterAlias = "x" // FieldDeleteBy schedules a claim's bytes for removal (RFC 3339, paper 2 // §Deletion). Every edge referencing such a claim carries the date too, so the // schedule travels with the reference and explains the gap the deletion leaves. FieldDeleteBy = "delete_by" FieldDeleteByAlias = "d" )
Aliases are bare; the codec adds the reserved "." prefix on the wire.
const ( NodeContributor = string(NodeClassContribution) + "/contributor" NodeHead = string(NodeClassContribution) + "/head" NodeBranches = string(NodeClassContribution) + "/branches" // NodeDelete and NodeExpiry are limiting claims: each names a target claim it // restricts (paper 2 §Deletion, §Key rotation). NodeDelete = string(NodeClassContribution) + "/delete" NodeExpiry = string(NodeClassContribution) + "/expiry" )
Closed contribution/* node type strings, for ClaimBuilder.Type.
const ( NodeTypeContributor = string(NodeClassContribution) + "/" + string(NodeSubtypeContributor) NodeTypeHead = string(NodeClassContribution) + "/" + string(NodeSubtypeHead) NodeTypBranches = string(NodeClassContribution) + "/" + string(NodeSubtypeBranches) )
Closed contribution/* node type strings, for ClaimBuilder.Type.
const ( // BranchUniverse is unconfined, privileged access rooted at Select.Claim, // which it therefore requires. BranchUniverse = "$universe" // BranchArchive confines to the whole Ranke-Archive: the closure of the // branch-table header. Select.Claim defaults to the current archive head. BranchArchive = "$archive" // TargetBranches names the branch table itself (§Access), the surface a grant over // branch creation is held against. It scopes no read, so Select.Branch rejects it. TargetBranches = "$branches" )
Reserved virtual branch scopes for Select.Branch (the $-target family, spec §Access); a real branch name confines to that branch's closure.
const ( // SpineRevKey records the spine revision a branch-table claim sits at — the // commit marker written last per revision. SpineRevKey = "_br" // ArchiveTagKey marks a claim as a member of the archive's closure, which covers // the branches and the spine — where the operator signing the tables sits. ArchiveTagKey = "_ba" )
const ReservedPrefix = "_"
ReservedPrefix marks the library-owned property namespace: any node/edge property key beginning with "_" is reserved (a tag or a codec flag), never a user field. A backend that surfaces properties (e.g. neo4j) uses it to separate reserved keys from claim fields.
const WireMediaType = "application/cbor-seq"
WireMediaType is the Content-Type a contribution stream is served under: a CBOR sequence is self-framing, so records concatenate with no envelope.
Variables ¶
var ( // --- Universe / storage (exported API) --- ErrNotFound = errors.New("ranke: not found") ErrIntegrity = errors.New("ranke: integrity check failed") ErrClosed = errors.New("ranke: closed") // ErrUnsupported: the backend does not support this operation (e.g. an // opaque byte store asked to tag). Callers gate on the relevant Capability. ErrUnsupported = errors.New("ranke: operation not supported by this backend") // ErrContentCapped: a layer holds a claim/reference but its stored content // is shorter than the expected content_size — capped or truncated (e.g. a // cache filled under a smaller cap in a previous run). A stack treats it // like a miss and descends to a layer that holds the full bytes. ErrContentCapped = errors.New("ranke: content capped (stored shorter than content_size)") // ErrBranchNotFound: the archive holds no branch of that name. Also matches // ErrNotFound, so a caller may read it either way. ErrBranchNotFound = errors.New("ranke.Archive.GetBranch: branch not found") ErrQueryNoHead = errors.New("ranke.Query: Select.Head is required under $universe (it has no natural head to scope by)") ErrQueryNoScope = errors.New("ranke.Query: Select.Branch is required (scope is mandatory — use BranchUniverse for an unconfined read)") ErrQueryScanShape = errors.New("ranke.Query: a scan (no Select.Path) reaches claims by no stated route, so Output.Shape must be single") ErrQueryEncoding = errors.New("ranke.Query: unknown Output.Encoding (native | json | cbor)") ErrQueryWhereForm = errors.New("ranke.Query: a where node is exactly one of and | or | not | {field, test}") ErrQueryComparisonForm = errors.New("ranke.Query: a comparison applies exactly one operator (eq | ne | lt | le | gt | ge | in | glob)") ErrQueryHops = errors.New("ranke.Query: a PathStep's hop bounds admit no count") ErrQueryEnum = errors.New("ranke.Query: value outside the set the schema fixes for its field") ErrQueryBounds = errors.New("ranke.Query: value below the minimum the schema fixes for its field") ErrQueryEnvelopeAxis = errors.New("ranke.Query: detail envelope returns the stored bytes, which this axis would have to change (`R-QDETAIL`)") ErrQueryOrderField = errors.New("ranke.Query: a sort key names the field it orders on") ErrQueryLayerName = errors.New("ranke.Query: execution.layer names a layer, so a stated one may not be empty") ErrReservedType = errors.New("ranke.Contribution: node type is the Sequencer's alone (lift it to add one)") ErrFutureDated = errors.New("ranke.Contribution: claim is dated after the base the contribution opened against") ErrBranchNotCreatable = errors.New("ranke.Contribution: branch is absent from the base, and creating one is a right of its own") ErrUnreadableReference = errors.New("ranke.Contribution: reference reaches a claim outside the branches this contribution may read") ErrWire = errors.New("ranke.Wire") ErrWireKind = errors.New("ranke.Wire: unknown record kind (0 claim | 1 content | 2 branches | 3 referencable | 4 lifted)") ErrWireNoBranch = errors.New("ranke.Wire: a claim record must name the branch it joins") ErrWireNoHeader = errors.New("ranke.Wire: a stream opens with the branches it writes to and the branches it may reference from") ErrWireLateConstraint = errors.New("ranke.Wire: every constraint record precedes the payload") ErrWireUndeclared = errors.New("ranke.Wire: claim names a branch the header does not declare") ErrKeyNotYetValid = errors.New("ranke.verify: claim is dated before its contributor key's pubkey_valid_from") ErrKeyExpired = errors.New("ranke.verify: claim is dated after its contributor key's pubkey_expires_after") ErrDeleteByNotCopied = errors.New("ranke.verify: an edge must carry exactly the delete_by its referenced claim declares") ErrStructureNotDeletable = errors.New("ranke: a contribution/* claim carries the graph's structure and its own identity, so it takes no delete_by") ErrCreatedAtNotMonotone = errors.New("ranke.verify: claim is dated before a claim it references") // --- ADT shape, checked wherever a claim arrives rather than at the builder // alone: a record decoded or assembled meets these too. ErrContentBothSlots = errors.New("ranke: a record carries both content and content_hash, which are mutually exclusive") ErrIDMismatch = errors.New("ranke.verify: the claim's id is not the hash of the envelope it is stored as") ErrEnvelopeHeaders = errors.New("ranke: an envelope carries the alg parameter alone, protected, and an empty unprotected header (`V-ENV`)") ErrEdgeOrder = errors.New("ranke.verify: a claim's edges are inlined ascending by id(e) (`V-EORDER`)") ErrUnknownTypeClass = errors.New("ranke.verify: type class is not one of the fixed set") ErrRelationDirection = errors.New("ranke.verify: a relation/* edge carries relation_direction 1 or -1, an edge of any other class 0") // ErrDeleteMarkNoTarget: a mark that names nothing explains no gap (`R-DGAP`). ErrDeleteMarkNoTarget = errors.New("ranke.verify: a contribution/delete claim must carry a contribution/delete edge naming its target") ErrTimestampForm = errors.New("ranke: a timestamp must be RFC 3339, UTC, at nanosecond precision (2026-01-05T12:00:00.000000000Z)") ErrDatedForm = errors.New("ranke: dated must be an RFC 3339 timestamp or a valid EDTF Level 1 value (`V-DATED`)") )
var EdgeClasses = []EdgeClass{ EdgeClassDerivation, EdgeClassRelation, EdgeClassContribution, }
EdgeClasses lists every edge class, for validation and enumeration.
Functions ¶
func AdmitCreatedAt ¶ added in v0.12.0
AdmitCreatedAt applies step 2's timestamp rule: a claim is dated at or before the base time t (§Timestamping). Both Sequencers call it, so the rule reads one way.
func BranchTagKey ¶ added in v0.3.0
BranchTagKey marks a claim as a member of branch b's closure, valued with the branch table's height at the revision it entered.
func CheckDeletable ¶ added in v0.13.0
CheckDeletable reports whether a claim of this type may schedule its own removal (`R-DSTRUCT`). Four subtypes may not, each being what another rule reads: a contributor's pubkey (`V-SIG`), the chain to the initial table (`V-ARCHIVE`), a gap's explanation (`R-DGAP`), a key's window (`R-DEXPIRY`). Subtypes beyond them are open vocabulary (`V-TYPE`), so any other claim MAY.
func DecodePublicKey ¶
DecodePublicKey parses a multikey into its scheme code and typed Go key.
func DefaultClaimsInBranches ¶ added in v0.11.0
func DefaultClaimsInBranches(ctx context.Context, u Universe, branches map[string]Id, ids []Id) ([]bool, error)
DefaultClaimsInBranches walks each closure once, marking what it reaches — slow, and correct wherever a layer indexes nothing of its own.
func DefaultCopyClaims ¶ added in v0.3.0
DefaultCopyClaims is the reference CopyClaims, walking claim-by-claim through the single-item helpers. DiscoveryComplete flips true once the walk drains.
func DefaultCopyContents ¶ added in v0.3.0
func DefaultCopyContents(ctx context.Context, dst, src Universe, refs []ContentRef, opts ...CopyOption) error
DefaultCopyContents is the reference CopyContents, copying blob-by-blob and skipping what the receiver holds. Honours WithProgress alone.
func DefaultGetClaimHeights ¶ added in v0.3.0
DefaultGetClaimHeights reads each committed height positionally, from claims loaded in delta form — height is a claim's own field (§4.1).
func DefaultSync ¶ added in v0.3.0
func DefaultSync(ctx context.Context, dst, src Universe, id Id) <-chan SyncResult
DefaultSync fills dst for id's closure from src, claims and content, fetching only the gap. A nil src leaves dst as it stands.
func DefaultTag ¶ added in v0.3.0
DefaultTag is the reference implementation of Tag: walk the branch-table spine and stamp membership claim by claim.
func DrainWire ¶ added in v0.5.0
func DrainWire(ctx context.Context, c Contribution, u Universe, wr *WireReader) error
DrainWire fills c as records arrive: content lands in u under its hash, each claim stages under its branch, and an undeclared branch stops the fill.
func EncodePublicKey ¶
EncodePublicKey wraps a Go public key as a multikey, the framing `V-SIGN` fixes: <multicodec varint naming the scheme><raw key bytes>.
func EncodeQuery ¶ added in v0.14.0
EncodeQuery renders a query as canonical JSON, omitting every zero-valued field, so DecodeQuery returns the query it started as.
func EncodeResults ¶ added in v0.4.0
func EncodeResults(results []QueryResult, out Output) error
EncodeResults fills each result's ClaimEncoded/PathEncoded per out.Encoding, in out.Form, inlining the content out.Content allows (`R-QCONTENT`). Native asks for the Go objects, which the executor already set and which keep their content whole — an in-process caller holds the claim itself, so a cap would only cost it the bytes.
func EncodingApplication ¶
EncodingApplication returns the "application/<sub>" media type.
func EncodingAudio ¶
EncodingAudio returns the "audio/<sub>" media type.
func EncodingExample ¶
EncodingExample returns the "example/<sub>" media type.
func EncodingFont ¶
EncodingFont returns the "font/<sub>" media type.
func EncodingImage ¶
EncodingImage returns the "image/<sub>" media type.
func EncodingMessage ¶
EncodingMessage returns the "message/<sub>" media type.
func EncodingModel ¶
EncodingModel returns the "model/<sub>" media type.
func EncodingMultipart ¶
EncodingMultipart returns the "multipart/<sub>" media type.
func EncodingText ¶
EncodingText returns the "text/<sub>" media type.
func EncodingVideo ¶
EncodingVideo returns the "video/<sub>" media type.
func GetClaimHeight ¶ added in v0.3.0
GetClaimHeight is the single-item form of Universe.GetClaimHeights.
func GetTag ¶ added in v0.3.0
func GetTag(ctx context.Context, u Universe, id Id, tag string) (found bool, value string, err error)
GetTag reports whether tag is set on the claim at id, and its value.
func HasContent ¶
HasContent is the single-item form of Universe.HasContents.
func HeightOf ¶ added in v0.3.0
HeightOf returns the generation number a new claim referencing refs must carry: 1 + max(refs' heights), or 0 for an initial claim. Pass every claim the new one references — contributor and predecessor edges count too.
func InClosure ¶ added in v0.3.0
InClosure reports whether id is reachable within scope branch from any of heads — GetFromClosure without materialising the claim.
func IsTextEncoding ¶ added in v0.3.0
IsTextEncoding reports whether a media type carries human-legible text — text/*, message/* (e.g. rfc822), and structured-text application types (application/json, application/xml, and any +json / +xml suffix). Binary types (image/audio/video/font, application/octet-stream, …) return false. An empty encoding is treated as non-text. Used to decide whether content is worth inlining as readable text vs left to a byte store.
func LoadEd25519PrivateKeyPEM ¶
func LoadEd25519PrivateKeyPEM(path string) (ed25519.PrivateKey, error)
LoadEd25519PrivateKeyPEM loads an Ed25519 private key from a PKCS#8 PEM file (`openssl genpkey -algorithm ed25519`).
func LoadEd25519PublicKeyPEM ¶
LoadEd25519PublicKeyPEM loads an Ed25519 public key from a SubjectPublicKeyInfo PEM file (`openssl pkey -pubout`).
func MarshalCBOR ¶ added in v0.15.5
MarshalCBOR returns v in CBOR Deterministic Encoding (RFC 8949 §4.2), for a payload other than a claim: a result id, a route of ids, an execution report. A claim's own bytes come from Claim.EncodeCBOR. One encoder serves the whole system, since a second would be a second answer about byte order.
func NewVerifyingReader ¶
func NewVerifyingReader(src io.ReadCloser, hash Id, size uint64) (io.ReadCloser, error)
NewVerifyingReader wraps src so reading to EOF also verifies the stream (§5.10): the final Read answers an integrity error rather than a clean io.EOF.
func PutContent ¶
PutContent is the single-item form of Universe.PutContents.
func ReportEnabled ¶ added in v0.3.0
func ReportEnabled(ctx context.Context, level ReportLevel) bool
ReportEnabled reports whether ctx is collecting events at level — the guard a backend uses before building expensive report detail.
func ReportEvent ¶ added in v0.3.0
func ReportEvent(ctx context.Context, engine, op string, level ReportLevel, detail string, attrs map[string]any)
ReportEvent logs one event into the report on ctx (no-op if off) — the hook a router or engine uses to record its part of a query.
func SyncedNow ¶ added in v0.3.0
func SyncedNow(id Id) <-chan SyncResult
SyncedNow returns a closed channel with an immediate success.
func TemporalMidpointMs ¶ added in v0.25.0
TemporalMidpointMs is edtfMidpointMs, exported for a storage layer to project at write time — a native `compare: temporal` ORDER BY sorts on the projection rather than parsing EDTF itself (`R-QTEMPORAL`).
func TypeDerivation ¶
TypeDerivation returns the "derivation/<sub>" node type.
func TypeEntity ¶
TypeEntity returns the "entity/<sub>" node type.
func TypeRelation ¶
TypeRelation returns the "relation/<sub>" node type.
func TypeSource ¶
TypeSource returns the "source/<sub>" node type.
func ValidateQuery ¶ added in v0.14.0
ValidateQuery holds a query to the schema's rules plus the one it cannot state, a step's Min against its Max. Wire and Go callers share it, so both reach one verdict.
func VerifyContent ¶
VerifyContent checks data against the content hash addresses and the expected size, answering ErrIntegrity on either mismatch (`V-CONTENT`, `V-HASH`).
func WantsDelta ¶ added in v0.3.0
WantsDelta reports whether opts ask for stored delta form, which a layer keeping none must fail rather than answer materialised.
func WithDetail ¶ added in v0.3.0
WithDetail returns sentinel with detail appended lazily.
func WithReport ¶ added in v0.3.0
func WithReport(ctx context.Context, level ReportLevel) (context.Context, func() []QueryEvent)
WithReport returns a ctx collecting events at or above level, plus a snapshot func. It makes the log readable for calls no ResultStream covers — which layer of a stack served a GetClaims, what a copy walk visited. An outer collector, if ctx already has one, is reused and its events included.
Types ¶
type Archive ¶
type Archive interface {
// Head is k, the half of the tuple that fixes which snapshot this is.
Head() Id
HasClaim(ctx context.Context, id Id) (bool, error)
GetClaim(ctx context.Context, id Id) (Claim, error)
GetClaimContent(ctx context.Context, id Id) (io.Reader, error)
HasBranch(ctx context.Context, name string) (bool, error)
GetBranch(ctx context.Context, name string) (Branch, error)
GetBranches(ctx context.Context) ([]Branch, error)
// MissingBranches are those of names this archive does not carry — the branches a
// contribution would create, so a caller knows whether it needs the right to.
MissingBranches(ctx context.Context, names []string) ([]string, error)
// Query answers an RQL read: resolve q.Select.Branch to a Scope, delegate to 𝒰.
Query(ctx context.Context, q Query) (ResultStream, error)
Verify(ctx context.Context, opts ...VerifyOption) (VerificationRun, error)
}
Archive is an immutable read snapshot RA_k = (𝒰, k): the Universe plus the head claim 𝒰(k), which plays the paper's branch-table role (spec §Branches).
type Branch ¶
type Branch interface {
Edge
// Name is the branch name — the edge's "name" field.
Name() string
// Head is the root of the branch's subgraph — the edge's Reference().
Head() Id
// Prev is the previous revision of this branch: the branch pointing at the
// head's contribution/diff predecessor, nil at the first revision.
Prev(ctx context.Context) (Branch, error)
// Subgraph access — membership and lookup within the branch's closure,
// resolved against the Universe the branch was read from.
HasClaim(ctx context.Context, id Id) (bool, error)
GetClaim(ctx context.Context, id Id) (Claim, error)
GetClaimContent(ctx context.Context, id Id) (io.Reader, error)
// Verify runs a (possibly long-running) verification over the branch's
// closure. See verify.go for options.
Verify(ctx context.Context, opts ...VerifyOption) (VerificationRun, error)
}
Branch is one entry of an archive's branch table — the named contribution/branch edge itself, plus navigation into its subgraph.
type Capabilities ¶ added in v0.2.0
type Capabilities struct {
// Overwrite: Put replaces an existing key's bytes, so a read-through repair
// restores a corrupted entry in place. WORM buckets report false.
Overwrite bool
// Delete: a stored key can be removed, for lawful deletion (R6) and eviction.
Delete bool
// Enumerate: stored keys can be listed, so a Universe can be recovered or
// audited without a known head.
Enumerate bool
// Persistent: stored data survives a process restart.
Persistent bool
// ReverseWalk: the backend follows edges backward natively and cheaply (neo4j
// indexes both directions). A stack ORs it over layers; a partition ANDs.
ReverseWalk bool
// RawClaims: the backend stores claims as CBOR
RawClaims bool
// ExternalContent: the backend holds externalized content of ANY size —
ExternalContent bool
// ContentCap is the largest .content value in bytes this backend holds; 0 = no limit
ContentCap uint64
// Tags: holds mutable per-claim tags (branch membership) and implements Tagger.
Tags bool
// Tier is the write-durability role this layer is configured in; the stack
// composes its write path from each layer's reported tier.
Tier StorageTier
}
Capabilities describes what a Universe's backend can do beyond the base get/put/has contract, so composites and config can reason about a deployment. The zero value is the most restrictive.
func (Capabilities) AllowsTier ¶ added in v0.3.0
func (c Capabilities) AllowsTier(t StorageTier) bool
AllowsTier reports whether a layer with these capabilities may be configured in tier t: authoritative demands verbatim, unbounded storage (RawClaims && ExternalContent), while every other tier is a routing role any layer can fill.
type Claim ¶
type Claim interface {
Node() Node
// Edges returns the edges in canonical order, keeping those every filter matches (AND).
Edges(filters ...Filter) []Edge
Tags() map[string]string
// Tag returns value of tag best effort, with "" as fallback
Tag(key string) string
HasTag(key string) bool
SetTag(ctx context.Context, u Universe) error
// Contributor returns this claim's contribution/contributor claim, which for
// the root (no-edge) contributor is itself.
Contributor() Contributor
IsContributor() bool
// AsContributor returns a contribution/contributor claim as a Contributor,
// caching its pubkey so later signing needs no Universe.
AsContributor(ctx context.Context, u Universe, signingKey ...crypto.Signer) (Contributor, error)
ID() Id
// GetContent reads the claim's content unscoped: inline from the claim,
// external streamed from u, as is a dropped inline body.
GetContent(ctx context.Context, u Universe) (io.Reader, error)
// EncodeJSON renders every record slot as text, content base64. It reports a
// claim; the id is verified against the CBOR form's bytes.
EncodeJSON(form Form) ([]byte, error)
// EncodeCBOR returns the serialized claim as canonical CBOR: FormOriginal as
// written, FormMaterialized with its overlay resolved (`R-QDETAIL`).
EncodeCBOR(form Form) ([]byte, error)
// Envelope returns the stored record — the serialized claim paired with the
// signature over it, the bytes id(v) hashes (`V-ENV`). This is what
// persistence writes and the wire carries. A claim rebuilt from parts holds
// no signature, so it has no envelope to give.
Envelope() ([]byte, error)
// contains filtered or unexported methods
}
Claim is a node together with the edges in its edges set. Atomically created (spec §4.3); immutable after.
func AssembleClaim ¶ added in v0.3.0
func AssembleClaim(parts ClaimParts) (Claim, error)
AssembleClaim rebuilds a Claim from parts, taking every id as given and ordering edges canonically, so faithful parts re-encode to identical bytes. The closure verifier over the authoritative Universe is what checks the result.
func DecodeClaim ¶
DecodeClaim decodes a claim's canonical CBOR into a Claim with its id set. An error tells callers the bytes are content rather than a claim.
func DefaultMaterialize ¶ added in v0.3.0
func DefaultMaterialize(ctx context.Context, u Universe, claims []Claim, opts ...GetOption) ([]Claim, error)
DefaultMaterialize resolves each claim's contribution/diff overlay in place per the read opts. Idempotent; predecessors load through GetClaim, so recursively.
func GetClaim ¶
GetClaim is the single-item form of Universe.GetClaims; materialisation is the Universe's job, so this delegates.
func GetFromClosure ¶ added in v0.3.0
func GetFromClosure(ctx context.Context, u Universe, branch string, heads []Id, id Id) (Claim, error)
GetFromClosure returns the claim at id when a reference-edge walk from heads reaches it within scope branch, else ErrNotFound. heads are the scope roots, unioned.
type ClaimBuilder ¶
type ClaimBuilder struct {
Type string
TypeClass NodeClass
TypeSub string
Encoding string
EncodingClass EncodingClass
EncodingSub string
InlineContent []byte
ContentHash Id
ContentSize uint64
CreatedAt time.Time
// Dated is the time the claim's subject is assumed to stem from, an EDTF Level 1
// value (`V-DATED`); "" leaves it absent.
Dated string
Contributor Contributor
// DiffOf makes this claim a diff over the referenced predecessor; the loader
// materialises the chain.
DiffOf Id
Edges []Edge
Fields map[string]string
// Height is the claim's generation number (§4.1): 0 on an initial claim, else
// 1 + max(reference heights), which a referencing claim must declare.
Height uint64
// SigningKey signs this claim's envelope. A contributor claim's pubkey is its
// InlineContent, multikey-encoded.
SigningKey crypto.Signer
// contains filtered or unexported fields
}
ClaimBuilder is the data-only input to ClaimBuilder{...}.Sign(): Type is required, and a Contributor except on the root contributor claim (§4.3).
func NewClaim ¶
func NewClaim(typ string, contributor Contributor) ClaimBuilder
NewClaim seeds a ClaimBuilder with the required type and attributing contributor. Chain With* setters for the optionals, then call .Sign().
func (ClaimBuilder) AllowInvalid ¶ added in v0.22.0
func (b ClaimBuilder) AllowInvalid() ClaimBuilder
AllowInvalid builds a claim the rules refuse: the type vocabulary, field limits, edge cardinality, the content slots and the key/pubkey pairing all go unjudged. What still happens is the sealing — canonical bytes, envelope, id — so the result is a real record breaking exactly what its caller aimed at, which is what a conformance case needs. A Sequencer verifies on admission, so such a claim reaches no archive through the front door.
func (ClaimBuilder) Sign ¶
func (b ClaimBuilder) Sign(signingKey ...crypto.Signer) (Claim, error)
Sign finalizes a ClaimBuilder into an immutable Claim. A variadic key overrides SigningKey, which otherwise comes from the Contributor (§5.7).
func (ClaimBuilder) WithAutoHeight ¶ added in v0.3.0
func (b ClaimBuilder) WithAutoHeight(ctx context.Context, u Universe) ClaimBuilder
WithAutoHeight makes Sign read each referenced claim's committed height from u and set 1 + max (0 with no references), exclusive with WithHeight.
func (ClaimBuilder) WithContributor ¶
func (b ClaimBuilder) WithContributor(c Contributor) ClaimBuilder
WithContributor sets the attributing contributor.
func (ClaimBuilder) WithCreatedAt ¶
func (b ClaimBuilder) WithCreatedAt(t time.Time) ClaimBuilder
WithCreatedAt sets the creation timestamp, which defaults to now in UTC.
func (ClaimBuilder) WithDated ¶ added in v0.25.0
func (b ClaimBuilder) WithDated(t time.Time) ClaimBuilder
WithDated sets `dated` to t's calendar day, UTC (`V-DATED`) — distinct from CreatedAt, when the archive witnessed it. For anything EDTF alone can say — an interval, a decade, a season, an uncertain or approximate value — use WithDatedEDTF directly.
func (ClaimBuilder) WithDatedEDTF ¶ added in v0.25.1
func (b ClaimBuilder) WithDatedEDTF(d string) ClaimBuilder
WithDatedEDTF sets `dated` to a raw EDTF Level 1 value (`V-DATED`), for a value WithDated's single calendar day can't express.
func (ClaimBuilder) WithDiff ¶ added in v0.3.0
func (b ClaimBuilder) WithDiff(id Id) ClaimBuilder
WithDiff makes this claim a diff over the predecessor at id, restating only what differs, and adds the contribution/diff edge.
func (ClaimBuilder) WithEdges ¶
func (b ClaimBuilder) WithEdges(edges ...Edge) ClaimBuilder
WithEdges appends the given edges to the builder's Edges slice.
func (ClaimBuilder) WithEncoding ¶
func (b ClaimBuilder) WithEncoding(e string) ClaimBuilder
WithEncoding sets the content media type ("class/sub").
func (ClaimBuilder) WithExternalContent ¶ added in v0.3.0
func (b ClaimBuilder) WithExternalContent(hash Id, size uint64) ClaimBuilder
WithExternalContent references content stored elsewhere by hash and byte size, exclusive with WithInlineContent.
func (ClaimBuilder) WithField ¶
func (b ClaimBuilder) WithField(key, value string) ClaimBuilder
WithField sets one implementation-defined node field (§4.1) in a copied map.
func (ClaimBuilder) WithHeight ¶ added in v0.3.0
func (b ClaimBuilder) WithHeight(h uint64) ClaimBuilder
WithHeight sets the generation number (§4.1) — 1 + max over the referenced heights, or 0 for an initial claim. The verifier re-derives and enforces it.
func (ClaimBuilder) WithInlineContent ¶ added in v0.3.0
func (b ClaimBuilder) WithInlineContent(c []byte) ClaimBuilder
WithInlineContent sets the content bytes the claim itself carries.
func (ClaimBuilder) WithSigningKey ¶
func (b ClaimBuilder) WithSigningKey(k crypto.Signer) ClaimBuilder
WithSigningKey sets the key used to sign the claim id.
func (ClaimBuilder) WithType ¶
func (b ClaimBuilder) WithType(t string) ClaimBuilder
WithType sets the claim type ("class/sub").
type ClaimParts ¶ added in v0.3.0
type ClaimParts struct {
ID Id // the node/claim id (a signature — taken as given, not recomputed)
Type string // "class/sub"
Encoding string // "class/sub", or "" when there is no content
CreatedAt time.Time // must retain nanosecond precision to re-encode identically
Height uint64 // §4.1 generation number (0 for an initial claim); part of the id-preimage
Dated string // EDTF Level 1 (`V-DATED`); "" when absent
ContentHash Id // nil when the claim carries no content
ContentSize uint64 //
InlineContent []byte // present for inline content; omitted for external
Fields map[string]string //
Edges []EdgeParts //
Tags map[string]string // mutable runtime tags (branch membership, revision) — not part of the id
}
ClaimParts rebuilds a stored claim without its canonical CBOR, which a graph-native cache holds as node and edge properties. External content needs no blob — the id commits to hash and size — while inline content needs the bytes.
type Comparison ¶ added in v0.3.0
type Comparison struct {
Eq any
Ne any
Lt any
Le any
Gt any
Ge any
In []any // set membership
Glob string // shell-style wildcard (path.Match)
}
Comparison tests one field with exactly one operator.
type Constraints ¶ added in v0.10.0
type Constraints struct {
// contains filtered or unexported fields
}
Constraints are what a contribution may do: the caller declares them and the Sequencer guarantees them, so an access system is built by composing them.
func NewConstraints ¶ added in v0.10.0
func NewConstraints(opts ...ContributionOption) Constraints
NewConstraints applies opts. The zero value is the strictest reading: every reserved type refused.
func (Constraints) AdmitBranch ¶ added in v0.12.0
AdmitBranch reports whether the contribution may write to branch, which the base carrying it settles: creating one is a right of its own (§Access, C over $branches).
func (Constraints) AdmitReferences ¶ added in v0.11.0
func (c Constraints) AdmitReferences(ctx context.Context, u Universe, base Archive, branch string, own []Claim) error
AdmitReferences enforces step 3's read requirement: every claim the contribution's own reference, other than each other, must lie in a scope it may read.
func (Constraints) AdmitType ¶ added in v0.10.0
func (c Constraints) AdmitType(nodeType string) error
AdmitType reports whether a claim of nodeType may be added under these constraints.
type ContentBlob ¶
ContentBlob is one content blob for a write: its hash and the bytes.
type ContentKind ¶ added in v0.3.0
type ContentKind int
ContentKind states whether and where a claim's content lives — the node's own definitive answer, which Claim.GetContent routes on.
const ( ContentNone ContentKind = iota // no content ContentInline // inline in the claim record ContentExternal // a separate Universe blob )
type ContentRef ¶
ContentRef addresses one content blob for a read: its hash plus the expected size, which backends use to allocate, range-fetch or verify.
type Contribution ¶ added in v0.3.0
type Contribution interface {
// Base is the (k, t) the contribution was opened against.
Base() (head Id, t time.Time)
// AddClaims fills the contribution (step 2), naming the branch the claims join.
// Several may be named, and an empty one is an error. Passing the claims is what
// lets step 2's rules reach every one of them.
AddClaims(branch string, claims []Claim) error
// AddWire fills from a WireMediaType stream, which declares its own branches.
// It takes the reader, so a caller that checked Branches hands on the same one.
AddWire(ctx context.Context, wr *WireReader) error
// CompleteAndVerify closes the contribution over its base and verifies it
// (steps 3–4), yielding a sealed VerifiedContribution.
CompleteAndVerify(ctx context.Context) (VerifiedContribution, error)
}
Contribution is an in-progress advance of a Ranke-Archive: open it against a base RA_k, fill it, then CompleteAndVerify seals and verifies it.
type ContributionOption ¶ added in v0.10.0
type ContributionOption func(*Constraints)
ContributionOption sets one constraint.
func WithCreatableBranches ¶ added in v0.12.0
func WithCreatableBranches(branches ...string) ContributionOption
WithCreatableBranches names the branches a contribution may bring into being, a branch the base does not carry being created by the merge that names it. TargetBranches admits any, the surface §Access holds a creation grant against.
func WithLiftedTypes ¶ added in v0.10.0
func WithLiftedTypes(types ...string) ContributionOption
WithLiftedTypes admits node types otherwise reserved to the Sequencer, so a caller holding it can create what it would mint.
func WithReferencableBranches ¶ added in v0.11.0
func WithReferencableBranches(branches ...string) ContributionOption
WithReferencableBranches names the branches a contribution may reference claims from (step 3). BranchArchive admits every branch, BranchUniverse the whole 𝒰.
type Contributor ¶
type Contributor interface {
Claim
// SigningKey is the private key matching this contributor's pubkey (§5.7), nil
// on one loaded for reading, which verifies claims rather than making them.
SigningKey() crypto.Signer
// Pubkey is the multikey public key (§5.7), which AsContributor resolves once
// and caches, so signing can check a key without a Universe.
Pubkey() []byte
}
Contributor is a typed view over a "contribution/contributor" claim, from Claim.AsContributor or Claim.Contributor.
func WithSigningKey ¶
func WithSigningKey(c Contributor, key crypto.Signer) Contributor
WithSigningKey returns a Contributor carrying the key matching c's pubkey, so later calls sign on its behalf. A nil key leaves it able to read, not to build.
type CopyConfig ¶
type CopyConfig struct {
Closure bool
Content bool
Progress func(CopyProgress)
}
CopyConfig is the resolved set of copy options, which Universe implementations obtain via NewCopyConfig.
func NewCopyConfig ¶
func NewCopyConfig(opts ...CopyOption) CopyConfig
NewCopyConfig applies opts in order and returns the resolved config.
type CopyOption ¶
type CopyOption func(*CopyConfig)
CopyOption tunes CopyClaims / CopyContents — see each method for what it honors.
func WithClosure ¶
func WithClosure() CopyOption
WithClosure copies each id's full provenance closure (CopyClaims only).
func WithContent ¶
func WithContent() CopyOption
WithContent also copies the content bytes the copied claims reference.
func WithProgress ¶
func WithProgress(fn func(CopyProgress)) CopyOption
WithProgress registers a best-effort progress callback, called on an unspecified goroutine at an implementation-chosen frequency. Keep it cheap: it runs on the copy's goroutine.
type CopyProgress ¶
type CopyProgress struct {
ClaimsCopied uint64 // claim records written so far
BytesCopied uint64 // content bytes written so far (only under WithContent)
// Outstanding work known so far: LOWER BOUNDS that may rise as the closure is
// walked until DiscoveryComplete, after which they only fall to 0.
ClaimsRemaining uint64
BytesRemaining uint64
// DiscoveryComplete reports the full work set enumerated: render an
// indeterminate indicator until it flips, then a real percentage.
// BytesRemaining counts what the receiver intends to fetch, at its discretion.
DiscoveryComplete bool
}
CopyProgress is a best-effort snapshot of an in-flight copy.
type Detail ¶ added in v0.3.0
type Detail string
Detail is how much each element carries (`R-QDETAIL`).
const ( DetailID Detail = "id" // identities only DetailClaims Detail = "claims" // the serialized claim, as Form and Content shape it (default; empty == claims) // DetailEnvelope is the stored record copied out: the bytes whose hash is the id, // carrying the signature over them (`R-QCANON`). Form and Content do not apply, // and it is CBOR alone — the bytes are what they are. DetailEnvelope Detail = "envelope" )
type Direction ¶ added in v0.3.0
type Direction string
Direction is which way a step follows an edge. Provenance (outgoing) is the cheap default; Uses/Connections walk backward, native on ReverseWalk backends.
type Edge ¶
type Edge interface {
Reference() Id
Type() string
TypeClass() EdgeClass
TypeSub() string
// Encoding is the content's MIME media type ("class/sub"), "" without content;
// a content-bearing edge declares one (§Nodes) — reasoning, a proof, a meaning.
Encoding() string
EncodingClass() EncodingClass
EncodingSub() string
// GetContentHash is the address of EXTERNAL content, H(content); nil for
// inline content (bytes in the edge, §Content) and for no content.
GetContentHash() Id
// GetContentSize is the content's full byte length (0 when no content), whatever
// this record holds of it.
GetContentSize() uint64
// ContentKind reports whether and where the edge's content lives — Inline,
// External, or None.
ContentKind() ContentKind
// ContentComplete reports whether this record holds every byte it declares; a read
// under a content cap serves a prefix (`R-QCONTENT`).
ContentComplete() bool
// GetInlineContent returns the inline content bytes (nil when none), which may be a
// PREFIX of what the edge declares — check ContentComplete. It errors when the
// content is external.
GetInlineContent() ([]byte, error)
// GetContent returns a reader over the content, transparently
// streaming external content from u; u may be nil for inline content.
GetContent(ctx context.Context, u Universe) (io.Reader, error)
// RelationDirection is RelationFrom (+1) or RelationTo (-1) on
// relation/* edges, 0 elsewhere (§4.7).
RelationDirection() RelationDirection
HasField(name string) bool
GetField(name string) (string, error)
Fields() []string
ID() Id
// contains filtered or unexported methods
}
Edge is a directed reference from the owning claim back to the older claim it cites (spec §4.2). Part of exactly one claim; may carry inline or external content.
func NewEdge ¶
func NewEdge(cfg EdgeConfig) (Edge, error)
NewEdge constructs an Edge from cfg (§4.2) — the public wrapper over the internal newEdge, which yields the concrete type.
type EdgeConfig ¶
type EdgeConfig struct {
Reference Id
// Referenced is the claim Reference names, for the fields an edge derives from its
// target: today the delete_by every edge must carry (`R-DPLANNED`). Supply it wherever
// the target is in hand, since an edge cannot learn this after it is built.
Referenced Claim
Type string
TypeClass EdgeClass
TypeSub string
Encoding string // content media type ("class/sub"); required with content, forbidden without
InlineContent []byte // exclusive with ContentHash
ContentHash Id // external content, with ContentSize
ContentSize uint64
RelationDirection RelationDirection // RelationFrom or RelationTo on relation/* edges, zero elsewhere
Fields map[string]string
}
EdgeConfig is the data-only input to NewEdge. Reference and a type (Type, or TypeClass+TypeSub) are required; NewEdge enforces the per-field rules below.
type EdgeFilterFieldValue ¶ added in v0.3.0
EdgeFilterFieldValue matches an edge carrying a field named Field whose value equals Value exactly. An edge lacking the field never matches.
func (EdgeFilterFieldValue) IsEdgeFilter ¶ added in v0.3.0
func (f EdgeFilterFieldValue) IsEdgeFilter() bool
IsEdgeFilter reports that this filter selects edges (not nodes).
func (EdgeFilterFieldValue) MatchEdge ¶ added in v0.3.0
func (f EdgeFilterFieldValue) MatchEdge(e Edge) bool
MatchEdge reports whether e carries the named field with the exact value.
func (EdgeFilterFieldValue) MatchNode ¶ added in v0.3.0
func (f EdgeFilterFieldValue) MatchNode(Node) bool
MatchNode always passes — this is an edge-only filter.
type EdgeFilterType ¶ added in v0.3.0
type EdgeFilterType struct {
Type string
}
EdgeFilterType matches an edge whose type ("class/sub") equals Type exactly.
func (EdgeFilterType) IsEdgeFilter ¶ added in v0.3.0
func (f EdgeFilterType) IsEdgeFilter() bool
IsEdgeFilter reports that this filter selects edges (not nodes).
func (EdgeFilterType) MatchEdge ¶ added in v0.3.0
func (f EdgeFilterType) MatchEdge(e Edge) bool
MatchEdge reports whether e's type ("class/sub") equals the target exactly.
func (EdgeFilterType) MatchNode ¶ added in v0.3.0
func (f EdgeFilterType) MatchNode(Node) bool
MatchNode always passes — this is an edge-only filter.
type EdgeFilterTypes ¶ added in v0.3.0
type EdgeFilterTypes struct {
Types []string
}
EdgeFilterTypes matches an edge whose type ("class/sub") is any of Types — EdgeFilterType widened to a set (OR within this one filter).
func (EdgeFilterTypes) IsEdgeFilter ¶ added in v0.3.0
func (f EdgeFilterTypes) IsEdgeFilter() bool
IsEdgeFilter reports that this filter selects edges (not nodes).
func (EdgeFilterTypes) MatchEdge ¶ added in v0.3.0
func (f EdgeFilterTypes) MatchEdge(e Edge) bool
MatchEdge reports whether e's type equals any of the target types.
func (EdgeFilterTypes) MatchNode ¶ added in v0.3.0
func (f EdgeFilterTypes) MatchNode(Node) bool
MatchNode always passes — this is an edge-only filter.
type EdgeParts ¶ added in v0.3.0
type EdgeParts struct {
ID Id // required — the cached edge id
Reference Id
Type string // "class/sub"
Encoding string // "class/sub", or "" when the edge has no content
RelationDirection RelationDirection
ContentHash Id
ContentSize uint64
InlineContent []byte
Fields map[string]string
}
EdgeParts is the parsed structure of one edge. ID (the derived edge id) is required: a field-oriented cache must store it, since recomputing it means re-serializing S(e) from the claim CBOR the cache does not hold.
type EdgeSubtype ¶ added in v0.3.0
type EdgeSubtype string
EdgeSubtype is a contribution/* edge subtype. Every subtype vocabulary is open (paper 1 §Type Vocabulary); these are the ones the ADT gives meaning to, so a verifier acts on them and passes any other through as an ordinary reference.
const ( EdgeSubtypeContributor EdgeSubtype = "contributor" EdgeSubtypeContributorAlias EdgeSubtype = "c" EdgeSubtypeHead EdgeSubtype = "head" EdgeSubtypeHeadAlias EdgeSubtype = "h" EdgeSubtypeBranches EdgeSubtype = "branches" EdgeSubtypeBranchesAlias EdgeSubtype = "B" EdgeSubtypeBranch EdgeSubtype = "branch" EdgeSubtypeBranchAlias EdgeSubtype = "b" EdgeSubtypePrune EdgeSubtype = "prune" EdgeSubtypePruneAlias EdgeSubtype = "p" EdgeSubtypeDiff EdgeSubtype = "diff" EdgeSubtypeDiffAlias EdgeSubtype = "d" // A limiting claim points at its target through an edge of its own class // (paper 1 §Type Vocabulary): delete documents a gap where bytes were, expiry // names the last time a contributor's key is valid. EdgeSubtypeDelete EdgeSubtype = "delete" EdgeSubtypeDeleteAlias EdgeSubtype = "x" EdgeSubtypeExpiry EdgeSubtype = "expiry" EdgeSubtypeExpiryAlias EdgeSubtype = "e" )
type EncodingClass ¶
type EncodingClass string
EncodingClass is the closed top-level MIME vocabulary (RFC 6838 media types); the subtype is open.
type EncodingSubtype ¶ added in v0.3.0
type EncodingSubtype string
EncodingSubtype is the open second-level media type. Every well-known subtype carries a compact alias resolved two ways for the canonical encoding.
type Execution ¶ added in v0.3.0
type Execution struct {
Layer string // pin to one named storage layer; empty = the backend chooses
// Report is the execution-report verbosity threshold (see ReportLevel); when
// set, the stream carries a QueryReport (ResultStream.Report).
Report ReportLevel
}
Execution selects where the query runs and how deeply it reports on itself.
type Failure ¶ added in v0.3.0
Failure is one verification failure: the claim that failed, its depth in the walk, and why.
type Field ¶ added in v0.3.0
type Field string
Field is a node/edge field name: open user vocabulary over [a-z0-9_] with no leading "_". Charsets outside that are reserved system namespaces, e.g. ".".
type Filter ¶
Filter selects a subset of edges matching some criterion. Passed to Claim.Edges as a variadic list — every filter must match (AND). Callers can implement their own; NewTypeFilter and NewEncodingFilter cover the common cases.
type Form ¶ added in v0.3.0
type Form string
Form is whether a claim is returned as written (the id-defining bytes) or resolved via its diff chain.
type GetOption ¶ added in v0.3.0
type GetOption func(*getConfig)
GetOption configures a claim read (Universe.GetClaims and the package GetClaim helper).
func WithNotDiffMaterialized ¶ added in v0.3.0
func WithNotDiffMaterialized() GetOption
WithNotDiffMaterialized returns claims in stored delta form, the contribution/diff overlay left unresolved.
type Graph ¶
type Graph interface {
// AddClaims stores claims in the Universe and advances the open-head
// frontier: each claim becomes a head, the ids it references drop out.
AddClaims(ctx context.Context, claims ...Claim) error
// ContainsClaim reports whether id is in the closure of an open head.
ContainsClaim(ctx context.Context, id Id) (bool, error)
// GetClaim loads the claim at id if it is reachable from an open head.
GetClaim(ctx context.Context, id Id) (Claim, error)
// Heads returns the open heads — the frontier claims (§4.5). A single
// head makes the graph a closure RG_h.
Heads() []Id
// IsConsolidated reports whether one claim already reaches everything the graph
// needs reached — the open frontier and whatever Cite named.
IsConsolidated() bool
// Cite makes ids roots the next Consolidate wraps alongside the open heads, for a
// claim that must be reachable from the head in its own right — one sitting behind
// a claim scheduled for deletion (§Deletion).
Cite(ids ...Id)
// Consolidate wraps every open head in one head claim, adds it, returns it.
// createdAt defaults to now and must satisfy monotonicity (§4.3).
Consolidate(ctx context.Context, contributor Contributor, createdAt ...time.Time) (Claim, error)
// Verify walks the closure from every open head and verifies each claim
// (§5.10 integrity + authenticity), returning a live run.
Verify(opts ...VerifyOption) VerificationRun
}
Graph is a Ranke-Graph handle: a subset RG ⊆ 𝒰 (spec §4.5). It holds the open-head frontier; membership is closure(heads, 𝒰), resolved on demand.
type HeightCache ¶ added in v0.3.0
type HeightCache struct {
// contains filtered or unexported fields
}
HeightCache memoises claim heights. A height is bound into the id (§4.1), so an entry holds forever. Construct with NewHeightCache; a nil cache simply misses.
func NewHeightCache ¶ added in v0.3.0
func NewHeightCache() *HeightCache
NewHeightCache returns an empty, ready-to-use cache.
func (*HeightCache) Get ¶ added in v0.3.0
func (c *HeightCache) Get(id Id) (uint64, bool)
Get returns the cached height for id, if present.
func (*HeightCache) GetClaimHeights ¶ added in v0.3.0
GetClaimHeights answers ids from the cache, loading the misses from u in one bulk DefaultGetClaimHeights and caching them.
func (*HeightCache) Note ¶ added in v0.3.0
func (c *HeightCache) Note(id Id, height uint64)
Note records id→height when absent, checking under the read lock first so the hot path never serialises writers.
func (*HeightCache) NoteClaims ¶ added in v0.3.0
func (c *HeightCache) NoteClaims(cs ...Claim)
NoteClaims records the height of every non-nil claim, so a get/put path warms the cache with a batch it already holds.
type History ¶ added in v0.3.0
type History interface {
// Append records id as the new head, returning the stamped item.
Append(ctx context.Context, id Id, height int, revision int) (HistoryItem, error)
// Latest returns kₙ, or the zero item when the timeline is empty.
Latest(ctx context.Context) (HistoryItem, error)
// At returns kᵢ; an out-of-range i is an error.
GetAtRevision(ctx context.Context, revision int) (HistoryItem, error)
GetBulk(ctx context.Context, fromRevision, toExcludingRevision int) ([]HistoryItem, error)
// Len returns the number of entries (n+1).
Len(ctx context.Context) (int, error)
Close() error
}
History persists the head-id timeline k₀…kₙ. Append records a new head, assigning its height and stamping the time; the rest read the timeline back. Oldest first: At(0) is k₀, Latest is kₙ, List runs k₀…kₙ.
type HistoryItem ¶ added in v0.3.0
type HistoryItem struct {
// contains filtered or unexported fields
}
HistoryItem is one entry in the head-id timeline: the head id, its height (position in the sequence, i=0 the oldest), and the time it was appended. Fields are unexported; construct one with NewHistoryItem and read via the getters.
func NewHistoryItem ¶ added in v0.3.0
NewHistoryItem builds a HistoryItem. It lets adapters outside package ranke reconstruct an item from persisted storage (id + its recorded height and append time).
func SpliceHistory ¶ added in v0.3.0
func SpliceHistory(existing, tagged []HistoryItem) []HistoryItem
SpliceHistory grafts tagged onto existing at the revision tagged begins at. TagArchive returns only the revisions it just (re)tagged — its first item's GetRevision is the splice point — so this keeps existing's entries below that revision and replaces everything from there with tagged. That makes it correct both for a plain forward advance (tagged starts one past the end, so nothing is dropped) and for a re-tag from an earlier revision (the superseded tail is discarded). An empty tagged leaves existing unchanged.
Entries are matched by GetRevision, not slice position, so a non-contiguous or unordered existing timeline still splices at the right boundary.
func TagArchive ¶ added in v0.3.0
func TagArchive(ctx context.Context, a Archive, opts ...TagArchiveOptions) ([]HistoryItem, error)
TagArchive descends a's branch-table spine and tags each revision's branch closures oldest→newest
func (HistoryItem) GetHeight ¶ added in v0.3.0
func (h HistoryItem) GetHeight() int
GetHeight returns the entry's height
func (HistoryItem) GetId ¶ added in v0.3.0
func (h HistoryItem) GetId() Id
GetId returns the head id this entry records.
func (HistoryItem) GetRevision ¶ added in v0.3.0
func (h HistoryItem) GetRevision() int
GetRevision returns the entry's position in the timeline (0 is the oldest).
func (HistoryItem) GetTimestamp ¶ added in v0.3.0
func (h HistoryItem) GetTimestamp() time.Time
GetTimestamp returns the time the head was appended.
type Id ¶
type Id interface {
String() string
Equal(other Id) bool
// Algorithm names the hash that built this id, e.g. "sha2-256".
Algorithm() string
// contains filtered or unexported methods
}
Id is a content-addressed identifier, and always a multihash (`V-HASH`): id(v) = H(S(env(v))) for a claim (`V-ID`), id(e) = H(S(e)) for an edge, and H(c) for external content. The envelope carries the signature that once framed a claim's id (`V-ENV`), so one framing now serves all three.
func HashContent ¶
HashContent returns the content-address (SHA2-256 multihash) of bytes.
func StrandedByDeletion ¶ added in v0.13.0
StrandedByDeletion reports which of own a walk from heads reaches only through a claim carrying delete_by (`R-DPLANNED`): deleting one removes the record its edges lived in, so a walk stops at the gap while what lay behind stays present.
The search stays inside own — a claim is referenced only by claims made after it, so nothing already in the archive leads to one this contribution brings.
type Keypair ¶
type Keypair struct {
Private crypto.Signer
Pubkey []byte // multikey-encoded (see EncodePublicKey)
}
Keypair pairs a private signing key with its multikey-encoded public key, the key material a contributor claim needs.
func LoadPrivateKey ¶
LoadPrivateKey loads an Ed25519 PKCS#8 PEM private key from path and pre-computes its multikey-encoded public key.
type Limit ¶ added in v0.3.0
type Limit struct {
Results int // max claims; 0 = unbounded
Time time.Duration // execution budget; 0 = none
}
Limit bounds a read.
type MergableContribution ¶ added in v0.3.0
type MergableContribution interface {
// Heads are the open head ids per branch, which the new branch-table claim
// references under those names.
Heads() map[string][]Id
}
MergableContribution is ready for step 6: its claims are durably in 𝒰 and its head claim(s) are known.
type Node ¶
type Node interface {
Type() string
TypeClass() NodeClass
TypeSub() string
// GetContentHash is the address of EXTERNAL content, H(content); nil for
// inline content (bytes in the node, §Content) and for no content.
GetContentHash() Id
// GetContentSize is the content's full byte length (0 when no content), whatever
// this record holds of it: paired with the hash it defends against truncation, and
// against GetInlineContent it says how much arrived.
GetContentSize() uint64
// ContentKind reports where the node's content lives — Inline, External, or
// None — reading through a diff overlay via the effective content source.
ContentKind() ContentKind
// ContentComplete reports whether this record holds every byte it declares. A read
// under a content cap serves a prefix (`R-QCONTENT`), so a caller needing the whole
// content asks here rather than assuming what GetInlineContent returned is all of it.
ContentComplete() bool
// GetInlineContent returns the inline content bytes, which may be a PREFIX of the
// content the node declares — check ContentComplete. It errors when the content is
// external; check ContentKind first, or use GetContent with a Universe.
GetInlineContent() ([]byte, error)
// GetContent returns a reader over the content, transparently
// streaming external content from u; u may be nil for inline content.
GetContent(ctx context.Context, u Universe) (io.Reader, error)
Encoding() string
EncodingClass() EncodingClass
EncodingSub() string
CreatedAt() time.Time
// Dated is the time the claim's subject is assumed to stem from, an EDTF Level 1
// value (`V-DATED`); "" when absent. Unlike CreatedAt it denotes an interval, not
// an instant, and is neither `V-TIME`- nor `V-MONO`-constrained.
Dated() string
// Height is the claim's generation number: 0 for an initial claim, else 1 + max
// over referenced heights (§4.1). In the node hash, so the id commits to it.
Height() uint64
// Edges returns the ids of edges created with this claim, in canonical order.
Edges() []Id
HasField(name string) bool
GetField(name string) (string, error)
Fields() []string
ID() Id
}
Node is the structural component of a claim; its id is the claim id. Identical content under different provenance yields different ids (spec §4.1).
type NodeClass ¶
type NodeClass string
NodeClass is the closed top-level vocabulary for node types.
const ( NodeClassContribution NodeClass = "contribution" NodeClassContributionAlias NodeClass = "c" NodeClassSource NodeClass = "source" NodeClassSourceAlias NodeClass = "s" NodeClassDerivation NodeClass = "derivation" NodeClassDerivationAlias NodeClass = "d" NodeClassEntity NodeClass = "entity" NodeClassEntityAlias NodeClass = "e" NodeClassRelation NodeClass = "relation" NodeClassRelationAlias NodeClass = "r" )
type NodeSubtype ¶ added in v0.3.0
type NodeSubtype string
NodeSubtype is the second-level node-type vocabulary (the "/sub" part).
const ( NodeSubtypeBranches NodeSubtype = "branches" NodeSubtypeBranchesAlias NodeSubtype = "B" NodeSubtypeContributor NodeSubtype = "contributor" NodeSubtypeContributorAlias NodeSubtype = "c" NodeSubtypeHead NodeSubtype = "head" NodeSubtypeHeadAlias NodeSubtype = "h" // The limiting claims (paper 1 §Type Vocabulary). Each takes the letter its // edge subtype takes, as contributor, head and diff already do. NodeSubtypeDelete NodeSubtype = "delete" NodeSubtypeDeleteAlias NodeSubtype = "x" NodeSubtypeExpiry NodeSubtype = "expiry" NodeSubtypeExpiryAlias NodeSubtype = "e" )
"branch" and "diff" are absent: both are edge subtypes alone. A branch is named by a contribution/branch edge on the table, and diff-ness lives in the contribution/diff edge, so no node carries either. @tbl:aliases still assigns them b and d — one table shared by nodes and edges — which the edge side holds.
type OrderKey ¶ added in v0.3.0
type OrderKey struct {
Field string
Compare Collation // how values compare; empty = lexical
Dir SortDir // asc | desc; empty = asc
}
OrderKey is one sort key; keys apply in priority order, ties by (created_at, id).
type Output ¶ added in v0.3.0
type Output struct {
Shape Shape // single | path
Detail Detail // id | claims
Form Form // original | materialized
Content *OutputContent // content inlined per claim; nil inlines none
Encoding ResultEncoding // serialized form of each claim (json | cbor)
}
Output shapes each result along orthogonal axes: Shape, Detail, Form, Content, Encoding.
type OutputContent ¶ added in v0.14.0
type OutputContent struct {
Max int // cap in bytes for the whole claim; 0 inlines in full
Overflow Overflow // where the prefix ends at the cap; empty is OverflowOmit
}
OutputContent caps the content inlined per claim (`R-QCONTENT`). Max bounds the claim rather than each record, spent along the claim's content sequence — its edges' content in S(v)'s order, then the node's — and what arrives is a prefix of it. Max 0 inlines in full, as a zero bound elsewhere in a query means unbounded.
type Overflow ¶ added in v0.3.0
type Overflow string
Overflow is where a claim's inlined content ends once Max is reached. A claim keeps every field it carries either way, so no value stands in for content left out.
type PathStep ¶ added in v0.3.0
type PathStep struct {
Edges []string
Dir Direction // default DirProvenance
Min *int // min hops; nil means 1. Hops(0) includes the step's start.
Max int // max hops; 0 = unbounded for this step
Nodes []string
}
PathStep follows typed edges over a hop range, optionally constraining endpoint node types. Entries are globs over "class/sub"; a leading "-" excludes.
type Query ¶ added in v0.3.0
type Query struct {
Select Select
Where *Where // nil = no filter
Output Output
Order []OrderKey // sort keys in priority order; empty = natural (created_at, id)
Limit Limit
Execution Execution
}
Query is a declarative read (RQL): generate a set of claims (Select), filter it (Where), shape each result (Output), then order and bound the read. Its meaning is fixed here, whichever layer answers it via Universe.Query.
func DecodeQuery ¶ added in v0.14.0
DecodeQuery reads a query from its canonical JSON. An absent field keeps its zero value; what a caller's silence becomes is the binding's to decide.
type QueryEvent ¶ added in v0.3.0
type QueryEvent struct {
At time.Duration `json:"at_ns"` // offset from QueryReport.StartedAt
Engine string `json:"engine"` // who emitted it: "native", "cypher", "stack", "partition", …
Op string `json:"op"` // what it did: "load-root", "step", "filter", "sort", "route", "translate-cypher", …
Level ReportLevel `json:"level"` // info | warn | error
Duration time.Duration `json:"duration_ns,omitempty"` // elapsed for a timed step; 0 for a point event
Detail string `json:"detail,omitempty"` // human message, or the translated query text (e.g. Cypher)
Attrs map[string]any `json:"attrs,omitempty"` // structured extras: layer/shard name, depth, edge/result counts, …
}
QueryEvent is one logged step or point during execution.
type QueryReport ¶ added in v0.3.0
type QueryReport struct {
StartedAt time.Time `json:"started_at"` // wall clock at query start
Elapsed time.Duration `json:"elapsed_ns"` // total execution time
Results int `json:"results"` // items emitted
Truncated bool `json:"truncated"` // whether Limit cut the read short
Events []QueryEvent `json:"events,omitempty"`
}
QueryReport is a query's execution log (Execution.Report set). It travels as the stream's final element under KindReport (`R-QSTREAM`), which ResultStream.Report reads back. Engine/layer identity is per-event, since one query can span several engines. A report travels a result sequence as its last record, so its field names are wire names: lower-case like every other, and a duration says its unit, since one serialises as a bare integer of nanoseconds.
func ReportOf ¶ added in v0.19.1
func ReportOf(results []QueryResult) *QueryReport
ReportOf returns the report the sequence's final element carries, nil when that element is a result. It is the one place a stream's Report reads from, so the element and the accessor cannot disagree.
type QueryResult ¶ added in v0.3.0
type QueryResult struct {
Kind ResultKind
ClaimId Id
PathId []Id
ClaimNative Claim
PathNative []Claim
ClaimEncoded []byte
PathEncoded [][]byte
Report *QueryReport // KindReport alone: the run's execution log
}
QueryResult is one element of a result stream: a reached claim shaped per Output, or the report a reported run ends with. Kind names the one field carrying the payload, so a caller switches once and streams that field, and a reader learns what an element holds without inspecting it (`R-QSTREAM`).
func AppendReport ¶ added in v0.19.1
func AppendReport(results []QueryResult, rep *QueryReport) []QueryResult
AppendReport ends results with rep as a tagged element, when there is a report to end with: `R-QREPORT` puts one in the stream when, and only when, the query asked for it, so a nil report leaves the sequence as it was.
type Receipt ¶ added in v0.3.0
type Receipt interface {
Head() Id
}
Receipt is the outcome of a committed merge — the new head the archive advanced to.
type RelationDirection ¶
type RelationDirection int8
RelationDirection tags an entity's role on a relation/* edge (§4.7): zero = not a relation edge, RelationFrom (+1) / RelationTo (-1) otherwise. All-from or all-to expresses a symmetric relation.
const ( RelationFrom RelationDirection = 1 RelationTo RelationDirection = -1 )
type ReportLevel ¶ added in v0.3.0
type ReportLevel string
ReportLevel classifies a QueryEvent.
const ( ReportError ReportLevel = "error" // failures — always logged when a report is requested ReportWarn ReportLevel = "warn" // fallbacks, caps hit, recoverable issues ReportInfo ReportLevel = "info" // high-level stages: select, filter, sort, results ReportDebug ReportLevel = "debug" // routing decisions, per-layer hits, engine lowering (e.g. Cypher) ReportTrace ReportLevel = "trace" // per-claim / per-edge steps — exhaustive )
Report levels are one ordered scale (Error < Warn < Info < Debug < Trace); Execution.Report sets the threshold and every event at or above it is kept. Empty means no report.
type ResultEncoding ¶ added in v0.3.0
type ResultEncoding string
ResultEncoding is the form a result is returned in, carrying the same information whichever it is.
const ( ResultNative ResultEncoding = "native" // Go objects in ClaimNative/PathNative (default; empty == native) ResultJSON ResultEncoding = "json" // Encoded holds text, content base64 ResultCBOR ResultEncoding = "cbor" // Encoded holds the stored canonical CBOR, verbatim )
type ResultKind ¶ added in v0.4.0
type ResultKind string
ResultKind names the QueryResult field an element's payload is in: for a result, the product of Output.Shape (single | path) and Output.Detail/Encoding (id | native | encoded); for the report a reported run ends with, KindReport.
const ( KindClaimId ResultKind = "claim_id" KindPathId ResultKind = "path_id" KindClaimNative ResultKind = "claim_native" KindPathNative ResultKind = "path_native" KindClaimEncoded ResultKind = "claim_encoded" KindPathEncoded ResultKind = "path_encoded" // KindClaimEnvelope / KindPathEnvelope tag stored bytes copied out under // DetailEnvelope, apart from an encoded serialized claim, since a reader parses // the one and hands the other on as bytes (`R-QSTREAM`). KindClaimEnvelope ResultKind = "claim_envelope" KindPathEnvelope ResultKind = "path_envelope" // KindReport tags the final element of a run that asked for a report // (`R-QREPORT`). The value is the one ranke-ts discriminates its framed report // record under, the wire having carried the report in band all along. KindReport ResultKind = "report" )
type ResultStream ¶ added in v0.3.0
type ResultStream interface {
// Next advances to the next element, returning false at end of stream or error.
Next() bool
// Result returns the current element (valid after Next returned true). A reported
// run ends with a KindReport element, which is the report itself.
Result() QueryResult
// Report returns the report the stream's last element carries, once Next has
// returned false — a convenience over that element rather than a channel beside
// it, so the two cannot disagree. nil when Execution.Report asked for none.
Report() *QueryReport
// Err returns the first error that stopped the stream, if any.
Err() error
// Close releases the stream's resources.
Close() error
}
ResultStream streams a query's elements one at a time, in the query's order: its results, then the report where one was asked for (`R-QSTREAM`).
func DefaultQuery ¶ added in v0.3.0
DefaultQuery is the reference implementation of Universe.Query, reading only through the public Universe API: walk the closure, materialise, filter, order, limit, shape.
type Scope ¶ added in v0.3.0
type Scope struct {
Head Id // closure anchor; nil = unconfined ($universe)
Branch string // resolved branch name — a native prune key
Height uint64 // branch-head height
Revision int // archive spine revision (_br)
}
Scope is the branch context a query runs in — the Archive's resolution of q.Select.Branch, Head confining to its closure and the rest pruning natively.
type Select ¶ added in v0.3.0
type Select struct {
Branch string // scope: BranchUniverse, BranchArchive, or a branch name
Head Id // narrows the scope to this claim's closure
Claim Id // anchors the frontier; nil leaves the pattern unanchored
Path []PathStep
}
Select is a generator: Branch is the scope, Head narrows it to one claim's closure (`R-QHEAD`), Claim anchors the frontier (`R-QANCHOR`) and Path is the traversal; no Path reads the frontier's outward closure (`R-QSTEPS`).
type Sequencer ¶ added in v0.3.0
type Sequencer interface {
// GetArchive returns the current immutable snapshot RA_k.
GetArchive(ctx context.Context) (Archive, error)
// GetContributor returns the contributor the Sequencer attests branch
// advances with.
GetContributor() Contributor
// NewContribution opens a contribution against the current archive, under the
// constraints opts declare (step 1).
NewContribution(ctx context.Context, opts ...ContributionOption) (Contribution, error)
// Merge commits a persisted contribution, advancing the head (step 6),
// and returns a Receipt.
Merge(ctx context.Context, c MergableContribution) (Receipt, error)
}
Sequencer is the single writer of a Ranke-Archive (RankeDB paper §Sequencer): it hands out immutable read snapshots and advances the head, k → k', by merging contributions. The concrete implementation (naive here, concurrent in a server) lives in an adapter.
An implementation is safe to drive from several goroutines. Which one a caller holds decides how fast that goes, never whether it is allowed.
type Shape ¶ added in v0.3.0
type Shape string
Shape is whether each result is a single item or a path (the chain to it).
type StorageTier ¶ added in v0.3.0
type StorageTier string
StorageTier is how a stack writes to a layer: the adapter constrains which tiers it allows, the deployment picks one, the layer reports the choice.
const ( // StorageTierAuthoritative: the source of truth, holding the archive verbatim — // a write MUST succeed here. Requires RawClaims && ExternalContent. StorageTierAuthoritative StorageTier = "authoritative" // StorageTierEager: written synchronously alongside the authoritative tier, // best-effort — the layer re-syncs from the authoritative copy (neo4j). StorageTierEager StorageTier = "eager" // StorageTierBackground: written in a background goroutine, best-effort. StorageTierBackground StorageTier = "background" // StorageTierLazy: populated on a read miss served from below (redis). StorageTierLazy StorageTier = "lazy" )
type SweepResult ¶ added in v0.20.0
SweepResult is one sweep's outcome: the claims whose bytes were removed, and the content blobs that went with them.
func DeletePlanned ¶ added in v0.20.0
DeletePlanned removes the bytes of every claim in the closure of heads whose delete_by has fallen due at now (`R-DPLANNED`), and is idempotent.
It never deletes the four `R-DSTRUCT` subtypes, whatever a field says; CheckDeletable is that set. The gap it leaves is explained by the date the citing edges already copied (`R-DGAP`), and external content goes with the claim.
type SyncResult ¶ added in v0.3.0
SyncResult is a Sync outcome: SyncedTo is the branch-table claim now fully readable, nil on error, and Err the failure.
type TagArchiveOptions ¶ added in v0.3.0
type TagArchiveOptions struct {
// RetagAll ignores the resume bound and descends to the spine root,
// re-tagging every revision from 0.
RetagAll bool
}
TagArchiveOptions tunes TagArchive.
type Universe ¶
type Universe interface {
// GetClaims returns the claims for ids, positionally; a missing claim fails
// the whole call with ErrNotFound, so callers tolerating gaps HasClaims first.
// Claims are diff-materialised unless WithNotDiffMaterialized asks for the delta.
GetClaims(ctx context.Context, ids []Id, opts ...GetOption) ([]Claim, error)
// PutClaims stores cs; idempotent, as claims are content-addressed.
PutClaims(ctx context.Context, cs []Claim) error
// HasClaims reports, positionally per id, whether each is present.
HasClaims(ctx context.Context, ids []Id) ([]bool, error)
// GetClaimsRaw returns each claim's stored canonical CBOR verbatim,
// positionally — verification hashes these bytes, replication copies them. A
// structure-only cache (RawClaims false) misses, so a stack routes below it.
GetClaimsRaw(ctx context.Context, ids []Id) ([][]byte, error)
// DeleteClaims removes the stored bytes of each id: a lawful deletion the graph
// still explains (`R-DGAP`), or a cache eviction. Idempotent — an id already
// absent is no error, so a sweep may run twice. ErrUnsupported where
// Capabilities.Delete is false, rather than a silent success.
//
// Removing bytes rewrites no id: every referencing claim still commits to the
// one it named, which is what leaves a gap rather than a hole. Whether a
// deletion is LAWFUL is the caller's to establish (-> DeletePlanned); this
// removes what it is told to.
DeleteClaims(ctx context.Context, ids []Id) error
// GetContents returns the bytes for each ref, positionally; a missing blob
// fails the whole call with ErrNotFound.
GetContents(ctx context.Context, refs []ContentRef) ([][]byte, error)
// PutContents stores blobs. Idempotent.
PutContents(ctx context.Context, blobs []ContentBlob) error
// HasContents reports, positionally per hash, whether each is present.
HasContents(ctx context.Context, hashes []Id) ([]bool, error)
// StreamContent returns a reader for one blob — the lazy, singular GetContents.
StreamContent(ctx context.Context, hash Id, size uint64) (io.ReadCloser, error)
// DeleteContents removes the blobs at hashes, on DeleteClaims' terms: idempotent,
// and ErrUnsupported without Capabilities.Delete.
DeleteContents(ctx context.Context, hashes []Id) error
// GetClaimHeights returns the committed heights (§4.1) of the claims at ids,
// positionally. Height is fixed at creation and read back cheaply here, since
// recomputing it over a large closure is expensive.
GetClaimHeights(ctx context.Context, ids []Id) ([]uint64, error)
// ClaimsInBranches reports, per id, whether any of branches holds it. Names map to
// heads, so a walker resolves by head and a graph-native backend by the name it
// indexes; BranchArchive names the archive entire.
ClaimsInBranches(ctx context.Context, branches map[string]Id, ids []Id) ([]bool, error)
// Query answers a declarative RQL read (the paper's §Filtered Reads) with
// scope as the resolved branch context, so head/height/revision are known. A
// byte store delegates to DefaultQuery, a graph-native backend lowers to its
// own query language; a query means the same whichever layer answers.
Query(ctx context.Context, q Query, scope Scope) (ResultStream, error)
// CopyClaims copies the claim records at ids from src into the receiver —
// roots under WithClosure, the exact set otherwise. WithClosure brings each
// id's full provenance, the "copy === merge" semantics yielding a mergeable
// state; bare, the copy is PARTIAL, for HasClaims-driven frontier sync where
// the caller guarantees the rest. WithContent adds the referenced content
// bytes. An interrupted copy leaves a partial result.
CopyClaims(ctx context.Context, src Universe, ids []Id, opts ...CopyOption) error
// CopyContents copies the content blobs at refs from src into the receiver,
// the content-only half of sync. Only WithProgress is honored.
CopyContents(ctx context.Context, src Universe, refs []ContentRef, opts ...CopyOption) error
// SetClaimsTags applies tags per claim, keyed by claim-id string: it clears
// every existing tag matching a clearTags glob, then applies that claim's
// pairs. A backend that cannot hold tags returns ErrUnsupported.
SetClaimsTags(ctx context.Context, clearTags []string, tags map[string]map[string]string) error
// GetClaimTags returns each claim's tags positionally, nil when it has none.
GetClaimTags(ctx context.Context, claims []Id) ([]map[string]string, error)
// Tag signals that the archive at head has advanced. Purely an accelerator: it
// changes how fast a read answers, and what a layer indexes is its business.
Tag(ctx context.Context, head Id) error
// Sync fills the receiver for id's closure by copying what it lacks from src
// (claims + content); a stack calls it on its eager layer with the layers below
// as src. A nil src leaves the receiver synced.
Sync(ctx context.Context, src Universe, id Id) <-chan SyncResult
// Capabilities reports optional backend abilities; composites derive theirs.
Capabilities() Capabilities
Close() error
}
Universe is 𝒰 from spec §4.5 — a content-addressed bag of claims and the content bytes they reference, shareable by many Archives. Operations are bulk so backends use their native batch path (S3 batch, Neo4j UNWIND, SQL bulk insert).
func NewMemoryUniverse ¶ added in v0.3.0
func NewMemoryUniverse() Universe
NewMemoryUniverse returns an ephemeral in-process Universe: canonical claim CBOR keyed by id, content keyed by hash. It stores the exact bytes like any byte store and decodes on read, so it is stable and drift-free — the right reference behaviour, with no live-claim aliasing.
type VerificationRun ¶ added in v0.3.0
type VerificationRun interface {
// Verified is the number of claims that passed so far.
Verified() int
// Failures is a snapshot of the failures found so far.
Failures() []Failure
// Done reports whether the walk has finished (completed or stopped).
Done() bool
// Err is a terminal error that aborted the walk (a load failure,
// ctx cancellation) — distinct from per-claim Failures. Nil otherwise.
Err() error
// Wait blocks until the walk is Done.
Wait()
}
VerificationRun is a live handle on a verification, safe to read while the walk runs — poll for progress, or Wait for completion.
type VerifiedContribution ¶ added in v0.3.0
type VerifiedContribution interface {
// Ids are the claim ids the contribution adds.
Ids() []Id
// Persist writes the sealed closure to 𝒰 (step 5), yielding a
// MergableContribution the Sequencer can merge.
Persist(ctx context.Context) (MergableContribution, error)
}
VerifiedContribution is a sealed, verified contribution: its contents are fixed, so by immutability whatever verified stays valid.
type VerifyOption ¶ added in v0.3.0
type VerifyOption func(*verifyConfig)
VerifyOption configures a verification run.
func WithCreatedAfter ¶ added in v0.3.0
func WithCreatedAfter(t time.Time) VerifyOption
WithCreatedAfter prunes any claim created before t. The closure walks toward older references, so this bounds verification to a recent window.
func WithExternalContent ¶ added in v0.3.0
func WithExternalContent() VerifyOption
WithExternalContent also fetches and verifies externalized content (default: inline content only — external blobs can be gigabytes).
func WithMaxClaims ¶ added in v0.3.0
func WithMaxClaims(n int) VerifyOption
WithMaxClaims caps the walk at n claims processed (0 = unlimited).
func WithMaxDepth ¶ added in v0.3.0
func WithMaxDepth(n int) VerifyOption
WithMaxDepth bounds the closure walk to depth n (0 = full closure).
func WithOnError ¶ added in v0.3.0
func WithOnError(fn func(Failure)) VerifyOption
WithOnError registers a callback fired as each failure is found. It runs on the run's goroutine, so it must be cheap and concurrency-safe.
func WithSkipRules ¶ added in v0.3.0
func WithSkipRules(names ...string) VerifyOption
WithSkipRules omits the verification rules named by VerifyRule.Name (see VerifyRuleSet), so a scan can drop expensive rules. Unknown names are ignored.
func WithStopAfter ¶ added in v0.3.0
func WithStopAfter(n int) VerifyOption
WithStopAfter stops the walk once n failures are found (1 = fail fast, 0 = verify everything).
func WithTrusted ¶ added in v0.3.0
func WithTrusted(fn func(Id) bool) VerifyOption
WithTrusted prunes the walk at any claim for which fn returns true, backed by whatever the caller has: a DB, a bloom filter, the Sequencer's committed set.
type VerifyRule ¶ added in v0.3.0
type VerifyRule struct{ Name, Rule string }
VerifyRule describes a registered verification rule: Name is the stable identifier (WithSkipRules), Rule the statement printed on violation.
func VerifyRuleSet ¶ added in v0.3.0
func VerifyRuleSet() []VerifyRule
VerifyRuleSet lists the verification rules, in application order — the menu a caller picks from when deciding what to skip.
type Where ¶ added in v0.3.0
type Where struct {
And []Where
Or []Where
Not *Where
Field string // leaf: the field tested
Test *Comparison // leaf: the comparison on Field
}
Where is a boolean tree: exactly one of And, Or, Not or a leaf (Field + Test).
type WireConstraints ¶ added in v0.11.0
type WireConstraints struct {
Branches []string // record 2, required
Referencable []string // record 3, required
Lifted []string // record 4, empty asks for nothing
Creatable []string // record 5, empty asks for nothing
}
WireConstraints are the constraints a stream declares, one record each, all of them ahead of the payload so a receiver reads them before taking anything.
Branches and Referencable narrow: declaring them can only reduce what the contribution does. Lifted widens, so a receiver relaying a stream from a party it does not trust checks that record against what that party may ask for.
func (WireConstraints) Narrow ¶ added in v0.11.0
func (w WireConstraints) Narrow(o WireConstraints) WireConstraints
Narrow returns the constraints both w and o permit. Declaring restricts, so two declarations compose to their overlap and a relay adds its own limits by merging rather than by appending a second record.
func (WireConstraints) Options ¶ added in v0.11.0
func (w WireConstraints) Options() []ContributionOption
Options renders the declarations as the options the contribution opens under.
type WireKind ¶ added in v0.5.0
type WireKind uint64
WireKind tags what a record carries, so a reader switches once per record.
const ( // WireClaim is [0, id, canonical claim CBOR, branch] — a claim and the branch // it joins, since a contribution may name several. WireClaim WireKind = 0 // WireContent is [1, hash, blob bytes]. Content is addressed by its hash and // lives in the Universe unbranched, so it names no branch. WireContent WireKind = 1 // WireBranches is [2, [branch, ...]] — the branches this contribution writes to. WireBranches WireKind = 2 // WireReferencable is [3, [branch, ...]] — the branches, $archive or $universe it // may reference claims from. WireReferencable WireKind = 3 // WireLifted is [4, [type, ...]] — the reserved node types it asks to create. WireLifted WireKind = 4 // WireCreatable is [5, [branch, ...]] — the branches it may bring into being, a // branch the base does not carry being created by the merge that names it. WireCreatable WireKind = 5 )
type WireReader ¶ added in v0.5.0
type WireReader struct {
// contains filtered or unexported fields
}
WireReader streams a contribution, decoding one record at a time.
func NewWireReader ¶ added in v0.5.0
func NewWireReader(r io.Reader) *WireReader
NewWireReader reads a contribution stream from r.
func (*WireReader) Constraints ¶ added in v0.11.0
func (wr *WireReader) Constraints() (WireConstraints, error)
Constraints are what the stream declares, read from its leading records alone — so a caller inspects them, and refuses what it will not grant, before taking the payload.
func (*WireReader) Err ¶ added in v0.5.0
func (wr *WireReader) Err() error
Err returns the first error that stopped the stream.
func (*WireReader) Next ¶ added in v0.5.0
func (wr *WireReader) Next() bool
Next decodes the next record, returning false at end of stream or on error. The kinds differ in arity, so the elements are taken raw and read per kind.
func (*WireReader) Record ¶ added in v0.5.0
func (wr *WireReader) Record() WireRecord
Record returns the record Next decoded.
type WireRecord ¶ added in v0.5.0
type WireRecord struct {
Kind WireKind
Claim Claim // WireClaim: decoded under the id the record names
Branch string // WireClaim: the branch this claim joins
Blob ContentBlob // WireContent: the bytes, checked against the hash
}
WireRecord is one decoded record: Kind names which fields carry the payload.
type WireWriter ¶ added in v0.5.0
type WireWriter struct {
// contains filtered or unexported fields
}
WireWriter writes a contribution stream. Records concatenate, so a contribution of any size streams without being buffered.
func NewWireWriter ¶ added in v0.5.0
func NewWireWriter(w io.Writer, cons WireConstraints) *WireWriter
NewWireWriter writes a contribution under cons, which heads the stream so a reader checks it before taking the rest.
func (*WireWriter) WriteClaim ¶ added in v0.5.0
func (ww *WireWriter) WriteClaim(branch string, c Claim) error
WriteClaim appends a claim joining branch, as the canonical record under its id — the bytes the id was signed over, so the receiver can verify against it.
func (*WireWriter) WriteContent ¶ added in v0.5.0
func (ww *WireWriter) WriteContent(b ContentBlob) error
WriteContent appends externalized content under its hash.
Source Files
¶
- archive.go
- claim.go
- claim_assemble.go
- claim_builder.go
- claim_helpers.go
- claim_type_branch.go
- claim_type_contributor.go
- codec.go
- codec_envelope.go
- codec_wire.go
- contribution.go
- deletion.go
- edge.go
- edge_taxonomy.go
- edtf.go
- encoding_taxonomy.go
- errors.go
- field_taxonomy.go
- filter.go
- graph.go
- history.go
- history_item.go
- id.go
- node.go
- node_taxonomy.go
- query.go
- query_codec.go
- query_content.go
- query_default.go
- query_encode.go
- query_report.go
- query_walk.go
- sequencer.go
- sign.go
- time_fields.go
- universe.go
- universe_default.go
- universe_default_tagger.go
- universe_memory.go
- universe_taxonomy.go
- verify.go
- verify_content.go
- verify_expiry.go
- verify_reference.go
- verify_run.go
- verify_shape.go
Directories
¶
| Path | Synopsis |
|---|---|
|
adapter
|
|
|
history/dev
package: adapter/history/dev / testkit type: adapter job: an in-memory History for tests and development — the head-id timeline k₀…kₙ held in a slice, stamped from an injected deterministic Clock limits: not durable and not concurrent (single-threaded, no locks); stores ids only, like adapter/history/mem but with a controllable clock so a generated archive's history is reproducible
|
package: adapter/history/dev / testkit type: adapter job: an in-memory History for tests and development — the head-id timeline k₀…kₙ held in a slice, stamped from an injected deterministic Clock limits: not durable and not concurrent (single-threaded, no locks); stores ids only, like adapter/history/mem but with a controllable clock so a generated archive's history is reproducible |
|
history/file
package: file / coordination type: adapter job: file-backed History storing the head-id timeline as a text file, one "id timestamp" line per entry, atomic-rename writes limits: single-node only (-> a db timeline for distributed); stores ids only (-> ranke)
|
package: file / coordination type: adapter job: file-backed History storing the head-id timeline as a text file, one "id timestamp" line per entry, atomic-rename writes limits: single-node only (-> a db timeline for distributed); stores ids only (-> ranke) |
|
history/mem
package: mem / coordination type: adapter job: in-memory History — the head-id timeline held in a slice, lost on process exit limits: not durable (-> adapter/history/file); stores ids only (-> ranke)
|
package: mem / coordination type: adapter job: in-memory History — the head-id timeline held in a slice, lost on process exit limits: not durable (-> adapter/history/file); stores ids only (-> ranke) |
|
sequencer
package: adapter/sequencer / adapter type: adapter job: package root for Sequencer adapters — concrete implementations of the ranke.Sequencer write path limits: no implementation here; concrete Sequencers live in subpackages — the blocking single-threaded reference (-> adapter/sequencer/dev) and the concurrent write path (-> adapter/sequencer/concurrent)
|
package: adapter/sequencer / adapter type: adapter job: package root for Sequencer adapters — concrete implementations of the ranke.Sequencer write path limits: no implementation here; concrete Sequencers live in subpackages — the blocking single-threaded reference (-> adapter/sequencer/dev) and the concurrent write path (-> adapter/sequencer/concurrent) |
|
sequencer/concurrent
package: adapter/sequencer/concurrent / adapter type: adapter job: the concurrent Sequencer — the paper's six steps with 2–5 run in parallel off the sequencing thread, and step 6 a serialised group commit folding a whole batch of contributions into ONE branch-table advance limits: single-process (the sequencing thread is a mutex, not consensus); its committed-id set grows with the archive; step 6 costs one closure test per contributed head, so a slow backend serialises there; no cross-branch merge, no limiting/expiry claims
|
package: adapter/sequencer/concurrent / adapter type: adapter job: the concurrent Sequencer — the paper's six steps with 2–5 run in parallel off the sequencing thread, and step 6 a serialised group commit folding a whole batch of contributions into ONE branch-table advance limits: single-process (the sequencing thread is a mutex, not consensus); its committed-id set grows with the archive; step 6 costs one closure test per contributed head, so a slow backend serialises there; no cross-branch merge, no limiting/expiry claims |
|
sequencer/dev
package: adapter/sequencer/dev / testkit job: the dev Sequencer's contribution — steps 2–5 (filling, completing, verifying, persisting) behind the ranke.Contribution contract type: adapter limits: one contribution at a time, filled from one goroutine; merging is step 6 and belongs to the Sequencer (-> dev.go)
|
package: adapter/sequencer/dev / testkit job: the dev Sequencer's contribution — steps 2–5 (filling, completing, verifying, persisting) behind the ranke.Contribution contract type: adapter limits: one contribution at a time, filled from one goroutine; merging is step 6 and belongs to the Sequencer (-> dev.go) |
|
storage
package: adapter / blobstore type: logic job: the BlobStore seam — three byte primitives (Get/Put/Has) become a full ranke.Universe limits: no storage of its own; concrete blob backends live in sub-packages (-> adapter/fs, adapter/mem)
|
package: adapter / blobstore type: logic job: the BlobStore seam — three byte primitives (Get/Put/Has) become a full ranke.Universe limits: no storage of its own; concrete blob backends live in sub-packages (-> adapter/fs, adapter/mem) |
|
storage/adaptertest
package: adaptertest / conformance type: test job: black-box conformance suite exercising any ranke.Universe via the public API limits: no medium-specific scenarios; each adapter adds those alongside (-> adapter/storage/fs, adapter/storage/mem)
|
package: adaptertest / conformance type: test job: black-box conformance suite exercising any ranke.Universe via the public API limits: no medium-specific scenarios; each adapter adds those alongside (-> adapter/storage/fs, adapter/storage/mem) |
|
storage/fs
package: fs / persistence type: adapter job: stores claims and content blobs as files in a single flat directory limits: no indexing or codec logic; a BlobStore behind storage.NewBlobUniverse (-> adapter)
|
package: fs / persistence type: adapter job: stores claims and content blobs as files in a single flat directory limits: no indexing or codec logic; a BlobStore behind storage.NewBlobUniverse (-> adapter) |
|
storage/mem
package: mem / persistence type: adapter job: ephemeral in-memory Universe for tests and short-lived sessions — a thin alias to the core reference implementation limits: nothing persists across process restarts (-> adapter/fs)
|
package: mem / persistence type: adapter job: ephemeral in-memory Universe for tests and short-lived sessions — a thin alias to the core reference implementation limits: nothing persists across process restarts (-> adapter/fs) |
|
storage/minimal
package: minimal / persistence type: adapter job: the smallest possible Universe — a map[string][]byte behind the BlobStore seam limits: ephemeral, unsynchronized illustration of the minimum an adapter must implement (-> adapter)
|
package: minimal / persistence type: adapter job: the smallest possible Universe — a map[string][]byte behind the BlobStore seam limits: ephemeral, unsynchronized illustration of the minimum an adapter must implement (-> adapter) |
|
storage/neo4j
package: neo4j / persistence-cache type: logic job: map ranke claims to/from neo4j node + relationship property maps (the cache's on-graph shape) limits: pure mapping, no I/O; the Cypher and driver calls live in neo4j.go.
|
package: neo4j / persistence-cache type: logic job: map ranke claims to/from neo4j node + relationship property maps (the cache's on-graph shape) limits: pure mapping, no I/O; the Cypher and driver calls live in neo4j.go. |
|
storage/partition
package: partition / persistence type: adapter job: shard one Universe across N backends — each key routed to a shard by hash(id) mod N (paper §Composing Universes) limits: no storage of its own (-> the shard Universes); N is fixed (consistent-hashing / resharding not modelled)
|
package: partition / persistence type: adapter job: shard one Universe across N backends — each key routed to a shard by hash(id) mod N (paper §Composing Universes) limits: no storage of its own (-> the shard Universes); N is fixed (consistent-hashing / resharding not modelled) |
|
storage/redis
package: redis / persistence-cache type: adapter job: stores claims and content blobs as keys in redis — a fast, shared, in-memory byte cache tier limits: a storage.BlobStore behind storage.NewBlobUniverse (-> adapter); not authoritative — a cache under a query layer and above a durable store (paper §Composing Universes)
|
package: redis / persistence-cache type: adapter job: stores claims and content blobs as keys in redis — a fast, shared, in-memory byte cache tier limits: a storage.BlobStore behind storage.NewBlobUniverse (-> adapter); not authoritative — a cache under a query layer and above a durable store (paper §Composing Universes) |
|
storage/rest
package: rest / persistence type: adapter job: stores claims and content blobs over a tiny HTTP blob API (GET/PUT/HEAD) limits: no auth, retries, or pagination; just the BlobStore primitives over HTTP (-> adapter)
|
package: rest / persistence type: adapter job: stores claims and content blobs over a tiny HTTP blob API (GET/PUT/HEAD) limits: no auth, retries, or pagination; just the BlobStore primitives over HTTP (-> adapter) |
|
storage/s3
package: s3 / persistence type: adapter job: stores claims and content blobs as objects in an S3 bucket limits: no indexing or codec logic; a BlobStore behind storage.NewBlobUniverse (-> adapter)
|
package: s3 / persistence type: adapter job: stores claims and content blobs as objects in an S3 bucket limits: no indexing or codec logic; a BlobStore behind storage.NewBlobUniverse (-> adapter) |
|
storage/sqlite
package: sqlite / persistence type: adapter job: stores claims and content blobs as rows in a single SQLite table limits: no indexing or codec logic; a BlobStore behind storage.NewBlobUniverse (-> adapter)
|
package: sqlite / persistence type: adapter job: stores claims and content blobs as rows in a single SQLite table limits: no indexing or codec logic; a BlobStore behind storage.NewBlobUniverse (-> adapter) |
|
storage/stack
package: stack / persistence type: logic job: the background filler — a bounded, deduplicating, lossy batch queue for opportunistic cache writes that must never slow or fail a read limits: puts claims into layers the stack chose; deciding WHICH layers and WHY is the router's (-> stack.go, query.go)
|
package: stack / persistence type: logic job: the background filler — a bounded, deduplicating, lossy batch queue for opportunistic cache writes that must never slow or fail a read limits: puts claims into layers the stack chose; deciding WHICH layers and WHY is the router's (-> stack.go, query.go) |
|
package: client / transport type: adapter job: the HTTP client for a running ranke-db — one credential, one base URL, and the request plumbing every endpoint call shares, including the server's machine-readable error codes limits: transport only; what the endpoints mean is the OpenAPI contract's and what travels over them is the library's (-> codec_wire, query_codec)
|
package: client / transport type: adapter job: the HTTP client for a running ranke-db — one credential, one base URL, and the request plumbing every endpoint call shares, including the server's machine-readable error codes limits: transport only; what the endpoints mean is the OpenAPI contract's and what travels over them is the library's (-> codec_wire, query_codec) |
|
cmd
|
|
|
ranke
command
package: main / cli type: cmd job: read-only CLI to inspect filesystem-backed Ranke-Graph archives limits: no mutation commands; building claims lives in tests + downstream apps (-> tests)
|
package: main / cli type: cmd job: read-only CLI to inspect filesystem-backed Ranke-Graph archives limits: no mutation commands; building claims lives in tests + downstream apps (-> tests) |
|
scenariodoc
command
package: main / cli type: cmd job: regenerate conformance/scenarios/*/scenario.md from each scenario's main.go comments limits: doesn't run scenarios; only extracts their doc comments (-> conformance/scenarios)
|
package: main / cli type: cmd job: regenerate conformance/scenarios/*/scenario.md from each scenario's main.go comments limits: doesn't run scenarios; only extracts their doc comments (-> conformance/scenarios) |
|
test
command
package: main / cli type: cmd job: `test` — a cobra CLI for running the project's customizable test tooling; today one subcommand, `performance`, drives the backend matrix limits: a thin flag→Config→RunMatrix adapter; the matrix logic lives in tests/performance (shared with `go test`)
|
package: main / cli type: cmd job: `test` — a cobra CLI for running the project's customizable test tooling; today one subcommand, `performance`, drives the backend matrix limits: a thin flag→Config→RunMatrix adapter; the matrix logic lives in tests/performance (shared with `go test`) |
|
vectors
command
package: main / vectors_broken type: cmd job: the records every implementation must reject, each isolating one failure — a wrong id, a record stored bare where an envelope belongs, an unresolvable contributor, a declared height that is not the derived one, content that misses its hash limits: derives from the toy graph (-> graph.go); each case breaks one thing, so a rejection names a cause
|
package: main / vectors_broken type: cmd job: the records every implementation must reject, each isolating one failure — a wrong id, a record stored bare where an envelope belongs, an unresolvable contributor, a declared height that is not the derived one, content that misses its hash limits: derives from the toy graph (-> graph.go); each case breaks one thing, so a rejection names a cause |
|
conformance
|
|
|
helpers
package: helpers / conformance type: test job: shared boilerplate for ../scenarios/<n>/main.go (bundle setup, reload+verify, id collection) limits: builds no claims itself; scenarios do that inline (-> conformance/scenarios)
|
package: helpers / conformance type: test job: shared boilerplate for ../scenarios/<n>/main.go (bundle setup, reload+verify, id collection) limits: builds no claims itself; scenarios do that inline (-> conformance/scenarios) |
|
scenarios/01_personal_graph
command
package: main / scenario type: cmd job: build & persist the scenario-01 personal-graph data bundle limits: doesn't verify variant reproductions; that's the run.sh harness (-> conformance/helpers)
|
package: main / scenario type: cmd job: build & persist the scenario-01 personal-graph data bundle limits: doesn't verify variant reproductions; that's the run.sh harness (-> conformance/helpers) |
|
scenarios/02_agent_analyses
command
package: main / scenario type: cmd job: build & persist the scenario-02 agent-analyses data bundle limits: doesn't verify variant reproductions; that's the run.sh harness (-> conformance/helpers)
|
package: main / scenario type: cmd job: build & persist the scenario-02 agent-analyses data bundle limits: doesn't verify variant reproductions; that's the run.sh harness (-> conformance/helpers) |
|
scenarios/03_agent_corrects_agent
command
package: main / scenario type: cmd job: build & persist the scenario-03 agent-corrects-agent data bundle limits: doesn't verify variant reproductions; that's the run.sh harness (-> conformance/helpers)
|
package: main / scenario type: cmd job: build & persist the scenario-03 agent-corrects-agent data bundle limits: doesn't verify variant reproductions; that's the run.sh harness (-> conformance/helpers) |
|
internal
|
|
|
exclusive
package: internal/exclusive / lock type: tool job: a cross-process lock, so tests sharing one live service serialise without `go test -p 1` limits: test support; it orders access and wipes nothing itself
|
package: internal/exclusive / lock type: tool job: a cross-process lock, so tests sharing one live service serialise without `go test -p 1` limits: test support; it orders access and wipes nothing itself |
|
vectors
package: internal/vectors / check type: logic job: runs an artifact set's cases through the library, so the generator's self-check and the conformance gate ask the same question of the same code limits: reports what the library did; deciding whether that is conformant is the caller's
|
package: internal/vectors / check type: logic job: runs an artifact set's cases through the library, so the generator's self-check and the conformance gate ask the same question of the same code limits: reports what the library did; deciding whether that is conformant is the caller's |
|
scripts
|
|
|
rqlgate
command
package: scripts/rqlgate / tool type: tool job: compare rql.schema.json against the Go query implementation — every constraint the schema states is probed against DecodeQuery, and an unknown keyword fails the gate limits: reads the schema and the ranke wire decoder; asserts nothing about the spec prose (-> scripts/rule-citations.sh for rule ids)
|
package: scripts/rqlgate / tool type: tool job: compare rql.schema.json against the Go query implementation — every constraint the schema states is probed against DecodeQuery, and an unknown keyword fails the gate limits: reads the schema and the ranke wire decoder; asserts nothing about the spec prose (-> scripts/rule-citations.sh for rule ids) |
|
package: tests / conformance type: test job: small error-checking helper shared across the integration suite limits: no test logic itself (-> tests/scenarios.go, tests/integration.go)
|
package: tests / conformance type: test job: small error-checking helper shared across the integration suite limits: no test logic itself (-> tests/scenarios.go, tests/integration.go) |
|
backends
package: tests/backends / integration type: tool job: the shared backend matrix — one named opener per storage configuration, each spinning up a FRESH, EMPTY local instance (podman pods for s3/redis/neo4j, or host-native services) limits: wiring only — no test logic and no assertions; the rows are consumed by the conformance matrix (-> tests/matrix) and the timing harness (-> tests/performance)
|
package: tests/backends / integration type: tool job: the shared backend matrix — one named opener per storage configuration, each spinning up a FRESH, EMPTY local instance (podman pods for s3/redis/neo4j, or host-native services) limits: wiring only — no test logic and no assertions; the rows are consumed by the conformance matrix (-> tests/matrix) and the timing harness (-> tests/performance) |
|
generator
package: tests/generator / testkit type: tool job: Generate — build a deterministic kitchen-sink Ranke-Archive from a Spec, driving the dev Sequencer's write path; return a Manifest naming every corner limits: builds via the public ranke API + the dev testkit adapters; the caller supplies the Universe (-> adapter); asserts nothing (-> tests).
|
package: tests/generator / testkit type: tool job: Generate — build a deterministic kitchen-sink Ranke-Archive from a Spec, driving the dev Sequencer's write path; return a Manifest naming every corner limits: builds via the public ranke API + the dev testkit adapters; the caller supplies the Universe (-> adapter); asserts nothing (-> tests). |
|
helpers
package: tests/helpers / testkit type: tool job: shared helpers for driving a ranke.Sequencer from tests and test tooling limits: the contract only — no fixtures, no assertions, no backend knowledge (-> tests, tests/backends)
|
package: tests/helpers / testkit type: tool job: shared helpers for driving a ranke.Sequencer from tests and test tooling limits: the contract only — no fixtures, no assertions, no backend knowledge (-> tests, tests/backends) |
|
matrix
package: tests/matrix / conformance type: test job: the cross-backend agreement matrix — build one deterministic archive into every available backend, run the shared RQL corpus against each, and assert every backend's answer matches the reference's limits: correctness only, never timing (-> tests/performance); it asks whether an answer is right, never how a backend produced it — routing, lowering, and cache tiers are the backend's business
|
package: tests/matrix / conformance type: test job: the cross-backend agreement matrix — build one deterministic archive into every available backend, run the shared RQL corpus against each, and assert every backend's answer matches the reference's limits: correctness only, never timing (-> tests/performance); it asks whether an answer is right, never how a backend produced it — routing, lowering, and cache tiers are the backend's business |
|
performance
package: tests/performance / integration type: tool job: the reusable performance-matrix harness — generate a deterministic size-N archive into each backend and time the chapters (write / verify / random access), reporting per-step latency distributions limits: decoupled from the testing package so both the _test.go entrypoint and cmd/test can drive it; timing only — the backend rows come from tests/backends and correctness belongs to tests/matrix
|
package: tests/performance / integration type: tool job: the reusable performance-matrix harness — generate a deterministic size-N archive into each backend and time the chapters (write / verify / random access), reporting per-step latency distributions limits: decoupled from the testing package so both the _test.go entrypoint and cmd/test can drive it; timing only — the backend rows come from tests/backends and correctness belongs to tests/matrix |
|
rql
package: tests/rql / integration type: tool job: the shared RQL corpus — a broad set covering each axis of the read language (traversal, filter, shape, order, bound) for the conformance matrix, plus the small subset the timing harness measures limits: queries and their names only; executing them and comparing answers live alongside (-> run.go), and the backend rows come from tests/backends
|
package: tests/rql / integration type: tool job: the shared RQL corpus — a broad set covering each axis of the read language (traversal, filter, shape, order, bound) for the conformance matrix, plus the small subset the timing harness measures limits: queries and their names only; executing them and comparing answers live alongside (-> run.go), and the backend rows come from tests/backends |