gate

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 17, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package gate holds the rules about when a ticket may move.

These are pure functions over already-loaded state, deliberately separated from the store. Two reasons: they can be unit-tested without touching a filesystem, and there is exactly one file to change when a rule changes — the CLI and the TUI both call in here rather than each carrying their own copy, which is the only way "enforced identically by both interfaces" is true rather than merely intended.

Index

Constants

View Source
const (
	CodeMissingField    = "missing_field"
	CodeBlocked         = "blocked"
	CodeUnknownLane     = "unknown_lane"
	CodeNoSuchLane      = "no_such_lane"
	CodeMissingOutcome  = "missing_outcome"
	CodeNeedsSignal     = "needs_nonmodel_signal"
	CodeNeedsQuestion   = "needs_question"
	CodeNeedsReason     = "needs_blocked_reason"
	CodeNeedsCommits    = "needs_commits"
	CodeSelfBlock       = "self_block"
	CodeMissingProduces = "missing_lane_output"
	CodePlanIncomplete  = "plan_incomplete"
	CodeNeedsHuman      = "needs_human"
	CodeStepNotChosen   = "step_not_chosen"
	CodeNotOwner        = "not_owner"
)

Violation codes. Agents branch on these, so they are stable strings rather than prose that might be reworded.

Variables

PromotionFields are required before a ticket may leave the backlog.

The point of the gate is that capture should be frictionless while execution should not be: anything can be thrown into the backlog, but nothing starts without a goal, a definition of done, the context it came from, and a human who owns the outcome. Acquiring those is the price of admission to a run.

Functions

func Actionable

func Actionable(env Env, t *ticket.Ticket) bool

Actionable reports whether a ticket could be picked up right now.

func Ready

func Ready(t *ticket.Ticket) bool

Ready reports whether a ticket satisfies the promotion gate, without reference to any particular target lane.

Types

type Env

type Env struct {
	Lanes *lane.Set
	// All is every ticket, used to evaluate blockers. Only id and status are read.
	All []*ticket.Ticket
}

Env is the surrounding state a decision needs.

type Request

type Request struct {
	To string

	// Question accompanies a move into a lane that requires one.
	Question string

	// Reason accompanies a move into a lane that will not take a ticket without
	// knowing what it is waiting on.
	Reason string

	// Actor is who is performing the move, used only in messages.
	Actor string

	// Interactive marks a move a person made by hand, in the board. It is the
	// only distinction available that an agent cannot simply assert: an agent
	// drives the CLI, and cannot press a key in someone's terminal. Lanes that
	// require a human to release a ticket rely on it.
	Interactive bool

	// NewAssignee accompanies a move that also hands the ticket to someone
	// else. A hand-over is always allowed, regardless of who currently owns
	// the ticket — otherwise an absent owner could freeze it forever.
	NewAssignee string
}

Request describes a proposed move.

type Violation

type Violation struct {
	Code    string `json:"code"`
	Field   string `json:"field,omitempty"`
	Message string `json:"message"`
}

Violation is one reason a move was refused. Field is set when the fix is to supply a value, so an agent can act on it without parsing the message.

func (Violation) String

func (v Violation) String() string

type Violations

type Violations []Violation

Violations is an ordered set of refusals.

func CheckAdvance

func CheckAdvance(env Env, t *ticket.Ticket, req Request) Violations

CheckAdvance decides whether t may move to req.To.

func (Violations) Err

func (vs Violations) Err() error

func (Violations) Fields

func (vs Violations) Fields() []string

Fields lists the field names that need filling in.

Jump to

Keyboard shortcuts

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