documentalist

package
v0.7.1 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package documentalist holds the deterministic part of the documentalist role (roles/documentalist): which docs became suspect because a source changed, which are only pending because the cascade is cut, the hygiene checks (budgets, duplicates, links, identifiers gone from the code), and the judge of the patches the agent proposes for suspect docs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Coverage

func Coverage(repo string, globs []string) (tracked, none, untracked []string, err error)

Coverage sorts the docs under the docs globs: those declaring their sources, which alone can be found suspect; those declaring none (`sources: []`), which describe no code; and those declaring nothing.

func Derive

func Derive(repo string, docs map[string]string, commands map[string]string) ([]verdict.Finding, map[string]string)

Derive regenerates the derived blocks of the docs from the commands the project declares by name (`settings.derive`). Commands live in the config, which only people change, never in a doc: a doc names one. Markers shown in code — a fenced block or a code span — are examples, not blocks. It returns what it found, and the new content of each doc whose blocks were stale.

func Header(content string) (meta string, lines int)

Header is a doc's header, as written, and how many lines it takes.

func InCodeAt added in v0.2.2

func InCodeAt(repo, rev, name string) (bool, error)

InCodeAt says whether a name is a whole word of the code (not Markdown) at rev.

func Post

func Post(runDir, repo string) int

Post judges the agent's patches, then turns the findings into a verdict. Suspect and pending docs are reported for a person, unless a patch handled them; a source that could not be judged, or a check that could not run, blocks.

func Pre

func Pre(runDir, repo string) int

Pre finds suspect and pending docs, runs the hygiene checks, and writes the suspect docs into task.md for the agent to judge. It exits 3 when a source repository cannot be read: a source that was not read has not been checked.

func QuoteIn added in v0.2.2

func QuoteIn(p, content, quote string) (found, code bool, line int)

QuoteIn finds a quote in a file, white space aside: found anywhere, found with a character of it outside a comment, and the line it starts on. A quote found only in a comment is not evidence (ADR-0014, step 2).

func Section

func Section(content, anchor string) (string, bool)

Section returns the text under the heading whose slug is anchor, up to the next heading of the same or a higher level. An empty anchor means the body.

func SourceFileAt added in v0.2.2

func SourceFileAt(repo string, d *Doc, p string) (content, commit string, ok bool)

SourceFileAt is a file under one of a doc's sources at the commit its `checked` names (`name:file` for another repository's), and that commit.

func SourcesAt added in v0.2.2

func SourcesAt(repo string, d *Doc, limit int) (evidence []string, fits bool, err error)

SourcesAt is each source of a doc, whole, at the commit its `checked` names, as a task shows it. fits is false past limit characters: then the doc's `checked` could not have been earned by reading them (ADR-0014). An error is a source that cannot be read at all.

func UnreadDocs added in v0.2.1

func UnreadDocs(repo string, globs []string) (string, error)

UnreadDocs is what the doctor says of the docs the role does not read: "" when there are none.

Types

type Budgets

type Budgets struct {
	DocLines     int `json:"doc-lines"`
	SectionWords int `json:"section-words"`
	CardWords    struct {
		Min int `json:"min"`
		Max int `json:"max"`
	} `json:"card-words"`
	FolderLines        int `json:"folder-lines"`
	RootAgentFileLines int `json:"root-agent-file-lines"`
}

Budgets are the size limits of the docs (roles/documentalist/role.yaml).

type Doc

type Doc struct {
	Path    string
	Sources []string
	Checked map[string]string // repository name ("" = this one) -> commit
	// JudgedInParts is the commit the doc was last judged in parts at: it is
	// not put before an agent again until a source changes after it.
	JudgedInParts string
	// Judged is the commit an agent judged the doc whole at without vouching
	// for every sentence: held the same way.
	Judged string
}

Doc is a documentation file that declares its sources.

func ParseDoc

func ParseDoc(path string, content []byte) (*Doc, error)

ParseDoc reads a doc's header. A doc without sources is not tracked.

type Duplicates

type Duplicates struct {
	MinWords   int     `json:"min-words"`
	Similarity float64 `json:"similarity"`
}

Duplicates says which repeated passages are worth reporting.

type Freshness

type Freshness struct {
	StaleAfterDays int `json:"stale-after-days"`
}

Freshness says how long a doc stays trusted without being read again.

type Problem

type Problem struct {
	Rule, Where, Message, Key string
	Size                      int
	Other                     string // a duplicate: the other doc holding the passage
}

Problem is what a hygiene check found. Key names the problem without its size, so the same problem is recognised before and after a patch; Size says how bad it is, so a patch that makes it worse is recognised too.

func CountsOff added in v0.2.0

func CountsOff(repo string, t Tree, docs []*Doc) []Problem

CountsOff reports, for every doc declaring its sources, each line count it states wrong for one of them (ADR-0014, step 2). While one stands, the doc's `checked` cannot move.

func ExternalLinks(repo string, docs []string) (problems []Problem, ok bool, err error)

ExternalLinks checks the docs' links to other sites with lychee (https://lychee.cli.rs), which reads its own lychee.toml and .lycheeignore in the repository. A link answered by an HTTP error is broken; one that could not be reached (no network, a timeout) is only counted, so a run offline is not a flood of findings. ok is false when lychee is not installed: the links stay unchecked, and the caller says why.

func Hygiene

func Hygiene(t Tree, b Budgets, d Duplicates) []Problem

Hygiene runs the checks that need no git history: budgets, duplicates, links, and citations of superseded decisions. A budget that is not set is said, never skipped silently.

func IdentifiersGone

func IdentifiersGone(repo string, docs map[string]string) ([]Problem, error)

IdentifiersGone reports the identifiers a doc names that were in the code when the doc was last edited, and are gone from it now (DOCER). A name that was never in the code is not reported: it may be a product term.

func IdentifiersRemoved

func IdentifiersRemoved(repo, rng string, docs map[string]string) ([]Problem, error)

IdentifiersRemoved reports, for the commits of a range, the identifiers a doc names that these commits removed from the code and that are gone now. It searches the code for those names only: IdentifiersGone searches it at each doc's last edit, minutes on a large repository, too long for a push; what went earlier is left for gardening.

type Ref added in v0.2.3

type Ref string

Ref is a setting naming a commit or a tag. Written unquoted, a commit of digits only (7515148) is a number to YAML: it is read as the text it is. One YAML would read otherwise than written (0123456, octal) never gets here: the config is refused, saying to quote it (role.CheckConfig).

func (*Ref) UnmarshalJSON added in v0.2.3

func (r *Ref) UnmarshalJSON(data []byte) error

type SampleSettings added in v0.2.2

type SampleSettings struct {
	Judge   string `json:"judge"`    // an --ai value: claude:opus, cmd:…
	AtLeast string `json:"at-least"` // provider, model or context (ADR-0005)
	// After: a commit (a tag) before which nothing is sampled — the
	// release whose engine earns `checked` (ADR-0014, step 0).
	After Ref `json:"after"`
}

SampleSettings is the `sample` setting: the judge reading the sample, and the least independence from the model that vouched it may stand at.

type Settings

type Settings struct {
	Docs        []string `json:"docs"`
	Propagation []struct {
		From string `json:"from"`
		To   string `json:"to"`
		When string `json:"when"`
	} `json:"propagation"`
	Budgets    Budgets    `json:"budgets"`
	Duplicates Duplicates `json:"duplicates"`
	Freshness  Freshness  `json:"freshness"`
	// MaxOpenMergeRequests stops gardening while this many of the role's
	// merge requests wait for review (ADR-0006).
	MaxOpenMergeRequests int `json:"max-open-merge-requests"`
	Truth                struct {
		Doc []string `json:"doc"` // docs the code follows: never rewritten to match it
	} `json:"truth"`
	AIMaxCalls int               `json:"ai-max-calls"`
	Derive     map[string]string `json:"derive"` // name -> command giving a derived block
	// Documented: the code the project wants described; a file of it no
	// doc names in its sources is reported.
	Documented []string `json:"documented"`
	// JudgeInParts judges a doc whose sources do not fit a task in parts,
	// instead of leaving it to a person (ADR-0009); PartsMax caps the parts
	// of one doc, PartsMaxPerRun those asked in one run.
	JudgeInParts   bool `json:"judge-in-parts"`
	PartsMax       int  `json:"parts-max"`
	PartsMaxPerRun int  `json:"parts-max-per-run"`
	// For measuring whole against parts on the same doc (tests/evaluation):
	// PartsAlways judges in parts even a doc that fits whole, PartChars
	// caps the sources' share of a part, so that small sources still split.
	PartsAlways bool `json:"parts-always"`
	PartChars   int  `json:"part-chars"`
	// History and Decisions: the project's globs of history docs and of
	// decision records, added to the names the usual tools give them
	// (records.go).
	History   []string `json:"history"`
	Decisions []string `json:"decisions"`
	// Language: the docs' language, whose glue and fact words the removal
	// rule reads ("en", "fr"); "" reads each doc's own (words.go).
	Language string `json:"language"`
	// Versions: how the project writes a version, when not in three parts
	// (a regexp), and the files saying its version (values.go).
	Versions struct {
		Pattern string   `json:"pattern"`
		Files   []string `json:"files"`
	} `json:"versions"`
	// WholeChars caps the characters a doc's sources may take to be judged
	// whole; past it, a person judges the doc, or it is judged in parts.
	WholeChars int `json:"whole-chars"`
	// Sample: who reads the weekly sample of the docs vouched for
	// (ADR-0014, step 4; workline sample).
	Sample SampleSettings `json:"sample"`
}

Settings are the role's settings, as merged by the engine.

func SettingsFrom added in v0.2.2

func SettingsFrom(merged map[string]any) (Settings, error)

SettingsFrom reads the role's settings as the engine merged them.

func (Settings) IsDoc added in v0.2.2

func (s Settings) IsDoc(p string) bool

IsDoc says whether a path is one of the docs the settings name.

func (Settings) WholeCap added in v0.2.2

func (s Settings) WholeCap() int

WholeCap is the cap on the characters a doc's sources may take to be judged whole.

type Tree

type Tree struct {
	Docs  map[string]string
	Files map[string]bool
}

Tree is what the hygiene checks look at: the docs' contents, and every file the repository tracks (links may point to any of them).

Jump to

Keyboard shortcuts

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