Documentation
¶
Overview ¶
Package types defines core data structures for the bd issue tracker.
Package types defines core data structures for the bd issue tracker.
Package types defines core data structures for the bd issue tracker.
Index ¶
- Constants
- Variables
- func CheckHierarchyDepth(parentID string, maxDepth int) error
- func ExtractPrefix(id string) string
- func GenerateChildID(parentID string, childNumber int) string
- func GenerateHashID(prefix, title, description string, created time.Time, workspaceID string) string
- func IsFailureClose(closeReason string) bool
- func ParseHierarchicalID(id string) (rootID, parentID string, depth int)
- func ParseWaitsForGateMetadata(metadata string) string
- type AgentState
- type AttestsMeta
- type BlockedIssue
- type BondRef
- type Comment
- type CompactionCandidate
- type DeleteIssuesResult
- type Dependency
- type DependencyCounts
- type DependencyType
- type EntityRef
- type EpicStatus
- type Event
- type EventType
- type Issue
- func (i *Issue) ComputeContentHash() string
- func (i *Issue) GetConstituents() []BondRef
- func (i *Issue) IsCompound() bool
- func (i *Issue) SetDefaults()
- func (i *Issue) Validate() error
- func (i *Issue) ValidateForImport(customStatuses []string) error
- func (i *Issue) ValidateWithCustom(customStatuses, customTypes []string) error
- func (i *Issue) ValidateWithCustomStatuses(customStatuses []string) error
- type IssueDetails
- type IssueFilter
- type IssueProvider
- type IssueType
- type IssueWithCounts
- type IssueWithDependencyMetadata
- type Label
- type MolType
- type MoleculeLastActivity
- type MoleculeProgressStats
- type RequiredSection
- type SortPolicy
- type StaleFilter
- type Statistics
- type Status
- type TreeNode
- type Validation
- type WaitsForMeta
- type WispType
- type WorkFilter
- type WorkType
Constants ¶
const ( WaitsForAllChildren = "all-children" // Wait for all dynamic children to complete WaitsForAnyChildren = "any-children" // Proceed when first child completes (future) )
WaitsForGate constants
const ( BondTypeSequential = "sequential" // B runs after A completes BondTypeParallel = "parallel" // B runs alongside A BondTypeConditional = "conditional" // B runs only if A fails BondTypeRoot = "root" // Marks the primary/root component )
Bond type constants for compound molecules
const ( IDPrefixMol = "mol" // Persistent molecules (bd-mol-xxx) IDPrefixWisp = "wisp" // Ephemeral wisps (bd-wisp-xxx) )
ID prefix constants for molecule/wisp instantiation. These prefixes are inserted into issue IDs: <project>-<prefix>-<id> Used by: cmd/bd/pour.go, cmd/bd/wisp.go (ID generation)
const ( ValidationAccepted = "accepted" ValidationRejected = "rejected" ValidationRevisionRequested = "revision_requested" )
Validation outcome constants
const MaxHierarchyDepth = 3
MaxHierarchyDepth is the maximum nesting level for hierarchical IDs. Prevents over-decomposition and keeps IDs manageable.
Variables ¶
var FailureCloseKeywords = []string{
"failed",
"rejected",
"wontfix",
"won't fix",
"canceled",
"cancelled",
"abandoned",
"blocked",
"error",
"timeout",
"aborted",
}
FailureCloseKeywords are keywords that indicate an issue was closed due to failure. Used by conditional-blocks dependencies to determine if the condition is met.
Functions ¶
func CheckHierarchyDepth ¶
CheckHierarchyDepth validates that adding a child to parentID won't exceed maxDepth. Returns an error if the depth would be exceeded. If maxDepth < 1, it defaults to MaxHierarchyDepth.
func ExtractPrefix ¶
ExtractPrefix returns the prefix portion of a bead ID (everything before the first hyphen, including the hyphen). For example, "sh-abc" returns "sh-". Returns empty string for IDs without a hyphen.
func GenerateChildID ¶
GenerateChildID creates a hierarchical child ID. Format: parent.N (e.g., "bd-af78e9a2.1", "bd-af78e9a2.1.2")
Max depth: 3 levels (prevents over-decomposition) Max breadth: Unlimited (tested up to 347 children)
func GenerateHashID ¶
func GenerateHashID(prefix, title, description string, created time.Time, workspaceID string) string
GenerateHashID creates a deterministic content-based hash ID. Format: prefix-{6-8-char-hex} with progressive extension on collision Examples: bd-a3f2dd (6), bd-a3f2dda (7), bd-a3f2dda8 (8)
The hash is computed from: - Title (primary identifier) - Description (additional context) - Created timestamp (RFC3339Nano for precision) - Workspace ID (prevents cross-workspace collisions)
Returns the full 64-char hash for progressive collision handling. Caller extracts hash[:6] initially, then hash[:7], hash[:8] on collisions.
Collision probability with 6 chars (24 bits): - 1,000 issues: ~2.94% chance (most extend to 7 chars) - 10,000 issues: ~94.9% chance (most extend to 7-8 chars)
Progressive strategy optimizes for common case: 97% stay at 6 chars.
func IsFailureClose ¶
IsFailureClose returns true if the close reason indicates the issue failed. This is used by conditional-blocks dependencies: B runs only if A fails. A "failure" close reason contains one of the FailureCloseKeywords (case-insensitive).
func ParseHierarchicalID ¶
ParseHierarchicalID extracts the parent ID and depth from a hierarchical ID. Returns: (rootID, parentID, depth)
Examples:
"bd-af78e9a2" → ("bd-af78e9a2", "", 0)
"bd-af78e9a2.1" → ("bd-af78e9a2", "bd-af78e9a2", 1)
"bd-af78e9a2.1.2" → ("bd-af78e9a2", "bd-af78e9a2.1", 2)
func ParseWaitsForGateMetadata ¶
ParseWaitsForGateMetadata extracts the waits-for gate type from dependency metadata. Note: spawner identity comes from dependencies.depends_on_id in storage/query paths; metadata.spawner_id is parsed for compatibility/future explicit targeting. Returns WaitsForAllChildren on empty/invalid metadata for backward compatibility.
Types ¶
type AgentState ¶
type AgentState string
AgentState represents the self-reported state of an agent
const ( StateIdle AgentState = "idle" // Agent is waiting for work StateSpawning AgentState = "spawning" // Agent is starting up StateRunning AgentState = "running" // Agent is executing (general) StateWorking AgentState = "working" // Agent is actively working on a task StateStuck AgentState = "stuck" // Agent is blocked and needs help StateDone AgentState = "done" // Agent completed its current work StateStopped AgentState = "stopped" // Agent has cleanly shut down StateDead AgentState = "dead" // Agent died without clean shutdown (timeout detection) )
Agent state constants
func (AgentState) IsValid ¶
func (s AgentState) IsValid() bool
IsValid checks if the agent state value is valid
type AttestsMeta ¶
type AttestsMeta struct {
// Skill is the identifier of the skill being attested (e.g., "go", "rust", "code-review")
Skill string `json:"skill"`
// Level is the proficiency level (e.g., "beginner", "intermediate", "expert", or numeric 1-5)
Level string `json:"level"`
// Date is when the attestation was made (RFC3339 format)
Date string `json:"date"`
// Evidence is optional reference to supporting evidence (e.g., issue ID, commit, PR)
Evidence string `json:"evidence,omitempty"`
// Notes is optional free-form notes about the attestation
Notes string `json:"notes,omitempty"`
}
AttestsMeta holds metadata for attests dependencies (skill attestations). Stored as JSON in the Dependency.Metadata field. Enables: Entity X attests that Entity Y has skill Z at level N.
type BlockedIssue ¶
type BlockedIssue struct {
Issue
BlockedByCount int `json:"blocked_by_count"`
BlockedBy []string `json:"blocked_by"`
}
BlockedIssue extends Issue with blocking information
type BondRef ¶
type BondRef struct {
SourceID string `json:"source_id"` // Source proto or molecule ID
BondType string `json:"bond_type"` // sequential, parallel, conditional
BondPoint string `json:"bond_point,omitempty"` // Attachment site (issue ID or empty for root)
}
BondRef tracks compound molecule lineage. When protos or molecules are bonded together, BondRefs record which sources were combined and how they were attached.
type Comment ¶
type Comment struct {
ID int64 `json:"id"`
IssueID string `json:"issue_id"`
Author string `json:"author"`
Text string `json:"text"`
CreatedAt time.Time `json:"created_at"`
}
Comment represents a comment on an issue
type CompactionCandidate ¶
type CompactionCandidate struct {
IssueID string
ClosedAt time.Time
OriginalSize int
EstimatedSize int
DependentCount int
}
CompactionCandidate represents an issue eligible for compaction. Used by the compact subsystem to identify and process closed issues that can have their description/notes summarized to save space.
type DeleteIssuesResult ¶
type DeleteIssuesResult struct {
DeletedCount int
DependenciesCount int
LabelsCount int
EventsCount int
OrphanedIssues []string
}
DeleteIssuesResult contains statistics from a batch delete operation. Used when deleting multiple issues with cascade/force options.
type Dependency ¶
type Dependency struct {
IssueID string `json:"issue_id"`
DependsOnID string `json:"depends_on_id"`
Type DependencyType `json:"type"`
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by,omitempty"`
// Metadata contains type-specific edge data (JSON blob)
// Examples: similarity scores, approval details, skill proficiency
Metadata string `json:"metadata,omitempty"`
// ThreadID groups conversation edges for efficient thread queries
// For replies-to edges, this identifies the conversation root
ThreadID string `json:"thread_id,omitempty"`
}
Dependency represents a relationship between issues
type DependencyCounts ¶
type DependencyCounts struct {
DependencyCount int `json:"dependency_count"` // Number of issues this issue depends on
DependentCount int `json:"dependent_count"` // Number of issues that depend on this issue
}
DependencyCounts holds counts for dependencies and dependents
type DependencyType ¶
type DependencyType string
DependencyType categorizes the relationship
const ( // Workflow types (affect ready work calculation) DepBlocks DependencyType = "blocks" DepParentChild DependencyType = "parent-child" DepConditionalBlocks DependencyType = "conditional-blocks" // B runs only if A fails DepWaitsFor DependencyType = "waits-for" // Fanout gate: wait for dynamic children // Association types DepRelated DependencyType = "related" DepDiscoveredFrom DependencyType = "discovered-from" // Graph link types DepRepliesTo DependencyType = "replies-to" // Conversation threading DepRelatesTo DependencyType = "relates-to" // Loose knowledge graph edges DepDuplicates DependencyType = "duplicates" // Deduplication link DepSupersedes DependencyType = "supersedes" // Version chain link // Entity types (HOP foundation - Decision 004) DepAuthoredBy DependencyType = "authored-by" // Creator relationship DepAssignedTo DependencyType = "assigned-to" // Assignment relationship DepApprovedBy DependencyType = "approved-by" // Approval relationship DepAttests DependencyType = "attests" // Skill attestation: X attests Y has skill Z // Convoy tracking (non-blocking cross-project references) DepTracks DependencyType = "tracks" // Convoy → issue tracking (non-blocking) // Reference types (cross-referencing without blocking) DepUntil DependencyType = "until" // Active until target closes (e.g., muted until issue resolved) DepCausedBy DependencyType = "caused-by" // Triggered by target (audit trail) DepValidates DependencyType = "validates" // Approval/validation relationship // Delegation types (work delegation chains) DepDelegatedFrom DependencyType = "delegated-from" // Work delegated from parent; completion cascades up )
Dependency type constants
func (DependencyType) AffectsReadyWork ¶
func (d DependencyType) AffectsReadyWork() bool
AffectsReadyWork returns true if this dependency type blocks work. Only blocking types affect the ready work calculation.
func (DependencyType) IsValid ¶
func (d DependencyType) IsValid() bool
IsValid checks if the dependency type value is valid. Accepts any non-empty string up to 50 characters. Use IsWellKnown() to check if it's a built-in type.
func (DependencyType) IsWellKnown ¶
func (d DependencyType) IsWellKnown() bool
IsWellKnown checks if the dependency type is a well-known constant. Returns false for custom/user-defined types (which are still valid).
type EntityRef ¶
type EntityRef struct {
// Name is the human-readable identifier (e.g., "polecat/Nux", "mayor")
Name string `json:"name,omitempty"`
// Platform identifies the execution context (e.g., "gastown", "github")
Platform string `json:"platform,omitempty"`
// Org identifies the organization (e.g., "steveyegge", "anthropics")
Org string `json:"org,omitempty"`
// ID is the unique identifier within the platform/org (e.g., "polecat-nux")
ID string `json:"id,omitempty"`
}
EntityRef is a structured reference to an entity (human, agent, or org). This is the foundation for HOP entity tracking and CV chains. Can be rendered as a URI: hop://<platform>/<org>/<id>
Example usage:
ref := &EntityRef{
Name: "polecat/Nux",
Platform: "gastown",
Org: "steveyegge",
ID: "polecat-nux",
}
uri := ref.URI() // "hop://gastown/steveyegge/polecat-nux"
func ParseEntityURI ¶
ParseEntityURI parses a HOP entity URI into an EntityRef. Format: hop://<platform>/<org>/<id> Also accepts legacy entity://hop/<platform>/<org>/<id> for backward compatibility. Returns nil and error if the URI is invalid.
type EpicStatus ¶
type EpicStatus struct {
Epic *Issue `json:"epic"`
TotalChildren int `json:"total_children"`
ClosedChildren int `json:"closed_children"`
EligibleForClose bool `json:"eligible_for_close"`
}
EpicStatus represents an epic with its completion status
type Event ¶
type Event struct {
ID int64 `json:"id"`
IssueID string `json:"issue_id"`
EventType EventType `json:"event_type"`
Actor string `json:"actor"`
OldValue *string `json:"old_value,omitempty"`
NewValue *string `json:"new_value,omitempty"`
Comment *string `json:"comment,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Event represents an audit trail entry
type EventType ¶
type EventType string
EventType categorizes audit trail events
const ( EventCreated EventType = "created" EventUpdated EventType = "updated" EventStatusChanged EventType = "status_changed" EventCommented EventType = "commented" EventClosed EventType = "closed" EventReopened EventType = "reopened" EventDependencyAdded EventType = "dependency_added" EventDependencyRemoved EventType = "dependency_removed" EventLabelAdded EventType = "label_added" EventLabelRemoved EventType = "label_removed" EventCompacted EventType = "compacted" )
Event type constants for audit trail
type Issue ¶
type Issue struct {
// ===== Core Identification =====
ID string `json:"id"`
ContentHash string `json:"-"` // Internal: SHA256 of canonical content
// ===== Issue Content =====
Title string `json:"title"`
Description string `json:"description,omitempty"`
Design string `json:"design,omitempty"`
AcceptanceCriteria string `json:"acceptance_criteria,omitempty"`
Notes string `json:"notes,omitempty"`
SpecID string `json:"spec_id,omitempty"`
// ===== Status & Workflow =====
Status Status `json:"status,omitempty"`
Priority int `json:"priority"` // No omitempty: 0 is valid (P0/critical)
IssueType IssueType `json:"issue_type,omitempty"`
// ===== Assignment =====
Assignee string `json:"assignee,omitempty"`
Owner string `json:"owner,omitempty"` // Human owner for CV attribution (git author email)
EstimatedMinutes *int `json:"estimated_minutes,omitempty"`
// ===== Timestamps =====
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by,omitempty"` // Who created this issue (GH#748)
UpdatedAt time.Time `json:"updated_at"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
CloseReason string `json:"close_reason,omitempty"` // Reason provided when closing
ClosedBySession string `json:"closed_by_session,omitempty"` // Claude Code session that closed this issue
// ===== Time-Based Scheduling (GH#820) =====
DueAt *time.Time `json:"due_at,omitempty"` // When this issue should be completed
DeferUntil *time.Time `json:"defer_until,omitempty"` // Hide from bd ready until this time
// ===== External Integration =====
ExternalRef *string `json:"external_ref,omitempty"` // e.g., "gh-9", "jira-ABC"
SourceSystem string `json:"source_system,omitempty"` // Adapter/system that created this issue (federation)
// ===== Custom Metadata =====
// Metadata holds arbitrary JSON data for extension points (tool annotations, file lists, etc.)
// Validated as well-formed JSON on create/update. See GH#1406.
Metadata json.RawMessage `json:"metadata,omitempty"`
// ===== Compaction Metadata =====
CompactionLevel int `json:"compaction_level,omitempty"`
CompactedAt *time.Time `json:"compacted_at,omitempty"`
CompactedAtCommit *string `json:"compacted_at_commit,omitempty"` // Git commit hash when compacted
OriginalSize int `json:"original_size,omitempty"`
// ===== Internal Routing (not synced via git) =====
SourceRepo string `json:"-"` // Which repo owns this issue (multi-repo support)
IDPrefix string `json:"-"` // Override prefix for ID generation (appends to config prefix)
PrefixOverride string `json:"-"` // Completely replace config prefix (for cross-rig creation)
// ===== Relational Data (populated for export/import) =====
Labels []string `json:"labels,omitempty"`
Dependencies []*Dependency `json:"dependencies,omitempty"`
Comments []*Comment `json:"comments,omitempty"`
// ===== Messaging Fields (inter-agent communication) =====
Sender string `json:"sender,omitempty"` // Who sent this (for messages)
Ephemeral bool `json:"ephemeral,omitempty"` // If true, not synced via git
WispType WispType `json:"wisp_type,omitempty"` // Classification for TTL-based compaction (gt-9br)
// ===== Context Markers =====
Pinned bool `json:"pinned,omitempty"` // Persistent context marker, not a work item
IsTemplate bool `json:"is_template,omitempty"` // Read-only template molecule
// ===== Bonding Fields (compound molecule lineage) =====
BondedFrom []BondRef `json:"bonded_from,omitempty"` // For compounds: constituent protos
// ===== HOP Fields (entity tracking for CV chains) =====
Creator *EntityRef `json:"creator,omitempty"` // Who created (human, agent, or org)
Validations []Validation `json:"validations,omitempty"` // Who validated/approved
QualityScore *float32 `json:"quality_score,omitempty"` // Aggregate quality (0.0-1.0), set by Refineries on merge
Crystallizes bool `json:"crystallizes,omitempty"` // Work that compounds (true: code, features) vs evaporates (false: ops, support) - affects CV weighting per Decision 006
// ===== Gate Fields (async coordination primitives) =====
AwaitType string `json:"await_type,omitempty"` // Condition type: gh:run, gh:pr, timer, human, mail
AwaitID string `json:"await_id,omitempty"` // Condition identifier (run ID, PR number, etc.)
Timeout time.Duration `json:"timeout,omitempty"` // Max wait time before escalation
Waiters []string `json:"waiters,omitempty"` // Mail addresses to notify when gate clears
// ===== Slot Fields (exclusive access primitives) =====
Holder string `json:"holder,omitempty"` // Who currently holds the slot (empty = available)
// ===== Source Tracing Fields (formula cooking origin) =====
SourceFormula string `json:"source_formula,omitempty"` // Formula name where step was defined
SourceLocation string `json:"source_location,omitempty"` // Path: "steps[0]", "advice[0].after"
// ===== Agent Identity Fields (agent-as-bead support) =====
HookBead string `json:"hook_bead,omitempty"` // Current work on agent's hook (0..1)
RoleBead string `json:"role_bead,omitempty"` // Role definition bead (required for agents)
AgentState AgentState `json:"agent_state,omitempty"` // Agent state: idle|running|stuck|stopped
LastActivity *time.Time `json:"last_activity,omitempty"` // Updated on each action (timeout detection)
RoleType string `json:"role_type,omitempty"` // Agent role type (application-defined)
Rig string `json:"rig,omitempty"` // Rig name (empty for town-level agents)
// ===== Molecule Type Fields (swarm coordination) =====
MolType MolType `json:"mol_type,omitempty"` // Molecule type: swarm|patrol|work (empty = work)
// ===== Work Type Fields (assignment model - Decision 006) =====
WorkType WorkType `json:"work_type,omitempty"` // Work type: mutex|open_competition (empty = mutex)
// ===== Event Fields (operational state changes) =====
EventKind string `json:"event_kind,omitempty"` // Namespaced event type: patrol.muted, agent.started
Actor string `json:"actor,omitempty"` // Entity URI who caused this event
Target string `json:"target,omitempty"` // Entity URI or bead ID affected
Payload string `json:"payload,omitempty"` // Event-specific JSON data
}
Issue represents a trackable work item. Fields are organized into logical groups for maintainability.
func (*Issue) ComputeContentHash ¶
ComputeContentHash creates a deterministic hash of the issue's content. Uses all substantive fields (excluding ID, timestamps, and compaction metadata) to ensure that identical content produces identical hashes across all clones.
func (*Issue) GetConstituents ¶
GetConstituents returns the BondRefs for this compound's constituent protos. Returns nil for non-compound issues.
func (*Issue) IsCompound ¶
IsCompound returns true if this issue is a compound (bonded from multiple sources).
func (*Issue) SetDefaults ¶
func (i *Issue) SetDefaults()
SetDefaults applies default values for fields that may be omitted during deserialization. Call this after json.Unmarshal to ensure missing fields have proper defaults:
- Status: defaults to StatusOpen if empty
- Priority: defaults to 2 if zero (note: P0 issues must explicitly set priority=0)
- IssueType: defaults to TypeTask if empty
func (*Issue) Validate ¶
Validate checks if the issue has valid field values (built-in statuses only)
func (*Issue) ValidateForImport ¶
ValidateForImport validates the issue for multi-repo import (federation trust model). Built-in types are validated (to catch typos). Non-built-in types are trusted since the source repo already validated them when the issue was created. This implements "trust the chain below you" from the HOP federation model.
func (*Issue) ValidateWithCustom ¶
ValidateWithCustom checks if the issue has valid field values, allowing custom statuses and types in addition to built-in ones.
func (*Issue) ValidateWithCustomStatuses ¶
ValidateWithCustomStatuses checks if the issue has valid field values, allowing custom statuses in addition to built-in ones.
type IssueDetails ¶
type IssueDetails struct {
Issue
Labels []string `json:"labels,omitempty"`
Dependencies []*IssueWithDependencyMetadata `json:"dependencies,omitempty"`
Dependents []*IssueWithDependencyMetadata `json:"dependents,omitempty"`
Comments []*Comment `json:"comments,omitempty"`
Parent *string `json:"parent,omitempty"`
// Epic progress fields (populated only for issue_type=epic with children)
EpicTotalChildren *int `json:"epic_total_children,omitempty"`
EpicClosedChildren *int `json:"epic_closed_children,omitempty"`
EpicCloseable *bool `json:"epic_closeable,omitempty"`
}
IssueDetails extends Issue with labels, dependencies, dependents, and comments. Used for JSON serialization in bd show and RPC responses.
type IssueFilter ¶
type IssueFilter struct {
Status *Status
Priority *int
IssueType *IssueType
Assignee *string
Labels []string // AND semantics: issue must have ALL these labels
LabelsAny []string // OR semantics: issue must have AT LEAST ONE of these labels
LabelPattern string // Glob pattern for label matching (e.g., "tech-*")
LabelRegex string // Regex pattern for label matching (e.g., "tech-(debt|legacy)")
TitleSearch string
IDs []string // Filter by specific issue IDs
IDPrefix string // Filter by ID prefix (e.g., "bd-" to match "bd-abc123")
SpecIDPrefix string // Filter by spec_id prefix
Limit int
// Pattern matching
TitleContains string
DescriptionContains string
NotesContains string
ExternalRefContains string
// Date ranges
CreatedAfter *time.Time
CreatedBefore *time.Time
UpdatedAfter *time.Time
UpdatedBefore *time.Time
ClosedAfter *time.Time
ClosedBefore *time.Time
// Empty/null checks
EmptyDescription bool
NoAssignee bool
NoLabels bool
// Numeric ranges
PriorityMin *int
PriorityMax *int
// Source repo filtering (for multi-repo support)
SourceRepo *string // Filter by source_repo field (nil = any)
// Ephemeral filtering
Ephemeral *bool // Filter by ephemeral flag (nil = any, true = only ephemeral, false = only persistent)
// Pinned filtering
Pinned *bool // Filter by pinned flag (nil = any, true = only pinned, false = only non-pinned)
// Template filtering
IsTemplate *bool // Filter by template flag (nil = any, true = only templates, false = exclude templates)
// Parent filtering: filter children by parent issue ID
ParentID *string // Filter by parent issue (via parent-child dependency)
NoParent bool // Exclude issues that are children of another issue
// Molecule type filtering
MolType *MolType // Filter by molecule type (nil = any, swarm/patrol/work)
// Wisp type filtering (TTL-based compaction classification)
WispType *WispType // Filter by wisp type (nil = any, heartbeat/ping/patrol/gc_report/recovery/error/escalation)
// Status exclusion (for default non-closed behavior)
ExcludeStatus []Status // Exclude issues with these statuses
// Type exclusion (for hiding internal types like gates)
ExcludeTypes []IssueType // Exclude issues with these types
// Time-based scheduling filters (GH#820)
Deferred bool // Filter issues with defer_until set (any value)
DeferAfter *time.Time // Filter issues with defer_until > this time
DeferBefore *time.Time // Filter issues with defer_until < this time
DueAfter *time.Time // Filter issues with due_at > this time
DueBefore *time.Time // Filter issues with due_at < this time
Overdue bool // Filter issues where due_at < now AND status != closed
// Metadata field filtering (GH#1406)
MetadataFields map[string]string // Top-level key=value equality; AND semantics (all must match)
HasMetadataKey string // Existence check: issue has this top-level key set (non-null)
}
IssueFilter is used to filter issue queries
type IssueProvider ¶
type IssueProvider interface {
// GetOpenIssues returns issues that are open or in_progress.
// Should return empty slice (not error) if no issues exist.
GetOpenIssues(ctx context.Context) ([]*Issue, error)
// GetIssuePrefix returns the configured prefix (e.g., "bd", "TEST").
// Should return "bd" as default if not configured.
GetIssuePrefix() string
}
IssueProvider abstracts issue storage for orphan detection. Implementations may be backed by Dolt or mocks.
type IssueType ¶
type IssueType string
IssueType categorizes the kind of work
const ( TypeBug IssueType = "bug" TypeFeature IssueType = "feature" TypeTask IssueType = "task" TypeEpic IssueType = "epic" TypeChore IssueType = "chore" TypeDecision IssueType = "decision" TypeMessage IssueType = "message" TypeMolecule IssueType = "molecule" // Molecule type for swarm coordination (internal use) )
Core work type constants - these are the built-in types that beads validates. All other types require configuration via types.custom in config.yaml.
const TypeEvent IssueType = "event"
TypeEvent is a system-internal type used by set-state for audit trail beads. Originally a Gas Town type, promoted to built-in internal type. It is not a core work type (not in IsValid) but is accepted by IsValidWithCustom / ValidateWithCustom and treated as built-in for hydration trust (GH#1356).
func (IssueType) IsBuiltIn ¶
IsBuiltIn returns true for core work types and system-internal types (i.e. TypeEvent). Used during multi-repo hydration to determine trust: - Built-in/internal types: validate (catch typos) - Custom types (!IsBuiltIn): trust from source repo
func (IssueType) IsValid ¶
IsValid checks if the issue type is a core work type. Core work types (bug, feature, task, epic, chore, decision, message) and molecule type are built-in. Other types (gate, convoy, etc.) require types.custom configuration.
func (IssueType) IsValidWithCustom ¶
IsValidWithCustom checks if the issue type is valid, including custom types. Custom types are user-defined via bd config set types.custom "type1,type2,..."
func (IssueType) Normalize ¶
Normalize maps issue type aliases to their canonical form. For example, "enhancement" -> "feature". Case-insensitive to match util.NormalizeIssueType behavior.
func (IssueType) RequiredSections ¶
func (t IssueType) RequiredSections() []RequiredSection
RequiredSections returns the recommended sections for this issue type. Returns nil for types with no specific section requirements.
type IssueWithCounts ¶
type IssueWithCounts struct {
*Issue
DependencyCount int `json:"dependency_count"`
DependentCount int `json:"dependent_count"`
CommentCount int `json:"comment_count"`
Parent *string `json:"parent,omitempty"` // Computed parent from parent-child dep (bd-ym8c)
}
IssueWithCounts extends Issue with dependency relationship counts
type IssueWithDependencyMetadata ¶
type IssueWithDependencyMetadata struct {
Issue
DependencyType DependencyType `json:"dependency_type"`
}
IssueWithDependencyMetadata extends Issue with dependency relationship type Note: We explicitly include all Issue fields to ensure proper JSON marshaling
type MolType ¶
type MolType string
MolType categorizes the molecule type for swarm coordination
type MoleculeLastActivity ¶
type MoleculeLastActivity struct {
MoleculeID string `json:"molecule_id"`
LastActivity time.Time `json:"last_activity"`
Source string `json:"source"` // "step_closed", "step_updated", "molecule_updated"
SourceStepID string `json:"source_step_id,omitempty"`
}
MoleculeLastActivity holds the most recent activity timestamp for a molecule.
type MoleculeProgressStats ¶
type MoleculeProgressStats struct {
MoleculeID string `json:"molecule_id"`
MoleculeTitle string `json:"molecule_title"`
Total int `json:"total"` // Total steps (direct children)
Completed int `json:"completed"` // Closed steps
InProgress int `json:"in_progress"` // Steps currently in progress
CurrentStepID string `json:"current_step_id"` // First in_progress step ID (if any)
FirstClosed *time.Time `json:"first_closed,omitempty"`
LastClosed *time.Time `json:"last_closed,omitempty"`
}
MoleculeProgressStats provides efficient progress info for large molecules. This uses indexed queries instead of loading all steps into memory.
type RequiredSection ¶
type RequiredSection struct {
Heading string // Markdown heading, e.g., "## Steps to Reproduce"
Hint string // Guidance for what to include
}
RequiredSection describes a recommended section for an issue type. Used by bd lint and bd create --validate for template validation.
type SortPolicy ¶
type SortPolicy string
SortPolicy determines how ready work is ordered
const ( // SortPolicyHybrid prioritizes recent issues by priority, older by age // Recent = created within 48 hours // This is the default for backwards compatibility SortPolicyHybrid SortPolicy = "hybrid" // SortPolicyPriority always sorts by priority first, then creation date // Use for autonomous execution, CI/CD, priority-driven workflows SortPolicyPriority SortPolicy = "priority" // SortPolicyOldest always sorts by creation date (oldest first) // Use for backlog clearing, preventing issue starvation SortPolicyOldest SortPolicy = "oldest" )
Sort policy constants
func (SortPolicy) IsValid ¶
func (s SortPolicy) IsValid() bool
IsValid checks if the sort policy value is valid
type StaleFilter ¶
type StaleFilter struct {
Days int // Issues not updated in this many days
Status string // Filter by status (open|in_progress|blocked), empty = all non-closed
Limit int // Maximum issues to return
}
StaleFilter is used to filter stale issue queries
type Statistics ¶
type Statistics struct {
TotalIssues int `json:"total_issues"`
OpenIssues int `json:"open_issues"`
InProgressIssues int `json:"in_progress_issues"`
ClosedIssues int `json:"closed_issues"`
BlockedIssues int `json:"blocked_issues"`
DeferredIssues int `json:"deferred_issues"` // Issues on ice
ReadyIssues int `json:"ready_issues"`
PinnedIssues int `json:"pinned_issues"` // Persistent issues
EpicsEligibleForClosure int `json:"epics_eligible_for_closure"`
AverageLeadTime float64 `json:"average_lead_time_hours"`
}
Statistics provides aggregate metrics
type Status ¶
type Status string
Status represents the current state of an issue
const ( StatusOpen Status = "open" StatusInProgress Status = "in_progress" StatusBlocked Status = "blocked" StatusDeferred Status = "deferred" // Deliberately put on ice for later StatusClosed Status = "closed" StatusPinned Status = "pinned" // Persistent bead that stays open indefinitely StatusHooked Status = "hooked" // Work attached to an agent's hook (GUPP) )
Issue status constants
func (Status) IsValidWithCustom ¶
IsValidWithCustom checks if the status is valid, including custom statuses. Custom statuses are user-defined via bd config set status.custom "status1,status2,..."
type TreeNode ¶
type TreeNode struct {
Issue
Depth int `json:"depth"`
ParentID string `json:"parent_id"`
Truncated bool `json:"truncated"`
}
TreeNode represents a node in a dependency tree
type Validation ¶
type Validation struct {
// Validator is who approved/rejected the work
Validator *EntityRef `json:"validator"`
// Outcome is the validation result: accepted, rejected, revision_requested
Outcome string `json:"outcome"`
// Timestamp is when the validation occurred
Timestamp time.Time `json:"timestamp"`
// Score is an optional quality score (0.0-1.0)
Score *float32 `json:"score,omitempty"`
}
Validation records who validated/approved work completion. This is core to HOP's proof-of-stake concept - validators stake their reputation on approvals.
func (*Validation) IsValidOutcome ¶
func (v *Validation) IsValidOutcome() bool
IsValidOutcome checks if the outcome is a known validation outcome.
type WaitsForMeta ¶
type WaitsForMeta struct {
// Gate type: "all-children" (wait for all), "any-children" (wait for first)
Gate string `json:"gate"`
// SpawnerID identifies which step/issue spawns the children to wait for.
// If empty, waits for all direct children of the depends_on_id issue.
SpawnerID string `json:"spawner_id,omitempty"`
}
WaitsForMeta holds metadata for waits-for dependencies (fanout gates). Stored as JSON in the Dependency.Metadata field.
type WispType ¶
type WispType string
WispType categorizes ephemeral wisps for TTL-based compaction (gt-9br)
const ( // Category 1: High-churn, low forensic value (TTL: 6h) WispTypeHeartbeat WispType = "heartbeat" // Liveness pings WispTypePing WispType = "ping" // Health check ACKs // Category 2: Operational state (TTL: 24h) WispTypePatrol WispType = "patrol" // Patrol cycle reports WispTypeGCReport WispType = "gc_report" // Garbage collection reports // Category 3: Significant events (TTL: 7d) WispTypeRecovery WispType = "recovery" // Force-kill, recovery actions WispTypeError WispType = "error" // Error reports WispTypeEscalation WispType = "escalation" // Human escalations )
WispType constants - see WISP-COMPACTION-POLICY.md for TTL assignments
type WorkFilter ¶
type WorkFilter struct {
Status Status
Type string // Filter by issue type (task, bug, feature, epic, merge-request, etc.)
Priority *int
Assignee *string
Unassigned bool // Filter for issues with no assignee
Labels []string // AND semantics: issue must have ALL these labels
LabelsAny []string // OR semantics: issue must have AT LEAST ONE of these labels
LabelPattern string // Glob pattern for label matching (e.g., "tech-*")
LabelRegex string // Regex pattern for label matching (e.g., "tech-(debt|legacy)")
Limit int
SortPolicy SortPolicy
// Parent filtering: filter to descendants of a bead/epic (recursive)
ParentID *string // Show all descendants of this issue
// Molecule type filtering
MolType *MolType // Filter by molecule type (nil = any, swarm/patrol/work)
// Wisp type filtering (TTL-based compaction classification)
WispType *WispType // Filter by wisp type (nil = any, heartbeat/ping/patrol/gc_report/recovery/error/escalation)
// Time-based deferral filtering (GH#820)
IncludeDeferred bool // If true, include issues with future defer_until timestamps
// Ephemeral issue filtering
// By default, GetReadyWork excludes ephemeral issues (wisps).
// Set to true to include them (e.g., for merge-request processing).
IncludeEphemeral bool
// Metadata field filtering (GH#1406)
MetadataFields map[string]string // Top-level key=value equality; AND semantics (all must match)
HasMetadataKey string // Existence check: issue has this top-level key set (non-null)
}
WorkFilter is used to filter ready work queries
type WorkType ¶
type WorkType string
WorkType categorizes how work assignment operates for a bead (Decision 006)