application

package
v0.23.0 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Overview

Package application provides application services.

Index

Constants

This section is empty.

Variables

View Source
var ErrAIDisabled = fmt.Errorf("model-assisted operations are disabled by project policy (allow_ai: false in .roady/policy.yaml)")

ErrAIDisabled is returned when project policy forbids model-assisted work. The check is kept even though Roady no longer calls a model: a team that set allow_ai=false meant "do not use a model on this project", and that intent does not change because the inference moved to the caller.

Functions

func NewProjectCoordinator added in v0.4.0

func NewProjectCoordinator(repo domain.WorkspaceRepository, audit domain.AuditLogger) *project.Coordinator

NewProjectCoordinator creates a Coordinator using the workspace repository.

func ParseSince added in v0.19.0

func ParseSince(value string, now time.Time) (time.Time, error)

ParseSince interprets a "how far back" window: a relative count of days (`7d`) or weeks (`2w`), or an absolute date (`2026-07-01`). An empty value means the whole history and returns the zero time.

It lives here because the CLI and the MCP server each had their own copy, and the copies disagreed: the CLI parsed with fmt.Sscanf, which stops at the first non-digit and reports no error, so `--since 7xd` silently meant seven days there while the identical string was rejected over MCP. A value a person types by hand should not mean two different things depending on which surface received it, and a malformed one should be refused rather than guessed at.

now is injected so callers can be deterministic in tests.

func ProviderFromPluginPath added in v0.14.0

func ProviderFromPluginPath(pluginPath string) string

ProviderFromPluginPath infers the provider name from a plugin binary path. The name is what task links are filed under, so an unrecognised plugin falling back to "external" would make every third-party syncer collide in ExternalRefs.

func ScanCodebaseTree added in v0.6.0

func ScanCodebaseTree(root string, maxLines int) string

ScanCodebaseTree returns a compact directory tree of source files relative to root. It skips hidden dirs, vendor, node_modules, and binary files. Output is truncated to maxLines to fit AI context windows.

Types

type AddFeatureResult added in v0.18.0

type AddFeatureResult struct {
	// Spec is the specification including the new feature.
	Spec *spec.ProductSpec

	// BacklogPath is the documentation file the feature was appended to,
	// empty when no sync happened.
	BacklogPath string

	// Warnings names what did not happen, for a caller to pass on rather
	// than announce success over.
	Warnings []string
}

AddFeatureResult reports what adding a feature actually changed.

The documentation sync can fail — or be skipped — while the spec write succeeds, so the outcome is more than a spec. Reporting a flat success in that case tells the caller its docs were updated when they were not.

func (*AddFeatureResult) Synced added in v0.18.0

func (r *AddFeatureResult) Synced() bool

Synced reports whether the feature reached the backlog document.

type AuditEventPublisher added in v0.4.0

type AuditEventPublisher struct {
	// contains filtered or unexported fields
}

AuditEventPublisher adapts AuditLogger to project.EventPublisher.

func NewAuditEventPublisher added in v0.4.0

func NewAuditEventPublisher(audit domain.AuditLogger) *AuditEventPublisher

NewAuditEventPublisher creates a new adapter.

func (*AuditEventPublisher) PublishPlanApproved added in v0.4.0

func (p *AuditEventPublisher) PublishPlanApproved(ctx context.Context, planID, approver string) error

PublishPlanApproved implements project.EventPublisher.

func (*AuditEventPublisher) PublishTaskBlocked added in v0.4.0

func (p *AuditEventPublisher) PublishTaskBlocked(ctx context.Context, taskID, reason string) error

PublishTaskBlocked implements project.EventPublisher.

func (*AuditEventPublisher) PublishTaskCompleted added in v0.4.0

func (p *AuditEventPublisher) PublishTaskCompleted(ctx context.Context, taskID, evidence string) error

PublishTaskCompleted implements project.EventPublisher.

func (*AuditEventPublisher) PublishTaskStarted added in v0.4.0

func (p *AuditEventPublisher) PublishTaskStarted(ctx context.Context, taskID, owner, rateID string) error

PublishTaskStarted implements project.EventPublisher.

func (*AuditEventPublisher) PublishTaskUnblocked added in v0.4.0

func (p *AuditEventPublisher) PublishTaskUnblocked(ctx context.Context, taskID string) error

PublishTaskUnblocked implements project.EventPublisher.

type AuditService

type AuditService struct {
	// contains filtered or unexported fields
}

func NewAuditService

func NewAuditService(repo domain.WorkspaceRepository) *AuditService

func (*AuditService) GetTimeline

func (s *AuditService) GetTimeline() ([]domain.Event, error)

func (*AuditService) GetVelocity

func (s *AuditService) GetVelocity() (float64, error)

GetVelocity returns the average verified tasks per day over the last 7 days.

func (*AuditService) Log

func (s *AuditService) Log(action string, actor string, metadata map[string]any) error

func (*AuditService) Provenance added in v0.14.0

func (s *AuditService) Provenance() provenance.Context

Provenance returns the identity currently being stamped.

func (*AuditService) SetProvenance added in v0.14.0

func (s *AuditService) SetProvenance(ctx provenance.Context)

SetProvenance sets the identity stamped onto subsequently recorded events.

func (*AuditService) VerifyIntegrity

func (s *AuditService) VerifyIntegrity() ([]string, error)

func (*AuditService) VerifyIntegrityDetailed added in v0.23.0

func (s *AuditService) VerifyIntegrityDetailed() ([]domain.ChainViolation, error)

VerifyIntegrityDetailed is VerifyIntegrity with the reason for each finding kept alongside it, so a caller can report how many entries failed under an algorithm this build knows — the only count that can mean tampering — separately from history it merely cannot check.

type AuditTrailService added in v0.14.0

type AuditTrailService struct {
	// contains filtered or unexported fields
}

AuditTrailService assembles evidence trails for GRC review from the event log, the plan, and execution state.

func NewAuditTrailService added in v0.14.0

func NewAuditTrailService(audit *EventSourcedAuditService, plain *AuditService, plan *PlanService, repo planStateLoader) *AuditTrailService

NewAuditTrailService wires the service. plain supplies chain verification; a nil plain simply reports the chain as unchecked rather than failing.

func (*AuditTrailService) BuildTrail added in v0.14.0

BuildTrail assembles the trail for the given query.

type BillingService added in v0.7.0

type BillingService struct {
	// contains filtered or unexported fields
}

func NewBillingService added in v0.7.0

func NewBillingService(repo domain.WorkspaceRepository, audit domain.AuditLogger) *BillingService

func (*BillingService) AddRate added in v0.7.0

func (s *BillingService) AddRate(rate billing.Rate) error

func (*BillingService) CompleteTask added in v0.7.0

func (s *BillingService) CompleteTask(taskID string) error

func (*BillingService) GetBudgetStatus added in v0.7.0

func (s *BillingService) GetBudgetStatus() (*billing.BudgetStatus, error)

func (*BillingService) GetCostReport added in v0.7.0

func (s *BillingService) GetCostReport(opts CostReportOpts) (*billing.CostReport, error)

func (*BillingService) GetDefaultRate added in v0.7.0

func (s *BillingService) GetDefaultRate() (*billing.Rate, error)

func (*BillingService) GetRate added in v0.7.0

func (s *BillingService) GetRate(rateID string) (*billing.Rate, error)

func (*BillingService) ListRates added in v0.7.0

func (s *BillingService) ListRates() (*billing.RateConfig, error)

func (*BillingService) LogTime added in v0.7.0

func (s *BillingService) LogTime(taskID string, rateID string, minutes int, description string) error

func (*BillingService) RemoveRate added in v0.7.0

func (s *BillingService) RemoveRate(rateID string) error

func (*BillingService) SetDefaultRate added in v0.7.0

func (s *BillingService) SetDefaultRate(rateID string) error

func (*BillingService) SetTax added in v0.7.0

func (s *BillingService) SetTax(name string, percent float64, included bool) error

func (*BillingService) StartTask added in v0.7.0

func (s *BillingService) StartTask(taskID string, rateID string) error

type CostReportOpts added in v0.7.0

type CostReportOpts struct {
	TaskID string
	Period string
	Format string
}

type DebtService added in v0.4.0

type DebtService struct {
	// contains filtered or unexported fields
}

DebtService provides debt analysis capabilities.

func NewDebtService added in v0.4.0

func NewDebtService(driftSvc *DriftService, auditSvc domain.AuditLogger) *DebtService

NewDebtService creates a new debt service.

func (*DebtService) GetDebtByCategory added in v0.4.0

func (s *DebtService) GetDebtByCategory() (map[debt.DebtCategory][]*debt.DebtItem, error)

GetDebtByCategory returns debt items grouped by category.

func (*DebtService) GetDebtByComponent added in v0.4.0

func (s *DebtService) GetDebtByComponent() (map[string][]*debt.DebtItem, error)

GetDebtByComponent returns debt items grouped by component.

func (*DebtService) GetDebtReport added in v0.4.0

func (s *DebtService) GetDebtReport(ctx context.Context) (*debt.DebtReport, error)

GetDebtReport generates a comprehensive debt report based on current drift.

func (*DebtService) GetDebtScore added in v0.4.0

func (s *DebtService) GetDebtScore(componentID string) (*debt.DebtScore, error)

GetDebtScore calculates the debt score for a specific component.

func (*DebtService) GetDebtSummary added in v0.4.0

func (s *DebtService) GetDebtSummary(ctx context.Context) (*DebtSummary, error)

GetDebtSummary returns a quick overview of the debt status.

func (*DebtService) GetDriftHistory added in v0.4.0

func (s *DebtService) GetDriftHistory(windowDays int) ([]events.DriftSnapshot, error)

GetDriftHistory returns historical drift snapshots.

func (*DebtService) GetDriftTrend added in v0.4.0

func (s *DebtService) GetDriftTrend(windowDays int) (events.DriftTrend, error)

GetDriftTrend analyzes drift patterns over time.

func (*DebtService) GetHealthLevel added in v0.4.0

func (s *DebtService) GetHealthLevel(ctx context.Context) (string, error)

GetHealthLevel returns an overall health assessment based on debt.

func (*DebtService) GetStickyDrift added in v0.4.0

func (s *DebtService) GetStickyDrift() ([]*debt.DebtItem, error)

GetStickyDrift returns all sticky debt items (unresolved >7 days).

func (*DebtService) GetTopDebtors added in v0.4.0

func (s *DebtService) GetTopDebtors(ctx context.Context, limit int) ([]*debt.DebtScore, error)

GetTopDebtors returns the components with the highest debt scores.

func (*DebtService) RecordDriftAccepted added in v0.4.0

func (s *DebtService) RecordDriftAccepted(componentID string, driftType drift.DriftType) error

RecordDriftAccepted records a drift acceptance event.

func (*DebtService) RecordDriftDetection added in v0.4.0

func (s *DebtService) RecordDriftDetection(ctx context.Context, driftReport *drift.Report) error

RecordDriftDetection records a drift detection event for historical tracking.

func (*DebtService) RecordDriftResolved added in v0.4.0

func (s *DebtService) RecordDriftResolved(componentID string, driftType drift.DriftType) error

RecordDriftResolved records a drift resolution event.

type DebtSummary added in v0.4.0

type DebtSummary struct {
	TotalItems     int     `json:"total_items"`
	StickyItems    int     `json:"sticky_items"`
	AverageScore   float64 `json:"average_score"`
	HealthLevel    string  `json:"health_level"`
	TopDebtor      string  `json:"top_debtor,omitempty"`
	TopDebtorScore float64 `json:"top_debtor_score,omitempty"`
}

DebtSummary provides a quick overview of debt status.

type DependencyRepository added in v0.4.0

type DependencyRepository interface {
	SaveDependencyGraph(graph *dependency.DependencyGraph) error
	LoadDependencyGraph() (*dependency.DependencyGraph, error)
	AddDependency(dep *dependency.RepoDependency) error
	RemoveDependency(depID string) error
	GetDependency(depID string) (*dependency.RepoDependency, error)
	ListDependencies() ([]*dependency.RepoDependency, error)
	UpdateRepoHealth(health *dependency.RepoHealth) error
	GetRepoHealth(repoPath string) (*dependency.RepoHealth, error)
}

DependencyRepository defines the storage interface for dependency data.

type DependencyService added in v0.4.0

type DependencyService struct {
	// contains filtered or unexported fields
}

DependencyService manages cross-repo dependencies.

func NewDependencyService added in v0.4.0

func NewDependencyService(repo DependencyRepository, rootPath string) *DependencyService

NewDependencyService creates a new dependency service.

func (*DependencyService) AddDependency added in v0.4.0

func (s *DependencyService) AddDependency(targetRepo string, depType dependency.DependencyType, description string) (*dependency.RepoDependency, error)

AddDependency adds a new dependency to the graph.

func (*DependencyService) CheckForCycles added in v0.4.0

func (s *DependencyService) CheckForCycles() (bool, error)

CheckForCycles checks if the dependency graph has cycles.

func (*DependencyService) GetDependency added in v0.4.0

func (s *DependencyService) GetDependency(depID string) (*dependency.RepoDependency, error)

GetDependency retrieves a specific dependency.

func (*DependencyService) GetDependencyGraph added in v0.4.0

func (s *DependencyService) GetDependencyGraph() (*dependency.DependencyGraph, error)

GetDependencyGraph returns the current dependency graph.

func (*DependencyService) GetDependencyOrder added in v0.4.0

func (s *DependencyService) GetDependencyOrder() ([]string, error)

GetDependencyOrder returns repos in dependency order (dependencies first).

func (*DependencyService) GetDependencySummary added in v0.4.0

func (s *DependencyService) GetDependencySummary() (*dependency.DependencySummary, error)

GetDependencySummary returns a summary of the dependency graph.

func (*DependencyService) GetUnhealthyDependencies added in v0.4.0

func (s *DependencyService) GetUnhealthyDependencies() ([]*dependency.RepoHealth, error)

GetUnhealthyDependencies returns all unhealthy dependencies.

func (*DependencyService) ImportFromSpec added in v0.4.0

func (s *DependencyService) ImportFromSpec(specDeps []dependency.SpecDependency) (*ImportResult, error)

ImportFromSpec imports dependencies from spec configuration.

func (*DependencyService) ListDependencies added in v0.4.0

func (s *DependencyService) ListDependencies() ([]*dependency.RepoDependency, error)

ListDependencies returns all dependencies.

func (*DependencyService) RemoveDependency added in v0.4.0

func (s *DependencyService) RemoveDependency(depID string) error

RemoveDependency removes a dependency by ID.

func (*DependencyService) ScanDependentRepos added in v0.4.0

func (s *DependencyService) ScanDependentRepos(healthScanner HealthScanner) (*ScanResult, error)

ScanDependentRepos scans health status of all dependent repositories.

type DiscoveredProject added in v0.11.0

type DiscoveredProject struct {
	Path       string
	SubProject string
}

DiscoveredProject identifies one project found during a walk. SubProject is empty for the root project of a repo. For sub-projects stored under <Path>/.roady/projects/<name>/, SubProject is set to <name>.

type DispatchOptions added in v0.18.0

type DispatchOptions struct {
	// Agent names the subagent taking the task. It becomes the owner and is
	// recorded against the transition.
	Agent string
	// Session groups the subagent's events. Empty means the dispatching
	// process's own session.
	Session string
	// Start moves the task to in_progress as part of dispatching. Off for a
	// dry run, where the caller wants the brief without claiming the work.
	Start bool
}

DispatchOptions identifies who is being handed the work.

type DispatchService added in v0.18.0

type DispatchService struct {
	// contains filtered or unexported fields
}

DispatchService prepares a ready task for handoff to a subagent.

func NewDispatchService added in v0.18.0

func NewDispatchService(repo domain.WorkspaceRepository, plan *PlanService, taskSvc *TaskService) *DispatchService

func (*DispatchService) Dispatch added in v0.18.0

func (s *DispatchService) Dispatch(ctx context.Context, taskID string, opts DispatchOptions) (*dispatch.Brief, error)

Dispatch builds the brief for a task and, when asked, claims it.

Only a ready task can be dispatched. Handing out work whose dependencies are unmet produces an agent that either blocks or, worse, implements against something that does not exist yet.

func (*DispatchService) SetAuditProvenance added in v0.18.0

func (s *DispatchService) SetAuditProvenance(a ...provenanceSetter)

SetAuditProvenance supplies every audit service whose identity stamp should be swapped while a dispatch is recorded.

type DriftService

type DriftService struct {
	// contains filtered or unexported fields
}

func NewDriftService

func NewDriftService(repo domain.WorkspaceRepository, audit domain.AuditLogger, inspector drift.CodeInspector, policy *PolicyService) *DriftService

func (*DriftService) AcceptDrift added in v0.4.0

func (s *DriftService) AcceptDrift() error

AcceptDrift locks the current spec snapshot and records the acceptance event.

func (*DriftService) DetectDrift

func (s *DriftService) DetectDrift(ctx context.Context) (*drift.Report, error)

func (*DriftService) RecordSemanticDrift added in v0.19.0

func (s *DriftService) RecordSemanticDrift(ctx context.Context, judgements []drift.SemanticJudgement, questions []drift.SemanticQuestion) (*drift.Report, error)

RecordSemanticDrift stores the judgements a caller's model returned for SemanticDrift, turning divergences into drift issues.

The verdict comes from outside Roady, so it is recorded as what it is: an audited assertion by a named caller, not something Roady established by comparing artifacts. Agreement records nothing — this reports drift, not a tally of everything checked.

func (*DriftService) SetActivityInspector added in v0.16.0

func (s *DriftService) SetActivityInspector(a RepoActivityInspector)

SetActivityInspector supplies the repository-movement signal used for staleness detection.

type EventSourcedAuditService added in v0.4.0

type EventSourcedAuditService struct {
	// contains filtered or unexported fields
}

EventSourcedAuditService implements AuditLogger using the event store. It bridges the existing audit interface with the new event sourcing system.

func NewEventSourcedAuditService added in v0.4.0

func NewEventSourcedAuditService(store events.EventStore, publisher events.EventPublisher) (*EventSourcedAuditService, error)

NewEventSourcedAuditService creates a new event-sourced audit service.

func (*EventSourcedAuditService) GetAllTaskStates added in v0.4.0

func (s *EventSourcedAuditService) GetAllTaskStates() map[string]*events.TaskState

GetAllTaskStates returns all task states from the projection.

func (*EventSourcedAuditService) GetCompletionVelocity added in v0.4.0

func (s *EventSourcedAuditService) GetCompletionVelocity() float64

GetCompletionVelocity returns tasks completed per day.

func (*EventSourcedAuditService) GetDispatcher added in v0.4.0

func (s *EventSourcedAuditService) GetDispatcher() *events.EventDispatcher

GetDispatcher returns the event dispatcher.

func (*EventSourcedAuditService) GetProjectedTimeline added in v0.20.0

func (s *EventSourcedAuditService) GetProjectedTimeline() []events.TimelineEntry

GetProjectedTimeline returns the audit timeline from the projection.

Deliberately not called GetTimeline. AuditService.GetTimeline returns the raw event log; this returns rendered projection entries with different fields. Sharing the name made them look interchangeable, and roady_timeline was written against this one while the CLI read the other — so the two surfaces described the same history differently until it was caught.

func (*EventSourcedAuditService) GetRecentTimeline added in v0.4.0

func (s *EventSourcedAuditService) GetRecentTimeline(n int) []events.TimelineEntry

GetRecentTimeline returns the most recent n timeline entries.

func (*EventSourcedAuditService) GetTaskState added in v0.4.0

func (s *EventSourcedAuditService) GetTaskState(taskID string) *events.TaskState

GetTaskState returns the current state of a task from the projection.

func (*EventSourcedAuditService) GetVerificationVelocity added in v0.4.0

func (s *EventSourcedAuditService) GetVerificationVelocity() float64

GetVerificationVelocity returns tasks verified per day.

func (*EventSourcedAuditService) LoadEvents added in v0.4.0

func (s *EventSourcedAuditService) LoadEvents() ([]*events.BaseEvent, error)

LoadEvents returns all events from the store.

func (*EventSourcedAuditService) LoadEventsSince added in v0.4.0

func (s *EventSourcedAuditService) LoadEventsSince(since time.Time) ([]*events.BaseEvent, error)

LoadEventsSince returns events since the given time.

func (*EventSourcedAuditService) Log added in v0.4.0

func (s *EventSourcedAuditService) Log(action string, actor string, metadata map[string]any) error

Log implements domain.AuditLogger.

func (*EventSourcedAuditService) Provenance added in v0.14.0

Provenance returns the identity currently being stamped.

func (*EventSourcedAuditService) RegisterHandler added in v0.4.0

func (s *EventSourcedAuditService) RegisterHandler(reg events.HandlerRegistration)

RegisterHandler registers an event handler with the dispatcher. If no dispatcher is set, this creates one.

func (*EventSourcedAuditService) SetDispatcher added in v0.4.0

func (s *EventSourcedAuditService) SetDispatcher(dispatcher *events.EventDispatcher)

SetDispatcher sets the event dispatcher for this service.

func (*EventSourcedAuditService) SetProvenance added in v0.14.0

func (s *EventSourcedAuditService) SetProvenance(ctx provenance.Context)

SetProvenance sets the identity stamped onto subsequently recorded events.

func (*EventSourcedAuditService) VerifyIntegrity added in v0.4.0

func (s *EventSourcedAuditService) VerifyIntegrity() ([]string, error)

VerifyIntegrity checks the audit chain.

It delegates to domain.VerifyChain, the same implementation AuditService uses. This function previously carried its own, which required each entry to follow the previous line and so reported tampering for the branch-and-merge shape concurrent appends legitimately produce — the case AuditService was fixed for in 0.14.0 and this copy never received. The same events.jsonl could be pronounced intact by one service and tampered-with by the other at the same moment, which makes the verdict evidence of nothing.

type ForecastService added in v0.4.0

type ForecastService struct {
	// contains filtered or unexported fields
}

ForecastService provides enhanced project forecasting with trend analysis.

func NewForecastService added in v0.4.0

func NewForecastService(
	projection *events.ExtendedVelocityProjection,
	repo domain.WorkspaceRepository,
) *ForecastService

NewForecastService creates a new forecast service.

func (*ForecastService) GetBurndown added in v0.4.0

func (s *ForecastService) GetBurndown() ([]analytics.BurndownPoint, error)

GetBurndown returns burndown chart data.

func (*ForecastService) GetForecast added in v0.4.0

func (s *ForecastService) GetForecast() (*analytics.ForecastResult, error)

GetForecast returns a comprehensive forecast for the current project.

func (*ForecastService) GetSimpleForecast added in v0.4.0

func (s *ForecastService) GetSimpleForecast() (*SimpleForecast, error)

GetSimpleForecast returns a simplified forecast result.

func (*ForecastService) GetVelocityStats added in v0.4.0

func (s *ForecastService) GetVelocityStats() analytics.VelocityStats

GetVelocityStats returns statistical summary of velocity.

func (*ForecastService) GetVelocityTrend added in v0.4.0

func (s *ForecastService) GetVelocityTrend() analytics.VelocityTrend

GetVelocityTrend returns the current velocity trend analysis.

func (*ForecastService) GetVelocityWindows added in v0.4.0

func (s *ForecastService) GetVelocityWindows() []analytics.VelocityWindow

GetVelocityWindows returns velocity for each configured time window.

type GitService added in v0.4.0

type GitService struct {
	// contains filtered or unexported fields
}

func NewGitService added in v0.4.0

func NewGitService(repo domain.WorkspaceRepository, taskSvc *TaskService) *GitService

func (*GitService) SyncMarkers added in v0.4.0

func (s *GitService) SyncMarkers(n int) ([]string, error)

SyncMarkers scans the last n commits for [roady:task-id] markers and completes tasks.

type HealthResult added in v0.6.0

type HealthResult struct {
	Name      string       `json:"name"`
	Status    HealthStatus `json:"status"`
	Latency   string       `json:"latency,omitempty"`
	Error     string       `json:"error,omitempty"`
	CheckedAt time.Time    `json:"checked_at"`
}

HealthResult holds health check results for a plugin.

type HealthScanner added in v0.4.0

type HealthScanner interface {
	ScanRepoHealth(repoPath string) (*dependency.RepoHealth, error)
}

HealthScanner defines an interface for scanning repo health.

type HealthStatus added in v0.6.0

type HealthStatus string

HealthStatus represents plugin health state.

const (
	HealthStatusHealthy   HealthStatus = "healthy"
	HealthStatusDegraded  HealthStatus = "degraded"
	HealthStatusUnhealthy HealthStatus = "unhealthy"
	HealthStatusUnknown   HealthStatus = "unknown"
)

type ImportResult added in v0.4.0

type ImportResult struct {
	Imported int               `json:"imported"`
	Skipped  int               `json:"skipped"`
	Errors   map[string]string `json:"errors,omitempty"`
}

ImportResult contains the results of importing dependencies from spec.

type InitService

type InitService struct {
	// contains filtered or unexported fields
}

func NewInitService

func NewInitService(repo domain.WorkspaceRepository, audit domain.AuditLogger) *InitService

func (*InitService) InitializeProject

func (s *InitService) InitializeProject(name string) error

func (*InitService) SetTemplate added in v0.6.0

func (s *InitService) SetTemplate(name string)

SetTemplate sets the template to use for project initialization.

type LockResult added in v0.21.0

type LockResult struct {
	SpecID       string
	LockUpdated  bool
	StateUpdated bool
}

LockResult reports what WriteLock changed, so a no-op says so and the command is safe to re-run in a script.

func (LockResult) Changed added in v0.21.0

func (r LockResult) Changed() bool

Changed reports whether anything was rewritten.

type LockState added in v0.21.0

type LockState struct {
	// SpecID is the id the specification declares.
	SpecID string
	// LockID is the id the drift baseline was captured under.
	LockID string
	// StateID is the project id execution state was created under.
	StateID string

	// LockPresent is false when no baseline has been captured at all.
	LockPresent bool
	// StatePresent is false when execution state does not exist yet.
	StatePresent bool
}

LockState reports whether the files derived from the spec still agree with it.

`roady init --template x` writes spec.yaml, spec.lock.json and state.json together, so they agree by construction. The realistic adoption path then replaces spec.yaml with one describing the actual project — and the two derived files keep the template's identity. Nothing reconciled them and nothing reported it, while `spec validate` answered "valid", which reads as "everything here is fine" at exactly the moment it is not.

func (LockState) InSync added in v0.21.0

func (s LockState) InSync() bool

InSync reports whether every derived file agrees with the spec.

func (LockState) Problems added in v0.21.0

func (s LockState) Problems() []string

Problems describes each disagreement and how to resolve it.

type OrgService added in v0.6.0

type OrgService struct {
	// contains filtered or unexported fields
}

OrgService provides organizational multi-project operations.

func NewOrgService added in v0.6.0

func NewOrgService(root string) *OrgService

NewOrgService creates a new OrgService rooted at the given directory.

func (*OrgService) AggregateMetrics added in v0.6.0

func (s *OrgService) AggregateMetrics() (*org.OrgMetrics, error)

AggregateMetrics collects metrics across the workspace's member repositories, including sub-projects under each repo's .roady/projects/<name>/.

Membership comes from org.yaml when it declares repos, so the aggregate covers repositories outside this directory and excludes checkouts inside it that nobody claimed. Without a declaration it walks the tree as before.

func (*OrgService) DetectCrossDrift added in v0.6.0

func (s *OrgService) DetectCrossDrift() (*org.CrossDriftReport, error)

DetectCrossDrift aggregates drift reports across the workspace's member repositories, including their sub-projects.

func (*OrgService) DiscoverProjects added in v0.6.0

func (s *OrgService) DiscoverProjects() ([]string, error)

DiscoverProjects walks the root directory tree and returns paths containing .roady directories. Backward-compatible shape — only root projects are returned. For full sub-project discovery use DiscoverProjectsWithSub.

func (*OrgService) DiscoverProjectsWithSub added in v0.11.0

func (s *OrgService) DiscoverProjectsWithSub() ([]DiscoveredProject, error)

DiscoverProjectsWithSub walks the root directory tree and returns every project found — both the root project of each repo (where a .roady/ lives) and every named sub-project under <repo>/.roady/projects/<name>/.

func (*OrgService) LoadMergedPolicy added in v0.6.0

func (s *OrgService) LoadMergedPolicy(projectPath string) (*policy.PolicyConfig, error)

LoadMergedPolicy loads org-level SharedPolicy and overlays project-level policy.yaml values.

func (*OrgService) LoadOrgConfig added in v0.6.0

func (s *OrgService) LoadOrgConfig() (*org.OrgConfig, error)

LoadOrgConfig loads the org config from .roady/org.yaml in the root directory.

func (*OrgService) ResolveMembers added in v0.19.0

func (s *OrgService) ResolveMembers() (*org.MemberSet, error)

ResolveMembers returns the repositories belonging to this workspace.

org.yaml has carried a repos: list since the type was introduced and nothing ever read it. A workspace could therefore declare its members and Roady would quietly walk the tree instead — missing any repository outside the root, silently including any scratch checkout inside it, and reporting aggregate progress that answered a different question from the one asked.

A declared list is now authoritative. Discovery remains the behaviour when nothing is declared, because declaring members is an option rather than a requirement, and a workspace that has never needed the distinction should not have to start.

func (*OrgService) SaveOrgConfig added in v0.6.0

func (s *OrgService) SaveOrgConfig(config *org.OrgConfig) error

SaveOrgConfig saves the org config to .roady/org.yaml in the root directory.

type PlanRepositoryAdapter added in v0.4.0

type PlanRepositoryAdapter struct {
	// contains filtered or unexported fields
}

PlanRepositoryAdapter adapts WorkspaceRepository to project.PlanRepository.

func NewPlanRepositoryAdapter added in v0.4.0

func NewPlanRepositoryAdapter(repo domain.WorkspaceRepository) *PlanRepositoryAdapter

NewPlanRepositoryAdapter creates a new adapter.

func (*PlanRepositoryAdapter) Load added in v0.4.0

Load implements project.PlanRepository.

func (*PlanRepositoryAdapter) Save added in v0.4.0

Save implements project.PlanRepository.

type PlanService

type PlanService struct {
	// contains filtered or unexported fields
}

func NewPlanService

func NewPlanService(repo domain.WorkspaceRepository, audit domain.AuditLogger) *PlanService

func (*PlanService) ApprovePlan

func (s *PlanService) ApprovePlan() error

func (*PlanService) ApprovePlanWithActor added in v0.4.0

func (s *PlanService) ApprovePlanWithActor(actor string) error

ApprovePlanWithActor atomically approves the plan and initializes task states.

func (*PlanService) GeneratePlan

func (s *PlanService) GeneratePlan(ctx context.Context) (*planning.Plan, error)

GeneratePlan updates the Plan based on the current Spec using a default heuristic.

func (*PlanService) GetBlockedTasks added in v0.4.0

func (s *PlanService) GetBlockedTasks(ctx context.Context) ([]project.TaskSummary, error)

GetBlockedTasks returns tasks that are currently blocked.

func (*PlanService) GetCoordinator added in v0.4.0

func (s *PlanService) GetCoordinator() *project.Coordinator

GetCoordinator returns the underlying project coordinator for advanced operations.

func (*PlanService) GetInProgressTasks added in v0.4.0

func (s *PlanService) GetInProgressTasks(ctx context.Context) ([]project.TaskSummary, error)

GetInProgressTasks returns tasks that are currently in progress.

func (*PlanService) GetPlan

func (s *PlanService) GetPlan() (*planning.Plan, error)

func (*PlanService) GetProjectSnapshot added in v0.4.0

func (s *PlanService) GetProjectSnapshot(ctx context.Context) (*project.ProjectSnapshot, error)

GetProjectSnapshot returns a consistent view of plan and execution state.

func (*PlanService) GetReadyTasks added in v0.4.0

func (s *PlanService) GetReadyTasks(ctx context.Context) ([]project.TaskSummary, error)

GetReadyTasks returns tasks that are ready to be started (unlocked and pending).

func (*PlanService) GetState

func (s *PlanService) GetState() (*planning.ExecutionState, error)

func (*PlanService) GetTaskSummaries added in v0.4.0

func (s *PlanService) GetTaskSummaries(ctx context.Context) ([]project.TaskSummary, error)

GetTaskSummaries returns summaries of all tasks with their current status.

func (*PlanService) GetTasksByOwner added in v0.14.0

func (s *PlanService) GetTasksByOwner(ctx context.Context, owner string) ([]project.TaskSummary, error)

GetTasksByOwner returns tasks assigned to owner. An empty owner returns unassigned tasks.

func (*PlanService) GetUsage

func (s *PlanService) GetUsage() (*domain.UsageStats, error)

func (*PlanService) PrunePlan

func (s *PlanService) PrunePlan() error

func (*PlanService) ReconcilePlan

func (s *PlanService) ReconcilePlan(proposedTasks []planning.Task) (*planning.Plan, []string, error)

ReconcilePlan merges new tasks with the existing plan state, returning any feature links it could not resolve.

func (*PlanService) RejectPlan

func (s *PlanService) RejectPlan() error

func (*PlanService) UpdatePlan

func (s *PlanService) UpdatePlan(tasks []planning.Task) (*planning.Plan, []string, error)

UpdatePlan replaces the plan's tasks with a caller-supplied set, which is how an external agent writes a plan back.

The warnings it returns name links Roady could not make sense of. They are not errors — the plan is written either way — but a caller that ignores them has written a plan that drift will report as orphaned.

type PluginConfigRepository added in v0.4.0

type PluginConfigRepository interface {
	LoadPluginConfigs() (*domainPlugin.PluginConfigs, error)
	GetPluginConfig(name string) (*domainPlugin.PluginConfig, error)
	SetPluginConfig(name string, cfg domainPlugin.PluginConfig) error
}

PluginConfigRepository provides access to plugin configurations

type PluginInfo added in v0.6.0

type PluginInfo struct {
	Name        string `json:"name"`
	Binary      string `json:"binary"`
	Version     string `json:"version,omitempty"`
	Description string `json:"description,omitempty"`
	Status      string `json:"status"` // "available", "missing", "unknown"
}

PluginInfo represents enriched plugin information.

type PluginService added in v0.6.0

type PluginService struct {
	// contains filtered or unexported fields
}

PluginService manages plugin registration, validation, and health.

func NewPluginService added in v0.6.0

func NewPluginService(repo *storage.FilesystemRepository) *PluginService

NewPluginService creates a new PluginService.

func (*PluginService) CheckAllHealth added in v0.6.0

func (s *PluginService) CheckAllHealth() (map[string]*HealthResult, error)

CheckAllHealth checks health of all registered plugins.

func (*PluginService) CheckHealth added in v0.6.0

func (s *PluginService) CheckHealth(name string) (*HealthResult, error)

CheckHealth checks the health of a single plugin.

func (*PluginService) ListPlugins added in v0.6.0

func (s *PluginService) ListPlugins() ([]PluginInfo, error)

ListPlugins returns all registered plugins with status information.

func (*PluginService) RegisterPlugin added in v0.6.0

func (s *PluginService) RegisterPlugin(name, binaryPath string) error

RegisterPlugin registers a plugin by name and binary path.

func (*PluginService) UnregisterPlugin added in v0.6.0

func (s *PluginService) UnregisterPlugin(name string) error

UnregisterPlugin removes a plugin by name.

func (*PluginService) ValidatePlugin added in v0.6.0

func (s *PluginService) ValidatePlugin(name string) (*ValidationResult, error)

ValidatePlugin loads a plugin and calls Init() to verify it works.

type PolicyService

type PolicyService struct {
	// contains filtered or unexported fields
}

func NewPolicyService

func NewPolicyService(repo domain.WorkspaceRepository) *PolicyService

func (*PolicyService) CheckCompliance

func (s *PolicyService) CheckCompliance() ([]policy.Violation, error)

CheckCompliance validates the current plan against active policies.

func (*PolicyService) ValidateActorCanTransition added in v0.14.0

func (s *PolicyService) ValidateActorCanTransition(actor string) error

ValidateActorCanTransition enforces .roady/team.yaml roles when the policy opts in via enforce_team_roles.

Enforcement is deliberately narrow: only an actor *listed* in team.yaml is checked. An unlisted actor passes, because team.yaml has always been a partial roster rather than an access-control list, and treating absence as denial would lock out every existing project the moment the flag is set. The rule it does enforce is the one people actually want: someone recorded as a viewer cannot move tasks.

func (*PolicyService) ValidateTransition

func (s *PolicyService) ValidateTransition(taskID string, event string) error

func (*PolicyService) ValidateTransitionForOwner added in v0.14.0

func (s *PolicyService) ValidateTransitionForOwner(taskID, event, owner string) error

ValidateTransitionForOwner is ValidateTransition with the acting owner known, which is what per-owner WIP limits need. An empty owner skips the per-owner check.

type PromptService added in v0.15.0

type PromptService struct {
	// contains filtered or unexported fields
}

PromptService assembles the context a language model needs, and hands it back rather than running inference.

It replaces AIPlanningService's provider calls. The prompt text is carried over unchanged — the value was always in knowing which parts of the spec, plan, and drift report matter for each question, and that judgement is still Roady's.

func NewPromptService added in v0.15.0

func NewPromptService(repo domain.WorkspaceRepository) *PromptService

func (*PromptService) DecomposeSpec added in v0.15.0

func (s *PromptService) DecomposeSpec(_ context.Context) (*prompt.Request, error)

DecomposeSpec builds a request to turn the spec into a task DAG.

func (*PromptService) ExplainDrift added in v0.15.0

func (s *PromptService) ExplainDrift(_ context.Context, report *drift.Report) (*prompt.Request, error)

ExplainDrift builds a request explaining a drift report in plain language.

func (*PromptService) ExplainSpec added in v0.15.0

func (s *PromptService) ExplainSpec(_ context.Context) (*prompt.Request, error)

ExplainSpec builds a request for a plain-language walkthrough of the spec.

func (*PromptService) PatchDrift added in v0.18.0

func (s *PromptService) PatchDrift(_ context.Context, report *drift.Report) (*prompt.Request, error)

PatchDrift builds a request asking for a patch that closes the drift, rather than prose explaining it.

The distinction is what the caller does next. ExplainDrift produces something a person reads; this produces something applied and reviewed, so it names the file each issue points at and asks for a unified diff. Roady frames the question and does not answer it — the caller's model has the working tree in view and Roady does not.

func (*PromptService) QueryProject added in v0.15.0

func (s *PromptService) QueryProject(_ context.Context, question string) (*prompt.Request, error)

QueryProject builds a request answering a free-form question about the project, with spec, plan, and state as context.

func (*PromptService) ReviewSpec added in v0.15.0

func (s *PromptService) ReviewSpec(_ context.Context) (*prompt.Request, error)

ReviewSpec builds a request for a critique of the spec.

func (*PromptService) SemanticDrift added in v0.19.0

SemanticDrift builds the question every other drift check cannot ask.

The structural detectors decide by comparing artifacts: a task is missing, an id is orphaned, a file does not exist. None of them can tell whether code that exists still does what the requirement asked for — "sessions expire after 30 minutes" is structurally satisfied by an implementation that expires them after thirty days. Answering that needs a reader.

So Roady assembles the pairing and hands it over: the requirement's own words, where the work landed, and the doc:line to check against. It does not judge. The caller's model has the working tree in view and Roady does not, which is the same reason PatchDrift returns a request rather than a diff.

Only requirements something claims to implement are asked about. A requirement with no task is structural drift the other detectors already report, and asking a model about absent code invites a confident answer about nothing.

func (*PromptService) SuggestPriorities added in v0.15.0

func (s *PromptService) SuggestPriorities(_ context.Context) (*prompt.Request, error)

SuggestPriorities builds a request to re-prioritise the current plan.

type RebuildResult added in v0.14.0

type RebuildResult struct {
	EventsReplayed int
	TasksAffected  int
	Changed        []StateChange
}

RebuildResult reports what a replay produced.

type RepoActivityInspector added in v0.16.0

type RepoActivityInspector interface {
	ActivitySince(since time.Time) drift.RepoActivity
}

RepoActivityInspector reports how far the repository has moved since a point in time. Injected so the domain stays free of git.

type ReportOptions added in v0.14.0

type ReportOptions struct {
	// Project names the project in the report header.
	Project string
	// Since bounds the "what changed" section. Zero means the whole history.
	Since time.Time
	// MaxChanges caps the change list so a long-running project does not
	// produce an unreadable report. Zero applies a sensible default.
	MaxChanges int
	// Now is the report timestamp, injectable for deterministic tests.
	Now time.Time
}

ReportOptions controls what a generated report covers.

type ReportService added in v0.14.0

type ReportService struct {
	// contains filtered or unexported fields
}

ReportService assembles a stakeholder-facing progress report from the planning, forecasting, drift, debt, and audit services. It owns no state of its own — it is a read-only composition over what those services already know.

func NewReportService added in v0.14.0

func NewReportService(
	plan *PlanService,
	forecast *ForecastService,
	driftSvc *DriftService,
	debtSvc *DebtService,
	audit *EventSourcedAuditService,
) *ReportService

NewReportService wires a ReportService. Every collaborator except plan is optional; a nil collaborator simply omits its section from the report, so a project without drift history or an event log still produces something useful.

func (*ReportService) Generate added in v0.14.0

func (s *ReportService) Generate(ctx context.Context, opts ReportOptions) (*report.Report, error)

Generate builds a report. Sections whose underlying service is unavailable or errors are omitted rather than failing the whole report: a stakeholder report that renders without a forecast is far more useful than no report.

type ScanResult added in v0.4.0

type ScanResult struct {
	ScannedAt      time.Time                         `json:"scanned_at"`
	TotalRepos     int                               `json:"total_repos"`
	HealthyRepos   int                               `json:"healthy_repos"`
	UnhealthyRepos int                               `json:"unhealthy_repos"`
	Unreachable    int                               `json:"unreachable"`
	Details        map[string]*dependency.RepoHealth `json:"details"`
}

ScanResult contains the results of a dependency scan.

func (*ScanResult) AllHealthy added in v0.4.0

func (r *ScanResult) AllHealthy() bool

AllHealthy returns true if all repos are healthy.

type SimpleForecast added in v0.4.0

type SimpleForecast struct {
	Velocity       float64
	RemainingTasks int
	TotalTasks     int
	EstimatedDays  float64
	Trend          analytics.TrendDirection
	TrendSlope     float64
}

SimpleForecast provides basic forecasting without the full service infrastructure. Useful for CLI commands that don't need all the complexity.

type SpecService

type SpecService struct {
	// contains filtered or unexported fields
}

func NewSpecService

func NewSpecService(repo domain.WorkspaceRepository) *SpecService

func (*SpecService) AddFeature

func (s *SpecService) AddFeature(title, description string) (*AddFeatureResult, error)

AddFeature adds a new functional unit and syncs it back to documentation.

func (*SpecService) AnalyzeDirectory

func (s *SpecService) AnalyzeDirectory(root string) (*spec.ProductSpec, error)

AnalyzeDirectory crawls a directory for markdown files and merges them into a single Spec.

func (*SpecService) GetSpec

func (s *SpecService) GetSpec() (*spec.ProductSpec, error)

func (*SpecService) ImportFromMarkdown

func (s *SpecService) ImportFromMarkdown(path string) (*spec.ProductSpec, error)

ImportFromMarkdown reads a markdown file and converts it into a ProductSpec.

func (*SpecService) LockStatus added in v0.21.0

func (s *SpecService) LockStatus() (*LockState, error)

LockStatus compares the files derived from the spec against it.

func (*SpecService) WriteLock added in v0.21.0

func (s *SpecService) WriteLock() (*LockResult, error)

WriteLock re-captures the drift baseline from the current spec and reconciles the execution state's project id with it.

It exists because there was no supported way to do either. An adopter who replaced the generated spec had to hand-write spec.lock.json — which works until it silently does not, since the lock is what every later drift check compares against.

type StateChange added in v0.14.0

type StateChange struct {
	TaskID string
	From   planning.TaskStatus
	To     planning.TaskStatus
}

StateChange is one task whose rebuilt status differs from what was on disk.

type StateRebuildService added in v0.14.0

type StateRebuildService struct {
	// contains filtered or unexported fields
}

StateRebuildService reconstructs execution state by replaying the event log.

state.json is a whole-file JSON document, so two collaborators who both moved a task conflict on it in git even when their work does not actually disagree. events.jsonl does not have that problem: it is append-only and union-merges cleanly. Rebuilding makes the conflict trivial to resolve — take either side, replay, and the result is the same either way.

func NewStateRebuildService added in v0.14.0

func NewStateRebuildService(repo domain.WorkspaceRepository) *StateRebuildService

func (*StateRebuildService) Rebuild added in v0.14.0

Rebuild replays the log and returns the resulting state without saving.

func (*StateRebuildService) Save added in v0.14.0

func (s *StateRebuildService) Save() (*RebuildResult, error)

Save replays and persists the result.

type StateRepositoryAdapter added in v0.4.0

type StateRepositoryAdapter struct {
	// contains filtered or unexported fields
}

StateRepositoryAdapter adapts WorkspaceRepository to project.StateRepository.

func NewStateRepositoryAdapter added in v0.4.0

func NewStateRepositoryAdapter(repo domain.WorkspaceRepository) *StateRepositoryAdapter

NewStateRepositoryAdapter creates a new adapter.

func (*StateRepositoryAdapter) Load added in v0.4.0

Load implements project.StateRepository.

func (*StateRepositoryAdapter) Save added in v0.4.0

Save implements project.StateRepository.

type SubProjectResolver added in v0.18.0

type SubProjectResolver struct {
	// contains filtered or unexported fields
}

SubProjectResolver answers cross-project dependency lookups by reading the named sub-project's execution state under .roady/projects/<name>/.

It exists so the domain can ask "is @auth:task-signup done?" without knowing anything about directories.

func NewSubProjectResolver added in v0.18.0

func NewSubProjectResolver(root string) *SubProjectResolver

func (*SubProjectResolver) ExternalTaskStatus added in v0.18.0

func (r *SubProjectResolver) ExternalTaskStatus(projectName, taskID string) (planning.TaskStatus, bool)

ExternalTaskStatus reports a task's status in another sub-project.

The second return distinguishes "not done" from "cannot be found", which callers need: an unresolvable reference is a broken plan, while an incomplete one is ordinary work in progress. Both block, for different reasons.

type SyncResult added in v0.6.0

type SyncResult struct {
	Action   string   `json:"action"`
	Files    []string `json:"files,omitempty"`
	Conflict bool     `json:"conflict"`
	Message  string   `json:"message"`
}

SyncResult holds the outcome of a push or pull operation.

type SyncService added in v0.4.0

type SyncService struct {
	// contains filtered or unexported fields
}

func NewSyncService added in v0.4.0

func NewSyncService(repo domain.WorkspaceRepository, taskSvc *TaskService) *SyncService

func NewSyncServiceWithPlugins added in v0.4.0

func NewSyncServiceWithPlugins(repo domain.WorkspaceRepository, pluginRepo PluginConfigRepository, taskSvc *TaskService) *SyncService

NewSyncServiceWithPlugins creates a SyncService with plugin config support

func (*SyncService) GetPluginConfig added in v0.4.0

func (s *SyncService) GetPluginConfig(name string) (*domainPlugin.PluginConfig, error)

GetPluginConfig returns the configuration for a named plugin

func (*SyncService) ListPluginConfigs added in v0.4.0

func (s *SyncService) ListPluginConfigs() ([]string, error)

ListPluginConfigs returns all configured plugin names

func (*SyncService) SetPluginConfig added in v0.4.0

func (s *SyncService) SetPluginConfig(name string, cfg domainPlugin.PluginConfig) error

SetPluginConfig saves a plugin configuration

func (*SyncService) SetPushEnabled added in v0.14.0

func (s *SyncService) SetPushEnabled(enabled bool)

SetPushEnabled turns write-back to the external tracker on or off.

func (*SyncService) SyncWithNamedPlugin added in v0.4.0

func (s *SyncService) SyncWithNamedPlugin(name string) ([]string, error)

SyncWithNamedPlugin syncs using a named plugin configuration from plugins.yaml

func (*SyncService) SyncWithPlugin added in v0.4.0

func (s *SyncService) SyncWithPlugin(pluginPath string) ([]string, error)

SyncWithPlugin syncs using a plugin binary path (uses empty config, relies on env vars)

func (*SyncService) SyncWithPluginConfig added in v0.4.0

func (s *SyncService) SyncWithPluginConfig(pluginPath string, config map[string]string) ([]string, error)

SyncWithPluginConfig syncs using a plugin binary path with explicit configuration

type TaskService

type TaskService struct {
	// contains filtered or unexported fields
}

func NewTaskService

func NewTaskService(repo domain.WorkspaceRepository, audit domain.AuditLogger, policy *PolicyService) *TaskService

func (*TaskService) AssignTask added in v0.6.0

func (s *TaskService) AssignTask(_ context.Context, taskID, assignee string) error

AssignTask sets the owner on a task without requiring a status transition.

func (*TaskService) BlockTask added in v0.4.0

func (s *TaskService) BlockTask(ctx context.Context, taskID, reason string) error

BlockTask blocks a task with a reason.

func (*TaskService) CompleteTask added in v0.4.0

func (s *TaskService) CompleteTask(ctx context.Context, taskID, evidence string) ([]string, error)

CompleteTask completes a task and returns newly unlocked task IDs.

func (*TaskService) GetCoordinator added in v0.4.0

func (s *TaskService) GetCoordinator() *project.Coordinator

GetCoordinator returns the underlying project coordinator for advanced operations.

func (*TaskService) LinkTask

func (s *TaskService) LinkTask(taskID string, provider string, ref planning.ExternalRef) error

func (*TaskService) ReopenTask added in v0.12.0

func (s *TaskService) ReopenTask(ctx context.Context, taskID string) error

ReopenTask transitions a Done or Verified task back to Pending so it can be re-planned and started again.

func (*TaskService) StartTask added in v0.4.0

func (s *TaskService) StartTask(ctx context.Context, taskID, owner, rateID string) error

StartTask starts a task using the coordinator with proper dependency validation.

func (*TaskService) TransitionTask

func (s *TaskService) TransitionTask(taskID string, event string, actor string, evidence string) error

func (*TaskService) UnblockTask added in v0.4.0

func (s *TaskService) UnblockTask(ctx context.Context, taskID string) error

UnblockTask unblocks a previously blocked task.

func (*TaskService) VerifyTask added in v0.4.0

func (s *TaskService) VerifyTask(ctx context.Context, taskID, verifier string) error

VerifyTask marks a completed task as verified.

type TeamService added in v0.6.0

type TeamService struct {
	// contains filtered or unexported fields
}

TeamService manages team membership and role-based access.

func NewTeamService added in v0.6.0

func NewTeamService(repo *storage.FilesystemRepository, audit domain.AuditLogger) *TeamService

func (*TeamService) AddMember added in v0.6.0

func (s *TeamService) AddMember(name string, role team.Role) error

AddMember adds or updates a team member.

func (*TeamService) GetMemberRole added in v0.6.0

func (s *TeamService) GetMemberRole(name string) (team.Role, error)

GetMemberRole returns the role for a given member name, or empty if not found.

func (*TeamService) ListMembers added in v0.6.0

func (s *TeamService) ListMembers() (*team.TeamConfig, error)

ListMembers returns the current team configuration.

func (*TeamService) RemoveMember added in v0.6.0

func (s *TeamService) RemoveMember(name string) error

RemoveMember removes a team member.

type Template added in v0.6.0

type Template struct {
	Name        string
	Description string
	Spec        func(projectName string) *spec.ProductSpec
}

Template represents a starter project template.

func BuiltinTemplates added in v0.6.0

func BuiltinTemplates() []Template

BuiltinTemplates returns the available starter templates.

func FindTemplate added in v0.6.0

func FindTemplate(name string) *Template

FindTemplate returns the template with the given name, or nil.

type TrailQuery added in v0.14.0

type TrailQuery struct {
	TaskID    string
	Agent     string
	SessionID string
	Since     time.Time
	Now       time.Time
}

TrailQuery selects what to build a trail about. Exactly one of TaskID, Agent, or SessionID identifies the subject.

type UsageService added in v0.4.0

type UsageService struct {
	// contains filtered or unexported fields
}

UsageService tracks command and AI token usage separately from audit logging.

func NewUsageService added in v0.4.0

func NewUsageService(repo domain.WorkspaceRepository) *UsageService

func (*UsageService) GetTotalTokens added in v0.4.0

func (s *UsageService) GetTotalTokens() (int, error)

GetTotalTokens returns the total token count across all providers.

func (*UsageService) GetUsage added in v0.4.0

func (s *UsageService) GetUsage() (*domain.UsageStats, error)

GetUsage returns the current usage statistics.

func (*UsageService) IncrementCommand added in v0.4.0

func (s *UsageService) IncrementCommand() error

IncrementCommand records that a command was executed.

func (*UsageService) RecordTokenUsage added in v0.4.0

func (s *UsageService) RecordTokenUsage(model string, inputTokens, outputTokens int) error

RecordTokenUsage records AI token usage for a specific model.

type ValidationResult added in v0.6.0

type ValidationResult struct {
	Name    string `json:"name"`
	Valid   bool   `json:"valid"`
	Error   string `json:"error,omitempty"`
	Latency string `json:"latency,omitempty"`
}

ValidationResult holds the result of plugin validation.

type WorkspaceSyncService added in v0.6.0

type WorkspaceSyncService struct {
	// contains filtered or unexported fields
}

WorkspaceSyncService handles git-based synchronization of the .roady/ directory.

func NewWorkspaceSyncService added in v0.6.0

func NewWorkspaceSyncService(root string, audit domain.AuditLogger) *WorkspaceSyncService

func (*WorkspaceSyncService) Pull added in v0.6.0

Pull fetches remote changes and merges .roady/ files. Returns conflict info if merge fails.

func (*WorkspaceSyncService) Push added in v0.6.0

Push stages and commits .roady/ changes, then pushes to the remote.

Jump to

Keyboard shortcuts

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