Documentation
¶
Overview ¶
CANARY: REQ=CBIN-134; FEATURE="ExactIDLookup"; ASPECT=Engine; STATUS=IMPL; UPDATED=2025-10-16
CANARY: REQ=CBIN-134; FEATURE="SectionLoader"; ASPECT=Engine; STATUS=IMPL; UPDATED=2025-10-16
Index ¶
- func FindSpecByID(reqID string) (string, error)
- func FindSpecBySearch(query string, limit int) ([]matcher.Match, error)
- func FindSpecInDB(db *storage.DB, reqID string) (string, error)
- func ListSections(content string) ([]string, error)
- func ParseSections(content string, sections []string) (string, error)
- type Dependency
- type DependencyGraph
- type DependencyStatus
- type DependencyType
- type DependencyValidator
- type GraphGenerator
- func (gg *GraphGenerator) BuildGraph(reqIDs []string) (*DependencyGraph, error)
- func (gg *GraphGenerator) FormatASCIITree(graph *DependencyGraph, rootReqID string) string
- func (gg *GraphGenerator) FormatCompactList(graph *DependencyGraph, reqID string) string
- func (gg *GraphGenerator) FormatDependencyChain(reqIDs []string) string
- func (gg *GraphGenerator) FormatDependencySummary(graph *DependencyGraph, reqID string) string
- func (gg *GraphGenerator) FormatMermaid(graph *DependencyGraph, rootReqID string, urlFor func(string) string) string
- func (gg *GraphGenerator) GetDependencyDepth(graph *DependencyGraph, reqID string) int
- func (gg *GraphGenerator) GetTransitiveDependencies(graph *DependencyGraph, reqID string) []string
- func (gg *GraphGenerator) SetStatusChecker(checker StatusCheckerInterface)
- type SpecFinder
- type SpecLoader
- type StatusChecker
- func (sc *StatusChecker) CheckAllDependencies(deps []Dependency) []DependencyStatus
- func (sc *StatusChecker) CheckDependency(dep Dependency) DependencyStatus
- func (sc *StatusChecker) FormatBlockingReport(deps []Dependency) string
- func (sc *StatusChecker) GetBlockingDependencies(deps []Dependency) []DependencyStatus
- type StatusCheckerInterface
- type TokenInfo
- type TokenProvider
- type ValidationResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FindSpecByID ¶
FindSpecByID locates spec.md file by exact requirement ID Uses glob pattern: .canary/specs/CBIN-XXX-*/spec.md
func FindSpecBySearch ¶
FindSpecBySearch performs fuzzy search across spec directories Reuses CBIN-133 fuzzy matcher for scoring and ranking
func FindSpecInDB ¶
FindSpecInDB queries database for fast spec lookup (optional fallback) If database is unavailable, returns error and caller should use FindSpecByID
func ListSections ¶
ListSections returns all section headers from markdown content Extracts all ## level headers
Types ¶
type Dependency ¶
type Dependency struct {
// Source is the requirement ID that has the dependency (e.g., "CBIN-147")
Source string
// Target is the requirement ID being depended upon (e.g., "CBIN-146")
Target string
// Type indicates whether this is a full, partial feature, or aspect dependency
Type DependencyType
// RequiredFeatures lists specific features needed for PartialFeatures dependencies.
// Only populated when Type is DependencyTypePartialFeatures.
RequiredFeatures []string
// RequiredAspect specifies the aspect needed for PartialAspect dependencies.
// Only populated when Type is DependencyTypePartialAspect.
RequiredAspect string
// Description provides human-readable context about why this dependency exists.
// This is optional and used for documentation purposes.
Description string
}
Dependency represents a dependency relationship between two requirements. It captures the source requirement, target requirement, type of dependency, and any specific features or aspects that must be satisfied.
func ParseDependencies ¶
func ParseDependencies(sourceReqID string, reader io.Reader) ([]Dependency, error)
ParseDependencies parses dependency declarations from a spec.md file reader. It looks for the "## Dependencies" section and extracts all dependency declarations.
Supported formats: - Full: "- CBIN-123 (Description)" - Partial Features: "- CBIN-123:Feature1,Feature2 (Description)" - Partial Aspect: "- CBIN-123:AspectName (Description)"
Returns a slice of Dependency objects. Returns empty slice if no dependencies found.
func ParseDependenciesFromFile ¶
func ParseDependenciesFromFile(sourceReqID, specPath string) ([]Dependency, error)
ParseDependenciesFromFile reads a spec.md file and extracts all dependencies. Returns a slice of Dependency objects or an error if the file cannot be read.
type DependencyGraph ¶
type DependencyGraph struct {
// Nodes maps requirement IDs to their list of outgoing dependencies.
// Key: Source requirement ID (e.g., "CBIN-147")
// Value: List of dependencies where this requirement is the source
Nodes map[string][]Dependency
}
DependencyGraph represents the complete dependency graph for all requirements. It provides methods for querying, traversal, and cycle detection.
func NewDependencyGraph ¶
func NewDependencyGraph() *DependencyGraph
NewDependencyGraph creates a new empty DependencyGraph.
func (*DependencyGraph) AddDependency ¶
func (dg *DependencyGraph) AddDependency(dep Dependency)
AddDependency adds a dependency to the graph. If the source node doesn't exist, it creates it.
func (*DependencyGraph) GetAllRequirements ¶
func (dg *DependencyGraph) GetAllRequirements() []string
GetAllRequirements returns all unique requirement IDs in the graph (both sources and targets).
func (*DependencyGraph) GetDependencies ¶
func (dg *DependencyGraph) GetDependencies(reqID string) []Dependency
GetDependencies returns all dependencies for a given requirement ID. Returns an empty slice if the requirement has no dependencies.
func (*DependencyGraph) GetReverseDependencies ¶
func (dg *DependencyGraph) GetReverseDependencies(reqID string) []Dependency
GetReverseDependencies returns all requirements that depend on the given requirement ID. This answers the question: "What would be blocked if this requirement changes?"
type DependencyStatus ¶
type DependencyStatus struct {
// Dependency is the dependency being evaluated
Dependency Dependency
// IsSatisfied indicates whether the dependency requirements are met.
// For Full: All features of target are TESTED or BENCHED
// For PartialFeatures: All RequiredFeatures are TESTED or BENCHED
// For PartialAspect: All features of RequiredAspect are TESTED or BENCHED
IsSatisfied bool
// Blocking indicates whether this unsatisfied dependency blocks implementation.
// Set to true when IsSatisfied is false.
Blocking bool
// Message provides human-readable explanation of the status.
// Examples:
// - "All required features are TESTED"
// - "Waiting for CBIN-146:ProjectRegistry to reach TESTED status (currently IMPL)"
// - "Target requirement CBIN-999 does not exist"
Message string
// MissingFeatures lists features that are not yet in TESTED/BENCHED status.
// Only populated for PartialFeatures dependencies when IsSatisfied is false.
MissingFeatures []string
// CurrentStatus describes the current status of the target requirement or features.
// Used for debugging and reporting.
CurrentStatus string
}
DependencyStatus represents the current satisfaction status of a dependency. It indicates whether the dependency is satisfied and provides contextual information.
type DependencyType ¶
type DependencyType int
DependencyType represents the type of dependency relationship between requirements.
const ( // DependencyTypeFull indicates the entire target requirement must be complete // (all features must be in TESTED or BENCHED status). DependencyTypeFull DependencyType = iota // DependencyTypePartialFeatures indicates only specific features of the target // requirement must be complete. DependencyTypePartialFeatures // DependencyTypePartialAspect indicates all features of a specific aspect // of the target requirement must be complete. DependencyTypePartialAspect )
func (DependencyType) String ¶
func (dt DependencyType) String() string
String returns a human-readable string representation of the DependencyType.
type DependencyValidator ¶
type DependencyValidator struct {
// contains filtered or unexported fields
}
DependencyValidator validates dependency graphs for cycles and missing requirements.
func NewDependencyValidator ¶
func NewDependencyValidator(graph *DependencyGraph) *DependencyValidator
NewDependencyValidator creates a new dependency validator for the given graph.
func (*DependencyValidator) SetSpecFinder ¶
func (dv *DependencyValidator) SetSpecFinder(finder SpecFinder)
SetSpecFinder configures the validator to check for missing requirements.
func (*DependencyValidator) Validate ¶
func (dv *DependencyValidator) Validate() ValidationResult
Validate performs comprehensive validation of the dependency graph. It checks for: 1. Circular dependencies (using DFS with recursion stack) 2. Missing requirements (if SpecFinder is configured)
type GraphGenerator ¶
type GraphGenerator struct {
// contains filtered or unexported fields
}
GraphGenerator builds and visualizes dependency graphs.
func NewGraphGenerator ¶
func NewGraphGenerator(loader SpecLoader) *GraphGenerator
NewGraphGenerator creates a new graph generator.
func (*GraphGenerator) BuildGraph ¶
func (gg *GraphGenerator) BuildGraph(reqIDs []string) (*DependencyGraph, error)
BuildGraph builds a complete dependency graph from a list of requirement IDs. It loads dependencies for each requirement and constructs the full graph.
func (*GraphGenerator) FormatASCIITree ¶
func (gg *GraphGenerator) FormatASCIITree(graph *DependencyGraph, rootReqID string) string
FormatASCIITree generates an ASCII tree visualization of the dependency graph. Shows the structure with Unicode box-drawing characters and optional status indicators.
Example output: CBIN-147 (Specification Dependencies) ├── CBIN-146 (Multi-Project Support) ✅ │ └── CBIN-129 (Migrations) ❌ └── CBIN-145 (Legacy Migration) ✅
func (*GraphGenerator) FormatCompactList ¶
func (gg *GraphGenerator) FormatCompactList(graph *DependencyGraph, reqID string) string
FormatCompactList formats dependencies as a compact comma-separated list. Example: "CBIN-146, CBIN-145, CBIN-129"
func (*GraphGenerator) FormatDependencyChain ¶
func (gg *GraphGenerator) FormatDependencyChain(reqIDs []string) string
FormatDependencyChain formats a list of requirement IDs as a chain. Example: "CBIN-147 → CBIN-146 → CBIN-129"
func (*GraphGenerator) FormatDependencySummary ¶
func (gg *GraphGenerator) FormatDependencySummary(graph *DependencyGraph, reqID string) string
FormatDependencySummary generates a multi-line summary of dependencies. Includes direct dependencies, transitive count, and depth.
func (*GraphGenerator) FormatMermaid ¶
func (gg *GraphGenerator) FormatMermaid(graph *DependencyGraph, rootReqID string, urlFor func(string) string) string
FormatMermaid renders the dependency graph rooted at rootReqID as a mermaid flowchart (flowchart TD). Node identifiers are sanitized via mermaidNodeID; node labels are the raw requirement IDs. Edges are deduped and traversal is cycle-safe (each edge is only ever emitted once, so a cycle cannot cause unbounded recursion). urlFor is optional; when it returns a non-empty URL for a requirement ID, a mermaid `click` directive is emitted for that node so viewers can jump straight to the ticket/doc. Click lines are emitted in sorted (deterministic) order.
func (*GraphGenerator) GetDependencyDepth ¶
func (gg *GraphGenerator) GetDependencyDepth(graph *DependencyGraph, reqID string) int
GetDependencyDepth returns the maximum depth of the dependency tree. Depth is the longest path from the root to any leaf node.
func (*GraphGenerator) GetTransitiveDependencies ¶
func (gg *GraphGenerator) GetTransitiveDependencies(graph *DependencyGraph, reqID string) []string
GetTransitiveDependencies returns all transitive dependencies of a requirement. Uses BFS to traverse the dependency graph and collect all reachable requirements.
func (*GraphGenerator) SetStatusChecker ¶
func (gg *GraphGenerator) SetStatusChecker(checker StatusCheckerInterface)
SetStatusChecker configures the generator to show dependency status in visualizations.
type SpecFinder ¶
type SpecFinder interface {
// SpecExists checks if a specification exists for the given requirement ID
SpecExists(reqID string) bool
// FindSpecPath returns the path to the spec.md file for a requirement
FindSpecPath(reqID string) (string, error)
}
SpecFinder is an interface for finding and checking specification existence. This allows validation against the actual filesystem or a mock for testing.
type SpecLoader ¶
type SpecLoader interface {
// LoadDependencies loads all dependencies for a given requirement ID
LoadDependencies(reqID string) ([]Dependency, error)
}
SpecLoader is an interface for loading dependencies from spec files.
type StatusChecker ¶
type StatusChecker struct {
// contains filtered or unexported fields
}
StatusChecker checks whether dependencies are satisfied based on CANARY token status.
func NewStatusChecker ¶
func NewStatusChecker(provider TokenProvider) *StatusChecker
NewStatusChecker creates a new status checker with the given token provider.
func (*StatusChecker) CheckAllDependencies ¶
func (sc *StatusChecker) CheckAllDependencies(deps []Dependency) []DependencyStatus
CheckAllDependencies checks all dependencies and returns their statuses.
func (*StatusChecker) CheckDependency ¶
func (sc *StatusChecker) CheckDependency(dep Dependency) DependencyStatus
CheckDependency checks whether a single dependency is satisfied. Satisfaction rules: - Full: All features of target requirement must be TESTED or BENCHED - PartialFeatures: All RequiredFeatures must be TESTED or BENCHED - PartialAspect: All features of RequiredAspect must be TESTED or BENCHED
IMPL status is NOT sufficient - dependencies require tests.
func (*StatusChecker) FormatBlockingReport ¶
func (sc *StatusChecker) FormatBlockingReport(deps []Dependency) string
FormatBlockingReport generates a human-readable report of blocking dependencies.
func (*StatusChecker) GetBlockingDependencies ¶
func (sc *StatusChecker) GetBlockingDependencies(deps []Dependency) []DependencyStatus
GetBlockingDependencies returns only the dependencies that are blocking (not satisfied).
type StatusCheckerInterface ¶
type StatusCheckerInterface interface {
// IsDependencySatisfied checks if a dependency is satisfied
IsDependencySatisfied(dep Dependency) bool
}
StatusChecker interface for checking dependency satisfaction
type TokenInfo ¶
TokenInfo represents a CANARY token from storage. This is used by StatusChecker to query token status.
type TokenProvider ¶
type TokenProvider interface {
// GetTokensByReqID returns all CANARY tokens for a given requirement ID
GetTokensByReqID(reqID string) []TokenInfo
}
TokenProvider is an interface for retrieving CANARY tokens from storage. This allows the status checker to query token status without tight coupling to storage.
type ValidationResult ¶
type ValidationResult struct {
// IsValid is true if the dependency graph is valid (no cycles, all requirements exist)
IsValid bool
// Cycles contains all detected circular dependencies.
// Each cycle is represented as a slice of requirement IDs forming the cycle.
// Example: ["CBIN-100", "CBIN-101", "CBIN-102", "CBIN-100"]
Cycles [][]string
// MissingRequirements lists requirement IDs that are referenced but don't exist
MissingRequirements []string
// Errors contains human-readable error messages
Errors []string
}
ValidationResult contains the results of dependency validation.
func (*ValidationResult) FormatErrors ¶
func (vr *ValidationResult) FormatErrors() string
FormatErrors returns a formatted string containing all validation errors.