Help us shape the future of Go! Take the 2026 Go Developer Survey

report

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package report renders seamark's text reports — the shared surface behind the CLI, the MCP server, and anything else that answers questions from the index. Reports are deliberately plain, compact text: agents consume them verbatim, so every line costs tokens.

Index

Constants

View Source
const CompanionsTitle = "history suggests also reviewing"

CompanionsTitle heads the closing list in change_set and in check. The trace and the skills read the label, so it is one string.

View Source
const HookLessonTotal = 8

HookLessonTotal is the total lesson cap of one edit-hook injection. The value is the cap the single-file hook always used.

View Source
const MinFixDensityHistory = 5

MinFixDensityHistory is the least history a fix-density figure needs before it is worth stating: "1 of the last 2 commits" is noise, not a 50% hotspot.

Variables

View Source
var ErrForeignConfig = errors.New("report: the lesson evidence was not read for this config")

ErrForeignConfig marks a selection request for a config that ReadEvidence did not read for. The evidence holds the cluster citations of the pins live in its own configs only, so a selection with another config can miss a covered cluster.

Functions

func ChangeSet

func ChangeSet(w io.Writer, st *store.Store, root string, files []string) error

ChangeSet reports what a planned edit to the given files drags along: the files history says change together with them, the externally visible symbols whose callers will feel the edit, and the effect tags the change can ultimately reach. This is the pre-edit question — "what am I about to forget?" — answered from evidence, not vibes.

func ChangeSetNames added in v0.8.0

func ChangeSetNames(st *store.Store, root string, files []string) (names, unindexed []string)

ChangeSetNames names the files of a change_set request the way the index names them (asIndexedFile). names holds one name per file, in request order. unindexed holds the names that the index does not know, in the same order. A selection sample of the change_set surface names its paths here, so it selects for the same files as ChangeSet.

func CheckAdvisory added in v0.2.0

func CheckAdvisory(w io.Writer, st *store.Store, root string, files []string)

CheckAdvisory prints the lessons governing a diff's files after a gate verdict — advisory by contract: it never contributes to the verdict, degrades to silence on any error, and is skipped entirely for machine-readable output. files comes from gate.ChangedPaths, so the advisory can never disagree with the verdict about what changed.

func CheckCompanions added in v0.6.0

func CheckCompanions(w io.Writer, st *store.Store, root string, files []string)

CheckCompanions prints, after a gate verdict, the files history says usually change with the diff's files but that the diff leaves untouched. A forgotten companion is the omission history can see and a policy over effects cannot. The list is advisory and never part of the verdict; files comes from gate.ChangedPaths, like the lessons advisory, so the section can never disagree with the verdict about what changed. It degrades to silence on any error.

func Decision

func Decision(w io.Writer, d *gate.Decision)

Decision writes the verdict block shared by `seamark gate`, `seamark check`, and the MCP check tool. Rule messages come from workspace policy files — untrusted in a cloned repo, hence the wash.

func Expand

func Expand(w io.Writer, st *store.Store, root, ref string) error

Expand resolves ref — a symbol name/FQN, "file:start[-end]", or "lessons:<dir>" — and writes what it names: source lines, or an area's raw review-lesson ledger. This is the second half of every other report's contract: they return refs, Expand turns a ref into content.

func FixCount

func FixCount(decisions []model.Decision) int

FixCount reports how many of these decisions were corrections — reverts, plus every commit the fix miner would classify as a fix. Exported because more than one surface ranks files by it (the `why` fix-density line, the HTML report's heat colours), and two surfaces counting different commits would disagree about which file is hot.

func LedgerForRegion

func LedgerForRegion(st *store.Store, region string) ([]model.Lesson, error)

LedgerForRegion returns every mined lesson in a region's area: the region itself, everything beneath it, and the ancestor regions that cover it. An empty region is the whole repo. This is the raw-material view shared by `lessons --list/--region` and `expand lessons:<dir>`.

func LessonScope

func LessonScope(file string) string

LessonScope is the area a file's raw-lesson hint points at: its directory, or the file itself at the repo root (root files stay file-scoped everywhere in the lessons layer). Exported because the hotspot map scopes a file's cell the same way — clicking a cell must find the lessons that would fire when editing it.

func LessonsForFiles added in v0.2.0

func LessonsForFiles(st *store.Store, cfg *reviews.Config, files []string, budget int) ([]model.Lesson, int, error)

LessonsForFiles is the multi-file moment-of-change surface (RFC-002 §8): every file's applicable pins merged by identity, ranked by confidence ACROSS the whole set (a weak pin from the first file must not out-place a strong one from the last), restatements collapsed once globally, mined recurrence appended, all under one budget with an exact held-back count. ReadEvidence loads the shared context — applied proposals, cluster coverage, finding metadata — once, not per file, and changeSetFold applies the budget rule. Lines show regions, never triggering files: the caller supplied the file list, and a region is exactly the mapping back onto it.

func LessonsForFilesBudget added in v0.7.0

func LessonsForFilesBudget(st *store.Store, cfg *reviews.Config, files []string,
	budget LessonBudget,
) (lessons []model.Lesson, heldBack int, err error)

LessonsForFilesBudget selects the lessons of one edit operation that touches files, under one two-part budget. It reads the evidence once (ReadEvidence) and applies hookFold. The union is the one of LessonsForFiles: each pin appears once and ranks across all files, and mined lessons appear once per cluster.

For one file the lessons equal LessonsForScopeBudget with the same caps. A parity test holds that equality. heldBack counts the applicable pins that the result omits: collapsed restatements, pins above the pin cap, and pins above the total cap. The reminder points at pins only, so heldBack ignores mined lessons above the total cap.

One count differs from the single-file selector on purpose. With no pin cap, the single-file selector drops pins above the total cap without a count. This selector counts them, so no pin is hidden.

A pin cap of zero selects the deliberate-view rules of the single-file selector: no restatement collapse, and every pin carries its confidence tier.

func LessonsForScope

func LessonsForScope(st *store.Store, cfg *reviews.Config, file string, limit int) ([]model.Lesson, error)

LessonsForScope returns the lessons to surface for a file, after the config's mute/pin/threshold rules — the single path every surface (why, orient, the edit hook) shares, so they never disagree.

func LessonsForScopeBudget

func LessonsForScopeBudget(st *store.Store, cfg *reviews.Config, file string, limit, pinBudget int) ([]model.Lesson, int, error)

LessonsForScopeBudget is LessonsForScope with a pin cap for ambient surfaces (the edit hook); trimmed reports how many applicable pins the budget held back, so the caller can point at them instead of hiding them.

func Orient

func Orient(w io.Writer, st *store.Store, root string) error

Orient writes the repo overview an agent needs before its first edit: scale, module layout, the load-bearing API, the files whose changes travel in groups, and the recent decision trail. One screen, not a tour — every extra line here is paid on every onboarding.

func PrintDistillPlan

func PrintDistillPlan(w io.Writer, res DistillSummary, pending []model.Proposal,
	notes map[int64][]string, scopeFlagged []string,
)

PrintDistillPlan renders a distillation run and the full pending plan: every proposal awaiting a decision, this run's newcomers included. Proposal text is model output — untrusted — so it is sanitized; notes are never truncated (they are the payload). notes carries caller-rendered annotation lines per proposal id — trigger confirmations and scope advisories (report does not import distill). scopeFlagged lists the pN ids whose delivery may miss the trigger; they get the tail hint. Nil for both: the plan prints exactly as before.

func PrintEditReminder added in v0.7.0

func PrintEditReminder(w io.Writer, files []string, lessons []model.Lesson, morePins int) error

PrintEditReminder writes the advisory block for one edit operation. For one file the bytes equal PrintLessonReminder, so a single-file client keeps its reminder. For several files each line names the lesson region, because the region maps a lesson back to the files. It writes nothing when there are no lessons.

func PrintFiringSummary

func PrintFiringSummary(w io.Writer, s reviews.Summary)

PrintFiringSummary renders the edit-hook firing log: how often lessons actually reached an agent, and which would surface but never have — the decay signal (a lesson whose region no edit touches is a pruning candidate). All lesson text is untrusted, hence sanitized.

func PrintLessonBlock added in v0.2.0

func PrintLessonBlock(w io.Writer, header string, lessons []model.Lesson, trimmed int)

PrintLessonBlock renders a compact lesson list for multi-file surfaces: the same [pin]/[×N] tags the hook uses, plus the region — on a surface spanning files, the region IS the map back to them.

func PrintLessonLedger

func PrintLessonLedger(w io.Writer, lessons []model.Lesson, cfg *reviews.Config, scope string)

PrintLessonLedger lists every mined lesson in scope ("" = repo-wide) — the raw material for tuning .seamark/lessons.yaml. Below-threshold one-offs are shown too (they are exactly what a reader might want to mute or pin), each marked if the current config already hides it, followed by copy-paste config syntax and the promotion nudge: spotting a pattern in this list is how a lesson becomes a pin.

func PrintLessonReminder

func PrintLessonReminder(w io.Writer, file string, lessons []model.Lesson, morePins int) error

PrintLessonReminder writes a compact standalone lessons block for one file — used by `seamark lessons` and the PreToolUse edit hook. Writes nothing when there are no lessons, so the hook stays silent. morePins is how many applicable pins the injection budget held back; they are pointed at, never silently dropped.

func PrintOutcomes added in v0.3.0

func PrintOutcomes(w io.Writer, applied []model.Proposal, readings map[int64]outcome.Reading)

PrintOutcomes renders the passive loop's verdicts under --stats: an aggregate count line, then one verdict sentence per measured pin. Not-landing pins print first because they are the ones that need action. When nothing was measured it prints nothing, not an empty header.

func PrintProposalLedger

func PrintProposalLedger(w io.Writer, pending, applied, dismissed []model.Proposal,
	clusters [][]model.Proposal, health map[int64]ProposalHealth,
)

PrintProposalLedger renders the distillation decision record: what is still pending (with the full note and the commands that decide it), then what was applied or dismissed with its evidence health, compactly. Read-only — unlike --distill, it never spends an agent call, so "what did I decide?" and "what is waiting?" cost nothing to ask.

func Why

func Why(w io.Writer, st *store.Store, root, query string) error

Why resolves query as a file or symbol and writes the full report: definition, callers/callees with derivation, co-change, decisions.

Types

type DistillSummary

type DistillSummary struct {
	GroupsTotal   int
	GroupsRead    int
	GroupsSkipped int
	GroupsFailed  int
	GroupsPending int
	PrunedStale   int
	Duplicates    int
	// TokensNote is the caller-rendered cost line ("~59k tokens sent …"),
	// empty when nothing was sent.
	TokensNote string
}

DistillSummary is the run-shape PrintDistillPlan reports; a mirror of distill.Result's counters, kept here so report does not import the distill package.

type Evidence added in v0.8.0

type Evidence struct {
	// contains filtered or unexported fields
}

Evidence is one read of the index for the lesson selection of a set of files. A fold applies a config and a budget rule to it without a store read, so two configs can select from one observation. The edit hook, change_set, and check select through it, so a sample that uses it selects as they do.

Evidence is not safe for concurrent use: a fold fills the confidence memo.

func ReadEvidence added in v0.8.0

func ReadEvidence(st *store.Store, files []string, cfgs ...*reviews.Config) (*Evidence, error)

ReadEvidence reads the lesson evidence of files once: the applied proposals, the cluster citations, the finding metadata, the recorded repository root, one time stamp, and the mined lessons of each file. It writes nothing.

A fold must use one of cfgs. The citations are read only for the applied proposals whose pin is live in one of cfgs, because the hook reads them on every edit. A fold with another config can miss a covered cluster, so HookSelection and ChangeSetSelection refuse it with ErrForeignConfig.

func (*Evidence) ChangeSetSelection added in v0.8.0

func (ev *Evidence) ChangeSetSelection(cfg *reviews.Config) (Selection, error)

ChangeSetSelection selects the lessons of one change_set answer or one check advisory under cfg and its change budget. Lessons and HeldBack equal the result of LessonsForFiles with cfg.ChangeSetBudget(). cfg must be one of the configs of ReadEvidence, else the error is ErrForeignConfig.

func (*Evidence) HookSelection added in v0.8.0

func (ev *Evidence) HookSelection(cfg *reviews.Config) (Selection, error)

HookSelection selects the lessons of one edit-hook injection under cfg and its hook budget. Lessons and HeldBack equal the result of LessonsForFilesBudget with HookBudget(cfg). cfg must be one of the configs of ReadEvidence, else the error is ErrForeignConfig.

type Exclusion added in v0.8.0

type Exclusion struct {
	Lesson model.Lesson
	// Covered is true when an applied pin, live in the config, cites
	// every finding of the cluster.
	Covered bool
	// BelowThreshold is true when the lesson recurs fewer times than
	// the threshold of the config.
	BelowThreshold bool
	// Mutes holds a copy of each entry of Config.Mute that hides the
	// lesson, in the order of Config.Mute.
	Mutes []reviews.MuteRule
}

Exclusion explains why the config keeps a mined lesson out of a selection. It names every reason that applies, and more than one reason can apply. The reasons come from the predicates that the surfaces apply, so a sample and the surfaces cannot disagree.

type LessonBudget added in v0.7.0

type LessonBudget struct {
	// Total caps all lessons of the injection. Zero means no cap.
	Total int
	// Pins caps the pins of the injection. Zero means no pin cap.
	Pins int
}

LessonBudget is the two-part budget of one ambient injection. One edit operation spends one budget, whatever the number of files: a budget per file would multiply the injected context by the file count.

func HookBudget added in v0.7.0

func HookBudget(cfg *reviews.Config) LessonBudget

HookBudget returns the budget of one edit-hook injection for cfg.

func (LessonBudget) Clamped added in v0.8.0

func (b LessonBudget) Clamped() LessonBudget

Clamped returns the budget with the pin cap at most the total cap. A larger pin cap lets the total cap remove pins after the pin count is final, and the held-back count must include every removed pin.

type ProposalHealth added in v0.2.0

type ProposalHealth struct {
	Tier     string
	Facts    string
	Era      string // e.g. "distilled under prompt v1, before the recurrence rule"
	Retarget string // recomputed regions when they differ; "" when current
	// Scope is the trigger-scope advisory (RFC-004 Phase 1): the note
	// names a path outside the pin's regions and co-change evidence
	// agrees. Empty when the signals do not agree — the common case.
	Scope string
	// Blocked reports confirmed triggers that cannot become delivery
	// scopes (region cap or vanished path). Without it a confirmed
	// miss would be invisible: no drift, no advisory.
	Blocked string
	// Outcome is the passive loop's verdict sentence (outcome.Line)
	// for applied pins. Empty when the pin cannot be measured: pending
	// proposals, pruned pins, hand-written pins without citations.
	Outcome string
	// Escalate is true for not-landing pins: the pin fires and the
	// mistake recurs anyway. Drives the escalation hint in the ledger.
	Escalate bool
	// Pruned is true for applied rows whose pin is not in
	// .seamark/lessons.yaml (hand-pruned, or an apply block never
	// pasted). The pin delivers nothing, so region advice is
	// suppressed — a retarget hint here would name a pin the command
	// cannot find.
	Pruned bool
}

ProposalHealth is one proposal's evidence-health summary for the ledger (RFC-002 §7): the confidence tier with its facts, the prompt era when it predates the current recurrence rules, and the regions today's inference would assign when they differ from the stored ones. Computed by the caller (it needs the workspace root); the printer only renders.

type Selection added in v0.8.0

type Selection struct {
	// Lessons is the selected list in delivery order: Pins, then Mined.
	Lessons []model.Lesson
	// HeldBack is the count that the surface prints. For the edit hook
	// it counts pins only: Restated, OverPinCap, and OverTotal. For
	// change_set and check it counts Restated, OverTotal, and
	// MinedOverTotal. So the count is not "over budget" alone.
	HeldBack int
	// Pins are the selected pins, in the order of Lessons. The hook list
	// can hold one pin identity twice, because the single-file selector
	// keeps a pin that lessons.yaml repeats. The change_set list holds
	// each identity once. So a pairing of two lists needs the identity
	// and its ordinal.
	//
	// The Rank of a pin is its confidence tier only when the index holds
	// an applied proposal row. Without such a row, no annotator runs, and
	// every pin has Rank 0, the value of confidence.TierWeak. So a view
	// must not derive a tier from Rank.
	Pins []reviews.SurfacedPin
	// Mined are the selected mined lessons, in the order of Lessons.
	Mined []model.Lesson
	// Restated holds the pins that the restatement collapse drops. On
	// change_set, a repeat of a pin identity is never in this list. The
	// fold keeps one pin per identity before the collapse.
	Restated []reviews.SurfacedPin
	// OverPinCap holds the pins above the pin cap of the edit hook.
	// change_set has no pin cap, so there it is empty.
	OverPinCap []reviews.SurfacedPin
	// OverTotal holds the pins above the total cap.
	OverTotal []reviews.SurfacedPin
	// MinedOverTotal holds the mined lessons above the total cap.
	MinedOverTotal []model.Lesson
	// Excluded explains each mined cluster that the config keeps out,
	// one entry per cluster, in first-file order. A cluster that an
	// earlier file selects is not an exclusion. The evidence reads at
	// most 100 mined lessons per file, so a lesson past that read is in
	// no list.
	Excluded []Exclusion
}

Selection is the typed result of one fold. Lessons and HeldBack are exactly what the production surface delivers and prints. The other fields state where each pin and mined lesson of the evidence went, with one exception. change_set keeps only the first pin of each identity, so a later pin with that identity is in no list and in no count. A selection sample explains a result from these fields, never from report text. So a sample must not show that pin as removed or excluded.

Jump to

Keyboard shortcuts

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