review

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package review owns the review document model: the document types, the strict, lenient and stored views of the baum.review/1 schema, normalisation of model output, validation with located findings, derived fields, version history and model-free refresh, plus the tile catalogue.

Index

Constants

View Source
const ExchangeUnknownNote = exchangeUnknownNote

ExchangeUnknownNote is the generator note a document carries while its review exchange leaves back-and-forths or changes after opening unknown, for a host that sets those figures itself, such as a stack review.

View Source
const FactsSchema = "baum.facts/1"

FactsSchema names a pull request's facts. They are not a review document: no version, no sections, nothing a model wrote, and never stored as a version.

View Source
const MaxIdentifierLength = 128

MaxIdentifierLength is the maxLength the review schema gives every identifier, identifier reference and risk category (schema revision 2026-10-07.1). Documents stored before it can hold longer ones.

View Source
const RiskRubricVersion = "risk-v1"

RiskRubricVersion names the rules riskScore applies. A change to the scale, the floors or what counts as a limitation needs a new version, so a stored score always says which rules produced it. A limitation that applies only to input no earlier document could hold (incomplete_sections: a section without its details) changes no score the version already produced, so it keeps the version.

Variables

This section is empty.

Functions

func AssembleStaged

func AssembleStaged(parts StagedParts, final bool) ([]byte, error)

AssembleStaged builds the staged document of the parts: the outline with each complete section in place, every other section without its details (failed when it is in Failed, else pending) and the context when written. A final document has no pending section, every section not complete being failed, and its reading time set (ReviewMinutes); a draft has neither.

func DeriveHunkURLs

func DeriveHunkURLs(document []byte) ([]byte, error)

DeriveHunkURLs gives every hunk of index.hunks without a github_url the one generation records, bundle.HunkDiffURL of its path and first new line, so a document whose fragments were not stored reads as it did when they were. A hunk without a path or a two-number new_range is left alone, and a document with nothing to derive is returned as given.

func DetailsOf

func DetailsOf(section []byte) []byte

DetailsOf returns a section's details in the shape the details stage writes them: its id, summary, attention, risks, evidence, blocks and tiles. A section that cannot be read is returned as it is.

func DocumentWithTileKinds

func DocumentWithTileKinds(document []byte, kinds []string) []byte

DocumentWithTileKinds removes every tile a model returned whose kind is not offered, from its sections and their risks, and a tiles list left empty. A document that is not the expected shape is returned unchanged for the validator to report.

It is exported for hosts that run the generate-and-repair loop themselves.

func EmbedHunkPatches

func EmbedHunkPatches(ctx context.Context, document []byte, patch FilePatch, maxBytes int64) ([]byte, error)

EmbedHunkPatches fills in the diff of every hunk of index.hunks that has none from its file's patch, read once per path with patch, and derives the hunk's github_url when it has none (DeriveHunkURLs), so the document can be read without the clone. A hunk's text is the patch's hunk with the same new range and the same counts of added and removed lines, as the viewer finds it; a hunk the patch does not hold, or whose file has no patch, keeps no diff. Reading stops once maxBytes of patch text have been read (0 is no limit), leaving later hunks without a diff. An error from patch, or the context ending, fails the call. The paths are asked for in the order of HunkPatchPaths, so a caller can read them ahead.

func FailPendingDetails

func FailPendingDetails(document []byte) []byte

FailPendingDetails returns the document with every section whose details are still being written (pending) marked as failed. Only a live draft holds pending details: a host applies this before it publishes or saves a version. The document is returned unchanged when no section is pending or it cannot be read as an object with sections.

func FitPreviousHunkAnchors

func FitPreviousHunkAnchors(b *bundlepkg.Bundle) error

FitPreviousHunkAnchors moves the hunk anchors of b's previous version to where their hunks sit in b's diff. A hunk ID names the path and changed lines, so a rebase that shifts the hunk keeps its ID and moves its lines. When Previous.HunkRanges shows the hunk with the same line count, its layout is taken as unchanged and an anchor is shifted by as many lines as the hunk moved. When the count differs, the hunk's context changed (the ID ignores context), so no shift is known to keep the anchored lines: the range is removed and the anchor names the whole hunk. Either way it is then fitted to the hunk as an authored anchor is. The model is shown, and the host carries over, the hunk's current lines rather than lines it no longer occupies.

func HunkPatchPaths

func HunkPatchPaths(document []byte) ([]string, error)

HunkPatchPaths lists, each once and in the order EmbedHunkPatches asks for them, the paths of the hunks of index.hunks whose diff it would fill in.

func OutlineOf

func OutlineOf(document []byte) []byte

OutlineOf returns a staged document's outline in the shape the outline stage writes it: the summary without its context and reading time, and each section's outline fields only. A document that cannot be read is returned as it is.

func PreserveRiskOmissionsForRepair

func PreserveRiskOmissionsForRepair(previous *bundlepkg.PreviousVersion, assessed, repaired []byte) []byte

PreserveRiskOmissionsForRepair removes prior risks that were absent from the provider's first assessment. A validation repair must not turn those omissions into explicit reactivations.

It is exported for hosts that run the generate-and-repair loop themselves.

func PreserveSectionRiskOmissions

func PreserveSectionRiskOmissions(previous *bundlepkg.PreviousVersion, assessed, repaired []byte) []byte

PreserveSectionRiskOmissions is PreserveRiskOmissionsForRepair for one section's details: it removes from a repair (repaired) the previous risks the first details of the section (assessed) left out, so a repair cannot reactivate them. Details that cannot be read are returned as they are.

func PreviousVersionOf

func PreviousVersionOf(document []byte, version int) (*bundle.PreviousVersion, error)

PreviousVersionOf carries a stored document into the next bundle without derived fields, after the stored-document rules (normalizeStored), so the next version keeps identifiers the current schema accepts.

func RestoreOmittedPreviousSections

func RestoreOmittedPreviousSections(document []byte, previous *bundlepkg.PreviousVersion, attachments []bundlepkg.Attachment) ([]byte, error)

RestoreOmittedPreviousSections returns the authored document with each previous section it omits restored as completion would restore it: the previous content with no hunks, only offered images and no risk lifecycle fields, with the previous sections first in their order and the new ones after. Sections the document carries are left as they are, so a risk omitted from them still reads as omitted. A stale section's risks keep their recorded state either way, so a host may restore early to edit restored content, and completion keeps the edited section. Unlike a section completion restores itself, the restored content is then normalized like any authored section: it loses its assessment, as every section without hunks does, since none takes part in the risk score. The document is returned unchanged when it omits no previous section.

func ReusableSectionDetails

func ReusableSectionDetails(previous *bundlepkg.PreviousVersion, outline []byte) map[string][]byte

ReusableSectionDetails returns, by section ID, the details the previous version holds for each outline section (PrepareOutline's document) whose hunks are those of the previous version's section with the same ID, when that section's details were complete (it has no details state): its summary, attention, active risks without their lifecycle fields, evidence, blocks and tiles, in the shape the details stage writes. A mitigated risk is left out, so completion keeps it mitigated. A host validates what it reuses (PrepareSectionDetails) and asks the model for any it rejects.

func ReviewMinutes

func ReviewMinutes(document []byte) int

ReviewMinutes estimates the whole minutes a reader needs to read an authored review document once: the words of the overview (the summary's text, attention, review exchange, release note and breaking change), the context, and each section's title, summary, attention, behavior steps (title, text, before, after and question), risks, evidence (claim, detail and expects) and decisions (title, text, rationale, trigger, rejected alternative and evidence), at 200 words a minute, plus the code lines it shows (code blocks, tile code excerpts and the lines a behavior step's first hunk anchor names) at 12 lines a minute. The sum is rounded up and kept within 1 to 240, the schema's range. A document that cannot be read takes 1 minute.

func SectionID

func SectionID(details []byte) string

SectionID returns the ID a section's details name, spelled as the outline spells section IDs, or "" when they name none.

func SectionTitle

func SectionTitle(title string, position int) string

SectionTitle is the label of the section at a 0-based position. Validation rejects blank titles, but documents stored before that keep them; such a section is labelled by its reading order, which is fixed once published.

func ShortenIdentifier

func ShortenIdentifier(id string) string

ShortenIdentifier returns an identifier as normalizeStored rewrites it: one of at most MaxIdentifierLength characters unchanged, and a longer one as its first characters, without trailing underscores, then an underscore and the first identifierHashLength hexadecimal digits of the SHA-256 of the whole identifier, MaxIdentifierLength characters at most. The result keeps the identifier's prefix and character set, so it matches the same schema pattern, and shortening it again changes nothing.

A host that keys its own records by a document identifier (a reader's read marks, a section approval) compares the stored key through this function, so a record made before the document was normalized still matches it.

func ShortenStoredIdentifiers

func ShortenStoredIdentifiers(document []byte) ([]byte, error)

ShortenStoredIdentifiers applies the identifier rule of the stored-document rules (normalizeStored) to an encoded document, for a host that serves stored documents and keys records of its own by their identifiers, so what it serves names sections and risks as a refresh will store them. The other rules only make a stored document pass validation, which a reader of the served document does not repeat. It returns document itself when it has no identifier over MaxIdentifierLength, and an error only when it has one and is not a JSON object.

func StoredOutline

func StoredOutline(document []byte) (outline, context []byte, err error)

StoredOutline returns the outline and the context of a stored document written in stages, for a host that writes again the details of its failed sections (agent's StagedRun.Outline): the summary and the sections the version wrote, not the stale ones it carried from an earlier version, with its relations, in the shape the outline stage writes, and the summary's context, nil when it has none. PrepareOutline drops the host's fields left in them.

func StripHunkEvidence

func StripHunkEvidence(document []byte) ([]byte, bool, error)

StripHunkEvidence removes diff and github_url from every hunk of index.hunks. It reports whether it removed anything; when it did not, the document is returned as given.

Types

type DocumentValidator

type DocumentValidator struct {
	Schema   []byte
	Revision string
	// contains filtered or unexported fields
}

DocumentValidator holds three views of the review schema: Schema is the lenient contract the model writes against, strict is the authored contract a normalized document must satisfy before completion, and full is the stored document with the host's derived fields, which also accepts tiles of the kinds the schema retired (storedDocumentSchema).

func NewDocumentValidator

func NewDocumentValidator() (*DocumentValidator, error)

NewDocumentValidator compiles the embedded review schema once per process and returns the same validator on every call, or the same error. The result is read-only, so it may be shared between goroutines.

func (*DocumentValidator) Complete

func (v *DocumentValidator) Complete(document []byte, b *bundlepkg.Bundle, directory string, model string, now time.Time) ([]byte, string)

Complete derives host-owned fields, then validates the full document. It never calls the model and never accepts derived fields from its output; model names the generator recorded in the document.

func (*DocumentValidator) CompleteStaged

func (v *DocumentValidator) CompleteStaged(document []byte, b *bundlepkg.Bundle, directory string, model, promptVersion string, now time.Time) ([]byte, string)

CompleteStaged is CompleteWithPrompt for a document a staged generator assembled: it validates it as PrepareStaged does, then derives the host-owned fields exactly as for a document written in one pass. A host completes a draft with pending sections the same way to show it, and publishes or saves only a document without them (FailPendingDetails).

func (*DocumentValidator) CompleteWithPrompt

func (v *DocumentValidator) CompleteWithPrompt(document []byte, b *bundlepkg.Bundle, directory string, model, promptVersion string, now time.Time) ([]byte, string)

CompleteWithPrompt is Complete for a host that versions its instruction prompt: promptVersion is recorded as generator.prompt_version, and an empty one records nothing. The model's output never sets it.

func (*DocumentValidator) ContextSchema

func (v *DocumentValidator) ContextSchema() ([]byte, error)

ContextSchema is the schema of the context stage's reply: the summary's context, as the model schema defines it, under a context key.

func (*DocumentValidator) Contract

func (v *DocumentValidator) Contract() map[string]any

Contract returns a copy of the strict authored schema as a decoded tree, with its $defs; changing it does not affect the validator.

It is exported for hosts that inspect the authored contract, such as in their tests.

func (*DocumentValidator) DetailsSchema

func (v *DocumentValidator) DetailsSchema(kinds []string) ([]byte, error)

DetailsSchema is the schema of the section details stage's reply for the offered tile kinds: a list of sections, each with its id and only the fields of its details (summary, attention, risks, evidence, blocks and tiles), as the model schema (ModelSchema(kinds)) defines them.

func (*DocumentValidator) ModelSchema

func (v *DocumentValidator) ModelSchema(kinds []string) ([]byte, error)

ModelSchema is the schema a run gives the model for the offered kinds. Without kinds it has no tiles at all. Otherwise the authored contract keeps only those kinds' tile variants, and each definition only the removed variants used, before the model-facing contract is derived from it.

It is exported for hosts that run the generate-and-repair loop themselves.

func (*DocumentValidator) OutlineSchema

func (v *DocumentValidator) OutlineSchema() ([]byte, error)

OutlineSchema is the schema of the outline stage's reply: the model schema without tiles, keeping only the document's schema, summary (without its context and reading time), sections (each with only its id, title, kind, hunks and assessment) and relations.

func (*DocumentValidator) Prepare

func (v *DocumentValidator) Prepare(document []byte, bundle *bundlepkg.Bundle, directory string) ([]byte, string)

Unresolved evidence remains visible as a model assertion; it cannot claim verification.

func (*DocumentValidator) PrepareContext

func (v *DocumentValidator) PrepareContext(outline, reply []byte, b *bundlepkg.Bundle, directory string) ([]byte, string)

PrepareContext merges the context stage's reply ({"context": ...}) into the outline (PrepareOutline's document) and validates it with the rules of a whole document. It returns the summary's context, normalized, and the findings, empty when it is valid.

func (*DocumentValidator) PrepareOutline

func (v *DocumentValidator) PrepareOutline(reply []byte, b *bundlepkg.Bundle, directory string) ([]byte, string)

PrepareOutline normalizes and validates the outline stage's reply. It returns the outline as a staged document whose sections all have pending details, and the findings, empty when it is valid. Only the outline fields are kept; the rules are those of a whole document (the schema, hunk and section IDs, the previous sections first in their order, at most one mechanical section), and every logical section with hunks must have an assessment.

func (*DocumentValidator) PrepareSectionDetails

func (v *DocumentValidator) PrepareSectionDetails(outline, details []byte, b *bundlepkg.Bundle, directory string) ([]byte, string)

PrepareSectionDetails merges one section's details, as the details stage wrote them, into the outline (PrepareOutline's document) and validates the section with the rules of a whole document, every other section left without its details. It returns the merged section, normalized, and the findings, empty when it is valid; every finding is the section's own, since the outline is valid and the other sections hold nothing to check.

func (*DocumentValidator) PrepareStaged

func (v *DocumentValidator) PrepareStaged(document []byte, b *bundlepkg.Bundle, directory string) ([]byte, string)

PrepareStaged is Prepare for a document a staged generator assembled (AssembleStaged): complete sections meet the authored rules, sections without their details the stored ones, and the summary may lack its context.

func (*DocumentValidator) Refresh

func (v *DocumentValidator) Refresh(document []byte, b *bundlepkg.Bundle, now time.Time) ([]byte, error)

Refresh changes evidence and derived summaries in place, preserving the reviewed revision, authored prose, section order and generation provenance. It reads the stored document after the stored-document rules (normalizeStored), so the refreshed document carries their rewrite; a stored document that still fails the schema is a *StoredDocumentError.

func (*DocumentValidator) SpliceSections

func (v *DocumentValidator) SpliceSections(latest, completed []byte, ids []string) ([]byte, error)

SpliceSections returns latest, the stored version as it is now (refreshed since, perhaps), with the sections ids replaced by those of completed, the same version completed again after their details were written (CompleteStaged), so that the details land without losing what a refresh brought in the meantime. What follows from the sections is taken from completed, which derived it from the same sections: the risk score and its limitations, the reading time and the risk line counts; the open agent findings per section are counted again from latest's agent reviews. The two must be the same generation (repository, pull request, version, head, base, merge base and generation time), and every id a section of both.

func (*DocumentValidator) ValidHunkIDs

func (v *DocumentValidator) ValidHunkIDs(bundle *bundlepkg.Bundle) bool

ValidHunkIDs reports whether every hunk ID in the bundle has the form the schema requires.

func (*DocumentValidator) Validate

func (v *DocumentValidator) Validate(document []byte, bundle *bundlepkg.Bundle) string

Validate checks a complete stored document against the schema and the document's semantic rules, and returns every finding in one pass, or "" when it is valid.

func (*DocumentValidator) ValidateStored

func (v *DocumentValidator) ValidateStored(document []byte, bundle *bundlepkg.Bundle) []string

ValidateStored checks a stored baum.review/1 document against the full schema and the document's semantic rules, and returns every finding, or nil when it is valid. It checks the document as every reader sees it, after the stored-document rules (normalizeStored), so an identifier stored before identifiers were bounded is not a finding, and neither is a tile of a retired kind the viewer renders or one the rules remove. Images are checked against the document's own index. The rules that need the generation bundle run only when bundle is non-nil.

type Facts

type Facts struct {
	Schema  string       `json:"schema"`
	Review  factsReview  `json:"review"`
	Summary factsSummary `json:"summary"`
	Stats   factsStats   `json:"stats"`
	// AgentReviews are the review tools' assessments; their findings name
	// no section, as there are none.
	AgentReviews []documentAgentReview `json:"agent_reviews"`
	// UnassignedHunks is every hunk, as no section covers any.
	UnassignedHunks []string      `json:"unassigned_hunks"`
	Index           documentIndex `json:"index"`
}

Facts are what a pull request shows before any review exists: the parts of a review document the host derives from the bundle alone (its change size, checks, sessions, conversation, threads, hunks and the agent reviews posted on it), filled by the same code that fills them when a document is completed or refreshed.

func BuildFacts

func BuildFacts(b *bundlepkg.Bundle, now time.Time) Facts

BuildFacts derives a pull request's facts from a bundle, as of now. It never calls a model; the bundle is the assembled, redacted one (assemble.Request.Facts builds it without a checkout).

type FilePatch

type FilePatch func(ctx context.Context, path string) (patch string, ok bool, err error)

FilePatch reads the masked patch of one changed file, from its first "@@" line, as locallink.Patcher answers it. ok is false when there is none to read: the file has no text patch, or the clone cannot provide it.

type OutputRedactor

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

OutputRedactor masks secret spans in what a model returned, before it is stored or shown: a review document, walked beside the authored contract so that references and closed values keep their exact text, or any other text. It counts the spans it masked across its calls and is not safe for concurrent use.

func NewOutputRedactor

func NewOutputRedactor(v *DocumentValidator, redactor *bundlepkg.Redactor, b *bundlepkg.Bundle, checkout map[string]bool) (*OutputRedactor, error)

NewOutputRedactor returns a redactor for output about the bundle, which must be redacted already; with a nil bundle no reference resolves. checkout lists the repository paths of the run's checkout, either tree. With a nil validator a document has no contract: every string, keys included, is free text.

func (*OutputRedactor) Document

func (r *OutputRedactor) Document(ctx context.Context, document []byte) ([]byte, error)

Document redacts one document. A document with nothing to mask is returned byte for byte, and output that is not JSON is redacted as text.

func (*OutputRedactor) Identifiers

func (r *OutputRedactor) Identifiers(ctx context.Context, document []byte) ([]byte, error)

Identifiers masks the secrets in the identifiers of a document as the model wrote it, and must run before DocumentValidator.Prepare. Prepare respells every identifier, category and tile-local name in lowercase with underscores, and a secret respelled that way (sk-ant-api03-AbC... as sk_ant_api03_abc...) is one no rule detects any more, so Document cannot find it after Prepare. The values scanned are those normalization respells, taken from its own walk, each bounded by the maxLength of its respelling. Each is scanned as maskClosed scans a closed value, whole and from after every run of characters that are not letters or digits (the runs Prepare respells as one underscore), and is masked in place with the format-preserving mask, which Prepare respells to x, 9 and underscores. A value whose respelling is over its maxLength, which validation rejects anyway, is scanned the same way, in smaller windows past its first closedCopyLimit restarts, then masked whole, counted only if a secret was found in it.

The same secret may be written in another identifier in a spelling that no rule detects, in upper case or already respelled. So the respelling of each finding in an identifier is a source, as is the key a rule detects inside it without the host or tail it took along (see addSources and keySources), and every identifier whose respelling holds a source as whole words is masked whole and counted. Free text is not scanned here, and Document masks it after Prepare, but its words that respell to a source are masked here (see freeSpellings). Every other string value of the document equal to a masked identifier is masked as it is, so a reference to it still matches.

A value masked for a secret counts in Masked as its spans and once in MaskedClosed, however many places hold it, and a host rejects the run when MaskedClosed is not zero; a value with nothing detected never counts. A document with nothing to mask, or one that is not JSON, is returned byte for byte; Prepare rejects the latter and Document redacts it as text.

A host calls Identifiers, then Prepare, then Document on what Prepare returned, all with one OutputRedactor, and checks MaskedClosed last.

func (*OutputRedactor) Masked

func (r *OutputRedactor) Masked() int

Masked returns the number of spans masked so far.

func (*OutputRedactor) MaskedClosed

func (r *OutputRedactor) MaskedClosed() int

MaskedClosed returns the number of values masked so far that a schema closes by pattern or date-time format: identifiers, categories, SHAs and the like, whether Document found the secret or Identifiers found it in the value as the model wrote it. They are free lowercase text, so a secret the model copied into one is masked in place, but a value that held one is not what the model was asked to write, and a host rejects the run when this is not zero. Each value counts once, however many spans it holds; the spans are in Masked as well.

func (*OutputRedactor) Text

func (r *OutputRedactor) Text(ctx context.Context, s string) (string, error)

Text redacts a string that is not a document.

type StagedParts

type StagedParts struct {
	Outline  []byte
	Sections map[string][]byte
	Failed   map[string]bool
	Context  []byte
}

StagedParts are the parts of a staged review written so far: the outline (PrepareOutline's document), the complete sections by ID (PrepareSectionDetails), the sections whose details failed, and the summary's context (PrepareContext), nil while it is not written.

type StoredDocumentError

type StoredDocumentError struct {
	Err error
}

StoredDocumentError reports that a stored document does not pass the current schema, or the document's own rules, even after normalizeStored. Refreshing it cannot succeed until it is regenerated or a stored-document rule repairs it, so a host can tell it apart from a failure of the refresh itself.

func (*StoredDocumentError) Error

func (e *StoredDocumentError) Error() string

func (*StoredDocumentError) Unwrap

func (e *StoredDocumentError) Unwrap() error

Directories

Path Synopsis
Package tilecatalogue holds the review tile catalogue: the kinds generation can offer and the selection guidance the model receives for each.
Package tilecatalogue holds the review tile catalogue: the kinds generation can offer and the selection guidance the model receives for each.

Jump to

Keyboard shortcuts

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