provenance

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2026 License: MIT Imports: 10 Imported by: 0

README

Provenance

A task dependency tracker with full PROV-O lineage for multi-agent workflows.

Provenance tracks work products, their dependencies, and their provenance across planning and implementation phases. It models three PROV-DM core types -- Entities (tasks), Agents (human/ML/software), and Activities -- connected by typed edges that record both dependencies and lineage.

Backed by SQLite (pure Go, no cgo). Uses bestiary as its ML model catalog (110+ models from models.dev).

Install

go get github.com/dayvidpham/provenance

Example

tr, _ := provenance.OpenMemory()
defer tr.Close()

// Create a task
task, _ := tr.Create("my-project", "Implement feature X", "",
    provenance.TaskTypeFeature, provenance.PriorityHigh, provenance.PhaseRequest)

// Register an ML agent from the bestiary catalog
agent, _ := tr.RegisterMLAgent("my-project",
    provenance.RoleArchitect, provenance.ProviderAnthropic,
    provenance.ModelID("claude-opus-4-6"))

// Track provenance: task attributed to agent
tr.AddEdge(task.ID, agent.ID.String(), provenance.EdgeAttributedTo)

Demo

go run ./cmd/demo

Exercises the full stack: bestiary catalog exploration, multi-provider agent registration (Anthropic + Google), PROV-O lineage edges, and persistence across sessions.

Documentation

  • CONCEPTS.md -- domain model, PROV-O/PROV-DM alignment, edge semantics, all type definitions
  • CONTRIBUTING.md -- development workflow, testing, commit conventions
  • CLAUDE.md -- coding standards, directory structure, quality gates

Development

Requires Go 1.24+. Nix optional for reproducible toolchain:

nix develop             # enters devshell with Go, gopls, ast-grep, delve

make fmt                # gofmt
make lint               # go vet + ast-grep
make test               # CGO_ENABLED=1 go test -race -count=1 ./...
make build              # CGO_ENABLED=0 go build ./...

License

MIT -- see LICENSE.

Documentation

Overview

Package provenance provides a task dependency tracker for multi-agent workflows.

Provenance replaces Beads (bd) as the task dependency tracker for the Aura Protocol agent system. It tracks work products, their dependencies, and their provenance across multi-agent planning and implementation workflows.

The package exposes a Tracker interface with methods to create, retrieve, update, and delete tasks. It also supports edges (dependencies), comments, and labels on tasks.

All entity IDs follow the format {Namespace}--{UUIDv7} for scoping and global uniqueness.

Index

Constants

View Source
const (
	StatusOpen       = ptypes.StatusOpen
	StatusInProgress = ptypes.StatusInProgress
	StatusClosed     = ptypes.StatusClosed
)

Status constants

View Source
const (
	PriorityCritical = ptypes.PriorityCritical
	PriorityHigh     = ptypes.PriorityHigh
	PriorityMedium   = ptypes.PriorityMedium
	PriorityLow      = ptypes.PriorityLow
	PriorityBacklog  = ptypes.PriorityBacklog
)

Priority constants

View Source
const (
	TaskTypeBug     = ptypes.TaskTypeBug
	TaskTypeFeature = ptypes.TaskTypeFeature
	TaskTypeTask    = ptypes.TaskTypeTask
	TaskTypeEpic    = ptypes.TaskTypeEpic
	TaskTypeChore   = ptypes.TaskTypeChore
)

TaskType constants

View Source
const (
	EdgeBlockedBy      = ptypes.EdgeBlockedBy
	EdgeDerivedFrom    = ptypes.EdgeDerivedFrom
	EdgeSupersedes     = ptypes.EdgeSupersedes
	EdgeDiscoveredFrom = ptypes.EdgeDiscoveredFrom
	EdgeGeneratedBy    = ptypes.EdgeGeneratedBy
	EdgeAttributedTo   = ptypes.EdgeAttributedTo
)

EdgeKind constants

View Source
const (
	AgentKindHuman           = ptypes.AgentKindHuman
	AgentKindMachineLearning = ptypes.AgentKindMachineLearning
	AgentKindSoftware        = ptypes.AgentKindSoftware
)

AgentKind constants

View Source
const (
	ProviderAnthropic = ptypes.ProviderAnthropic
	ProviderGoogle    = ptypes.ProviderGoogle
	ProviderOpenAI    = ptypes.ProviderOpenAI
	ProviderLocal     = ptypes.ProviderLocal
)

Provider constants

View Source
const (
	RoleHuman      = ptypes.RoleHuman
	RoleArchitect  = ptypes.RoleArchitect
	RoleSupervisor = ptypes.RoleSupervisor
	RoleWorker     = ptypes.RoleWorker
	RoleReviewer   = ptypes.RoleReviewer
)

Role constants

View Source
const (
	PhaseRequest      = ptypes.PhaseRequest
	PhaseElicit       = ptypes.PhaseElicit
	PhasePropose      = ptypes.PhasePropose
	PhaseReview       = ptypes.PhaseReview
	PhasePlanUAT      = ptypes.PhasePlanUAT
	PhaseRatify       = ptypes.PhaseRatify
	PhaseHandoff      = ptypes.PhaseHandoff
	PhaseImplPlan     = ptypes.PhaseImplPlan
	PhaseWorkerSlices = ptypes.PhaseWorkerSlices
	PhaseCodeReview   = ptypes.PhaseCodeReview
	PhaseImplUAT      = ptypes.PhaseImplUAT
	PhaseLanding      = ptypes.PhaseLanding
	PhaseUnscoped     = ptypes.PhaseUnscoped
)

Phase constants

View Source
const (
	StageNotStarted = ptypes.StageNotStarted
	StageInProgress = ptypes.StageInProgress
	StageBlocked    = ptypes.StageBlocked
	StageComplete   = ptypes.StageComplete
)

Stage constants

Variables

View Source
var (
	ErrNotFound          = ptypes.ErrNotFound
	ErrCycleDetected     = ptypes.ErrCycleDetected
	ErrAlreadyClosed     = ptypes.ErrAlreadyClosed
	ErrInvalidID         = ptypes.ErrInvalidID
	ErrAgentKindMismatch = ptypes.ErrAgentKindMismatch
)
View Source
var DefaultNamespace = namespace.DefaultNamespace

DefaultNamespace derives a namespace URI from the current git repo's remote URL, falling back to a file:// URI of the working directory. See namespace.DefaultNamespace for full documentation.

View Source
var ErrNoRemote = namespace.ErrNoRemote

ErrNoRemote is returned by FromGitRemote when the remote URL is empty. See namespace.ErrNoRemote for full documentation.

View Source
var FromDirectory = namespace.FromDirectory

FromDirectory returns a file:// URI for the given directory path. See namespace.FromDirectory for full documentation.

View Source
var FromGitRemote = namespace.FromGitRemote

FromGitRemote normalizes a git remote URL to a canonical HTTPS URI. See namespace.FromGitRemote for full documentation.

Functions

func DefaultModelRegistry

func DefaultModelRegistry() ptypes.ModelRegistry

DefaultModelRegistry returns the model registry backed by bestiary. It uses bestiary.Models() as the single source of truth.

func NewRegistry

func NewRegistry(entries []ModelEntry) ptypes.ModelRegistry

NewRegistry creates a ModelRegistry from the given entries. Use this for custom or test registries.

func RegistryFromBestiary

func RegistryFromBestiary(models []bestiary.ModelInfo) ptypes.ModelRegistry

RegistryFromBestiary converts bestiary model data into a provenance ModelRegistry. Only Provider, Name (as ModelID), DisplayName, and Family are extracted.

Types

type Activity

type Activity = ptypes.Activity

Entity types

type ActivityID

type ActivityID = ptypes.ActivityID

ID types

func ParseActivityID

func ParseActivityID(s string) (ActivityID, error)

ParseActivityID parses "namespace--uuid" into an ActivityID. See ptypes.ParseActivityID for full documentation.

type Agent

type Agent = ptypes.Agent

Entity types

type AgentID

type AgentID = ptypes.AgentID

ID types

func ParseAgentID

func ParseAgentID(s string) (AgentID, error)

ParseAgentID parses "namespace--uuid" into an AgentID. See ptypes.ParseAgentID for full documentation.

type AgentKind

type AgentKind = ptypes.AgentKind

Enum types

type Comment

type Comment = ptypes.Comment

Entity types

type CommentID

type CommentID = ptypes.CommentID

ID types

func ParseCommentID

func ParseCommentID(s string) (CommentID, error)

ParseCommentID parses "namespace--uuid" into a CommentID. See ptypes.ParseCommentID for full documentation.

type Edge

type Edge = ptypes.Edge

Entity types

type EdgeKind

type EdgeKind = ptypes.EdgeKind

Enum types

type HumanAgent

type HumanAgent = ptypes.HumanAgent

Entity types

type Label

type Label = ptypes.Label

Entity types

type ListFilter

type ListFilter = ptypes.ListFilter

Supporting types

type MLAgent

type MLAgent = ptypes.MLAgent

Entity types

type MLModel

type MLModel = ptypes.MLModel

Entity types

type ModelEntry

type ModelEntry = ptypes.ModelEntry

Model registry types

type ModelID

type ModelID = ptypes.ModelID

Model registry types

type ModelRegistry

type ModelRegistry = ptypes.ModelRegistry

Model registry types

type Option

type Option func(*options)

Option configures a Tracker at creation time.

func WithModelRegistry

func WithModelRegistry(r ptypes.ModelRegistry) Option

WithModelRegistry overrides the default model registry used to seed the ml_models table and validate model names at registration time. A nil registry is ignored (the default is preserved).

type Phase

type Phase = ptypes.Phase

Enum types

type Priority

type Priority = ptypes.Priority

Enum types

type Provider

type Provider = ptypes.Provider

Enum types

type Role

type Role = ptypes.Role

Enum types

type SoftwareAgent

type SoftwareAgent = ptypes.SoftwareAgent

Entity types

type Stage

type Stage = ptypes.Stage

Enum types

type Status

type Status = ptypes.Status

Enum types

type Task

type Task = ptypes.Task

Entity types

type TaskID

type TaskID = ptypes.TaskID

ID types

func ParseTaskID

func ParseTaskID(s string) (TaskID, error)

ParseTaskID parses "namespace--uuid" into a TaskID. See ptypes.ParseTaskID for full documentation.

type TaskType

type TaskType = ptypes.TaskType

Enum types

type Tracker

type Tracker interface {
	// Close releases all resources held by the tracker.
	// It is safe to call Close multiple times.
	Close() error

	// Create creates a new task. A UUIDv7 TaskID with the given namespace is
	// assigned automatically. Returns ErrInvalidID if namespace is empty.
	Create(namespace, title, description string, taskType TaskType, priority Priority, phase Phase) (Task, error)

	// Show retrieves a task by ID.
	// Returns ErrNotFound if no task with that ID exists.
	Show(id TaskID) (Task, error)

	// Update applies partial updates to a task. Only non-nil fields in fields
	// are written. Returns ErrNotFound if the task does not exist.
	Update(id TaskID, fields UpdateFields) (Task, error)

	// CloseTask marks a task as closed with the given reason.
	// Returns ErrNotFound if the task does not exist.
	// Returns ErrAlreadyClosed if the task is already closed.
	CloseTask(id TaskID, reason string) (Task, error)

	// List returns tasks matching the filter. An empty ListFilter returns all
	// tasks ordered by creation time (ascending).
	List(filter ListFilter) ([]Task, error)

	// AddEdge creates a typed edge from sourceID to targetID.
	// For EdgeBlockedBy: cycle detection is enforced; returns ErrCycleDetected
	// if the edge would introduce a cycle.
	// For other kinds: the edge is inserted directly without cycle checking.
	AddEdge(sourceID TaskID, targetID string, kind EdgeKind) error

	// RemoveEdge deletes the edge from sourceID to targetID with the given kind.
	// Returns nil if the edge did not exist.
	RemoveEdge(sourceID TaskID, targetID string, kind EdgeKind) error

	// Edges returns all edges originating from id.
	// If kind is non-nil, only edges of that kind are returned.
	Edges(id TaskID, kind *EdgeKind) ([]Edge, error)

	// Blocked returns tasks that are not closed and have at least one open blocker.
	Blocked() ([]Task, error)

	// Ready returns tasks that are not closed and have no open blockers.
	Ready() ([]Task, error)

	// DepTree returns all blocked-by edges reachable from id via depth-first
	// traversal. The result is in DFS order.
	DepTree(id TaskID) ([]Edge, error)

	// Ancestors returns all tasks that transitively block the given task.
	// In the blocked-by graph, A→B means "A is blocked by B". Ancestors of A
	// are B and everything B transitively waits for.
	// The given task itself is never included. Returns empty slice if none.
	Ancestors(id TaskID) ([]Task, error)

	// Descendants returns all tasks that are transitively waiting for the given
	// task to complete.
	// In the blocked-by graph, A→B means "A is blocked by B". Descendants of B
	// are A and everything that transitively depends on A.
	// The given task itself is never included. Returns empty slice if none.
	Descendants(id TaskID) ([]Task, error)

	// AddLabel attaches a label to a task. Idempotent.
	AddLabel(id TaskID, label string) error

	// RemoveLabel detaches a label from a task. Idempotent.
	RemoveLabel(id TaskID, label string) error

	// Labels returns all labels attached to a task.
	Labels(id TaskID) ([]string, error)

	// AddComment adds a comment to a task authored by authorID.
	// Returns ErrNotFound if the task or author agent does not exist.
	AddComment(id TaskID, authorID AgentID, body string) (Comment, error)

	// Comments returns all comments on a task in chronological order.
	Comments(id TaskID) ([]Comment, error)

	// RegisterHumanAgent registers a new human agent with a UUIDv7 ID.
	RegisterHumanAgent(namespace, name, contact string) (HumanAgent, error)

	// RegisterMLAgent registers a new ML agent. The (provider, modelName) pair
	// must exist in the ml_models seed table; returns ErrNotFound if unknown.
	RegisterMLAgent(namespace string, role Role, provider Provider, modelName ModelID) (MLAgent, error)

	// RegisterSoftwareAgent registers a new software agent with a UUIDv7 ID.
	RegisterSoftwareAgent(namespace, name, version, source string) (SoftwareAgent, error)

	// Agent returns the base agent (kind only) by ID.
	// Returns ErrNotFound if the agent does not exist.
	Agent(id AgentID) (Agent, error)

	// HumanAgent returns the human agent by ID.
	// Returns ErrNotFound if not found; ErrAgentKindMismatch if the agent is
	// a different kind.
	HumanAgent(id AgentID) (HumanAgent, error)

	// MLAgent returns the ML agent by ID.
	// Returns ErrNotFound if not found; ErrAgentKindMismatch if the agent is
	// a different kind.
	MLAgent(id AgentID) (MLAgent, error)

	// SoftwareAgent returns the software agent by ID.
	// Returns ErrNotFound if not found; ErrAgentKindMismatch if the agent is
	// a different kind.
	SoftwareAgent(id AgentID) (SoftwareAgent, error)

	// StartActivity records the start of an activity for the given agent.
	// A UUIDv7 ActivityID is assigned automatically.
	StartActivity(agentID AgentID, phase Phase, stage Stage, notes string) (Activity, error)

	// StartActivityWithID records the start of an activity using a
	// caller-supplied ActivityID, idempotently: a second call with the same id
	// is a no-op (INSERT ... ON CONFLICT(id) DO NOTHING) returning the existing
	// row. Use a deterministic id (e.g. a name-based UUIDv5 over the caller's
	// logical identity) to make activity emission safe to replay, e.g. across
	// durable-workflow recovery. Returns the canonical persisted activity.
	StartActivityWithID(id ActivityID, agentID AgentID, phase Phase, stage Stage, notes string) (Activity, error)

	// EndActivity records the end time of an activity.
	// Returns ErrNotFound if the activity does not exist.
	EndActivity(id ActivityID) (Activity, error)

	// Activities returns all activities, optionally filtered by agent.
	// Pass nil to return activities for all agents.
	Activities(agentID *AgentID) ([]Activity, error)
}

Tracker is the central API for Provenance task management. All methods are safe for concurrent use. Use OpenSQLite or OpenMemory to obtain an implementation.

func OpenMemory

func OpenMemory(opts ...Option) (Tracker, error)

OpenMemory creates a Tracker backed by an in-memory SQLite database. Useful for tests and ephemeral sessions. The database is destroyed when the Tracker is closed.

func OpenSQLite

func OpenSQLite(dbPath string, opts ...Option) (Tracker, error)

OpenSQLite creates a Tracker backed by a SQLite database at dbPath. The database file and parent directories are created if they do not exist. The schema is applied on every open (idempotent).

Use WithModelRegistry to override the default model registry:

tr, err := provenance.OpenSQLite(path,
	provenance.WithModelRegistry(provenance.RegistryFromBestiary(bestiary.Models())))

type UpdateFields

type UpdateFields = ptypes.UpdateFields

Supporting types

Directories

Path Synopsis
cmd
demo command
Command demo exercises the full provenance + bestiary integration stack.
Command demo exercises the full provenance + bestiary integration stack.
internal
graph
Package graph provides the dominikbraun/graph.Store adapter backed by the Provenance SQLite database.
Package graph provides the dominikbraun/graph.Store adapter backed by the Provenance SQLite database.
helpers
Package helpers provides graph traversal utilities for the Provenance blocked-by dependency graph.
Package helpers provides graph traversal utilities for the Provenance blocked-by dependency graph.
sqlite
Package sqlite provides the SQLite persistence layer for the Provenance task dependency tracker.
Package sqlite provides the SQLite persistence layer for the Provenance task dependency tracker.
testutil
Package testutil provides shared test fixtures and helpers for Provenance internal packages.
Package testutil provides shared test fixtures and helpers for Provenance internal packages.
pkg
namespace
Package namespace derives PROV-O namespace URIs from git repository metadata.
Package namespace derives PROV-O namespace URIs from git repository metadata.
ptypes
Package ptypes provides the public type definitions for the Provenance task dependency tracker.
Package ptypes provides the public type definitions for the Provenance task dependency tracker.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL