backlog

package
v0.28.0 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: MIT Imports: 23 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 (
	Cautious     = "cautious"
	Normal       = "normal"
	Enterprising = "enterprising"
)

The autonomy levels, from the least to the most the role does alone.

View Source
const (
	FromLevel   = "level"   // the autonomy level's preset
	FromSetting = "setting" // the project set this kind itself
	FromDemoted = "demoted" // undone undone-max times across the issues: proposed everywhere
)

Where a kind's mode comes from, as the task and the report say it.

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 (
	NextMax        = 5
	NextMaxLimit   = 20
	StuckDays      = 14
	StuckDaysLimit = 365
)

The defaults and bounds of `next-max` and `stuck-days`.

View Source
const (
	WaitsReady    = "ready"    // ready, nothing started since
	WaitsAsked    = "asked"    // its reporter's answer
	WaitsProposed = "proposed" // a person's answer to a proposal on the issue
	WaitsObsolete = "obsolete" // a second judge, its announcement due
)

What a stuck issue waits on, in the order an issue is said for the first: an issue appears once.

View Source
const (
	TouchPart    = "part"    // a part of the changed issue: read again
	TouchWaits   = "waits"   // waits on it: listed for a person
	TouchSources = "sources" // names the same code: listed for a person
	TouchImport  = "import"  // opened from the lines that changed: read again
)

How an issue is touched by a change.

View Source
const (
	ItemOpened      = "opened"       // opened by this import
	ItemWouldOpen   = "would-open"   // without --apply: would be opened
	ItemAlreadyOpen = "already-open" // an open issue held it before the import
	ItemClosed      = "closed"       // a closed issue holds it: not opened again
	ItemPastCap     = "past-cap"     // not opened, past the cap of open; the import run again opens it
	ItemDone        = "done"         // judged done, the words that say so quoted
	ItemNotItem     = "not-item"     // not a requirement: an introduction, a history, a heading
)

What became of an item of a file an import read, as its map says (docs/spec/backlog-acts.md, "Importing a file").

View Source
const (
	UndoneMax      = 3
	UndoneMaxLimit = 20
)

UndoneMax is how many acts of a kind done alone a person undoes, across the issues, before that kind is proposed on every issue; one undone is proposed again on its own issue only (ADR-0038, amended).

View Source
const (
	ProposalsMax      = 10
	ProposalsMaxLimit = 100
)

ProposalsMax is how many issues may wait on a person at once before the role slows down: past it, a run reads only the issues a person answered on (ADR-0038: silence is never a yes).

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 (
	SpecReviewer = "reviewer"
	SpecKey      = "spec"
)

SpecReviewer is the role whose comment on an issue holds its spec's review; SpecKey keys that comment (`sticky=reviewer/spec`).

View Source
const AcceptedSays = "A person's yes: to what the product owner proposes; on a pull request, to merge it"

AcceptedSays is the description of a person's yes, as the forge's list of labels shows it: on an issue, to what the product owner proposes (ADR-0038); on a pull request, to merge it, by the project's merge policy (ADR-0042). GitHub keeps 100 characters.

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 Below = "in the comment below"

Below is where a line of the role's comment says the comment it wrote to the reporter is, until it links to it.

View Source
const DescriptionName = "Description"

DescriptionName names an issue's description among the sections a refine writes (Proposal.Added) and those the role wrote (State.Wrote).

View Source
const DescriptionWordsMax = 100

DescriptionWordsMax bounds a description rewritten in plain words, its words outside a fold and fenced code: past it, it is not written.

View Source
const (
	DidDays = 35
)

The acts kept: those of the last DidDays days, at most didMax over the backlog, each said in at most didLine characters.

View Source
const EvidenceKey = "parts"

EvidenceKey is the sticky comment's key on a parent: <!-- workline:sticky=<role>/parts -->.

View Source
const JudgeKeyPrefix = "obsolete-"

JudgeKeyPrefix names the folder of a judge's question on an announced issue, its number after it: in/judge/obsolete-12/.

View Source
const JudgeQuestion = "" /* 244-byte string literal not displayed */

JudgeQuestion is what the second judge is asked of an announced issue.

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 LabelObsolete = "workline:obsolete"

LabelObsolete marks an issue announced as obsolete: taking it off keeps the issue open.

View Source
const (
	LabelProposed = "workline:proposed"
)

The labels of a proposal (ADR-0038): the role's, on an issue waiting on a person; and a person's yes, read in either spelling.

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 ObsoleteDays = 7

ObsoleteDays is how long an announcement waits, in days, when the role's settings do not say.

View Source
const Reading = 2

Reading numbers the role's way of reading an issue. It is raised by a change that may give an issue the role read and left with nothing an act: a fix of what the engine dropped, of what the task tells the agent. An issue read under an older one is read again once (LeftBehind, BroughtBack). 2: a question asked before drops only itself, not the refine; an issue a comment brought back is read as any other.

View Source
const SpecRecordUnread = "spec-record-unread"

SpecRecordUnread is the rule said of an issue whose reviewer's record does not read (#302).

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

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

View Source
const SuggestAfter = 10

SuggestAfter is the acts done alone at a level before the sample suggests another.

View Source
const SuggestUndone = 10

SuggestUndone is the share of the acts done alone, in percent, a person may undo before the sample suggests the level below.

Variables

View Source
var ActKinds = []string{"sources", "close-duplicate", "close-obsolete", "milestone", "order", "refine", "ready", "ask", "split", "depend", "rename", "open"}

ActKinds are the kinds of act as the settings name them, in the order the task and the report list them.

View Source
var AutonomyLevels = []string{Cautious, Normal, Enterprising}

AutonomyLevels are the autonomy levels a project may pick.

View Source
var BlockedByMarker = forge.Marker("blocked-by")

BlockedByMarker ends the line the engine keeps in a body on a forge without the relation.

View Source
var DefaultExempt = []string{"pinned", "security"}

DefaultExempt are the labels that keep an issue from being announced obsolete, when the role's settings do not say.

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", "keep", "sources", "milestone", "order", "refine", "ready", "unready", "ask", "split", "rename", "depend", "undepend"}

Kinds are the intentions that are acts on the backlog.

View Source
var PathLike = regexp.MustCompile(`[\w.-]+(?:/[\w.-]+)+|[\w-]+\.[A-Za-z]{1,5}\b`)

PathLike is a path a text names: `src/a.go`, `docs/x.md`, a folder `internal/doctor`, a file named alone `csv.go`, or a link's address.

View Source
var SpecMarker = forge.Marker("sticky=" + SpecReviewer + "/" + SpecKey)

SpecMarker marks the reviewer's comment on an issue's spec.

View Source
var Watched = []work.Meaning{work.Need, work.Scope}

Watched are the sections whose change touches the issues built on an issue: what it needs, and the part of the code it holds.

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 AcceptedLabel added in v0.23.0

func AcceptedLabel(f any) string

AcceptedLabel is the label a person agrees with, as the role creates it on the forge: scoped on GitLab, so it replaces workline::proposed where the plan has scoped labels exclusive. Either spelling is a yes.

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 AnnounceMarker added in v0.12.0

func AnnounceMarker(role string) string

AnnounceMarker marks the comment announcing an issue obsolete.

func AnnouncementComment added in v0.12.0

func AnnouncementComment(author string, c Proposal, role string, a Announcement, days int) string

AnnouncementComment is the comment announcing an issue obsolete: to its reporter and its watchers, why, the code quoted, from when it may be closed and how to keep it open; then the block the engine reads back.

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 Basis added in v0.15.0

func Basis(body string) map[string]string

Basis is what an issue's state keeps of its watched sections, to tell a person's change from the engine's: their text, the engine's own lines (a draft line, a blocked-by line) left out, each under its heading in the body.

func BasisText added in v0.23.0

func BasisText(body, name string) string

BasisText is the text Basis keeps of a body's watched section, by its meaning: "" when the body has none.

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 Blockers added in v0.14.0

func Blockers(is forge.Issue) []int

Blockers are the issues one waits on, open or closed: the forge's relation and its body's lines, by number.

func BodyBlockers added in v0.14.0

func BodyBlockers(body string) []int

BodyBlockers are the issues a body's "Blocked by" lines name.

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 BroughtBack added in v0.23.0

func BroughtBack(b forge.Backlog, is forge.Issue, st *State, notes []forge.Note) ([]forge.Note, error)

BroughtBack are the comments that brought back an issue a person set aside, when it was read for them under an older way of reading and stays aside: a counted comment written after the role's label came off (the forge's label events), heard since. Such an issue is read again once, as LeftBehind's, so a fix of how the role reads one reaches it (ADR-0038, amended). None when it is not aside, was read under this Reading, or lacks no section; a comment written with the "not now" brought nothing back.

func ByPerson added in v0.23.0

func ByPerson(is forge.Issue) bool

ByPerson says whether a person opened an issue: not through Openings (no key of a finding or an import on a line of its own in its body, as Openings writes it — one quoted or inside a sentence is a person's text) and not by a bot — a GitHub app's `[bot]` login, a GitLab project or group bot. A person's new issue is read before an import's catch-up (ADR-0018, amended).

func ChildBody added in v0.11.0

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

ChildBody is a split's child's body: a line naming its parent, then its four sections, the need and how it is accepted as drafts; and the headings it wrote, for its state.

func CitedIssues added in v0.23.0

func CitedIssues(text, pages string) []int

CitedIssues are the issues a text cites, by number, lowest first.

func ClosingComment added in v0.12.0

func ClosingComment(c Proposal, role string) string

ClosingComment is what an obsolete issue is told as it is closed after its announcement.

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 CompareDue added in v0.21.0

func CompareDue(a, b forge.Milestone) int

CompareDue orders two milestones: by their due date, the earlier first, one with a date before one without; then by title, as versions (CompareMilestones). GitHub and GitLab both give a milestone a due date.

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 Counted added in v0.23.0

func Counted(notes []forge.Note, is forge.Issue) []forge.Note

Counted are an issue's comments that count (ADR-0038): its reporter's and the project's people's — never a bot's, an outsider's, an author the forge does not name, the engine's own, nor a bare "+1".

func CycleText added in v0.14.0

func CycleText(c []int) string

CycleText says a cycle: "#12 waits on #14, which waits on #12".

func Day added in v0.15.0

func Day(s string) string

Day reads a forge's time — RFC 3339 or YYYY-MM-DD — as its day in UTC; "" when it does not read.

func Days added in v0.15.0

func Days(day string, now time.Time) int

Days is how many days lie between a day and now's, in UTC.

func Decisions added in v0.23.0

func Decisions(repo string) map[int]string

Decisions are the decision records the commit holds, by number: the path of each.

func DeletedSections added in v0.23.0

func DeletedSections(s *State, body string) []string

DeletedSections are the sections the role wrote (State.Wrote) that a person took out of the body since — the heading gone, or its text —, with those the state holds already: each a "no" for that section, never written again (ADR-0038).

func DescriptionDigest added in v0.23.0

func DescriptionDigest(body string) string

DescriptionDigest is what the state keeps of a description, spaces aside: the digest an import's key holds of the text it opened.

func DescriptionOf added in v0.23.0

func DescriptionOf(body string) string

DescriptionOf is an issue's description as a person reads it: the text above its sections, the engine's lines left out.

func DraftLine added in v0.6.0

func DraftLine(role string) string

DraftLine opens a drafted section: the marker alone, which a reader does not see. The role's one comment says the section is a draft and how to make it yours: workline:accepted, or an edit (ADR-0038). An issue an earlier engine drafted holds a visible line too; read the same.

func Drafted added in v0.23.0

func Drafted(name string) bool

Drafted says whether the role writes a section, by its heading, as a draft, a person's to make theirs: the need and how it is accepted, an example, the steps to reproduce. Not marked a draft, it is 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 ExemptLabel added in v0.12.0

func ExemptLabel(is forge.Issue, s Setting) string

ExemptLabel is the first of an issue's labels that keeps it from being announced or closed as obsolete, or "".

func FenceFor added in v0.23.0

func FenceFor(text string) string

FenceFor is a code fence longer than any run of backticks in text: three, or one more than its longest run, so nothing in it closes the block.

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 HasDraft added in v0.23.0

func HasDraft(body string, st *State) bool

HasDraft says whether an issue's body holds a draft of the role's still.

func Heard added in v0.23.0

func Heard(st *State, counted int) int

Heard is how many counted comments the state says the role read; a state written before it counted them (no `heard`) counted every comment not the engine's (`comments`): those it holds are taken as read, never more than there are now.

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 Imported added in v0.15.0

func Imported(body string) (path string, from, to int, ok bool)

Imported is the file and lines an issue was opened from by an import, ok false when its body no longer says so or holds no import key.

func InCommit added in v0.23.0

func InCommit(repo, path string) bool

InCommit says whether the commit the run is on holds path, a file or a folder.

func Inert added in v0.23.0

func Inert(text string) string

Inert is a text the role writes on a forge with every line that starts with `/` escaped, outside fenced code: GitLab runs a quick action at a line's start when a comment or a description is written, and when it is edited (ADR-0038). The escape shows as the `/` it was.

func IsDraft added in v0.23.0

func IsDraft(body string, m work.Meaning, st *State) bool

IsDraft says whether an issue's section is still the role's draft: its text marked so, and as the role wrote it (the state's `wrote`) — one a person edited is theirs, the marker left in it or not. A draft written before the role kept its digest is told by its marker alone.

func IssueStates added in v0.23.0

func IssueStates(ids []int, open map[int]bool, closed map[int]string) string

IssueStates says, for the issues a text cites, which are open and which closed and why: "#81 (open), #206 (closed as not planned)"; an issue the forge does not list (a merge request, another project's) is left out.

func JudgeMaterial added in v0.12.0

func JudgeMaterial(repo string, is forge.Issue, a Announcement, code string) string

JudgeMaterial is what the second judge reads: the issue, the announcement's evidence, and the code quoted as it is now.

func KeptComment added in v0.12.0

func KeptComment(why string) string

KeptComment tells an announced issue why it stays open, when no person kept it.

func KeptMarker added in v0.12.0

func KeptMarker(role string) string

KeptMarker marks the comment saying why an announced issue stays open.

func LeftBehind added in v0.23.0

func LeftBehind(is forge.Issue, st *State, comments []string, role string) bool

LeftBehind says whether an issue was read under an older Reading and left with nothing: lacking a section, and the role never named its code nor did anything on it; nothing on it waits on anyone — no proposal, no label of the role's, not set aside, no question to its reporter left unanswered, not split, not ready. A section a person deleted is theirs, not lacking. Read again once, a fix of the engine reaches it.

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 — by its due date, then its title (CompareDue) —, an issue in none after every one in one; then the priority, an issue with none after the last (scale.Priority.Rank); then the lowest number.

func LinesChange added in v0.15.0

func LinesChange(repo, path string, from, to int, opened, base, head string) (was, now string, nfrom, nto int, changed bool, err error)

LinesChange says whether a commit between base and head changed lines [from, to] of path as they were at opened — the commit the issue was opened at, its lines then — with the text at base and at head, and where the lines are now; an empty now when they are gone. A commit git cannot read — gone after a force-push, beyond a shallow clone — is an error, never read as no change.

func LinkDecisions added in v0.23.0

func LinkDecisions(text, pages string, decisions map[int]string) string

LinkDecisions makes each decision a text names bare — "ADR-0038" — a link to its page on the forge (pages, a file's path after it), when the commit holds it; one in a link or a code span is left.

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 LocateIn added in v0.15.0

func LocateIn(lines []string, text string) (from, to int, original string, ok bool)

LocateIn finds a quote in a file's lines, as Locate does.

func MarkClosed added in v0.23.0

func MarkClosed(text, pages string, closed map[int]bool) string

MarkClosed says "(closed)" after each issue a text cites that is closed (closed, by number), once: a reader never takes it for work to come.

func MarkedBlockers added in v0.21.0

func MarkedBlockers(body string) []int

MarkedBlockers are the issues the engine's own line in a body names: the role's, whoever set the forge's relation.

func ModesLine added in v0.13.0

func ModesLine(modes []KindMode) string

ModesLine says every kind's mode on one line, for the report.

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 Next added in v0.15.0

func Next(open []forge.Issue, report, n int) []forge.Issue

Next lists the first n issues of the order bearing workline:ready that wait on no open issue and have no parts, the report left out: where to start (ADR-0028, ADR-0031).

func NextMilestone added in v0.8.0

func NextMilestone(repo string, open []forge.Milestone) string

NextMilestone is the nearest open milestone not released, in the milestones' order (CompareDue); "" when there is none.

func NextReady added in v0.14.0

func NextReady(ordered []forge.Issue, open map[int]bool) *forge.Issue

NextReady is the first issue of an ordered list bearing workline:ready that waits on no open issue: the one offered to whoever builds next (ADR-0028); nil when there is none. A parent is never offered: its parts are what is built, and a person accepts it (ADR-0029).

func NotReady added in v0.6.0

func NotReady(body string, st *State, 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 nor edited.

func ObsoleteKey added in v0.12.0

func ObsoleteKey(q Quote) string

ObsoleteKey names a quote's evidence: its file or issue, and a digest of its text, spaces aside.

func Offered added in v0.15.0

func Offered(is forge.Issue, open map[int]bool) bool

Offered says whether an issue may be offered to whoever builds next: ready, waiting on no open issue, no parent (ADR-0028, ADR-0029).

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) (cycles [][]int)

Order sorts issues in the backlog's order (docs/spec/backlog-acts.md, "Ordering"): Kahn's, the next the first by Less whose blockers among them are all placed. When none can be, those left hold a cycle: it is returned, the cycle's first by Less placed, and the order goes on — a cycle is reported, never followed (ADR-0028).

func Own added in v0.23.0

func Own(is forge.Issue, st *State) []string

Own are the sections of a body still the role's own — a draft no person accepted, or a text as the role wrote it (the state's `wrote`) —: those it rewrites to answer a person's comment on its proposal (ADR-0038). A person's section, edited or deleted, is never among them.

func Parts added in v0.14.0

func Parts(is forge.Issue) []int

Parts are an issue's children as the forge shows them, one rule for the report, the order and the comment: its relation (GitHub's sub-issues, GitLab's tasks) and the task list under "## Sub-issues" in its body — where a split links its children, or lists them. A part a person unlinked is no longer one.

func PathsIn added in v0.23.0

func PathsIn(repo, text string) []string

PathsIn are the files and folders a text names that the commit holds, in the order named, at most maxSources.

func Place added in v0.15.0

func Place(is forge.Issue) string

Place says an issue's milestone and priority: "milestone v1.0, priority 2", "no milestone, no priority".

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 PriorityLabels added in v0.8.0

func PriorityLabels(is forge.Issue) []int

PriorityLabels lists the levels an issue's priority labels give, read by name where the project keeps them (scale.Used), 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 ProposalUnread added in v0.26.1

func ProposalUnread(comments []string, role string) error

ProposalUnread says why the engine's block of the last text proposed to an issue's reporter does not read; nil when it reads, or none was proposed. An agreement to it writes nothing: said (#302), never left for a person to wonder at.

func Proposed added in v0.23.0

func Proposed(is forge.Issue) bool

Proposed says whether an issue bears the role's label, either spelling.

func ProposedLabel added in v0.23.0

func ProposedLabel(f any) string

ProposedLabel is the label the role puts on an issue waiting on a person, as the forge names it: scoped on GitLab.

func ReadyRemoves added in v0.23.0

func ReadyRemoves(is forge.Issue) []string

ReadyRemoves are the labels an issue moved to ready loses: those of its way there, and a person's yes, in either spelling, with the role's proposal label (ADR-0038).

func RecordMarker

func RecordMarker(role string) string

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

func RecordOpening added in v0.15.0

func RecordOpening(runDir string, index int, outcome string, issue int) error

RecordOpening adds what opening the intention at index did to the run folder: a forge's list may not show an issue opened a moment ago, and an import's map reads it from here.

func RecordedOpenings added in v0.15.0

func RecordedOpenings(runDir string) map[int]Recorded

RecordedOpenings reads what the openings of a run did, by intention index.

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 where the Layout puts it among those there, after the text, which stays as it is — a thematic break between the person's part and the builder's; 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 RepoPath added in v0.23.0

func RepoPath(p string) string

RepoPath is the path of the repository a name stands for: a link's address to a file on the forge read as that file, the punctuation around it left out.

func ReportTitle

func ReportTitle(role string) string

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

func Revisable added in v0.20.0

func Revisable(is forge.Issue, st *State, r *SpecReview) []string

Revisable are the sections of a body the role may rewrite to answer the reviewer's findings (#128): those the findings lie in that are still the role's own — a draft no person accepted, or a text as the role wrote it (the state's `wrote`). A person's section is theirs: never rewritten.

func RevisionsMax added in v0.23.0

func RevisionsMax(settings map[string]Setting) int

RevisionsMax is the same, from the settings.

func Rewrite added in v0.23.0

func Rewrite(is forge.Issue, st *State, revising bool) (bool, string)

Rewrite says whether the role may rewrite an issue's description in plain words, and why not: opened by a role, and as the role wrote it — the digest it recorded when opening it (State.Wrote), else an import's key; a finding opened before by a bot and its body unchanged since the role last read it. Rewritten once (State.Plain), it is again only to answer a person's comment (revising). Edited by a person, it is theirs.

func Rewritten added in v0.15.0

func Rewritten(st *State, body string) []string

Rewritten are the watched sections a person rewrote since the state was kept, spaces aside: a section written where there was none is not a change to what others were built on, nor is a state that kept none yet.

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 SectionAt added in v0.20.0

func SectionAt(body string, line int) string

SectionAt is the section of a body a line lies in, by its `## ` (or `### `) heading above it; "" above the first, or in the body's footer.

func SectionDigest added in v0.20.0

func SectionDigest(body, name string) string

SectionDigest is the digest of a section's text, as the role wrote it: another text there is a person's.

func Settings

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

Settings reads the role's `acts` setting.

func SpecHold added in v0.20.0

func SpecHold(is forge.Issue, comments []string) (rule, why string)

SpecHold says why an issue's spec holds it from ready, "" when nothing does: rule and why, as a dropped act says them. A person's label `workline:accepted` is their yes to the issue as it reads: it lifts the hold, whatever the reviewer found.

func SpecUnread added in v0.26.1

func SpecUnread(err error) string

SpecUnread is what is said of an issue whose reviewer's record does not read: the record, why, and what becomes of the issue — held for a person, never read again in silence, which loops an agent call a night.

func SplitInto added in v0.14.0

func SplitInto(is forge.Issue, st *State) []int

SplitInto are its parts and the children the role's split recorded in its state (st may be nil): never closed by the role, nor split again.

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 StillAside added in v0.23.0

func StillAside(st *State, is forge.Issue, notes []forge.Note) bool

StillAside says whether an issue a person set aside stays so: its body as it was then, and no comment of a person since the role last read it. Either brings it back (ADR-0038).

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 SuggestFromActs added in v0.16.0

func SuggestFromActs(level string, done, undone int) (string, string)

SuggestFromActs is the level the weekly sample suggests from the acts done alone at a level and those a person undid, and why; "" when none. Below SuggestAfter acts, none: too few to say. At cautious, the role does alone only what checks facts: nothing to suggest from.

func TestNames added in v0.21.0

func TestNames(item string) []string

TestNames are the tests a Verification item names, each in a code span: a test file (a path, with ::name after it for one test in it), a test's own name, or any name right after the word test, test case or conformance case. The rest of the item is prose, and names none.

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.

func Unheard added in v0.23.0

func Unheard(st *State, notes []forge.Note, is forge.Issue) []forge.Note

Unheard are the counted comments the role has not read yet: a person's word on the issue since it last read it (ADR-0038). Which comment is the role's is told by its marker, never by its author: the role may write with a person's token.

func UnreadRecord added in v0.26.1

func UnreadRecord(text, opening string) error

UnreadRecord says why a record the engine hid in a text does not read (#302): the line holding its opening, quoted as code so a summary shows it, or that the text holds none.

func VerificationItems added in v0.14.0

func VerificationItems(body string) []string

VerificationItems are the items of a body's Verification section: each list item, or, with no list, the section whole.

func Waiting added in v0.14.0

func Waiting(is forge.Issue, open map[int]bool) []int

Waiting are the open issues one waits on: a blocker closed, or not an open issue, holds nothing back.

func WithBlockers added in v0.14.0

func WithBlockers(body string, add []int) string

WithBlockers is a body with the engine's line naming these blockers too: the line there rewritten with them added, or added after the text. A person's own "Blocked by" line is left as it is.

func WithoutBlockers added in v0.21.0

func WithoutBlockers(body string, drop []int) string

WithoutBlockers is a body with these blockers taken off the engine's line: the line rewritten with those left, or taken out, with the blank line before it, when none is. A person's own "Blocked by" line is left as it is.

Types

type Acts added in v0.16.0

type Acts struct {
	Level string
	Did   []Did
	// contains filtered or unexported fields
}

Acts is what the weekly sample reads of the role's acts on the forge: those done alone each issue's state keeps, the level of the last, and the acts a person undid, with what shows it.

func ReadActs added in v0.16.0

func ReadActs(f forge.Backlog, role string) (*Acts, error)

ReadActs reads the role's acts done alone from every issue's state, open or closed — one forge call an issue —, oldest first; nil when no issue holds any.

func (*Acts) Undone added in v0.16.0

func (a *Acts) Undone(i int) (string, bool)

Undone says whether a person undid the i-th act, and what shows it.

type Announcement added in v0.12.0

type Announcement struct {
	Quote     Quote  `yaml:"quote"`
	Why       string `yaml:"why"`
	Commit    string `yaml:"commit"`
	Announced string `yaml:"announced"`    // the day it was announced, YYYY-MM-DD
	By        string `yaml:"by,omitempty"` // the model that proposed it
}

Announcement is what the engine wrote when it announced an issue obsolete, read back from its comment's block.

func LastAnnouncement added in v0.12.0

func LastAnnouncement(notes []forge.Note, role string) (*Announcement, []forge.Note)

LastAnnouncement reads the last announcement on an issue, and the notes written after it; nil when there is none, or it does not read.

func (Announcement) Key added in v0.12.0

func (a Announcement) Key() string

Key is the evidence an announcement rests on: kept open once, not announced again for it.

type Answer added in v0.23.0

type Answer struct {
	Notes    []string `yaml:"notes,flow"` // the comments read, by the forge's id
	Who      string   `yaml:"who"`        // the last one's author
	Revision int      `yaml:"revision"`   // this revision's number, from 1
}

Answer is a person's comment on an issue waiting on them, read as "revise" (ADR-0038): the issue read again with it, 👀 put on each, the drafts rewritten in place, one line in reply.

type Backlog added in v0.14.0

type Backlog struct {
	Next    *forge.Issue
	Waiting map[int][]int // each issue waiting on an open one, and on which
	Blocked []int         // those issues, in the backlog's order
	Cycles  [][]int
}

Backlog is what the order says of the open issues: the first ready one offered, those waiting, the cycles (ADR-0028). The report issue is left out.

func ReadBacklog added in v0.14.0

func ReadBacklog(open []forge.Issue, report int) Backlog

ReadBacklog orders the open issues and says what waits.

type Board added in v0.15.0

type Board struct {
	NextMax   int
	StuckDays int
	Next      []forge.Issue
	Stuck     []Wait
	// contains filtered or unexported fields
}

Board is what is next and what is stuck, for the job's summary.

func MakeBoard added in v0.15.0

func MakeBoard(open []forge.Issue, report int, waits []Wait, proposed []Pending, cfg Config, now time.Time) Board

MakeBoard reads the board from the open issues, the report left out; the waits pre found on the forge; the proposals the report holds. An issue appears once, in its first list; a wait not past stuck-days, an announcement aside, is not stuck.

func (Board) Empty added in v0.15.0

func (b Board) Empty() bool

Empty says whether the board lists no issue.

func (Board) StuckLine added in v0.23.0

func (b Board) StuckLine(w Wait) string

StuckLine says what a stuck issue waits on, since when, and what to do, as the job's summary says it (ADR-0031; ADR-0038).

type Change added in v0.15.0

type Change struct {
	Issue int      `yaml:"issue"`               // the issue whose sections changed, or the one opened from the lines
	What  []string `yaml:"what,flow,omitempty"` // the sections a person rewrote
	Path  string   `yaml:"path,omitempty"`      // an imported file whose lines changed
	Lines string   `yaml:"lines,omitempty"`     // those lines then, and now: "7-8 → 7-9"
	Since string   `yaml:"since,omitempty"`     // the day it was found, YYYY-MM-DD
	Touch []Touch  `yaml:"touched"`             // the open issues it touches
	Was   string   `yaml:"was,omitempty"`       // the text before, for the agent (not kept in the record)
	Now   string   `yaml:"now,omitempty"`       // the text after, for the agent (not kept in the record)
}

Change is a change to what open issues were built on, as the record keeps it until a person ticks it seen or its issues are closed.

func (Change) Key added in v0.15.0

func (c Change) Key() string

Key is the change's box in the report: an issue's sections and the lines it was imported from are two changes, which one run may find together.

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"`
	After        []int    `yaml:"after,flow,omitempty"` // the children it waits on, by their place in the split, from 1 (ADR-0028)
}

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

type ClosedImport added in v0.21.0

type ClosedImport struct {
	Issue    forge.Issue
	From, To int
	Lines    string // as a skip names them: "12", or "12-14"
}

ClosedImport is a closed issue an import opened from a file, and the lines of the file that hold its item.

func ClosedImports added in v0.21.0

func ClosedImports(all []forge.Issue, file string, lines []string, from, to int) []ClosedImport

ClosedImports lists the closed issues opened from file by an import whose item lies in its lines from to to (ADR-0018, amended): the plan of an import sees them, so an item a closed issue holds is answered, not proposed again. An issue's item is found by its text in the file as it reads, else by the lines its body says it was opened from.

type Closing

type Closing struct {
	Issue int    `yaml:"issue"`
	Act   string `yaml:"act"`
	Level string `yaml:"level,omitempty"` // the autonomy level it was done at
}

Closing is one issue the role closed.

type Config added in v0.13.0

type Config struct {
	Level        string             // cautious, normal or enterprising
	Acts         map[string]Setting // each kind's mode and cap, the project's laid over the level's
	Origins      map[string]string  // each kind's: level or setting
	MovedPercent int                // the share of the open issues a run moves
	NextMax      int                // the ready issues the job's summary lists first; 0 none (ADR-0031)
	StuckDays    int                // the days an issue waits on a person before the summary says it stuck
	// UndoneMax: the acts of a kind a person undoes, across the issues,
	// before that kind is proposed everywhere; ProposalsMax, the issues
	// waiting on a person before the role reads only those answered
	// (ADR-0038).
	UndoneMax    int
	ProposalsMax int
	// ChangedNeeds: a person's change to a Need or a Scope, or to an
	// imported file's lines, flags the issues built on it (ADR-0032); off
	// unless set (ADR-0038).
	ChangedNeeds bool
	// Gone are the settings the project still sets that the role no
	// longer reads: said, never silently ignored.
	Gone []string
	// Archived are the files no longer a source, as globs: an issue
	// imported from one is not flagged when its lines change (ADR-0032).
	Archived []string
	// SpecReview: the project's line runs the reviewer after the role, so
	// ready is held while the reviewer's important findings on the spec are
	// open (#128); set by the caller, from the routing.
	SpecReview bool
}

Config is how far the role goes in a run, read from its settings.

func ReadConfig added in v0.13.0

func ReadConfig(settings map[string]any) (Config, error)

ReadConfig reads the role's settings: the level, the acts, the moved share, what the summary lists first, the undoing and the proposals waiting. A level or a number out of range is an error, never read as a default (principle 12).

func (Config) Modes added in v0.13.0

func (c Config) Modes(demoted []string) []KindMode

Modes lists each kind of act's mode, the kinds demoted proposed whatever the level or the setting.

type Coverage added in v0.15.0

type Coverage struct {
	File       string   `json:"file"`
	Items      []Mapped `json:"items"`
	NotCovered []Mapped `json:"not-covered"`
}

Coverage is an import's map: every item of the file to its issue or its reason, and the lines left with neither.

func Cover added in v0.15.0

func Cover(repo, file string, lines []string, shares []ImportShare, before, after []forge.Issue, applied bool) (*Coverage, []verdict.Finding)

Cover builds an import's map from the shares the engine cut and the agent's answers, checking each reason: a quote found in the file, an issue that is there. Before and after are the forge's issues, open and closed, before the import and after it; applied, whether it wrote. A line not blank that no item nor reason holds is not covered, and the share that was to answer for it is flagged.

func (*Coverage) Entries added in v0.18.0

func (c *Coverage) Entries() []string

Entries are the map's lines for a job's summary: each item to its issue or its reason, then each item not covered, said so.

func (*Coverage) Text added in v0.15.0

func (c *Coverage) Text() string

Text writes the map for a person: each item to its issue or its reason, then those not covered.

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 Did added in v0.16.0

type Did struct {
	Issue int    `yaml:"issue,omitempty"` // left out in the issue's own state
	Act   string `yaml:"act"`             // its kind, as the settings name it: close-duplicate, rename…
	Level string `yaml:"level"`           // the autonomy level it was done at
	Day   string `yaml:"day"`             // the day, YYYY-MM-DD, UTC
	Line  string `yaml:"line,omitempty"`
	Yes   string `yaml:"yes,omitempty"` // who accepted it: done on their yes, not alone
	// contains filtered or unexported fields
}

Did is one act the role did.

type Done added in v0.13.0

type Done struct {
	Issue int    `yaml:"issue,omitempty"` // left out in the issue's own state
	Act   string `yaml:"act"`
	Was   string `yaml:"was,omitempty"`
	Set   string `yaml:"set,omitempty"`
	Level string `yaml:"level,omitempty"` // the autonomy level it was done at
}

Done is one act of the role's a person may undo: its issue, its kind, the value it had and the value the role set.

type Evidence added in v0.14.0

type Evidence struct {
	Body       string
	Parts      int
	Closed     int      // the parts closed, or gone from the forge
	Undone     []int    // the parts closed without delivering: not planned, a duplicate, gone
	Unproved   []string // the Verification items no part delivered quotes, or whose test is not in the code
	NoTest     []string // the tests a quoted item names that the code does not hold
	TestUnread []string // the tests a quoted item names that could not be looked for, with why
	Unread     []Part   // the parts whose closer the forge refused to say, with why
	AllClosed  bool
}

Evidence is a parent's report, as the engine writes it.

func ReadEvidence added in v0.14.0

func ReadEvidence(parent forge.Issue, parts []Part, role string, tests TestFinder) Evidence

ReadEvidence writes a parent's report from its parts: what each became and what closed it; each item of its Verification proved by a part delivered that quotes it — in its own Verification, or in the text of the pull request or commit that closed it — and, when it names a test, that test found in the code by tests (nil: not looked for); or said not proved.

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 ImportOpen added in v0.15.0

type ImportOpen struct {
	Title   string
	Quote   Quote
	Capped  bool // not opened, past the cap of open
	Dropped bool // refused by the engine, a finding saying why
	// Opening is what opening it did, as the run recorded it: the issue
	// that holds it, and whether it was opened then.
	Opening *Recorded
}

ImportOpen is an item the agent proposed to open, and what the engine decided of it.

type ImportShare added in v0.15.0

type ImportShare struct {
	From, To int // the lines it was given
	// Own is its last line to answer for: those after it are read again by
	// the next share, which answers for them.
	Own   int
	Opens []ImportOpen
	Skips []Skip
}

ImportShare is one share of the file an import read, and the agent's answer on it.

type Judged added in v0.12.0

type Judged struct {
	Yes    *bool  `yaml:"yes"`
	Why    string `yaml:"why"`
	Model  string `yaml:"model"`
	Level  string `yaml:"level"`
	Author string `yaml:"author"`
	Error  string `yaml:"error"`
}

Judged is a second judge's answer on an announced issue (ADR-0005), written by the engine beside the question pre asked.

func (Judged) Says added in v0.12.0

func (j Judged) Says() string

Says is the judge's answer as a line: yes or no, why, and how far it stood from the model that proposed it.

type KindMode added in v0.13.0

type KindMode struct {
	Kind   string
	Mode   string
	Max    int
	Drafts string // refine: Need and Validation proposed when "propose"
	Origin string
}

KindMode is one kind of act's mode in a run, and where it comes from.

func (KindMode) Say added in v0.13.0

func (m KindMode) Say() string

Say says one kind's mode in a few words: "act, 5 a run (level)".

type Ledger added in v0.23.0

type Ledger struct {
	Report int    // an open report issue of an earlier engine: its record read once, then it is closed
	Record Record // the issues' records, as one
	Broken error  // the old report's record does not read
	States map[int]*State
	Notes  map[int][]forge.Note
	// Aside are the issues a person took workline:proposed off since the
	// last run, without accepting: "not now", that issue only, until it
	// changes.
	Aside map[int]bool
	// Undone are the role's acts a person undid since the last run, other
	// than closings; Standing, those still watched (ADR-0026).
	Undone   []Undo
	Standing []Done
	// Own are the blockers the role set on each open issue: a depend's, a
	// split's after (ADR-0028).
	Own map[int][]int
	// Signs are what a person did that a run with no agent still writes:
	// a yes, an answer, a label taken off, an act undone, the report to
	// move.
	Signs []string
}

Ledger is what the role holds, read from each open issue's state: the record it keeps there, as one; and, the first run after a report issue, that report's record, moved to the issues (ADR-0038).

func ReadLedger added in v0.23.0

func ReadLedger(f forge.Backlog, role string, open []forge.Issue) (*Ledger, error)

ReadLedger reads what the role holds on each open issue, from its state comment; the record of an earlier engine's report, the first time; the acts a person undid since.

func (*Ledger) Demoted added in v0.23.0

func (l *Ledger) Demoted(max int) []string

Demoted are the kinds of act proposed on every issue: those a person undid at least max times, across the issues (UndoneMax).

func (*Ledger) OwnBlockers added in v0.23.0

func (h *Ledger) OwnBlockers(is forge.Issue) []int

OwnBlockers are the blockers of an issue the role set, still among its blockers: those its record keeps (a depend, a split's after) and those the engine's line in its body names. A person's link, or line, is never among them (ADR-0028).

func (*Ledger) Stale added in v0.23.0

func (h *Ledger) Stale(open []forge.Issue) map[int][]int

Stale are the links the role set whose reason is gone: each open issue with its own blockers that are no longer open — closed, or gone from the forge. A closed blocker holds nothing back; the engine takes the link off, with no agent (ADR-0028).

func (*Ledger) UndoneOn added in v0.23.0

func (l *Ledger) UndoneOn(id int) []string

UndoneOn are the kinds of act a person undid on an issue: proposed there from then on, whatever the level (ADR-0038, amended).

func (*Ledger) Waiting added in v0.23.0

func (l *Ledger) Waiting(open []forge.Issue) int

Waiting are the open issues that wait on a person: the role's label on them.

type Mapped added in v0.15.0

type Mapped struct {
	Lines string `json:"lines"`
	From  int    `json:"from"`
	To    int    `json:"to"`
	Words string `json:"words"`
	State string `json:"state,omitempty"`
	Issue int    `json:"issue,omitempty"`
	Why   string `json:"why,omitempty"`
}

Mapped is one entry of an import's map: an item, by its lines and first words, and the issue that holds it or why none does.

type Obsolete added in v0.12.0

type Obsolete struct {
	Announcement *Announcement // nil: none waiting
	Due          bool          // its delay passed, nothing cancels it: a judge decides
	From         string        // the day it may be closed from
	Keep         string        // why it is kept open, when it is
	Say          bool          // the issue is told why it is kept: no person did it
}

Obsolete is where an issue's announcement stands.

func ReadObsolete added in v0.12.0

func ReadObsolete(repo string, is forge.Issue, notes []forge.Note, st *State, role string, s Setting, now time.Time) Obsolete

ReadObsolete says where an issue's announcement stands: none waiting (none, or settled already — its evidence in the state's kept), kept open (someone wrote, the label taken off, an exempt label, the code quoted gone), waiting for its day, or due for the judge.

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
	Wrote   []string // the sections the role wrote in its body, recorded in the keeper's state (#128)
	Quiet   bool     // where it came from hidden from a reader, kept for the engine: an import, a person's words
	// Found says where the role found it, for a person: "while reviewing
	// ccffcb2, outside that change"; the line it ends with is then "Found
	// by the … role …".
	Found string
}

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 Part added in v0.14.0

type Part struct {
	ID      int
	Issue   forge.Issue
	Closers []forge.Closer
	Unread  error
	Gone    bool
}

Part is one child as the parent's report reads it: the issue, open or closed, and what closed it; Gone when the forge no longer has it; Unread when the forge refused to say what closed it.

func (Part) Delivered added in v0.14.0

func (p Part) Delivered() bool

Delivered says whether a part's work is done: closed, and not as not planned nor as a duplicate. GitLab and the local forge keep no reason: a closing there is taken as done.

type Pending

type Pending struct {
	Issue int    `yaml:"issue,omitempty"` // left out in the issue's own state
	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"`
	// Proposal is what the engine would do, as decided: done as it says
	// when a person of the project labels the issue workline:accepted
	// (ADR-0038).
	Proposal *Proposal `yaml:"proposal,omitempty"`
	// Since is the day it was first proposed, YYYY-MM-DD: the job's summary
	// says it stuck past stuck-days (ADR-0031).
	Since string `yaml:"since,omitempty"`
}

Pending is an act proposed to a person, on its issue.

func (Pending) Doable added in v0.12.0

func (q Pending) Doable() bool

Doable says whether the engine can do a proposal a person accepted: what it would do recorded, and not one only a person or the import does.

func (Pending) ID added in v0.23.0

func (q Pending) ID() string

ID is a pending proposal's key: its issue and kind, or the text an issue to open would be opened from.

func (Pending) Undrafted added in v0.22.0

func (q Pending) Undrafted() bool

Undrafted says whether a proposal on an issue was recorded with its line alone, the act not kept — by an engine before acts were recorded: its issue is read again, and the act drafted then.

type Plan

type Plan struct {
	Decisions []Decision        `yaml:"decisions"`
	Findings  []verdict.Finding `yaml:"findings"`
	Record    Record            `yaml:"record"`
	// Report is an earlier engine's report issue, still open: its record
	// moved to the issues, and Moved, it is closed at the end of the run
	// (ADR-0038).
	Report int  `yaml:"report,omitempty"`
	Moved  bool `yaml:"moved,omitempty"`
	// Visit are the open issues with a state, written back at the end of
	// the run (Persist); SetAside, those a person took workline:proposed
	// off; Answers, a person's comments read as "revise" on each.
	Visit    []int           `yaml:"visit,flow,omitempty"`
	SetAside map[int]bool    `yaml:"set-aside,omitempty"`
	Answers  map[int]*Answer `yaml:"answers,omitempty"`
	// 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, cfg Config, closes map[int]Proposal, read []int, judged map[int]Judged, changes []Change, answers map[int]*Answer) (*Plan, error)

Decide plans the acts proposed, given at their place in the run, as far as the config lets the role go (ADR-0026). 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 cfg.MovedPercent of the open issues (milestone and order). judged holds the second judge's answers on the issues announced obsolete (ADR-0024); changes, what open issues were built on that pre found changed, and the issues it read again for them (ADR-0032); answers, a person's comments pre read as "revise" (ADR-0038).

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) Persist added in v0.23.0

func (p *Plan) Persist(f forge.Forge, role string) error

Persist writes what the run leaves on each issue (ADR-0038): its record in its state comment, edited in place; the label workline:proposed on an issue waiting on a person, off one that no longer waits, off one a person accepted; 👀 on a person's comments read, and one line in reply. The old report, read this run, is closed with a link to the filter. Each write is idempotent: a resumed run writes the same.

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
	BlockedBy   []int    `yaml:"blocked-by,flow,omitempty"` // depend: the issues it waits on; undepend: those taken off (ADR-0028)
	// Native, the engine's: the blockers an undepend takes off the forge's
	// own relation, the rest being in the engine's line; never the agent's.
	Native []int  `yaml:"native,flow,omitempty"`
	Quote  *Quote `yaml:"quote"`
	Why    string `yaml:"why"`
	// Refining: the sections written, Need and Validation as drafts, with
	// a real example of the need or a bug's steps to reproduce, drafts too,
	// never required; 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"`
	Example      string `yaml:"example,omitempty"`
	Steps        string `yaml:"steps,omitempty"`
	Validation   string `yaml:"validation,omitempty"`
	// Description, the text above its sections rewritten in plain words:
	// only where the role opened it and no person edited it (Rewrite).
	Description string   `yaml:"description,omitempty"`
	Added       []string `yaml:"added,omitempty"`
	// Revise, the engine's: the sections with text this refine may rewrite,
	// to answer the reviewer's findings on the spec (#128) — the role's own
	// only (Revisable); never taken from the agent.
	Revise []string `yaml:"revise,omitempty"`
	// Refused, the engine's: the sections the role wrote that a person
	// deleted (State.Deleted), never written again (ADR-0038).
	Refused   []string `yaml:"refused,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"`
	// LeftOut, the engine's: the questions asked before, taken out of it;
	// said once the act is decided, never when it is dropped.
	LeftOut []string `yaml:"-"`
	// 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
	// Hearsay, the engine's: the words it quotes are only in a comment by
	// someone outside the project — proposed, never done alone (ADR-0038).
	Hearsay bool `yaml:"hearsay,omitempty"`
	// 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"`
	// Obsolete (ADR-0024): Announced, on the engine's closing, the day of
	// the announcement it follows; Announce and Until, the engine's, that
	// this act announces rather than closes, and the day from which it may
	// close; Judge, the engine's, the second judge's yes and its level;
	// Say, on a keep, that the issue is told why.
	Announced string `yaml:"announced,omitempty"`
	Announce  bool   `yaml:"announce,omitempty"`
	Until     string `yaml:"until,omitempty"`
	Judge     string `yaml:"judge,omitempty"`
	Say       bool   `yaml:"say,omitempty"`
	// Advice, the engine's: a closing whose kind is off (close-obsolete,
	// by default), said on the issue for a person to close, never done by
	// the role nor by a yes (ADR-0038: off, the code kept).
	Advice bool `yaml:"advice,omitempty"`
	// Ticked, the engine's: who ticked this proposal's box in the report, a
	// person of the project — checked again on the forge, the act done as
	// the record says, never as the intention does (ADR-0025).
	Ticked string `yaml:"ticked,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 (ProposalUnread says so).

func (Proposal) Kind

func (c Proposal) Kind() string

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

func (Proposal) Text added in v0.23.0

func (c Proposal) Text(m work.Meaning) string

Text is the text a refine gives a section, by its meaning: the fields of a refine are named by meaning.

type Quote

type Quote struct {
	Path  string `yaml:"path,omitempty"`
	Issue int    `yaml:"issue,omitempty"`
	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 proposed on every issue: undone too often (UndoneMax)
	// Done are the role's own acts a person may undo, other than closings:
	// a rename, a priority, a milestone, ready, a split (ADR-0026); Undone,
	// those a person undid, with what shows it.
	Done     []Done    `yaml:"done,omitempty"`
	Undone   []Undo    `yaml:"undone,omitempty"`
	Proposed []Pending `yaml:"proposed,omitempty"` // acts proposed, kept until their issue is closed, set aside or proposed again
	// Did are the acts the role did, with their day and level, for its
	// comment on each issue and the weekly sample (ADR-0033).
	Did []Did `yaml:"did,omitempty"`
}

Record is what the role holds on the backlog, read from each issue's state (Ledger) and written back to each at the end of a run (Persist): never kept in one place (ADR-0038).

type Recorded added in v0.15.0

type Recorded struct {
	Index   int    `yaml:"index"` // the intention's place in the run
	Outcome string `yaml:"outcome"`
	Issue   int    `yaml:"issue"`
}

Recorded is what one opening of a run did (RecordOpening).

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)
	Days   *int     // close-obsolete: the days an announcement waits; ObsoleteDays when nil
	Exempt []string // close-obsolete: labels that keep an issue from it; DefaultExempt when nil
	Drafts string   // refine: propose has Need and Validation drafts proposed, Scope and Verification written (ADR-0026)
}

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

func (Setting) Delay added in v0.12.0

func (s Setting) Delay() int

Delay reads close-obsolete's delay; ObsoleteDays when it is not set.

type Skip added in v0.15.0

type Skip struct {
	Lines  any    `yaml:"lines"` // "12", or "12-14"
	Reason string `yaml:"reason"`
	Quote  *Quote `yaml:"quote,omitempty"`
	Issue  int    `yaml:"issue,omitempty"`
	Why    string `yaml:"why,omitempty"`
}

Skip is an item of a file an import read and does not open, and why, as the agent answers it: done, the words that say so quoted; held, the issue that holds it; not-item, why.

type SpecReview added in v0.20.0

type SpecReview struct {
	Body    string   // the digest of the body it read (BodyDigest); "" when no review was whole
	Round   int      // the reviews in a row that found an important finding open, this one included
	Open    int      // the important findings open, as it read the body
	In      []string // the sections their causes lie in, by heading
	Stopped bool     // the rounds spent: put to a person, not read again
}

SpecReview is what the reviewer's comment records of the spec it read.

func ReadSpecReview added in v0.20.0

func ReadSpecReview(comments []string) (*SpecReview, error)

ReadSpecReview reads the reviewer's record from an issue's comments: nil when it has none. The last comment carrying the marker is read (GitLab: one another token wrote is left behind). One that does not read is an error (#302), never taken for none: read as none, the spec was read again at round 1, night after night, in silence.

func SpecCleared added in v0.20.0

func SpecCleared(is forge.Issue, comments []string) (*SpecReview, bool)

SpecCleared says whether the reviewer read the issue's body as it is and found no important finding open.

func SpecOpen added in v0.20.0

func SpecOpen(is forge.Issue, comments []string) *SpecReview

SpecOpen is the reviewer's record when it holds important findings open on the body as it is, for the product owner to answer; nil otherwise.

func (SpecReview) String added in v0.20.0

func (r SpecReview) String() string

String is the record as the comment hides it.

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
	// After are the blockers the role's split set on each child, among
	// its siblings: the role's own links, taken off once a blocker closes
	// (ADR-0028).
	After map[int][]int `yaml:"after,flow,omitempty"`
	Kept  []string      `yaml:"kept,omitempty"` // the evidence an announcement as obsolete rested on, kept open: not announced again for it
	// Sections are its Need and Scope as last read or written (Basis): a
	// person's change to them touches the issues built on it (ADR-0032).
	Sections map[string]string `yaml:"sections,omitempty"`
	// Wrote are the sections the role wrote, each the digest of its text:
	// another text there is a person's (SectionDigest). Answered is the
	// review of its spec the role was last given, by the digest of the
	// body that review read (#128): a review restarting at round 1 is
	// another review, never taken for one answered.
	Wrote    map[string]string `yaml:"wrote,omitempty"`
	Answered string            `yaml:"answered,omitempty"`
	// Plain is the digest of the description the role rewrote in plain
	// words (ADR-0038, amended): another text there is a person's.
	Plain string `yaml:"plain,omitempty"`
	// Deleted are the sections the role wrote that a person took out of
	// the body: a "no" for each, never written again (ADR-0038).
	Deleted []string `yaml:"deleted,flow,omitempty"`
	// What the role holds on this issue, in place of a report (ADR-0038):
	// the acts it proposes here; those it did alone a person may undo;
	// those a person undid — proposed here from then on —; what it did,
	// each with its day; the kind of act it closed it with, should it open
	// again.
	Proposed []Pending `yaml:"proposed,omitempty"`
	Done     []Done    `yaml:"done,omitempty"`
	Undone   []Undo    `yaml:"undone,omitempty"`
	Did      []Did     `yaml:"did,omitempty"`
	Closed   string    `yaml:"closed,omitempty"`
	// Label is the label the role put on it while it waits on a person
	// (workline:proposed); Aside, the body's digest when a person took it
	// off: nothing proposed until the issue changes.
	Label string `yaml:"label,omitempty"`
	Aside string `yaml:"aside,omitempty"`
	// Heard are the comments of its reporter and the project's people the
	// role read; Revisions, the times it revised its drafts for them.
	Heard     *int `yaml:"heard,omitempty"`
	Revisions int  `yaml:"revisions,omitempty"`
	// Rules is the role's way of reading an issue when it last read it
	// (Reading): an issue it left with nothing is read again once they
	// change.
	Rules int `yaml:"rules,omitempty"`
}

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.

func (*State) Keep added in v0.15.0

func (s *State) Keep(body string)

Keep records in the state the body the engine read or left: its digest, and its watched sections.

func (*State) KeptText added in v0.23.0

func (s *State) KeptText(name string) string

KeptText is the text the state kept of a watched section, by its meaning, under whichever heading it was kept: "" when none.

func (*State) SetWrote added in v0.23.0

func (s *State) SetWrote(name, digest string)

SetWrote records that the role wrote a section under a heading, by its digest: in place of what it recorded under another heading of the same meaning.

type TestFinder added in v0.21.0

type TestFinder func(name string) (string, error)

TestFinder says where the code holds a test a Verification item names: the file, or "" when it holds none; an error when it could not look, never read as none (ADR-0029).

func CodeTests added in v0.21.0

func CodeTests(repo string) TestFinder

CodeTests finds a test in the repository at HEAD: a test file named by its path, one test in it by path::name, or a name found as a word in a test file (TestNames). The run's commit, never the working tree.

type Touch added in v0.15.0

type Touch struct {
	Issue int    `yaml:"issue"`
	How   string `yaml:"how"`
	Files string `yaml:"files,omitempty"` // the code shared, for TouchSources
	Read  bool   `yaml:"read,omitempty"`  // read again by the run that found it, with the change
}

Touch is an open issue a change touches, and how.

func Touched added in v0.15.0

func Touched(id int, open []forge.Issue, sources map[int][]string, scope bool) []Touch

Touched lists the open issues a change to issue id's sections touches, none twice, a part first: its open parts (read again), the open issues that wait on it, and — its Scope changed — those whose sources share a file with its own: a Need rewritten moves what is built on it, not every issue on the same code.

type Undo added in v0.13.0

type Undo struct {
	Issue    int    `yaml:"issue,omitempty"` // left out in the issue's own state
	Act      string `yaml:"act"`
	Evidence string `yaml:"evidence"`
	Day      string `yaml:"day,omitempty"` // when a run found it, YYYY-MM-DD: the weekly sample counts it against one act
}

Undo is an act a person undid, and what shows it.

type Wait added in v0.15.0

type Wait struct {
	Issue int    `yaml:"issue"`
	Waits string `yaml:"waits"`
	Since string `yaml:"since"`          // the day it started waiting, YYYY-MM-DD
	Act   string `yaml:"act,omitempty"`  // proposed: the kind of act
	Line  string `yaml:"line,omitempty"` // proposed with no issue (an issue to open): its line
}

Wait is an issue waiting on a person, and since when.

func AskedWait added in v0.15.0

func AskedWait(id int, notes []forge.Note, role string) (w *Wait, known bool)

AskedWait is an issue's wait on its reporter: since the last round written to them, when no person wrote after it; known false when the forge does not say that round's day.

func ObsoleteWait added in v0.15.0

func ObsoleteWait(id int, o Obsolete) *Wait

ObsoleteWait is an announced issue's wait on a second judge: since the day its delay ended, while due and neither closed nor kept.

func ReadyWait added in v0.15.0

func ReadyWait(id int, t forge.Trail) (w *Wait, known bool)

ReadyWait is a ready issue's wait, from its trail: since the day it last got the label, when no pull or merge request nor commit named it since; known false when the forge does not say that day.

Jump to

Keyboard shortcuts

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