backlog

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package backlog decides what becomes of a role's acts on a project's issues (docs/spec/backlog-acts.md): each is checked against the code and the forge, then done, proposed to a person, or dropped. Closing is the first act built.

Index

Constants

View Source
const (
	Act     = "act"
	Propose = "propose"
	Off     = "off"
)

Modes of an act.

View Source
const (
	LabelToRefine = "workline:to-refine"
	LabelDraft    = "workline:draft"    // the role drafted its Need or Validation
	LabelAccepted = "workline:accepted" // a person accepted the drafts: only who may triage sets a label
	LabelReady    = "workline:ready"
)

The labels of an issue on its way to ready (docs/spec/routing.md).

View Source
const (
	Opened     = "opened"      // a new issue
	StillOpen  = "open"        // an open issue holds the subject: nothing written
	Settled    = "settled"     // closed as not planned or as a duplicate: a person's no, nothing written
	FoundAgain = "found-again" // closed otherwise, the subject found again: said once on it, not reopened
	Capped     = "capped"      // new, past the run's cap: not opened, found again at a later run
)

Outcomes of an opening.

View Source
const AgreeWord = "agreed"

AgreeWord is the reply that agrees to a text proposed to a reporter: its first line, case, spaces and a final "." or "!" aside (ADR-0021).

View Source
const Keeper = "product-owner"

Keeper is the role whose state comment an opened issue is given: the product owner reads it from its next run, as any other issue.

View Source
const LabelTriage = "needs-triage"

LabelTriage marks an issue a role opened on a finding of its own, until a person or the product owner takes it (ADR-0018, "Opening issues, for every role").

View Source
const Levels = 4

Levels are the priorities an issue takes: 1, the most pressing, to 4 (docs/spec/backlog-acts.md, "Ordering").

View Source
const PriorityPrefix = "workline:priority/"

PriorityPrefix starts each priority label: workline:priority/1 to /4.

View Source
const SubIssuesHeading = "## Sub-issues"

SubIssuesHeading heads the task list of a parent's children, on a forge without sub-issues.

Variables

View Source
var DraftMarker = forge.Marker("draft")

DraftMarker marks a section the role drafted and no person made theirs.

View Source
var Kinds = []string{"open", "close", "sources", "milestone", "order", "refine", "ready", "ask", "split", "rename"}

Kinds are the intentions that are acts on the backlog.

View Source
var Sections = []string{"Need", "Verification", "Validation", "Scope"}

Sections are an issue's, in the order they are written.

Functions

func Accepted added in v0.7.0

func Accepted(is forge.Issue) bool

Accepted says whether a person accepted an issue's drafts, by its label — read on the issue, never taken from a proposal.

func Agreement added in v0.11.0

func Agreement(notes []forge.Note, is forge.Issue, role string) string

Agreement is who agreed, in a reply, to the text last proposed to an issue's reporter (ADR-0021): after the last round, that round a proposal, the last comment of the reporter or of a person of the project — never a bot's, nor someone's the forge does not name — has AgreeWord as its first line. "" when there is none.

func Ask added in v0.6.0

func Ask(author, questions string, round int) string

Ask is the comment asking the reporter what is missing; a later round says it follows their answer.

func AskMarker added in v0.6.0

func AskMarker(role string, round int) string

AskMarker marks the comment asking an issue's reporter: the first round's as it always was, a later one's with its round.

func Before added in v0.8.0

func Before(is forge.Issue) string

Before says an issue's place in the order, to put it back: its priority and its milestone.

func BodyDigest added in v0.6.0

func BodyDigest(body string) string

BodyDigest is what the state keeps of a body, to tell when a person changed it.

func CappedByRole added in v0.7.1

func CappedByRole(f forge.Backlog, role string, open []forge.Issue) []int

CappedByRole lists the issues an act was proposed on only because a run's cap was reached: they are read again, though nothing changed on them.

func ChildBody added in v0.11.0

func ChildBody(parent int, ch Child, role string) string

ChildBody is a split's child's body: a line naming its parent, then its four sections, Need and Validation as drafts.

func ClosedByRole

func ClosedByRole(f forge.Backlog, role string, open []forge.Issue) []int

ClosedByRole lists the issues the role's record says it closed, read from its report issue's comments; nil when there is none or it does not read.

func CodeKey added in v0.10.0

func CodeKey(path, line string) string

CodeKey is the subject of a finding on a line of code: its file and the line as it reads, spaces aside. Two roles finding the same line get the same key; the line changed, it is another subject.

func Comment

func Comment(c Proposal, role string) string

Comment is what the closed issue is told.

func CompareMilestones added in v0.8.0

func CompareMilestones(a, b string) int

CompareMilestones orders two milestone titles as versions: their numbers compared as numbers (v1.9 before v1.10), the rest as text.

func DraftLine added in v0.6.0

func DraftLine(role string) string

DraftLine opens a drafted section; deleting it makes the section a person's.

func EngineMarker added in v0.11.0

func EngineMarker(comment string) (string, bool)

EngineMarker says whether the engine wrote a comment, and its marker: the engine ends each of its comments with one; a person quoting one holds it inside, and is a person's all the same.

func FormatRecord

func FormatRecord(r Record) string

FormatRecord is the body of the report's record comment.

func FormatState

func FormatState(s State) string

FormatState is the body of an issue's state comment, its marker left to the forge's Sticky.

func ImportKey

func ImportKey(q Quote) string

ImportKey is the marker key of an issue opened from a file's text: the file and a digest of the text, so the same text is never opened twice.

func Less added in v0.8.0

func Less(a, b forge.Issue) bool

Less is the backlog's order (docs/spec/backlog-acts.md, "Ordering"): the nearest milestone first, an issue in none after every one in one; then the priority, an issue with none after priority 4; then the lowest number.

func ListChildren added in v0.11.0

func ListChildren(body string, ids []int) string

ListChildren is a parent's body with its children as a task list under SubIssuesHeading: added after its text, or the list already there rewritten.

func Locate

func Locate(repo, path, text string) (from, to int, original string, ok bool)

Locate finds a quote in a file, as written but for spaces: the lines it spans, from 1, and those lines as the file has them.

func MovedPercent added in v0.8.0

func MovedPercent(settings map[string]any) int

MovedPercent reads the role's `moved-percent-max` setting: the share of the open issues a run may move, in percent; a fifth when it is not set.

func NextMilestone added in v0.8.0

func NextMilestone(repo string, open []string) string

NextMilestone is the nearest open milestone not released, in version order; "" when there is none.

func NotReady added in v0.6.0

func NotReady(body string, accepted bool) []string

NotReady says what keeps an issue's body from ready: a section missing or empty, Need or Validation still a draft no person accepted.

func OpenedBy added in v0.10.0

func OpenedBy(body string) string

OpenedBy is the role that opened an issue on a finding of its own through Openings, or "".

func Order added in v0.8.0

func Order(issues []forge.Issue)

Order sorts issues in the backlog's order.

func PeopleComments

func PeopleComments(comments []string) int

PeopleComments counts an issue's comments that are not the engine's.

func Priority added in v0.8.0

func Priority(is forge.Issue) int

Priority is an issue's level, the most pressing of its labels; 0 when it has none.

func PriorityLabel added in v0.8.0

func PriorityLabel(n int) string

PriorityLabel is the label of a priority level.

func PriorityLabels added in v0.8.0

func PriorityLabels(is forge.Issue) []int

PriorityLabels lists the levels an issue's priority labels give, in the order of its labels; more than one is a person's doing.

func ProposalComment added in v0.11.0

func ProposalComment(author string, c Proposal, role string) string

ProposalComment is the comment proposing an outsider's issue refined: what the role understood, its sections as it would write them, what it needs, and how to agree. Nothing is written in the body before (ADR-0021). The sections are kept in a YAML block, read back when it is agreed to.

func ProposalMarker added in v0.11.0

func ProposalMarker(role string, round int) string

ProposalMarker marks the comment proposing an outsider's issue refined.

func RecordMarker

func RecordMarker(role string) string

RecordMarker marks the report's comment holding what the role did.

func Refine added in v0.6.0

func Refine(body string, c Proposal, role string) (string, []string, []string)

Refine is an issue's body with the sections it lacks written: one there but empty (an issue form's "_No response_") filled in place, one missing added after the text, which stays as it is; added and kept name the sections written and those already there, left alone.

func Released added in v0.8.0

func Released(repo, milestone string) bool

Released says whether a tag named after the milestone exists: the release it was for is out.

func ReportTitle

func ReportTitle(role string) string

ReportTitle is the title of the role's report issue.

func Round added in v0.11.0

func Round(comment, role string) bool

Round says whether a comment is one of the engine's rounds with an issue's reporter: an ask or a proposal.

func RoundsMax added in v0.11.0

func RoundsMax(settings map[string]Setting) int

RoundsMax is how many times an issue's reporter is written to — asked, or proposed a refined text — before a person takes it: acts.ask.rounds, three when it is not set (ADR-0021).

func Settings

func Settings(settings map[string]any) map[string]Setting

Settings reads the role's `acts` setting.

func SplitKey added in v0.11.0

func SplitKey(parent int, title string) string

SplitKey is the marker key of a split's child: its parent and its title, so a split run again finds the children it opened.

func StateMarker

func StateMarker(role string) string

StateMarker marks the comment holding an issue's state.

func StripDrafts added in v0.7.0

func StripDrafts(body string) string

StripDrafts takes the draft lines out of a body: the drafts are a person's once accepted.

func TitleKey added in v0.10.0

func TitleKey(title string) string

TitleKey is the subject of a finding that names no code: its title, spaces and case aside.

Types

type Child added in v0.11.0

type Child struct {
	Title        string   `yaml:"title"`
	Need         string   `yaml:"need"`
	Verification string   `yaml:"verification"`
	Validation   string   `yaml:"validation"`
	Scope        string   `yaml:"scope"`
	Sources      []string `yaml:"sources,omitempty"`
}

Child is one part of a split need: an issue of its own, with its four sections (ADR-0022).

type Closing

type Closing struct {
	Issue int    `yaml:"issue"`
	Act   string `yaml:"act"`
}

Closing is one issue the role closed.

type Decision

type Decision struct {
	Index  int      `yaml:"index"` // the intention's place in the run
	Mode   string   `yaml:"mode"`  // act, propose, or off (dropped)
	Act    Proposal `yaml:"act"`
	Capped bool     `yaml:"capped,omitempty"` // proposed only for the cap
}

Decision is what becomes of one act.

type Exchange added in v0.11.0

type Exchange struct {
	Rounds   int      // the engine's comments to the reporter
	Answered bool     // a person's comment after the last of them
	Asked    []string // each one's text, its marker left out
}

Exchange is the conversation with an issue's reporter, read from its comments: the engine's asks and proposals, in order, and whether a person wrote after the last one.

func ReadExchange added in v0.11.0

func ReadExchange(comments []string, role string) Exchange

ReadExchange reads the conversation with an issue's reporter.

type Opening added in v0.10.0

type Opening struct {
	Role    string   // the role that found it, named in the issue
	Key     string   // the marker's key: issue=<subject>, or import=<a file's text>
	Also    []string // older keys the same subject was opened under
	Title   string
	Body    string
	From    string   // where it was opened from, said after "Opened": " from `ROADMAP.md`"
	Sources []string // the code it is about, for the keeper's state
	Commit  string   // the commit it was seen at
	Triage  bool     // a role's finding: labelled needs-triage, capped, said once when found after it was closed
}

Opening is a subject a role opens an issue for.

type Openings added in v0.10.0

type Openings struct {
	Max int // a run's findings opened as issues, at most; the rest Capped
	// contains filtered or unexported fields
}

Openings is the one way every role opens an issue (ADR-0018): a stable key per subject, hidden in the issue's body; the issues open and closed looked in, once a run; no AI. A subject an issue holds is never opened again: open, it is left as it is; closed as not planned or as a duplicate, it is a person's no, left as it is; closed otherwise, it is said once on it that it was found again, and it stays closed.

func NewOpenings added in v0.10.0

func NewOpenings(f forge.Forge, max int) (*Openings, error)

NewOpenings prepares a run's openings on f, at most max findings opened.

func (*Openings) Open added in v0.10.0

func (o *Openings) Open(op Opening) (string, int, error)

Open opens the issue for op once, and says what became of it, with the issue holding it.

type Pending

type Pending struct {
	Issue int    `yaml:"issue"`
	Act   string `yaml:"act"`
	Line  string `yaml:"line"`
	Key   string `yaml:"key,omitempty"` // an issue to open: the text it would be opened from (ImportKey)
	// Capped: proposed only because the run's cap was reached, not left to
	// a person by its mode: its issue is read again at the next run.
	Capped bool `yaml:"capped,omitempty"`
}

Pending is an act proposed to a person, as the report says it.

type Plan

type Plan struct {
	Decisions []Decision        `yaml:"decisions"`
	Findings  []verdict.Finding `yaml:"findings"`
	Record    Record            `yaml:"record"`
	Report    int               `yaml:"report"`  // the report issue, 0 when none is open yet
	Changed   bool              `yaml:"changed"` // the record changed: wrong closings found, proposals settled
	// contains filtered or unexported fields
}

Plan is what a run does with its acts, decided once, so a resumed run does the same.

func Decide

func Decide(f forge.Backlog, repo, role string, settings map[string]Setting, closes map[int]Proposal, read []int, movedPercent int) (*Plan, error)

Decide plans the acts proposed, given at their place in the run. read lists the issues the run read: a proposal made only for a cap is dropped once its issue was read again, decided again or not. A run moves at most movedPercent of the open issues (milestone and order).

func (*Plan) Acts

func (p *Plan) Acts(i int) bool

Acts says whether the act at index i is done, not proposed nor dropped.

func (*Plan) Decision

func (p *Plan) Decision(i int) *Decision

Decision is what becomes of the act at index i, nil when it is none.

func (*Plan) ReportBody

func (p *Plan) ReportBody() string

ReportBody is the report issue's body: what the run did and proposes.

type Proposal

type Proposal struct {
	Do          string   `yaml:"do"` // close or sources: the intention's kind
	Issue       int      `yaml:"issue"`
	Reason      string   `yaml:"reason,omitempty"`
	DuplicateOf int      `yaml:"duplicate-of,omitempty"`
	Sources     []string `yaml:"sources,omitempty"`
	Milestone   string   `yaml:"milestone,omitempty"`
	Title       string   `yaml:"title,omitempty"` // an issue to open, or an issue's new title (rename)
	Into        []Child  `yaml:"into,omitempty"`  // the children of a split
	Quote       *Quote   `yaml:"quote"`
	Why         string   `yaml:"why"`
	// Refining: the sections written, Need and Validation as drafts; Added,
	// the engine's, says which the body did not have yet.
	Scope        string   `yaml:"scope,omitempty"`
	Verification string   `yaml:"verification,omitempty"`
	Need         string   `yaml:"need,omitempty"`
	Validation   string   `yaml:"validation,omitempty"`
	Added        []string `yaml:"added,omitempty"`
	Questions    string   `yaml:"questions,omitempty"` // asking the reporter; for an outsider's refine, what it still needs
	// The engine's, for the conversation with the reporter: the round this
	// comment would be, and whether a refine is proposed to the reporter in
	// a comment rather than written in the body (an outsider's issue).
	Round      int  `yaml:"round,omitempty"`
	ToReporter bool `yaml:"to-reporter,omitempty"`
	// Agreed, the engine's: who agreed in a reply to the text last proposed
	// to the reporter, which this refine writes; checked again on the forge
	// (Agreement), never taken from the agent.
	Agreed string `yaml:"agreed,omitempty"`
	Spent  bool   `yaml:"spent,omitempty"` // the rounds spent: proposed to a person
	// Ordering: the priority set (1 to 4); a milestone left because it is
	// released (From, the engine's); and, the engine's, the issue's
	// priority and milestone before the run, written in the report.
	Priority int    `yaml:"priority,omitempty"`
	From     string `yaml:"from,omitempty"`
	Before   string `yaml:"before,omitempty"`
}

Proposal is an act on an issue the agent proposed: a closing, or the code it is about named as its sources.

func LastProposal added in v0.11.0

func LastProposal(comments []string, role string) *Proposal

LastProposal reads the sections of the last refined text proposed to an issue's reporter; nil when none was, or it does not read.

func (Proposal) Kind

func (c Proposal) Kind() string

Kind is the kind of act, as settings name it.

type Quote

type Quote struct {
	Path  string `yaml:"path"`
	Issue int    `yaml:"issue"`
	Text  string `yaml:"text"`
}

Quote is the evidence an act cites: a text in a file, or in an issue.

type Record

type Record struct {
	Closed   []Closing `yaml:"closed,omitempty"`
	Wrong    []Closing `yaml:"wrong,omitempty"`        // closings found wrong: their issue open again
	Propose  []string  `yaml:"propose,flow,omitempty"` // kinds of act back to propose, until the person says
	Proposed []Pending `yaml:"proposed,omitempty"`     // acts proposed, kept until their issue is closed or proposed again
}

Record is what the role did, kept on its report issue.

type Setting

type Setting struct {
	Mode   string
	Max    int
	Rounds int // asking: the times an issue's reporter is written to, then a person (ask only)
}

Setting is a kind of act's mode and cap.

type State

type State struct {
	Sources   []string `yaml:"sources"`
	Confirmed string   `yaml:"confirmed"`
	Judged    string   `yaml:"judged,omitempty"`   // the commit the role last read it at
	Comments  int      `yaml:"comments,omitempty"` // people's comments when it was last read
	Body      string   `yaml:"body,omitempty"`     // a digest of its body, when the role last read or wrote it
	Priority  int      `yaml:"priority,omitempty"` // the priority the role last set: another on the issue is a person's
	Title     string   `yaml:"title,omitempty"`    // the title the role last set: another on the issue is a person's
	Split     []int    `yaml:"split,omitempty"`    // the children the role split it into: it is not split again
}

State is what the engine knows of an issue, kept in one comment on it.

func ReadState

func ReadState(comments []string, role string) (*State, bool, error)

ReadState reads an issue's state from its comments.

Jump to

Keyboard shortcuts

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