Documentation
¶
Overview ¶
Package domain contains pure domain types for the backlog subsystem. It imports only standard library packages — no ent, no headless, no git deps — so it can be imported by any layer (server, adapters, pkg/events) without creating an import cycle with the parent session package.
Index ¶
- Constants
- Variables
- func CanTransitionBacklog(from, to BacklogStatus) bool
- func TransitionGuard(item BacklogItemTransitionInput, to BacklogStatus) error
- func ValidTransitions() map[BacklogStatus]map[BacklogStatus]bool
- type AcCriteriaJSON
- type AcCriterion
- type AcStatus
- type BacklogItemTransitionInput
- type BacklogStatus
- type CriterionVerdict
- type ReviewOutcome
- type StuckReason
Constants ¶
const ( ReviewVerdictPass = ReviewOutcomePass ReviewVerdictFail = ReviewOutcomeFail ReviewVerdictPartial = ReviewOutcomePartial ReviewVerdictUnverifiable = ReviewOutcomeUnverifiable )
Backward-compatible aliases so callers can be migrated incrementally. Prefer ReviewOutcome* constants in new code.
const DefaultBacklogPriority = 3
DefaultBacklogPriority is the default priority assigned to new backlog items when no priority is specified. Lower values indicate higher priority.
Variables ¶
var ( ErrACRequired = errors.New("acceptance criteria required before marking ready") ErrPlanRequired = errors.New("plan must be approved or skip_planning must be true before spawning work session") ErrPlanArtifactsRequired = errors.New("plan artifacts path is required when planning is not skipped") ErrVerdictRequired = errors.New("PASS verdict or manual override required before marking done") ErrCodeNotOnMain = errors.New("code changes must actually be on main (merged locally or via a merged PR) before marking done; provide override_reason to bypass") )
Sentinel errors for transition guards.
var AllStuckReasons = []StuckReason{ StuckReasonPRReadyUnmerged, StuckReasonReworkCap, StuckReasonAbandonedReview, StuckReasonStaleWork, StuckReasonBouncing, StuckReasonPushFailed, StuckReasonOrphanedTriage, StuckReasonAutonomousStuck, }
AllStuckReasons lists every valid StuckReason constant.
Functions ¶
func CanTransitionBacklog ¶
func CanTransitionBacklog(from, to BacklogStatus) bool
CanTransitionBacklog reports whether a transition from one backlog status to another is permitted.
func TransitionGuard ¶
func TransitionGuard(item BacklogItemTransitionInput, to BacklogStatus) error
TransitionGuard validates business rules before a status transition. It returns nil when the transition is allowed, or a sentinel error when a guard condition is violated. It does NOT check CanTransition — callers must invoke CanTransition separately if structural validity is also required.
func ValidTransitions ¶
func ValidTransitions() map[BacklogStatus]map[BacklogStatus]bool
ValidTransitions returns a deep copy of the authoritative transition table. Callers that need a local snapshot (e.g. for concurrent reads without repeated map lookups) should call this once at construction time.
Types ¶
type AcCriteriaJSON ¶
type AcCriteriaJSON string
AcCriteriaJSON is the JSON-serialized form of []AcCriterion stored in the DB. Using a named type prevents silently passing Description or other string fields where serialized AC criteria are expected.
const AcCriteriaJSONEmpty AcCriteriaJSON = ""
AcCriteriaJSONEmpty is the zero value — an empty criteria list.
func SerializeAcCriteria ¶
func SerializeAcCriteria(criteria []AcCriterion) (AcCriteriaJSON, error)
SerializeAcCriteria serializes acceptance criteria to an AcCriteriaJSON value.
func (AcCriteriaJSON) IsEmpty ¶
func (j AcCriteriaJSON) IsEmpty() bool
IsEmpty reports whether j contains no criteria JSON.
func (AcCriteriaJSON) Parse ¶
func (j AcCriteriaJSON) Parse() ([]AcCriterion, error)
Parse deserializes the criteria from JSON.
type AcCriterion ¶
type AcCriterion struct {
Index int `json:"index"`
Text string `json:"text"`
Status AcStatus `json:"status"` // pending, in_progress, done, fail
Note string `json:"note,omitempty"`
}
AcCriterion is a single acceptance criterion for a backlog item.
func ParseAcCriteria ¶
func ParseAcCriteria(raw AcCriteriaJSON) ([]AcCriterion, error)
ParseAcCriteria deserializes acceptance criteria from a JSON string.
type AcStatus ¶
type AcStatus string
AcStatus represents the status of a single acceptance criterion.
type BacklogItemTransitionInput ¶
type BacklogItemTransitionInput struct {
Status BacklogStatus
AcCriteria AcCriteriaJSON // serialized acceptance criteria
PlanApproved bool
SkipPlanning bool
PlanArtifactsPath string // path to plan artifacts written by triage session
OverallOutcome ReviewOutcome // from linked ReviewVerdict
OverrideReason string
// HasUnshippedCode is true when a work session committed code
// (LastCommitSha != "") that has not been verified to actually be on main —
// locally (merged/committed directly) or remotely (merged PR, pulled or not).
// A PrURL alone does NOT clear this: an open, unmerged, or later-reverted PR
// still has PrURL set, so it was never proof the code shipped. The
// review→done guard uses this to block premature done transitions.
HasUnshippedCode bool
}
BacklogItemTransitionInput carries the fields needed by TransitionGuard.
type BacklogStatus ¶
type BacklogStatus string
BacklogStatus represents the lifecycle state of a backlog item.
const ( BacklogStatusIdea BacklogStatus = "idea" BacklogStatusRefining BacklogStatus = "refining" BacklogStatusReady BacklogStatus = "ready" BacklogStatusInProgress BacklogStatus = "in_progress" BacklogStatusReview BacklogStatus = "review" BacklogStatusPRPending BacklogStatus = "pr_pending" BacklogStatusDone BacklogStatus = "done" BacklogStatusArchived BacklogStatus = "archived" )
type CriterionVerdict ¶
type CriterionVerdict struct {
CriterionIndex int `json:"criterion_index"`
Outcome ReviewOutcome `json:"outcome"`
Evidence string `json:"evidence"`
}
CriterionVerdict holds the review outcome for a single acceptance criterion.
type ReviewOutcome ¶
type ReviewOutcome string
ReviewOutcome is a typed verdict outcome value (PASS, FAIL, PARTIAL, UNVERIFIABLE).
const ( ReviewOutcomePass ReviewOutcome = "PASS" ReviewOutcomeFail ReviewOutcome = "FAIL" ReviewOutcomePartial ReviewOutcome = "PARTIAL" ReviewOutcomeUnverifiable ReviewOutcome = "UNVERIFIABLE" )
func AggregateOutcome ¶
func AggregateOutcome(verdicts []CriterionVerdict) ReviewOutcome
AggregateOutcome computes the overall outcome from a slice of CriterionVerdicts. Priority (highest to lowest): FAIL > PARTIAL > UNVERIFIABLE > PASS. Returns FAIL when the slice is empty to prevent auto-approval of empty reviews.
func (ReviewOutcome) IsValid ¶
func (o ReviewOutcome) IsValid() bool
IsValid reports whether o is a recognised review outcome.
type StuckReason ¶ added in v1.38.0
type StuckReason string
StuckReason is a validated string-backed enum of the classes a backlog item can be "stuck" for — matching the house BacklogStatus/ReviewOutcome style (validated at the boundary via IsValid, not a truly-unrepresentable sum type). Only these compile-time constants should ever reach MarkStuck; no unvalidated string should reach the DB.
const ( // StuckReasonPRReadyUnmerged: a pr_pending item's PR is green, mergeable, // and unmerged past the threshold (see prReadyToMergeSolo). StuckReasonPRReadyUnmerged StuckReason = "pr_ready_unmerged" // StuckReasonReworkCap: the auto-rework loop hit maxAutoReworkIterations // and parked the item for manual action. StuckReasonReworkCap StuckReason = "rework_cap" // StuckReasonAbandonedReview: a review-status item has a review verdict on // record but nothing active in flight. StuckReasonAbandonedReview StuckReason = "abandoned_review" // StuckReasonStaleWork: an in_progress item's active work session reported // no progress for longer than maxWorkSessionStaleness. StuckReasonStaleWork StuckReason = "stale_work" // StuckReasonBouncing: an item crossed in_progress <-> review >= bounceThreshold // times within bounceLookback with no PASS verdict. StuckReasonBouncing StuckReason = "bouncing" // StuckReasonPushFailed: pushAndCreatePR failed (push rejected / gh pr // create errored) leaving a post-review item with no pr_number. StuckReasonPushFailed StuckReason = "push_failed" // StuckReasonOrphanedTriage: an idea-status item's triage session ended // (crashed, was killed, or the process exited) without ever transitioning // the item to ready — previously only surfaced when a human manually // re-triggered triage (tombstoneOrphanTriageSessions); this reason lets the // periodic stuck sweep catch it without a manual retry. StuckReasonOrphanedTriage StuckReason = "orphaned_triage" // StuckReasonAutonomousStuck: an autonomous driver run stopped after // maxTurns without a DONE signal. Previously only surfaced as a one-off // ephemeral notification (onAutonomousDriverComplete), invisible to the // Unfinished tab's durable stuck-reason system. StuckReasonAutonomousStuck StuckReason = "autonomous_stuck" )
func (StuckReason) IsValid ¶ added in v1.38.0
func (r StuckReason) IsValid() bool
IsValid reports whether r is a known stuck reason value.