ptypes

package
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: 5 Imported by: 0

Documentation

Overview

Package ptypes provides the public type definitions for the Provenance task dependency tracker. It contains all enum types, ID types, entity structs, supporting types, and sentinel errors.

This package imports bestiary to support Provider.IsValid() catalog membership checks. It is NOT zero-dependency — bestiary is a direct dependency. This reverses the FIX-4 architectural decision from the prior wave (UAT-2), which had imposed a zero-dep constraint on pkg/ptypes.

Consumers of the library should continue to use the root "github.com/dayvidpham/provenance" package, which re-exports everything from ptypes via transparent type aliases.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound is returned when a requested entity does not exist.
	// This occurs in Show, Update, CloseTask, RemoveEdge, HumanAgent, MLAgent,
	// SoftwareAgent, and AddComment when the task/agent/activity ID is unknown.
	ErrNotFound = error(errSentinel("provenance: entity not found"))

	// ErrCycleDetected is returned when adding a blocked-by edge would
	// create a cycle in the dependency graph.
	// This is returned by AddEdge with EdgeBlockedBy when the proposed
	// edge would form a cycle. To fix: recheck the dependency direction —
	// the target (child) must be work that finishes BEFORE the source (parent).
	ErrCycleDetected = error(errSentinel("provenance: dependency cycle detected"))

	// ErrAlreadyClosed is returned when attempting to close an already-closed task.
	// To fix: check the task's Status before calling CloseTask, or use Update
	// to reopen the task first.
	ErrAlreadyClosed = error(errSentinel("provenance: task is already closed"))

	// ErrInvalidID is returned when a string cannot be parsed as a valid ID.
	// The expected wire format is "namespace--uuidv7".
	// To fix: ensure the ID string was produced by TaskID.String(), AgentID.String(),
	// ActivityID.String(), or CommentID.String(), or that the namespace is non-empty
	// and the UUID portion is a valid v7 UUID.
	ErrInvalidID = error(errSentinel("provenance: invalid ID format"))

	// ErrAgentKindMismatch is returned when querying a typed agent with the wrong kind.
	// For example, calling HumanAgent() on an ID that belongs to an MLAgent.
	// To fix: call Agent() first to inspect the Kind field, then call the
	// appropriate typed method (HumanAgent, MLAgent, or SoftwareAgent).
	ErrAgentKindMismatch = error(errSentinel("provenance: agent kind mismatch"))
)

Sentinel errors returned by Tracker operations. Callers should use errors.Is() to detect these.

Functions

This section is empty.

Types

type Activity

type Activity struct {
	ID        ActivityID `json:"id"`
	AgentID   AgentID    `json:"agentId"`
	Phase     Phase      `json:"phase"`
	Stage     Stage      `json:"stage"`
	StartedAt time.Time  `json:"startedAt"`
	EndedAt   *time.Time `json:"endedAt,omitempty"`
	Notes     string     `json:"notes,omitempty"`
}

Activity represents a recorded action (PROV-O Activity).

type ActivityID

type ActivityID struct {
	Namespace string
	UUID      uuid.UUID
}

ActivityID uniquely identifies an activity (PROV-O Activity). Wire format: "namespace--uuid".

func ParseActivityID

func ParseActivityID(s string) (ActivityID, error)

ParseActivityID parses "namespace--uuid" into an ActivityID. Uses strings.LastIndex to split on the rightmost "--" separator. Returns ErrInvalidID if the format is invalid or the UUID is malformed.

func (ActivityID) String

func (id ActivityID) String() string

String returns the wire format: "namespace--uuid".

type Agent

type Agent struct {
	ID   AgentID   `json:"id"`
	Kind AgentKind `json:"kind"`
}

Agent is the base type for all agents (PROV-O Agent). Use Kind to determine which typed agent to query.

Agents use table-per-type (TPT) inheritance in SQLite:

  • Base: agents table (id, kind_id)
  • Human: agents_human (agent_id, name, contact)
  • ML: agents_ml (agent_id, role_id, model_id)
  • Software: agents_software (agent_id, name, version, source)

type AgentID

type AgentID struct {
	Namespace string
	UUID      uuid.UUID
}

AgentID uniquely identifies an agent (PROV-O Agent). Wire format: "namespace--uuid".

func ParseAgentID

func ParseAgentID(s string) (AgentID, error)

ParseAgentID parses "namespace--uuid" into an AgentID. Uses strings.LastIndex to split on the rightmost "--" separator. Returns ErrInvalidID if the format is invalid or the UUID is malformed.

func (AgentID) String

func (id AgentID) String() string

String returns the wire format: "namespace--uuid".

type AgentKind

type AgentKind int

AgentKind discriminates the agent TPT hierarchy.

const (
	AgentKindHuman           AgentKind = iota // 0: Human user
	AgentKindMachineLearning                  // 1: AI/ML model agent
	AgentKindSoftware                         // 2: Software tool or script
)

func (AgentKind) IsValid

func (a AgentKind) IsValid() bool

func (AgentKind) MarshalText

func (a AgentKind) MarshalText() ([]byte, error)

func (AgentKind) String

func (a AgentKind) String() string

func (*AgentKind) UnmarshalText

func (a *AgentKind) UnmarshalText(b []byte) error

type Comment

type Comment struct {
	ID        CommentID `json:"id"`
	TaskID    TaskID    `json:"taskId"`
	AuthorID  AgentID   `json:"authorId"`
	Body      string    `json:"body"`
	CreatedAt time.Time `json:"createdAt"`
}

Comment is a timestamped note attached to a task.

type CommentID

type CommentID struct {
	Namespace string
	UUID      uuid.UUID
}

CommentID uniquely identifies a comment. Wire format: "namespace--uuid".

func ParseCommentID

func ParseCommentID(s string) (CommentID, error)

ParseCommentID parses "namespace--uuid" into a CommentID. Uses strings.LastIndex to split on the rightmost "--" separator. Returns ErrInvalidID if the format is invalid or the UUID is malformed.

func (CommentID) String

func (id CommentID) String() string

String returns the wire format: "namespace--uuid".

type Edge

type Edge struct {
	SourceID string   `json:"sourceId"` // Task ID (always)
	TargetID string   `json:"targetId"` // Task, Agent, or Activity ID
	Kind     EdgeKind `json:"kind"`
}

Edge represents a typed relationship originating from a task. Source is always a TaskID. Target may be a TaskID, AgentID, or ActivityID depending on the EdgeKind:

  • EdgeBlockedBy, EdgeDerivedFrom, EdgeSupersedes, EdgeDiscoveredFrom: target is TaskID
  • EdgeGeneratedBy: target is ActivityID
  • EdgeAttributedTo: target is AgentID

type EdgeKind

type EdgeKind int

EdgeKind classifies the relationship between entities.

const (
	EdgeBlockedBy      EdgeKind = iota // 0: Task → Task: affects task readiness
	EdgeDerivedFrom                    // 1: Task → Task: PROPOSAL-2 derived from PROPOSAL-1
	EdgeSupersedes                     // 2: Task → Task: PROPOSAL-3 supersedes PROPOSAL-2
	EdgeDiscoveredFrom                 // 3: Task → Task: found during work on parent
	EdgeGeneratedBy                    // 4: Task → Activity: which activity produced this
	EdgeAttributedTo                   // 5: Task → Agent: which agent owns this
)

func (EdgeKind) IsValid

func (e EdgeKind) IsValid() bool

func (EdgeKind) MarshalText

func (e EdgeKind) MarshalText() ([]byte, error)

func (EdgeKind) String

func (e EdgeKind) String() string

func (*EdgeKind) UnmarshalText

func (e *EdgeKind) UnmarshalText(b []byte) error

type HumanAgent

type HumanAgent struct {
	Agent
	Name    string `json:"name"`
	Contact string `json:"contact,omitempty"` // email, slack handle, etc.
}

HumanAgent represents a human user.

type Label

type Label struct {
	TaskID TaskID `json:"taskId"`
	Name   string `json:"name"`
}

Label is a string tag attached to a task.

type ListFilter

type ListFilter struct {
	Status    *Status
	Priority  *Priority
	Type      *TaskType
	Phase     *Phase // Filter by protocol phase
	Label     string // empty means no label filter
	Namespace string // empty means all namespaces
}

ListFilter specifies criteria for listing tasks. Zero-value fields are ignored (no filter on that field).

type MLAgent

type MLAgent struct {
	Agent
	Role  Role    `json:"role"`
	Model MLModel `json:"model"`
}

MLAgent represents a machine learning model acting as an agent. Role stays on the agent: same model with different roles = different registrations.

type MLModel

type MLModel struct {
	ID       int      `json:"id"`
	Provider Provider `json:"provider"`
	Name     ModelID  `json:"name"`
}

MLModel represents a row in the ml_models lookup table. The combination (Provider, Name) is unique.

type ModelEntry

type ModelEntry struct {
	Provider    Provider // maps to provider_id in ml_models
	Name        ModelID  // model identifier, e.g. "claude-opus-4-6"
	DisplayName string   // human-readable, e.g. "Claude Opus 4.6"
	Family      string   // model family, e.g. "claude-opus"
}

ModelEntry describes a model known to the registry. The (Provider, Name) pair is the unique key used for ml_models seeding.

type ModelID

type ModelID string

ModelID is the canonical identifier for an ML model (e.g., "claude-opus-4-6").

type ModelRegistry

type ModelRegistry interface {
	// Models returns all known model entries.
	Models() []ModelEntry

	// Lookup returns the model entry matching the given provider and name,
	// or false if the model is not in the registry.
	Lookup(provider Provider, name string) (ModelEntry, bool)

	// ModelsByProvider returns all models from a given provider.
	ModelsByProvider(provider Provider) []ModelEntry
}

ModelRegistry is a queryable catalog of ML models.

It is used at database creation time (Models for seeding) and at agent registration time (Lookup for validation).

Implementations:

  • provenance.DefaultModelRegistry() — backed by bestiary.Models() (single source of truth)
  • provenance.NewRegistry(entries) — custom registries for tests or non-bestiary sources
  • provenance.RegistryFromBestiary(models) — adapter from bestiary model data

type Phase

type Phase int

Phase identifies a phase in the epoch lifecycle. Every task has a required phase. Use PhaseUnscoped for generic tasks that are not specific to a protocol phase.

const (
	PhaseRequest      Phase = iota // p1
	PhaseElicit                    // p2
	PhasePropose                   // p3
	PhaseReview                    // p4
	PhasePlanUAT                   // p5
	PhaseRatify                    // p6
	PhaseHandoff                   // p7
	PhaseImplPlan                  // p8
	PhaseWorkerSlices              // p9
	PhaseCodeReview                // p10
	PhaseImplUAT                   // p11
	PhaseLanding                   // p12
	PhaseUnscoped                  // Generic tasks not tied to a specific protocol phase
)

func (Phase) IsValid

func (p Phase) IsValid() bool

func (Phase) MarshalText

func (p Phase) MarshalText() ([]byte, error)

func (Phase) String

func (p Phase) String() string

func (*Phase) UnmarshalText

func (p *Phase) UnmarshalText(b []byte) error

type Priority

type Priority int

Priority represents task urgency (0 = critical, 4 = backlog).

const (
	PriorityCritical Priority = iota // 0: security, data loss, broken builds
	PriorityHigh                     // 1: major features, important bugs
	PriorityMedium                   // 2: default
	PriorityLow                      // 3: polish, optimization
	PriorityBacklog                  // 4: future ideas
)

func (Priority) IsValid

func (p Priority) IsValid() bool

func (Priority) MarshalText

func (p Priority) MarshalText() ([]byte, error)

func (Priority) String

func (p Priority) String() string

func (*Priority) UnmarshalText

func (p *Priority) UnmarshalText(b []byte) error

type Provider

type Provider string

Provider identifies the organization behind an ML model.

Provider is an open string type: any non-empty string is accepted by MarshalText and UnmarshalText. The well-known constants below are preserved for source compatibility, but callers must not assume the set is closed — the bestiary catalog contains ~110 providers (and growing).

For catalog membership checks use the IsValid() method, which delegates to bestiary.Provider(p).IsKnown(). Case-sensitive: "anthropic" is valid, "ANTHROPIC" is not.

const (
	// Well-known providers — kept for source and binary compatibility.
	// The set is not closed: any non-empty string is a valid Provider.
	ProviderAnthropic Provider = "anthropic"
	ProviderGoogle    Provider = "google"
	ProviderOpenAI    Provider = "openai"
	ProviderLocal     Provider = "local"
)

func (Provider) IsValid

func (p Provider) IsValid() bool

IsValid reports whether p is a known provider per the bestiary catalog. Equivalent to bestiary.Provider(p).IsKnown() — case-sensitive, exact match.

Examples:

ptypes.Provider("anthropic").IsValid() // true
ptypes.Provider("ANTHROPIC").IsValid() // false (case-sensitive)
ptypes.Provider("").IsValid()          // false
ptypes.Provider("   ").IsValid()       // false

func (Provider) MarshalText

func (p Provider) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler. Any Provider value round-trips without error; the caller is responsible for validating non-empty values before marshaling if strict validation is needed.

func (Provider) String

func (p Provider) String() string

func (*Provider) UnmarshalText

func (p *Provider) UnmarshalText(b []byte) error

UnmarshalText implements encoding.TextUnmarshaler. The input is whitespace-trimmed, lowercased, and accepted unconditionally (any string is valid after trimming). Use p.IsValid() at the call-site when catalog membership must be enforced.

type Role

type Role int

Role identifies an agent's role in the protocol. Only used by ML agents (agents_ml.role_id).

const (
	RoleHuman      Role = iota // 0: Human user (conceptual; not stored on agents_ml)
	RoleArchitect              // 1: Architect agent
	RoleSupervisor             // 2: Supervisor agent
	RoleWorker                 // 3: Worker agent
	RoleReviewer               // 4: Reviewer agent
)

func (Role) IsValid

func (r Role) IsValid() bool

func (Role) MarshalText

func (r Role) MarshalText() ([]byte, error)

func (Role) String

func (r Role) String() string

func (*Role) UnmarshalText

func (r *Role) UnmarshalText(b []byte) error

type SoftwareAgent

type SoftwareAgent struct {
	Agent
	Name    string `json:"name"`
	Version string `json:"version"`
	Source  string `json:"source"` // git remote URL or filesystem path
}

SoftwareAgent represents a software tool or script.

type Stage

type Stage int

Stage captures fine-grained progress within a phase.

const (
	StageNotStarted Stage = iota // 0
	StageInProgress              // 1
	StageBlocked                 // 2
	StageComplete                // 3
)

func (Stage) IsValid

func (s Stage) IsValid() bool

func (Stage) MarshalText

func (s Stage) MarshalText() ([]byte, error)

func (Stage) String

func (s Stage) String() string

func (*Stage) UnmarshalText

func (s *Stage) UnmarshalText(b []byte) error

type Status

type Status int

Status represents the lifecycle state of a task.

const (
	StatusOpen       Status = iota // 0: Task is created but not yet started
	StatusInProgress               // 1: Work is actively happening
	StatusClosed                   // 2: Work is complete
)

func (Status) IsValid

func (s Status) IsValid() bool

func (Status) MarshalText

func (s Status) MarshalText() ([]byte, error)

func (Status) String

func (s Status) String() string

func (*Status) UnmarshalText

func (s *Status) UnmarshalText(b []byte) error

type Task

type Task struct {
	ID          TaskID     `json:"id"`
	Title       string     `json:"title"`
	Description string     `json:"description"`
	Status      Status     `json:"status"`
	Priority    Priority   `json:"priority"`
	Type        TaskType   `json:"type"`
	Phase       Phase      `json:"phase"`           // Required — protocol artifacts distinguished by phase
	Owner       *AgentID   `json:"owner,omitempty"` // nil if unassigned
	Notes       string     `json:"notes,omitempty"`
	CreatedAt   time.Time  `json:"createdAt"`
	UpdatedAt   time.Time  `json:"updatedAt"`
	ClosedAt    *time.Time `json:"closedAt,omitempty"`
	CloseReason string     `json:"closeReason,omitempty"`
}

Task represents a work product (PROV-O Entity). Every task has a required Phase — use PhaseUnscoped for generic tasks.

type TaskID

type TaskID struct {
	Namespace string
	UUID      uuid.UUID
}

TaskID uniquely identifies a task (PROV-O Entity). The Namespace scopes the ID to a project (e.g., "aura-plugins"). The UUID is a UUIDv7 (time-sortable, globally unique). Wire format: "namespace--uuid".

func ParseTaskID

func ParseTaskID(s string) (TaskID, error)

ParseTaskID parses "namespace--uuid" into a TaskID. Uses strings.LastIndex to split on the rightmost "--" separator, which correctly handles namespaces that contain "--" themselves. Returns ErrInvalidID if the format is invalid or the UUID is malformed.

func (TaskID) String

func (id TaskID) String() string

String returns the wire format: "namespace--uuid".

type TaskType

type TaskType int

TaskType classifies the kind of work. Protocol artifacts are distinguished by Phase, not by TaskType.

const (
	TaskTypeBug     TaskType = iota // 0: Something broken
	TaskTypeFeature                 // 1: New functionality
	TaskTypeTask                    // 2: Work item (tests, docs, refactoring)
	TaskTypeEpic                    // 3: Large feature with subtasks
	TaskTypeChore                   // 4: Maintenance (dependencies, tooling)
)

func (TaskType) IsValid

func (t TaskType) IsValid() bool

func (TaskType) MarshalText

func (t TaskType) MarshalText() ([]byte, error)

func (TaskType) String

func (t TaskType) String() string

func (*TaskType) UnmarshalText

func (t *TaskType) UnmarshalText(b []byte) error

type UpdateFields

type UpdateFields struct {
	Title       *string
	Description *string
	Status      *Status
	Priority    *Priority
	Phase       *Phase
	Owner       *AgentID
	Notes       *string
}

UpdateFields specifies which task fields to modify. Nil pointer fields are not modified.

Jump to

Keyboard shortcuts

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