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 / bookmark type: crypto job: the bookmark record (`V-BMENV`) — a COSE_Sign1 over S([i, s, k]) that 𝒰_hist holds under id_seq(i, s) — plus id_seq itself, the minted seed, and the checks a fetched record is held to (`V-BMSIG`, `V-BMSLOT`, `V-BMREF`) limits: stores nothing; the store is bookmark_store.go's and the list its searches walk is bookmarks.go's (-> bookmarks)
package: ranke / bookmark_locator type: logic job: BookmarkLocator — which bookmark list to open, given as a seed or as the id of one entry, so the seed is settled before any cursor over the list exists limits: names a list and resolves it; the cursor and its searches are bookmarks.go's (-> bookmarks, bookmark_store)
package: ranke / bookmark_store type: io job: the 𝒰_hist interface — bookmark records by id_seq(i, s) — with the in-process reference implementation and the refusal a backend holding no 𝒰_hist hands out limits: opaque bytes by key and nothing else; the record's shape and its rules are bookmark.go's, the list over a store bookmarks.go's (-> bookmark, bookmarks)
package: ranke / bookmarks type: logic job: Bookmarks — one bookmark list over 𝒰_hist: the writer's Append at the next free index and the O(log n) searches that find a list's range from any one of its entries limits: holds no signing key (Append takes the contributor per call) and no store of its own; the record and its rules are bookmark.go's (-> bookmark, bookmark_store)
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 — and the form a branch name takes 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 / 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 / spine_item type: data job: one revision of the branch-table spine for timeline tracking limits: a value type over U, unrelated to the bookmark list that locates a moving head (-> bookmarks); the walk that builds it is universe_default_tagger.go's
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, and FormatTimestamp writes the form 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, `V-ARCHIVEHEIGHT` the initial branch table's height limits: needs no Universe read and no reference resolution, so a record that arrived as bytes is judged as readily as one this library built
Index ¶
- Constants
- Variables
- func AdmitCreatedAt(c Claim, base time.Time) error
- func BranchTagKey(branch string) string
- func CheckBookmarkHead(ctx context.Context, u Universe, bm Bookmark) error
- 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 FormatTimestamp(t time.Time) 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 IsEncryptedKey(pemBytes []byte) bool
- func IsTextEncoding(encoding string) bool
- func LoadEd25519PrivateKeyPEM(path string, opts ...KeyOption) (ed25519.PrivateKey, error)
- func LoadEd25519PublicKeyPEM(path string) (ed25519.PublicKey, error)
- func MarshalCBOR(v any) ([]byte, error)
- func MintSeed() ([]byte, error)
- func NewVerifyingReader(src io.ReadCloser, hash Id, size uint64) (io.ReadCloser, error)
- func ParseEd25519PrivateKeyPEM(pemBytes []byte, opts ...KeyOption) (ed25519.PrivateKey, error)
- func ParseEd25519PublicKeyPEM(pemBytes []byte) (ed25519.PublicKey, 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 SignBookmark(self Contributor, index uint64, seed []byte, head Id) ([]byte, error)
- 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 ValidateBranchName(name string) error
- 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 Bookmark
- type BookmarkLocator
- type BookmarkStore
- type Bookmarks
- func (b *Bookmarks) Append(ctx context.Context, self Contributor, head Id) (Bookmark, error)
- func (b *Bookmarks) BookmarkId() Id
- func (b *Bookmarks) GetAtIndex(ctx context.Context, i int) (Bookmark, error)
- func (b *Bookmarks) GetBulk(ctx context.Context, from, toExcluding int) ([]Bookmark, error)
- func (b *Bookmarks) Latest(ctx context.Context) (Bookmark, error)
- func (b *Bookmarks) Len(ctx context.Context) (int, error)
- func (b *Bookmarks) Seed() []byte
- func (b *Bookmarks) Verify(ctx context.Context) error
- 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) WithHeightResolver(ctx context.Context, resolve HeightResolver) 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 HeightResolver
- type Id
- type KeyOption
- 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 SpineItem
- 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") // ErrSequencerGenesis: the bookmark list holds no entry, so this archive does // not exist yet and every operation on it waits for Found. A caller branches on // Sequencer.InGenesis rather than on this error. ErrSequencerGenesis = errors.New("ranke.Sequencer: the archive awaits its first contributor (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}") ErrQueryTimeOperand = errors.New("ranke.Query: a comparison on a time field takes a `V-TIME` timestamp or an EDTF Level 1 value (`R-QTIMEOP`)") 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") ErrBranchName = errors.New("ranke: a branch name is at most 128 bytes over [a-z0-9_] with no leading _") 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") ErrKeyWindowField = errors.New("ranke.verify: contributor key validity bound is not RFC 3339") ErrContributorUnresolved = errors.New("ranke.verify: contributor claim unresolved") 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") ErrHeightMismatch = errors.New("ranke.verify: claim height ≠ 1 + max(reference heights)") ErrCreatedAtNotMonotone = errors.New("ranke.verify: claim is dated before a claim it references") ErrRefsBranchTable = errors.New("ranke.verify: claim references a branch table") ErrKeyEncrypted = errors.New("ranke: the key is encrypted, and decrypting one is the caller's (openssl pkcs8 -topk8 -nocrypt)") ErrKeyFormat = errors.New("ranke: the key is not a PKCS#8 PEM (openssl pkcs8 -topk8 converts one)") // --- 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`)") // ErrArchiveFirstTableHeight: the archive's initial branch table stands on its // contributor edge alone, so height 1 is the only value that re-derives. ErrArchiveFirstTableHeight = errors.New("ranke.verify: an archive's first branch-table claim must have height 1 (`V-ARCHIVEHEIGHT`)") // ErrUnexplainedGap: a claim's bytes are missing and nothing explains the gap — // no copied delete_by on the edge reaching it, no contribution/delete mark against // it. Indistinguishable from data loss, which is why it fails. ErrUnexplainedGap = errors.New("ranke.verify: a missing claim with no explained gap (no copied delete_by, no contribution/delete mark)") )
var EdgeClasses = []EdgeClass{ EdgeClassDerivation, EdgeClassRelation, EdgeClassContribution, }
EdgeClasses lists every edge class, for validation and enumeration.
Functions ¶
func AdmitCreatedAt ¶
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 ¶
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 CheckBookmarkHead ¶ added in v0.27.0
CheckBookmarkHead holds a bookmark's k to `V-BMREF`: it resolves to a contribution/branches claim. One 𝒰 read, which is why a fetch leaves it to the explicit verification a list offers (-> Bookmarks.Verify).
func CheckDeletable ¶
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 ¶
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 ¶
DefaultCopyClaims is the reference CopyClaims, walking claim-by-claim through the single-item helpers. DiscoveryComplete flips true once the walk drains.
func DefaultCopyContents ¶
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 ¶
DefaultGetClaimHeights reads each committed height positionally, from claims loaded in delta form — height is a claim's own field (§4.1).
func DefaultSync ¶
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 ¶
DefaultTag is the reference implementation of Tag: walk the branch-table spine and stamp membership claim by claim.
func DrainWire ¶
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 ¶
EncodeQuery renders a query as canonical JSON, omitting every zero-valued field, so DecodeQuery returns the query it started as.
func EncodeResults ¶
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 FormatTimestamp ¶ added in v0.28.0
FormatTimestamp renders t in `V-TIME` form: RFC 3339, UTC, fixed-width nanoseconds — the one spelling a time comparison takes (`R-QTIMEOP`).
func GetClaimHeight ¶
GetClaimHeight is the single-item form of Universe.GetClaimHeights.
func GetTag ¶
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 ¶
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 ¶
InClosure reports whether id is reachable within scope branch from any of heads — GetFromClosure without materialising the claim.
func IsEncryptedKey ¶ added in v0.32.0
IsEncryptedKey reports whether the PEM holds an encrypted private key, which is what lets a caller ask for a passphrase only when one is wanted.
func IsTextEncoding ¶
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, opts ...KeyOption) (ed25519.PrivateKey, error)
LoadEd25519PrivateKeyPEM is ParseEd25519PrivateKeyPEM over the file at path.
func LoadEd25519PublicKeyPEM ¶
LoadEd25519PublicKeyPEM is ParseEd25519PublicKeyPEM over the file at path.
func MarshalCBOR ¶
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 MintSeed ¶ added in v0.28.0
MintSeed returns a fresh bookmark seed: seedBytes of crypto/rand, distinct from every other list's. Whoever founds a list mints its seed and keeps it — the value arrives at a Bookmarks already made (-> Seed), so nothing inside mints.
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 ParseEd25519PrivateKeyPEM ¶ added in v0.31.0
func ParseEd25519PrivateKeyPEM(pemBytes []byte, opts ...KeyOption) (ed25519.PrivateKey, error)
ParseEd25519PrivateKeyPEM reads an Ed25519 private key from a PKCS#8 PEM block (`openssl genpkey -algorithm ed25519`).
func ParseEd25519PublicKeyPEM ¶ added in v0.31.0
ParseEd25519PublicKeyPEM reads an Ed25519 public key from a SubjectPublicKeyInfo PEM block (`openssl pkey -pubout`).
func PutContent ¶
PutContent is the single-item form of Universe.PutContents.
func ReportEnabled ¶
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 ¶
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 SignBookmark ¶ added in v0.27.0
SignBookmark returns the record 𝒰_hist holds at id_seq(index, seed): S([i, s, k]) signed under self, whose id the protected header carries as kid (`V-BMENV`, `V-BMSIG`).
func SyncedNow ¶
func SyncedNow(id Id) <-chan SyncResult
SyncedNow returns a closed channel with an immediate success.
func TemporalMidpointMs ¶
TemporalMidpointMs is edtfMidpointMs, exported so a storage layer can project `dated` at write time and sort on the projection natively (`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 ValidateBranchName ¶ added in v0.30.0
ValidateBranchName holds a branch label to the form `R-FIELDS` gives a name — `[a-z0-9_]`, no leading underscore, at most 128 bytes. The charset admits no `$`, so a branch can never take a reserved target's name (BranchArchive, BranchUniverse, TargetBranches) and be shadowed by it at read time.
func ValidateQuery ¶
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 ¶
WantsDelta reports whether opts ask for stored delta form, which a layer keeping none must fail rather than answer materialised.
func WithDetail ¶
WithDetail returns sentinel with detail appended lazily.
func WithReport ¶
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 Bookmark ¶ added in v0.27.0
type Bookmark struct {
// contains filtered or unexported fields
}
Bookmark is one entry of a bookmark list: the index i it sits at, the seed s its list is keyed on, and the head id k it records (`V-BMENV`). Signer is the contribution/contributor claim its envelope names as kid, whose key signed it.
func DecodeBookmark ¶ added in v0.27.0
DecodeBookmark reads a stored record as a bookmark and holds it to `V-BMENV`: a tagged COSE_Sign1 whose protected header carries alg and kid alone, over a three-element S([i, s, k]). The signature is another rule's (`V-BMSIG`), since checking it needs the kid's contributor claim.
func NewBookmark ¶ added in v0.27.0
NewBookmark builds a bookmark value, for a reader reconstructing one it holds the parts of. The record a store keeps is SignBookmark's.
func VerifyBookmark ¶ added in v0.27.0
VerifyBookmark reads the record offered at slot and holds it to the three rules a fetch can afford: its shape (`V-BMENV`), its signature against the pubkey of the contributor its kid names (`V-BMSIG`), and id_seq(i, s) recomputed from its own payload reproducing the slot it came from (`V-BMSLOT`).
func (Bookmark) Seed ¶ added in v0.27.0
Seed returns s, fixed once per list and carried by every entry, so any one of them opens the list.
type BookmarkLocator ¶ added in v0.28.0
type BookmarkLocator struct {
// contains filtered or unexported fields
}
BookmarkLocator names one bookmark list. Its two arms carry different contracts, and both deliver the seed before the cursor exists — which is what keeps a list's key material immutable for the life of a Bookmarks.
func At ¶ added in v0.28.0
func At(id Id) BookmarkLocator
At locates a PRUNED list from the id of any surviving entry, whose verified record yields the seed every bookmark carries — so index 0 need not exist (foundation paper §Backup). Pruning is out-of-band, BookmarkStore having no Delete.
func Seed ¶ added in v0.28.0
func Seed(s []byte) BookmarkLocator
Seed locates the list keyed on s, which starts at index 0 and is never pruned, so its genesis is detectable by probing id_seq(0, s). Any non-empty s serves: it keeps lists apart and is no security value, though a minted one carries 128 bits (`V-BMENV`).
type BookmarkStore ¶ added in v0.27.0
type BookmarkStore interface {
// Get returns the record at key, ErrNotFound where the slot holds nothing.
Get(ctx context.Context, key Id) ([]byte, error)
// Put stores record at key, replacing whatever the slot held.
Put(ctx context.Context, key Id, record []byte) error
}
BookmarkStore is 𝒰_hist, the bookmark store: records under id_seq(i, s), a keyspace defined apart from 𝒰 and freely co-located with it physically (foundation paper §Bookmarks). Its guarantees are deliberately weaker than 𝒰's — a bookmark is only a locator, so an entry may be overwritten or purged.
func UnsupportedBookmarks ¶ added in v0.28.0
func UnsupportedBookmarks() BookmarkStore
UnsupportedBookmarks is the store a Universe reporting Capabilities.Bookmarks false hands out: every operation is ErrUnsupported, the shape tags already take where a backend holds no side-data. One type serves every such backend, so a refusal is never reimplemented per adapter.
type Bookmarks ¶ added in v0.27.0
type Bookmarks struct {
// contains filtered or unexported fields
}
Bookmarks is one bookmark list: entries under id_seq(i, seed) in hist, each recording an archive head in 𝒰. The first three fields are written at construction and never again, so Seed() and BookmarkId() need no lock and cannot answer nil. The rest is the bounds cache.
func NewBookmarks ¶ added in v0.27.0
NewBookmarks is a cursor over the list keyed on seed, which starts at index 0 (-> Seed). Nothing is minted here: a seed that arrives already made is what lets the field be final, where a constructor minting one would have to report failure.
func OpenBookmarks ¶ added in v0.27.0
OpenBookmarks recovers a list from the id of ANY of its entries (foundation paper §Backup): the verified record there yields the seed every entry carries, and its index seeds the search. No index is privileged — 0 may have been purged.
func (*Bookmarks) Append ¶ added in v0.27.0
Append records head as the next bookmark, signed under self. The index is one past the settled top rather than the caller's, so a write can neither skip a slot nor clobber one — which is how the list stays gapless (`R-C7BOOKMARK`, `V-BMGAPLESS`).
func (*Bookmarks) BookmarkId ¶ added in v0.27.0
BookmarkId returns the id of one entry of this list, which is the single value a bundle keeps to reopen the archive later (foundation paper §Backup). Fixed at construction, so it answers the same value from any goroutine at any time.
func (*Bookmarks) GetAtIndex ¶ added in v0.27.0
GetAtIndex returns the entry at index i; a slot outside the list's range is an error.
func (*Bookmarks) GetBulk ¶ added in v0.27.0
GetBulk returns the half-open index range [from, toExcluding).
func (*Bookmarks) Latest ¶ added in v0.27.0
Latest returns the top entry, or the zero Bookmark when the list holds none. The writer's own last Append answers it, so a commit pays for no read.
func (*Bookmarks) Len ¶ added in v0.27.0
Len returns how many entries the list holds, counting from its lowest present index.
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 ¶
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
// Bookmarks: holds 𝒰_hist, so this backend can carry an archive's locator. A
// rebuildable projection reports false — the head would be lost with the reindex.
Bookmarks 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 ¶
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 ¶
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 ¶
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.
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 answers the claim's generation number (§4.1) from the references the
// assembled claim carries: FixedHeight for a value already known, HeightsIn or
// HeightsFrom to derive it. A referencing claim must set one.
Height HeightResolver
// 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 ¶
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 ¶
func (b ClaimBuilder) WithAutoHeight(ctx context.Context, u Universe) ClaimBuilder
WithAutoHeight resolves the height against u.
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
func (b ClaimBuilder) WithHeight(h uint64) ClaimBuilder
WithHeight sets the generation number (§4.1) as a value already known — 1 + max over the referenced heights, or 0 for an initial claim. HeightsIn and HeightsFrom derive it instead. The verifier re-derives and enforces it either way.
func (ClaimBuilder) WithHeightResolver ¶ added in v0.33.0
func (b ClaimBuilder) WithHeightResolver(ctx context.Context, resolve HeightResolver) ClaimBuilder
WithHeightResolver makes Sign ask resolve for the height, against every reference the closed claim carries. For a caller whose heights live somewhere other than a Universe — a database, or claims in memory.
func (ClaimBuilder) WithInlineContent ¶
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 ¶
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 ¶
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 ¶
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 ¶
func NewConstraints(opts ...ContributionOption) Constraints
NewConstraints applies opts. The zero value is the strictest reading: every reserved type refused.
func (Constraints) AdmitBranch ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
type ContributionOption func(*Constraints)
ContributionOption sets one constraint.
func WithCreatableBranches ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
EdgeFilterFieldValue matches an edge carrying a field named Field whose value equals Value exactly. An edge lacking the field never matches.
func (EdgeFilterFieldValue) IsEdgeFilter ¶
func (f EdgeFilterFieldValue) IsEdgeFilter() bool
IsEdgeFilter reports that this filter selects edges (not nodes).
func (EdgeFilterFieldValue) MatchEdge ¶
func (f EdgeFilterFieldValue) MatchEdge(e Edge) bool
MatchEdge reports whether e carries the named field with the exact value.
func (EdgeFilterFieldValue) MatchNode ¶
func (f EdgeFilterFieldValue) MatchNode(Node) bool
MatchNode always passes — this is an edge-only filter.
type EdgeFilterType ¶
type EdgeFilterType struct {
Type string
}
EdgeFilterType matches an edge whose type ("class/sub") equals Type exactly.
func (EdgeFilterType) IsEdgeFilter ¶
func (f EdgeFilterType) IsEdgeFilter() bool
IsEdgeFilter reports that this filter selects edges (not nodes).
func (EdgeFilterType) MatchEdge ¶
func (f EdgeFilterType) MatchEdge(e Edge) bool
MatchEdge reports whether e's type ("class/sub") equals the target exactly.
func (EdgeFilterType) MatchNode ¶
func (f EdgeFilterType) MatchNode(Node) bool
MatchNode always passes — this is an edge-only filter.
type EdgeFilterTypes ¶
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 ¶
func (f EdgeFilterTypes) IsEdgeFilter() bool
IsEdgeFilter reports that this filter selects edges (not nodes).
func (EdgeFilterTypes) MatchEdge ¶
func (f EdgeFilterTypes) MatchEdge(e Edge) bool
MatchEdge reports whether e's type equals any of the target types.
func (EdgeFilterTypes) MatchNode ¶
func (f EdgeFilterTypes) MatchNode(Node) bool
MatchNode always passes — this is an edge-only filter.
type EdgeParts ¶
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 ¶
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 ¶
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 ¶
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 ¶
Failure is one verification failure: the claim that failed, its depth in the walk, and why. It is an error itself, so it travels as the cause of one: errors.Is reaches the rule through Unwrap, errors.As recovers the claim and depth.
type Field ¶
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 ¶
type Form string
Form is whether a claim is returned as written (the id-defining bytes) or resolved via its diff chain.
type GetOption ¶
type GetOption func(*getConfig)
GetOption configures a claim read (Universe.GetClaims and the package GetClaim helper).
func WithNotDiffMaterialized ¶
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 ¶
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 ¶
func NewHeightCache() *HeightCache
NewHeightCache returns an empty, ready-to-use cache.
func (*HeightCache) Get ¶
func (c *HeightCache) Get(id Id) (uint64, bool)
Get returns the cached height for id, if present.
func (*HeightCache) GetClaimHeights ¶
GetClaimHeights answers ids from the cache, loading the misses from u in one bulk DefaultGetClaimHeights and caching them.
func (*HeightCache) Note ¶
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 ¶
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 HeightResolver ¶ added in v0.33.0
HeightResolver answers the generation number (§4.1) a claim carries, given the references its assembled edge set holds — the contributor edge included, since the edge set is the input. `V-HEIGHT` fixes the answer at 1 + max over those references' heights, so a resolver that cannot reach one errors rather than treating it as height 0, which would build a claim verification refuses.
func FixedHeight ¶ added in v0.33.0
func FixedHeight(h uint64) HeightResolver
FixedHeight answers h whatever the references are — the resolver for a caller that already holds the value, and what WithHeight sets.
func HeightsFrom ¶ added in v0.33.0
func HeightsFrom(claims ...Claim) HeightResolver
HeightsFrom derives the height from claims already in hand, for a caller building against claims in memory rather than a Universe. A reference none of claims carries is reported absent, which is what catches a claim citing one the caller left out.
func HeightsIn ¶ added in v0.33.0
func HeightsIn(u Universe) HeightResolver
HeightsIn derives the height from u: 1 + max over the references' committed heights, and 0 for a claim referencing nothing.
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 IdSeq ¶ added in v0.27.0
IdSeq computes id_seq(i, s) := H(S([i, s])) (`V-IDSEQ`) — a two-element array of an unsigned integer and a byte string, which CBOR's major type alone separates from any claim's map encoding (`V-SER`).
func StrandedByDeletion ¶
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 KeyOption ¶ added in v0.32.0
type KeyOption func(*keyConfig)
KeyOption supplies what reading a key may need beyond its bytes.
func WithPassphrase ¶ added in v0.32.0
WithPassphrase decrypts an encrypted key with pass.
func WithPassphraseFrom ¶ added in v0.32.0
WithPassphraseFrom fetches the passphrase only if the key proves encrypted, so an unencrypted one never prompts, never reads an environment and never blocks.
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 is ParseKeypair over the file at path.
func ParseKeypair ¶ added in v0.31.0
ParseKeypair reads an Ed25519 PKCS#8 PEM private key and pre-computes its multikey-encoded public key. Bytes rather than a path, a key arriving as readily from an environment variable, a pipe or a paste (-> keysource).
type Limit ¶
type Limit struct {
Results int // max claims; 0 = unbounded
Time time.Duration // execution budget; 0 = none
}
Limit bounds a read.
type MergableContribution ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
type Sequencer interface {
// InGenesis reports no archive here yet, leaving Found the one operation.
InGenesis() bool
// Found creates the archive, once: the Sequencer's initial claim, the first
// contributor carrying pubkey, and the branch binding it, so the list alone
// reaches it. Returns its claim, which `V-SIG` lets only the Sequencer sign.
Found(ctx context.Context, pubkey []byte, branch string) (Claim, error)
// 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
// BookmarkId returns the id of a bookmark in this archive's list — the one
// written at bootstrap. Any single bookmark id recovers the latest recorded
// head (foundation paper §Backup), so this is what a bundle keeps to be
// reopened later via OpenBookmarks.
BookmarkId() Id
// 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: it mints the branch table (step 6)
// and takes the advance into effect against a new bookmark (step 7).
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 ¶
type Shape string
Shape is whether each result is a single item or a path (the chain to it).
type SpineItem ¶ added in v0.28.0
type SpineItem struct {
// contains filtered or unexported fields
}
SpineItem is one revision of the branch-table spine: head id, height, and creation time.
func NewSpineItem ¶ added in v0.28.0
NewSpineItem builds a SpineItem. It lets adapters outside package ranke reconstruct an item from persisted storage.
func SpliceSpine ¶ added in v0.28.0
SpliceSpine grafts tagged onto existing at tagged's first revision, dropping existing's entries from there on. An empty tagged leaves existing as is.
func TagArchive ¶
TagArchive descends a's branch-table spine and tags each revision's branch closures oldest→newest
func (SpineItem) GetRevision ¶ added in v0.28.0
GetRevision returns the entry's position in the timeline (0 is the oldest).
func (SpineItem) GetTimestamp ¶ added in v0.28.0
GetTimestamp returns the time the head was appended.
type StorageTier ¶
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 ¶
SweepResult is one sweep's outcome: the claims whose bytes were removed, and the content blobs that went with them.
func DeletePlanned ¶
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 ¶
SyncResult is a Sync outcome: SyncedTo is the branch-table claim now fully readable, nil on error, and Err the failure.
type TagArchiveOptions ¶
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
// Bookmarks returns this backend's 𝒰_hist, the second address scheme keyed on
// id_seq(i, s) rather than on a record's bytes (foundation paper §Bookmarks).
// The Universe owning it is what lets the bookmark list inherit the layering,
// replication and backup of the store beneath it (RankeDB paper §Sequencer);
// a separate port cannot, which is why there is no way to obtain one.
// Capabilities.Bookmarks false returns a store answering ErrUnsupported.
Bookmarks() BookmarkStore
// 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 ¶
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 ¶
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 ¶
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 ¶
type VerifyOption func(*verifyConfig)
VerifyOption configures a verification run.
func WithCreatedAfter ¶
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 ¶
func WithExternalContent() VerifyOption
WithExternalContent also fetches and verifies externalized content (default: inline content only — external blobs can be gigabytes).
func WithMaxClaims ¶
func WithMaxClaims(n int) VerifyOption
WithMaxClaims caps the walk at n claims processed (0 = unlimited).
func WithMaxDepth ¶
func WithMaxDepth(n int) VerifyOption
WithMaxDepth bounds the closure walk to depth n (0 = full closure).
func WithOnError ¶
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 ¶
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 ¶
func WithStopAfter(n int) VerifyOption
WithStopAfter stops the walk once n failures are found (1 = fail fast, 0 = verify everything).
func WithTrusted ¶
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 ¶
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 ¶
func VerifyRuleSet() []VerifyRule
VerifyRuleSet lists the verification rules, in application order — the menu a caller picks from when deciding what to skip.
type Where ¶
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 ¶
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 ¶
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 ¶
func (w WireConstraints) Options() []ContributionOption
Options renders the declarations as the options the contribution opens under.
type WireKind ¶
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 ¶
type WireReader struct {
// contains filtered or unexported fields
}
WireReader streams a contribution, decoding one record at a time.
func NewWireReader ¶
func NewWireReader(r io.Reader) *WireReader
NewWireReader reads a contribution stream from r.
func (*WireReader) Constraints ¶
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 ¶
func (wr *WireReader) Err() error
Err returns the first error that stopped the stream.
func (*WireReader) Next ¶
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 ¶
func (wr *WireReader) Record() WireRecord
Record returns the record Next decoded.
type WireRecord ¶
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 ¶
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 ¶
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 ¶
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 ¶
func (ww *WireWriter) WriteContent(b ContentBlob) error
WriteContent appends externalized content under its hash.
Source Files
¶
- archive.go
- bookmark.go
- bookmark_locator.go
- bookmark_store.go
- bookmarks.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
- 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
- spine_item.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
|
|
|
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 seven steps with 2–5 run in parallel off the sequencing thread, and steps 6–7 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 seven steps with 2–5 run in parallel off the sequencing thread, and steps 6–7 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/storage / 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/storage / 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, content blobs and bookmark records 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, content blobs and bookmark records 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 / bookmarks type: logic job: the partition's 𝒰_hist — every shard holds the whole bookmark list, the one place this adapter broadcasts where it would otherwise route by key limits: carries no policy beyond that choice; the record and its rules are the library's (-> partition.go, bookmark_store in the library)
|
package: partition / bookmarks type: logic job: the partition's 𝒰_hist — every shard holds the whole bookmark list, the one place this adapter broadcasts where it would otherwise route by key limits: carries no policy beyond that choice; the record and its rules are the library's (-> partition.go, bookmark_store in the library) |
|
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 / bookmarks type: logic job: the stack's 𝒰_hist — a delegating BookmarkStore that puts and gets through the same tier rules, fan-out and fall-through the claim path uses limits: carries no policy of its own; every decision is stack.go's, called not copied (-> stack.go, bookmark_store in the library)
|
package: stack / bookmarks type: logic job: the stack's 𝒰_hist — a delegating BookmarkStore that puts and gets through the same tier rules, fan-out and fall-through the claim path uses limits: carries no policy of its own; every decision is stack.go's, called not copied (-> stack.go, bookmark_store in the library) |
|
cmd
|
|
|
ranke
command
package: cmd/ranke / 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: cmd/ranke / 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: cmd/scenariodoc / 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: cmd/scenariodoc / 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: cmd/test / 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: cmd/test / 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: cmd/vectors / bookmarks type: cmd job: the 𝒰_hist cases — one valid bookmark list every implementation must open, plus a record per rule a bookmark can break: its envelope, its signature, its slot, its k, and its list's contiguity limits: builds records, not lists on disk; the head each one records comes from the conformance graph (-> graph.go)
|
package: cmd/vectors / bookmarks type: cmd job: the 𝒰_hist cases — one valid bookmark list every implementation must open, plus a record per rule a bookmark can break: its envelope, its signature, its slot, its k, and its list's contiguity limits: builds records, not lists on disk; the head each one records comes from the conformance graph (-> graph.go) |
|
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: conformance/scenarios/01_personal_graph / 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: conformance/scenarios/01_personal_graph / 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: conformance/scenarios/02_agent_analyses / 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: conformance/scenarios/02_agent_analyses / 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: conformance/scenarios/03_agent_corrects_agent / 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: conformance/scenarios/03_agent_corrects_agent / 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 |
|
package: keysource / logic type: io job: the one grammar an app resolves a key argument through — a file, an environment variable, stdin or a prompt — with the rules that keep the material off disk and off the command line limits: yields bytes and reads nothing into a key; what a PEM means is the library's (-> ranke.ParseKeypair).
|
package: keysource / logic type: io job: the one grammar an app resolves a key argument through — a file, an environment variable, stdin or a prompt — with the rules that keep the material off disk and off the command line limits: yields bytes and reads nothing into a key; what a PEM means is the library's (-> ranke.ParseKeypair). |
|
package: queries / contributors type: logic job: the reads a caller needs before it can write anything — a branch's contributors, and the one carrying a given public key limits: reads an Archive snapshot and nothing else; every helper is ordinary RQL, so this is a worked example as much as a library (-> query for the language itself)
|
package: queries / contributors type: logic job: the reads a caller needs before it can write anything — a branch's contributors, and the one carrying a given public key limits: reads an Archive snapshot and nothing else; every helper is ordinary RQL, so this is a worked example as much as a library (-> query for the language itself) |
|
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 |