Documentation
¶
Overview ¶
Package provadapter is Pasture's thin low-level adapter over the released Provenance global-journal surface (github.com/dayvidpham/provenance at dayvidpham/provenance#4/#5/#6, module pinned to main@ecc7663). It owns exactly the boundary conversions and system-actor activation that pasture#14 places between the portable protocol identity domain (pkg/protocol/portable, produced by the in-memory compiler internal/codegen/ir) and Provenance's durable identity, authority, and command-digest domains.
Scope boundary (pasture#14). This package deliberately does NOT define any pasture.* material event, effect-to-command mapping, task-closure policy, task backend semantics, timeline projection, or public CLI vocabulary — those are pasture#43, the exclusive consumer of this adapter. Everything here is a pure, side-effect-free conversion or a single-purpose registry activation against a real Provenance store; there is no split audit-store write path.
The four capabilities delivered here, each independently testable against a real Provenance store (OpenMemory / a temp-file tracker):
- refs.go: validated, round-tripping conversions between the portable AssignmentRef/TaskRef/RoleID/MutationRef/AgentRef domain and Provenance's AssignmentID/TaskID/AssignmentSlotID/OperationID/ActorID domains, rejecting wrong or empty domains without making the dependency-free portable package depend on Provenance.
- authority.go: derivation of a non-aliasing Provenance OperationAuthorityID from a portable bootstrap-agent or assignment authority, preserving authority kind/slot/task so two authorities of the SAME actor over different assignment kinds/slots/tasks can never alias to one key; plus the retained-initiating-identity -> historical ActorID resolution used for committed replay/lookup (never re-resolving whichever assignment is current).
- digest.go: byte-preserving conversion of a #43-produced ir.CanonicalCommandDigest to the raw Provenance command-digest bytes handed to LookupCommitted and Apply, with no re-canonicalization and no caller digest flag.
- actors.go: activation of the reserved pasture-system actor namespace (ordinals 0..1023, manifest-v1 ordinal zero seeded as pasture-system/default / software_agent) over a real Provenance actor-namespace registry, with the fixed big-endian ordinal-UUID wire encoding.
- facade.go: the thin Apply/LookupCommitted facade over the single Provenance journal write path (no split audit store), routing every call through the ref/authority/digest conversions above and surfacing the closed Absent/Committed/Conflict outcome with the underlying typed provenance error round-tripped for errors.Is/As.
- migrate.go: the finite serial legacy-baseline migration coordinator over MigrateLegacyBaseline — deterministic (RecordedAt, LegacyRowID) ordering, read-only source byte-hash integrity before and after, whole-batch stop-on-first-failure with typed errors round-tripped, and idempotent re-run counts surfaced.
- legacyaudit.go: the separately-named, read-only 'pasture legacy-audit event list' API over NON-TASK legacy rows, preserving raw actor text, contexts, and source identity verbatim in deterministic order — the surface #43's CLI wires (no CLI wiring here).
Index ¶
- Constants
- Variables
- func ActorIDFromAgentRef(agent portable.AgentRef) (provenance.ActorID, error)
- func AssignmentAuthorityID(assignment portable.AssignmentRef, slot portable.RoleID, task portable.TaskRef) (provenance.OperationAuthorityID, error)
- func AssignmentIDFromRef(ref portable.AssignmentRef) (provenance.AssignmentID, error)
- func AssignmentRefFromID(id provenance.AssignmentID) (portable.AssignmentRef, error)
- func BootstrapAuthorityID(agent portable.AgentRef) (provenance.OperationAuthorityID, error)
- func CommandDigestBytes(d ir.CanonicalCommandDigest) ([]byte, error)
- func HistoricalActorID(c ir.MutationContinuation, ...) (provenance.ActorID, error)
- func MutationRefFromID(op provenance.OperationID) (portable.MutationRef, error)
- func OperationIDFromRef(ref portable.MutationRef) (provenance.OperationID, error)
- func OrdinalActorID(ordinal uint64) (provenance.ActorID, error)
- func PastureSystemClaim() provenance.ActorNamespaceClaim
- func PastureSystemDefaultActorID() provenance.ActorID
- func PastureSystemDefaultEntry() provenance.FixedActorEntry
- func PastureSystemDefaultRegistration() provenance.FixedSoftwareAgentRegistration
- func RoleIDFromSlotID(slot provenance.AssignmentSlotID) (portable.RoleID, error)
- func SlotIDFromRoleID(role portable.RoleID) (provenance.AssignmentSlotID, error)
- func TaskIDFromRef(ref portable.TaskRef) (provenance.TaskID, error)
- func TaskRefFromID(id provenance.TaskID) (portable.TaskRef, error)
- func ValidateActorID(id provenance.ActorID) error
- type ActivationResult
- type ApplyRequest
- type BaselineMigrationOutcome
- type BaselineMigrationRequest
- type Journal
- type LegacyAuditEvent
- type LegacyAuditSource
- type Outcome
- type OutcomeKind
- type SourceHasher
Constants ¶
const ( // PastureSystemNamespace is the reserved namespace claimed at activation. PastureSystemNamespace = "pasture-system" // PastureSystemDefaultName is manifest-v1 ordinal zero's registered name. PastureSystemDefaultName = "pasture-system/default" // PastureSystemReservedOrdinals is the count of reserved ordinals (0..1023). PastureSystemReservedOrdinals = 1024 )
Variables ¶
var ErrSourceMutatedDuringMigration = errors.New("provadapter: legacy source mutated during migration")
ErrSourceMutatedDuringMigration is the sentinel the coordinator raises when the external source's bytes changed across the migration, violating the read-only extraction invariant (§13). It is distinct from any Provenance migration sentinel so a caller can tell an integrity breach from a domain rejection.
var PastureSystemRange = provenance.UUIDRange{ Min: [16]byte{}, Max: provenance.BigEndianUUID(pastureSystemMaxOrdinal), }
PastureSystemRange is the inclusive [0, 1023] fixed-UUID range the pasture-system namespace claims: Min is the all-zero UUID (ordinal 0) and Max is ordinal 1023 as a 16-byte big-endian value.
Functions ¶
func ActorIDFromAgentRef ¶
func ActorIDFromAgentRef(agent portable.AgentRef) (provenance.ActorID, error)
ActorIDFromAgentRef converts a portable bootstrap AgentRef to a Provenance ActorID. The AgentRef's spelling must be a valid "namespace/uuid" wire form. This is the one-directional bootstrap-actor resolution the authority and continuation paths reuse; there is no reverse ActorID -> AgentRef helper because a live ActorID is not, by itself, a portable bootstrap-agent identity.
func AssignmentAuthorityID ¶
func AssignmentAuthorityID(assignment portable.AssignmentRef, slot portable.RoleID, task portable.TaskRef) (provenance.OperationAuthorityID, error)
AssignmentAuthorityID derives the non-aliasing OperationAuthorityID for a portable assignment authority, preserving the assignment episode identity, its responsibility slot, and its task. Two authorities of the same actor over a different slot, a different task, or a different (predecessor/successor) assignment yield distinct keys and therefore cannot alias.
func AssignmentIDFromRef ¶
func AssignmentIDFromRef(ref portable.AssignmentRef) (provenance.AssignmentID, error)
AssignmentIDFromRef converts a portable AssignmentRef to a Provenance AssignmentID (the opaque, transition-invariant responsibility-episode identity).
func AssignmentRefFromID ¶
func AssignmentRefFromID(id provenance.AssignmentID) (portable.AssignmentRef, error)
AssignmentRefFromID converts a Provenance AssignmentID back to a portable AssignmentRef. It round-trips exactly with AssignmentIDFromRef.
func BootstrapAuthorityID ¶
func BootstrapAuthorityID(agent portable.AgentRef) (provenance.OperationAuthorityID, error)
BootstrapAuthorityID derives the non-aliasing OperationAuthorityID for a portable bootstrap-agent authority (the genesis/system root an operation executes under). It shares no key space with any assignment authority.
func CommandDigestBytes ¶
func CommandDigestBytes(d ir.CanonicalCommandDigest) ([]byte, error)
CommandDigestBytes returns the raw Provenance command-digest bytes for a #43-produced ir.CanonicalCommandDigest, byte-for-byte preserving the digest #43 computed. The result is the exact input to Journal.Apply's OperationInput.CommandDigest and to the LookupCommitted lookup key. A zero/invalid digest is rejected: an empty digest must never stand in for a missing resolved command.
func HistoricalActorID ¶
func HistoricalActorID( c ir.MutationContinuation, resolveAssignment func(portable.AssignmentRef) (provenance.ActorID, error), ) (provenance.ActorID, error)
HistoricalActorID resolves a completed MutationContinuation's retained initiating identity to the historical ActorID used for its committed replay/lookup. It uses the identity the continuation RETAINED at initiation and never re-resolves whichever assignment happens to be current later: a bootstrap continuation resolves its retained AgentRef directly; an assignment continuation resolves its retained AssignmentRef through the caller-supplied resolveAssignment (the historical-occupant lookup), which #43 backs with a point-in-time store query keyed on the retained ref — not the live owner.
func MutationRefFromID ¶
func MutationRefFromID(op provenance.OperationID) (portable.MutationRef, error)
MutationRefFromID converts a Provenance OperationID back to a portable MutationRef. It round-trips exactly with OperationIDFromRef.
func OperationIDFromRef ¶
func OperationIDFromRef(ref portable.MutationRef) (provenance.OperationID, error)
OperationIDFromRef converts a portable MutationRef to a Provenance OperationID (the caller-supplied idempotency alternate key). The MutationRef identifies one logical stateful invocation across retries; a stable ref maps to a stable OperationID, which is exactly what Apply's replay short-circuit keys on.
func OrdinalActorID ¶
func OrdinalActorID(ordinal uint64) (provenance.ActorID, error)
OrdinalActorID returns the fixed pasture-system ActorID for a reserved ordinal in [0, 1023]. The UUID is the ordinal rendered big-endian into 16 bytes with no version/variant bits, so ordinal zero is the all-zero (uuid.Nil) UUID. An ordinal at or beyond 1024 is rejected: it lies outside the claimed range.
func PastureSystemClaim ¶
func PastureSystemClaim() provenance.ActorNamespaceClaim
PastureSystemClaim is the exact ActorNamespaceClaim activation registers. Its fields are fixed, so an exact re-activation is idempotent and any drift in a stored claim of the same namespace is detectable field-by-field.
func PastureSystemDefaultActorID ¶
func PastureSystemDefaultActorID() provenance.ActorID
PastureSystemDefaultActorID is manifest-v1 ordinal zero: the all-zero-UUID pasture-system/default identity. It is the default committing actor for system-authored operations (e.g. legacy-baseline migration).
func PastureSystemDefaultEntry ¶
func PastureSystemDefaultEntry() provenance.FixedActorEntry
PastureSystemDefaultEntry is the fixed-actor manifest entry activation seeds for ordinal zero: pasture-system/default, kind software_agent.
func PastureSystemDefaultRegistration ¶
func PastureSystemDefaultRegistration() provenance.FixedSoftwareAgentRegistration
PastureSystemDefaultRegistration is the complete atomic activation request for manifest-v1 ordinal zero. The manifest and software-agent names intentionally match so every public actor lookup returns the same durable identity.
func RoleIDFromSlotID ¶
func RoleIDFromSlotID(slot provenance.AssignmentSlotID) (portable.RoleID, error)
RoleIDFromSlotID converts a Provenance AssignmentSlotID back to a portable RoleID. It round-trips exactly with SlotIDFromRoleID.
func SlotIDFromRoleID ¶
func SlotIDFromRoleID(role portable.RoleID) (provenance.AssignmentSlotID, error)
SlotIDFromRoleID converts a portable RoleID to a Provenance AssignmentSlotID (the responsibility-slot domain; see the package NOTE on AssignmentRoleID).
func TaskIDFromRef ¶
func TaskIDFromRef(ref portable.TaskRef) (provenance.TaskID, error)
TaskIDFromRef converts a portable TaskRef to a Provenance TaskID. The TaskRef's spelling must be a valid "namespace/uuid" wire form; a portable reference that is not a task identity (wrong domain) is rejected.
func TaskRefFromID ¶
func TaskRefFromID(id provenance.TaskID) (portable.TaskRef, error)
TaskRefFromID converts a Provenance TaskID back to a portable TaskRef. It round-trips exactly with TaskIDFromRef.
func ValidateActorID ¶
func ValidateActorID(id provenance.ActorID) error
ValidateActorID rejects a structurally invalid ActorID: the zero value (empty namespace) is never a usable identity, while a namespaced all-zero UUID (the pasture-system/default identity) is valid. This is the boundary check the adapter applies before handing an actor to a store call.
Types ¶
type ActivationResult ¶
type ActivationResult struct {
DefaultActorID provenance.ActorID
}
ActivationResult identifies the exact default actor installed by activation. Success means the namespace claim, software-agent rows, and manifest entry all exist atomically; callers do not need a race-prone fresh-versus-retry flag.
func ActivatePastureSystem ¶
func ActivatePastureSystem(tr provenance.Tracker) (ActivationResult, error)
ActivatePastureSystem atomically claims the pasture-system namespace, reserves fixed-UUID ordinals 0..1023, and installs only ordinal zero as the fixed pasture-system/default software agent. Exact retries are inert, claim-only persisted state is repaired, and any claim, actor, or manifest conflict aborts without partial writes. Ordinals 1..1023 remain unmaterialized.
type ApplyRequest ¶
type ApplyRequest struct {
// Mutation is the portable idempotency handle for this logical operation; it
// converts to the Provenance OperationID the §9.4 replay short-circuit keys on,
// so a stable Mutation across retries is a stable OperationID.
Mutation portable.MutationRef
// Actor is the already-resolved committing actor of the whole operation (§2.1):
// the pasture-system default from activation, or a historical actor from
// HistoricalActorID. It is validated with ValidateActorID before the store call.
Actor provenance.ActorID
// Authority is the JournalID of the bootstrap/assignment authority this
// operation executes under; nil marks a genesis operation whose sole effect is
// one bootstrap authority (§4.6, §10 rule 6).
Authority *provenance.JournalID
// Command is the #43-produced canonical command digest; the facade maps it
// byte-preservingly to the Provenance CommandDigest with no re-canonicalization
// and no caller digest flag (digest.go).
Command ir.CanonicalCommandDigest
// RecordedAt is the caller-supplied wall-clock stamp copied onto the operation
// anchor for audit/display only (§12); it never establishes causality or order.
RecordedAt int64
// Effects is the caller-validated, #43-produced operation body folded in slice
// order (§9.3.1). The facade neither defines nor interprets it.
Effects []provenance.Effect
}
ApplyRequest is one logical operation expressed in the adapter's boundary vocabulary. The facade converts Mutation and Command through the adapter's own conversions (OperationIDFromRef, CommandDigestBytes) and validates Actor before touching the journal; Effects are the caller-validated, #43-produced operation body passed through opaquely.
type BaselineMigrationOutcome ¶
type BaselineMigrationOutcome struct {
Result provenance.MigrationResult
OrderedRowIDs []provenance.TaskID
SourceUnchanged bool
}
BaselineMigrationOutcome reports how a coordinated migration resolved. Result is the released whole-batch MigrationResult (fresh vs short-circuited anchor counts, §13); OrderedRowIDs is the deterministic (RecordedAt, LegacyRowID) presentation order the coordinator applied; SourceUnchanged is true once the post-migration source hash matched the pre-migration hash.
func RunBaselineMigration ¶
func RunBaselineMigration(j provenance.Journal, req BaselineMigrationRequest, hashSource SourceHasher) (BaselineMigrationOutcome, error)
RunBaselineMigration drives one finite, deterministic, read-only-verified legacy-baseline migration over the pinned Provenance MigrateLegacyBaseline. It sorts the rows by (RecordedAt, LegacyRowID), hashes the source before and after, runs the whole-batch migration, and re-verifies source integrity on both the success and failure paths.
On a Provenance migration rejection (unmappable owner, schema mismatch, injected fault) the batch commits nothing and the typed error is returned verbatim for errors.Is/As; the coordinator still re-checks source integrity so a caller learns if a partial/aborted run somehow perturbed the source. On success the returned outcome carries the whole-batch MigrationResult and SourceUnchanged=true.
type BaselineMigrationRequest ¶
type BaselineMigrationRequest struct {
// System is the migration's committing actor (the pasture-system actor, §2.1),
// validated with ValidateActorID before the batch runs.
System provenance.ActorID
// BootstrapAuthority is the genesis-established bootstrap authority JournalID the
// per-task baseline anchors execute under (§4.6, §13).
BootstrapAuthority provenance.JournalID
// Owners resolves a legacy owner string to a registered ActorID. A non-empty
// legacy owner absent from this map fails the WHOLE batch (§13 item 4).
Owners map[string]provenance.ActorID
// Rows are the legacy task rows to migrate, in any input order.
Rows []provenance.LegacyTaskRow
}
BaselineMigrationRequest is the coordinator's whole-batch request. It mirrors the released provenance.MigrationInput but names the committing system actor and the established genesis bootstrap authority explicitly, and takes the legacy rows in any order (the coordinator sorts them deterministically before presenting them).
type Journal ¶
type Journal struct {
// contains filtered or unexported fields
}
Journal is the thin facade over a single Provenance Journal. Construct it with NewJournal over the Journal from an open Provenance tracker; every mutation flows through the one underlying journal, so there is no split write path.
func NewJournal ¶
func NewJournal(api provenance.Journal) (*Journal, error)
NewJournal wraps a Provenance Journal (e.g. Tracker.Journal()) in the facade. A nil api is rejected so the failure surfaces at construction rather than as a nil-dereference on the first call.
func (*Journal) Apply ¶
func (j *Journal) Apply(req ApplyRequest) (Outcome, error)
Apply commits one logical operation atomically through the single journal write path (§9.5). It converts the mutation reference to an OperationID, the canonical command digest to raw Provenance command-digest bytes, and validates the committing actor, then folds the caller's effects in one operation. It returns:
- OutcomeCommitted, nil — the operation committed (fresh) or replayed idempotently (Committed.ShortCircuited is true on a §9.4 replay).
- OutcomeConflict, err — the OperationID was reused with a differing four-field identity (§11); nothing was committed and err wraps provenance.ErrOperationConflict for errors.Is/As recovery.
- zero Outcome, err — a boundary conversion or journal error (validation, authority scope, genesis discipline, …), returned verbatim.
func (*Journal) LookupCommitted ¶
func (j *Journal) LookupCommitted(mutation portable.MutationRef) (Outcome, error)
LookupCommitted returns the side-effect-free committed result for a mutation reference (§9.4). It converts the reference to an OperationID and reads the journal, returning OutcomeAbsent for a never-applied operation (nil error, no side effects) or OutcomeCommitted with the reconstructed result. It never returns OutcomeConflict: a lookup compares no identity, so an absent and a committed result are the only closed variants (§3.2).
type LegacyAuditEvent ¶
type LegacyAuditEvent struct {
// LegacyRowID is the row's identity within its source table; it is the
// total-order tiebreak in the deterministic listing order.
LegacyRowID string
// SourceTable is the source-identity qualifier the row was extracted from, kept
// so #43 can attribute a raw row to its origin.
SourceTable string
// RecordedAt is the row's original recorded wall-clock time; it is the primary
// key of the deterministic (RecordedAt, LegacyRowID) listing order.
RecordedAt time.Time
// RawActor is the legacy actor text exactly as stored — uninterpreted and
// unresolved. An empty string is preserved as an empty string.
RawActor string
// RawContexts are the original context strings in source order, preserved
// verbatim (never deduplicated or reordered).
RawContexts []string
// Payload is the opaque source payload, byte-preserved. It is copied defensively
// on extraction so the returned event cannot alias the source's buffer.
Payload json.RawMessage
}
LegacyAuditEvent is one raw non-task legacy audit row, preserved verbatim for #43's typed import. Every field is the source's original value with no interpretation: RawActor keeps the legacy actor string exactly (it is NOT resolved to an ActorID here — an unmapped legacy actor is a first-class value), RawContexts keeps the original context strings in source order, Payload is the opaque source bytes byte-preserved, and SourceTable + LegacyRowID together are the row's source identity.
func ListLegacyAuditEvents ¶
func ListLegacyAuditEvents(src LegacyAuditSource) ([]LegacyAuditEvent, error)
ListLegacyAuditEvents extracts all non-task legacy audit rows from src read-only and returns them in the deterministic (RecordedAt, LegacyRowID) display order, preserving each row's raw actor text, contexts, and source identity verbatim. It is the API #43's CLI wires; it performs no import, no normalisation, and no CLI I/O.
The returned slice is a fresh, independently-owned copy: RawContexts and Payload are deep-copied so a caller mutating the result can never reach back into the source's buffers, keeping the extraction strictly read-only.
type LegacyAuditSource ¶
type LegacyAuditSource interface {
// ExtractLegacyAuditEvents returns every non-task legacy audit row read-only, in
// any order. It must not mutate the source. An extraction failure is returned as
// an error, which ListLegacyAuditEvents surfaces verbatim.
ExtractLegacyAuditEvents() ([]LegacyAuditEvent, error)
}
LegacyAuditSource is the read-only extractor #43's CLI supplies for the concrete pre-journal audit source (the released Provenance surface does not own the legacy audit schema, so the source is provided by the caller). The coordinator calls it exactly once per listing and never mutates it.
type Outcome ¶
type Outcome struct {
Kind OutcomeKind
Committed provenance.CommittedResult
Conflict *provenance.OperationConflict
}
Outcome is the closed result of a facade Apply or LookupCommitted. Committed carries the underlying provenance.CommittedResult verbatim (anchor JournalID, the emitted task-event closure in JournalID order, and the slot-keyed result bindings) for the OutcomeCommitted case; Conflict carries the typed provenance.OperationConflict for the OutcomeConflict case. Both are the exact values Provenance returned — the facade re-shapes only the discriminator, never the payload.
type OutcomeKind ¶
type OutcomeKind int
OutcomeKind is the closed variant of a facade Apply/LookupCommitted result. It is a 1:1 mirror of provenance.CommittedResultKind, re-expressed in the adapter's own vocabulary so callers switch on a total, exhaustive set.
const ( // OutcomeAbsent: no committed operation exists for the mutation reference. // LookupCommitted returns this with a nil error and no side effects; Apply // never returns it (a fresh Apply either commits or conflicts). OutcomeAbsent OutcomeKind = iota // OutcomeCommitted: the operation is committed. For a fresh Apply it is the // just-folded result; for a replayed Apply or a LookupCommitted it is the // reconstructed already-committed result (Committed.ShortCircuited distinguishes // an idempotent Apply replay). OutcomeCommitted // OutcomeConflict: the mutation reference was reused with a differing four-field // replay identity (§11). Only Apply produces it; nothing was committed. OutcomeConflict )
func (OutcomeKind) String ¶
func (k OutcomeKind) String() string
type SourceHasher ¶
SourceHasher returns a stable byte digest of the external pre-journal source the migration reads from. The coordinator calls it immediately before and after the migration and requires byte-equality, so it must be a deterministic function of the source's persisted bytes (e.g. a hash of the ordered legacy rows or a content hash of the source tables). It reads only; it must never mutate the source.