Documentation
¶
Overview ¶
Description images: the rendered-image and markdown-upload walk of a pull request description, image identity and sniffing, the attachment listing of a bundle, and the archive that carries the images to a run.
Package bundle defines the evidence bundle: the input a review generation run reads, and the diff index that anchors its hunks.
Bundle is a dedicated type, not a host's stored rows or API types directly: its fields are the only way data leaves the host for the model, so a new column elsewhere cannot widen what a generation run reads by accident.
Code checkout. A generation run reads the repository's code, not only the diff, so its risk and behavior judgments can account for callers, invariants and existing tests the diff does not show; this file exports the head tree and compared merge-base paths into one budgeted archive and unpacks it for the run.
GitHub evidence mapping every host applies the same way, whether it reads stored rows or asks GitHub directly: identifiers, states, bot flags and review thread placement.
Index ¶
- Constants
- Variables
- func ApplyCaps(bundle *Bundle, caps Caps)
- func ApplyCheckoutOmissions(b *Bundle, omissions []CheckoutOmission)
- func AttachCommitChanges(ctx context.Context, comparer CommitComparer, pr *PullRequest) error
- func AttachThreads(b *Bundle, threads []ReviewThreadInput)
- func AttachmentID(sourceURL string) string
- func BudgetExceededReason(name string) string
- func CapReviewConfigContent(config *ReviewConfig) bool
- func ChangePaths(change FileChange) []string
- func ChangesReviewConfig(hunks []Hunk) bool
- func CheckRunID(databaseID int64) string
- func CommandOutcome(status string) string
- func CommandText(input []byte) string
- func ExplicitAutomationProvider(body string) (provider string, ok bool)
- func Fit(bundle *Bundle, caps Caps) error
- func FlagBotContribution(item *ConversationItem)
- func FlagBotReport(item *ConversationItem, markers []string)
- func GitHubContentURL(u *url.URL) bool
- func HunkDiffURL(path string, line int) string
- func IsBotActor(actorType string) bool
- func KeepKnownCommandTargets(sessions []Session, knownPath func(string) bool)
- func KnownPaths(paths ...string) func(string) bool
- func MarkdownUploads(body string) map[string]string
- func MaxAttachmentsArchiveBytes(maxImages int, maxImageBytes int64) int64
- func ProviderFromLogin(login string) string
- func PullRequestState(state string, merged bool) string
- func Redact(ctx context.Context, bundle *Bundle, redactor *Redactor) error
- func RedactFilePatch(ctx context.Context, redactor *Redactor, path, patch string) (masked string, ok bool, err error)
- func RoleForPath(filePath string) string
- func SetDigest(bundle *Bundle) error
- func SniffImage(content []byte) (contentType string, width, height int, ok bool)
- func SortChecks(checks []Check)
- func SortConversation(items []ConversationItem)
- func StatusCheckID(nodeID string, databaseID int64) string
- func TargetPath(target string) string
- func UnpackAttachments(ctx context.Context, archive, dir string, attachments []Attachment, ...) error
- func UnpackCheckout(ctx context.Context, archive, dir string, caps CheckoutConfig) error
- func UnpackHeadCheckout(ctx context.Context, archive, dir string, caps CheckoutConfig) error
- func ValidAttachmentID(id string) bool
- type Attachment
- type BlobFetcher
- type Bundle
- type Caps
- type Check
- type CheckoutBuilder
- type CheckoutConfig
- type CheckoutOmission
- type CommandEntry
- type CommandEvent
- type Commit
- type CommitComparer
- type ComparedFile
- type Comparison
- type ConversationItem
- type DescriptionImage
- type DiffLimits
- type FileChange
- type FileComparison
- type Hunk
- type PatchFetcher
- type PinnedExport
- type PreviousSection
- type PreviousVersion
- type Prompt
- type PullRequest
- type Redactor
- type Reference
- type RenderedImage
- type ReviewConfig
- type ReviewThreadComment
- type ReviewThreadInput
- type Session
- type SessionDecision
- type SessionEvent
- type SessionValidation
- type Sources
- type Thread
- type ValidationCommitLabel
- type ValidationGap
- type ValidationSetAside
Constants ¶
const ( AttachmentStored = "stored" AttachmentUnsupported = "unsupported" AttachmentTooLarge = "too_large" AttachmentOverLimit = "over_limit" AttachmentExternal = "external" AttachmentFailed = "failed" )
Capture states of a description image.
const ( OmittedSizeReason = "omitted_size" OmittedSubmoduleReason = "omitted_submodule" OmittedBinaryReason = "binary" OmittedBudgetReason = "omitted_budget" )
Checkout omission reasons. OmittedBinaryReason is the reason diff.go gives a binary hunk, so omitting a file git also diffs as binary leaves its hunk as it was.
const ( RoleCode = "code" RoleTest = "test" RoleGenerated = "generated" RoleMigration = "migration" RoleDocs = "docs" RoleConfig = "config" RoleVendored = "vendored" )
const ( ReferenceIssueKey = "issue_key" ReferenceSpec = "spec" ReferenceCherryPick = "cherry_pick" ReferenceStackedOn = "stacked_on" ReferenceSupersedes = "supersedes" ReferenceIncludes = "includes" ReferenceFollowUp = "follow_up" ReferenceAuthorshipDisclosure = "authorship_disclosure" ReferenceImage = "image" ReferenceVideo = "video" )
Reference kinds.
const CitedPromptHeadBytes = 1024
CitedPromptHeadBytes is how much of a cited prompt's text the first shortening keeps.
const EvidenceBudgetExceededReason = "evidence byte budget exceeded"
EvidenceBudgetExceededReason prefixes the error Fit returns when the bundle cannot be made to fit its byte limits.
const PromptScanChars = 1 << 20
PromptScanChars is the most characters of a prompt's text, and of its reply, a session source reads. It is generous enough that the cut never fires in practice: byte trimming (Fit) is what bounds prompt text, in the documented trim order. It keeps one oversized prompt from being read whole.
const ProvisionalReviewConfigPath = "REVIEW.md"
ProvisionalReviewConfigPath is where this loader looks for REVIEW.md until the shaping location is settled.
const SummaryCommentMarker = "<!-- baum:pr-summary -->"
SummaryCommentMarker opens the pull-request summary comment a baum host posts. That comment is the host's own output, not evidence about the pull request, so it is left out of the conversation; anyone else's comment starting with the marker is an ordinary one.
Variables ¶
var ( // ErrOutputTooLarge reports git output over the configured limit. A // patch fetcher returns it to make that file textless. ErrOutputTooLarge = errors.New("git output exceeds configured limit") // ErrPatchUnreadable reports a file git could not diff. A patch fetcher // returns it to make that file textless. ErrPatchUnreadable = errors.New("git could not diff the file") )
var ErrInvalidArchive = errors.New("invalid archive")
ErrInvalidArchive reports a checkout or attachments archive that does not have the shape this package writes: an unexpected entry, a path outside the tree, a missing file or a corrupt stream.
var ErrNotFound = errors.New("not found")
ErrNotFound reports that a source has no such commit, path or repository. A blob or export source returns it, or an error wrapping it, so the REVIEW.md loader and the checkout export can treat the absence as an ordinary outcome.
Functions ¶
func ApplyCaps ¶
ApplyCaps enforces the count ceilings, after sorting, so the same rows in any order produce the same selection: sessions by confidence then earliest start; comments to the newest N plus every review verdict. It does not cap prompts or command events: the source that collects sessions already selected them (MaxPromptsPerSession, MaxCommandEventsPerSession). Nor does it cap patch lines or alt text: Fit does, after redaction.
func ApplyCheckoutOmissions ¶
func ApplyCheckoutOmissions(b *Bundle, omissions []CheckoutOmission)
ApplyCheckoutOmissions marks every diff hunk of an omitted file, at either of its paths, textless and appends one generator.truncated note per omission reason with the number of files it omitted. A hunk whose old and new paths were both omitted takes the reason of the later path.
func AttachCommitChanges ¶
func AttachCommitChanges(ctx context.Context, comparer CommitComparer, pr *PullRequest) error
AttachCommitChanges reads the line change of every commit made after the pull request was opened, for the review exchange's changes after opening. A commit the comparer cannot compare keeps no counts, which leaves that figure unknown rather than failing the build.
func AttachThreads ¶
func AttachThreads(b *Bundle, threads []ReviewThreadInput)
AttachThreads sets the bundle's threads, ordered by ID, places each review comment of the conversation in its thread, and records review threads as available. A thread's URL is its first comment's, and its line is set only for a current right-side line, the only new-side position a hunk holds.
func AttachmentID ¶
AttachmentID derives an image's ID from its markdown source URL.
func BudgetExceededReason ¶
BudgetExceededReason names which checkout budget a failure exceeded: exceeding it fails the run naming the budget.
func CapReviewConfigContent ¶
func CapReviewConfigContent(config *ReviewConfig) bool
CapReviewConfigContent bounds config.Content to its leading bytes in place, reporting whether it cut anything.
func ChangePaths ¶
func ChangePaths(change FileChange) []string
ChangePaths returns the pathspecs that let a single-file diff detect the change as a rename: the old path and, when it differs, the new path.
func ChangesReviewConfig ¶
ChangesReviewConfig reports whether the diff adds, edits, renames or removes REVIEW.md: a rename away from the location carries it as OldPath.
func CheckRunID ¶
CheckRunID is a check run's identifier: its GitHub database ID.
func CommandOutcome ¶
CommandOutcome maps a tool result's status to a command event's closed outcome vocabulary (succeeded, failed, interrupted, unknown). An empty status, a tool use with no recorded result, is "unknown".
func CommandText ¶
CommandText reads the shell command line from a tool use's raw input JSON, trying the "command" and "cmd" keys different vendors use (sessions/codexsession/tool_results.go tries the same pair). A command value may be a string or a string array (argv-style vendors); both are normalised to one shell-syntax string. The text is for ParseCommandParaphrase only and must never enter a bundle.
func ExplicitAutomationProvider ¶
ExplicitAutomationProvider reports the disclosed automation provider named in a comment or review body. ok is true for any disclosure, including a generic "generated by <tool>" phrase naming no recognised provider, in which case provider is empty.
func Fit ¶
Fit trims the encoded bundle in the documented order until its content is within MaxBytes, then checks the diff index against its own MaxDiffIndexBytes. The diff index is every hunk's entry without its patch text; patch text is content. So trimming can empty every patch but never drops a hunk, and the hunk count alone never exceeds the content limit. The documented order is assistant replies, older prompts, command paraphrases, comment bodies oldest first (keeping review verdicts), generated and vendored patch text, superseded session decisions, ordinary patch text, the text of cited prompts, then whole sessions from lowest confidence. A session's current decisions go only with the session: they are a short, reviewed account of what its prompts decided, so they outlast every cut of raw prompt text. The prompts at the turns they cite are kept with them: the older-prompts stage spares them, and before any session is dropped their text is shortened, longest first, to a leading CitedPromptHeadBytes and then, if still needed, emptied, keeping each prompt's entry and index so a surviving decision's prompt anchors still resolve. REVIEW.md content is cut first, ahead of every documented stage, because it is supplementary guidance rather than PR evidence, and because a fixed content cap would otherwise make a MaxBytes configured below it permanently unsatisfiable. The attachments part counts as content but no stage cuts it: the files it lists reach the agent whole (the description-image rules).
Fit runs after Redact. It first cuts each hunk's patch to MaxHunkPatchLines and each attachment's alt text and heading to MaxImageAltBytes, so those cuts always follow redaction: a patch reaches Redact with the margin diff parsing keeps past the line cap, and a secret the cap runs through is masked whole.
func FlagBotContribution ¶
func FlagBotContribution(item *ConversationItem)
FlagBotContribution sets Bot and BotTool from the recognised disclosures: bot reports and agent reviews are flagged with their tool. A REVIEW.md marker registry, which would set BotReport, is not built.
func FlagBotReport ¶
func FlagBotReport(item *ConversationItem, markers []string)
FlagBotReport sets BotReport on a bot's item whose body carries one of markers, the bot-report markers a REVIEW.md marker registry names. The registry is not built yet, so hosts pass none and BotReport stays false.
func GitHubContentURL ¶
GitHubContentURL also admits the asset storage GitHub redirects uploads to.
func HunkDiffURL ¶
HunkDiffURL is a hunk's DiffURL: GitHub's diff fragment shape, diff-<sha256(path)>R<line>, for the path and first new line it records. A document's github_url is this value, so a host can derive it from the hunk's path and new_range rather than store it.
func IsBotActor ¶
IsBotActor reports whether a GitHub actor type (GraphQL's __typename, or REST's user type) is a Bot.
func KeepKnownCommandTargets ¶
KeepKnownCommandTargets clears every command target of sessions that knownPath does not accept and that is not one of the session's own touched paths or a directory above one, for a host that paraphrases commands before the paths it knows are all read.
func KnownPaths ¶
KnownPaths returns a knownPath predicate for ParseCommandParaphrase that accepts each of paths and every directory above it, but not the repository root. Paths are cleaned and a leading "./" is ignored.
func MarkdownUploads ¶
MarkdownUploads maps each upload's asset UUID to its markdown source URL, without a query or fragment: a pasted signed link keeps no token.
func MaxAttachmentsArchiveBytes ¶
MaxAttachmentsArchiveBytes bounds an attachments archive: every image at its limit, a tar header and padding for each, and the end marker.
func ProviderFromLogin ¶
ProviderFromLogin reports the automation provider a bot login's name discloses, or "" when none is recognised.
func PullRequestState ¶
PullRequestState is GitHub's state lower-cased, or "merged" once the pull request is merged.
func Redact ¶
Redact masks secrets and e-mail addresses in every bundle string field, after reference extraction (which runs against the unredacted bundle) and before the byte-fit pass and the hunk line cap it starts with. Each field is redacted as one text, so a secret spanning lines is found, and keeps its length and lines. The hunks of one file are redacted together, as the file's patch, so the engine follows a key that runs on from one hunk into the next (goredact v0.4.0 and later mask it in both); each hunk keeps its diff markers and its header's line ranges. Runs of base64 lines and base64 hunk headings are masked as key material too, a deliberate over-mask (redactPatches, base64Masks). A patch still holds the margin diff parsing keeps past the line cap, and the lines an earlier hunk of the file drops are read too, so a secret the cap runs through is masked as in the whole patch. MaskedSpanCount is the number of spans masked, e-mail addresses and base64 runs the engine left included. It counts the spans in the text Redact reads, each file's patch up to its last hunk's margin, so a secret spanning hunks counts once, and one only in lines the cap then drops counts too.
Mentions are not rewritten: nothing in the bundle is posted to a code host as it is, and a field may hold code (a patch, a suggestion block, a prompt), where an "@" is an annotation, decorator or package scope. Text published to a code host has its mentions defanged where it is published.
Every free-text or URL field is covered, including References[].Value — ReferenceAuthorshipDisclosure copies up to 80 trailing characters of raw text and an image/video reference copies the matched URL, so a secret masked in Body/Title could otherwise still surface here — and branch names, check names/URLs, requested-reviewer logins, comment paths and a session decision's title, summary, rationale, rejected alternative, evidence and files, none of which are structurally constrained enough to skip. SHA, ID and closed-enum fields (Kind, State, Role, Change, Outcome, a decision's Who, Category and Trigger, ...) are not redacted: they are not free text, and running secret detection on a hex SHA risks a false-positive match corrupting the hash a hunk/commit anchor resolves against. DiffURL is a generated hash fragment, reference Source is a fixed tag with a numeric comment ID, and AuthorAssociation is a GitHub enum; these also contain no user-authored text. ReviewConfig.Content (REVIEW.md) is likewise not redacted: unlike a PR body or comment, it has no audience but the review agent itself — it never displays to a human viewer — and the model can already read the same unredacted file directly off the checkout via its Read tool, so masking the bundled copy would only create an inconsistency between the two, not add any protection.
func RedactFilePatch ¶
func RedactFilePatch(ctx context.Context, redactor *Redactor, path, patch string) (masked string, ok bool, err error)
RedactFilePatch masks one file's patch, its text from the first hunk header on, as Redact masks the hunks diff parsing takes from the same patch: parseFileHunks reads it, with no line cap, and redactPatches masks the hunks as one file's text. A patch read after the bundle was built, such as the viewer's excerpt of a hunk whose text a document left out, therefore shows no secret the stored hunk would have hidden. The result is the masked hunk texts, each ending in a newline and without a CR before it, as stored hunks hold them. ok is false for a patch diff parsing reads as textless: binary, without a hunk, or with a line over its limit.
func RoleForPath ¶
RoleForPath derives a hunk's role from its repository-relative path. Rules are checked in order; the first match wins.
func SetDigest ¶
SetDigest stamps bundle.Digest with the SHA-256 of the encoded bundle, so identical content in any order produces an identical digest.
func SniffImage ¶
SniffImage accepts PNG, JPEG, GIF and WebP by content and reads their size.
func SortChecks ¶
func SortChecks(checks []Check)
SortChecks orders checks by ID, so the same checks always encode the same.
func SortConversation ¶
func SortConversation(items []ConversationItem)
SortConversation orders items by creation time, undated items last, then by ID.
func StatusCheckID ¶
StatusCheckID is a commit status's identifier: its GraphQL node ID, or its database ID when the host has no node ID.
func TargetPath ¶
TargetPath is the repository path a command target names: the target without a trailing Go package pattern "/...".
func UnpackAttachments ¶
func UnpackAttachments(ctx context.Context, archive, dir string, attachments []Attachment, maxImageBytes int64) error
UnpackAttachments writes exactly the images the bundle lists to attachments/<id>.<ext> in the run directory, read-only. An archive holding anything else, missing a listed image or not matching its hash fails with ErrInvalidArchive. An empty archive path means the run has no images.
The caller must bound the archive's size before calling (see MaxAttachmentsArchiveBytes). A maxImageBytes of zero puts no per-entry limit before the hash check.
func UnpackCheckout ¶
func UnpackCheckout(ctx context.Context, archive, dir string, caps CheckoutConfig) error
UnpackCheckout writes a gzip-compressed checkout archive into dir as the read-only head/ and merge-base/ trees, enforcing caps again so a run never reads more than the builder was allowed to write. An archive that does not have the shape WriteArchive produces fails with ErrInvalidArchive; one over a budget fails with BudgetExceededReason naming it, and so does a zero cap.
The caller must bound the archive's size before calling (see MaxArchiveBytes): the gzip stream is drained after the tar trailer without a limit, and directory entries do not count toward MaxTotalFiles.
func UnpackHeadCheckout ¶
func UnpackHeadCheckout(ctx context.Context, archive, dir string, caps CheckoutConfig) error
UnpackHeadCheckout is UnpackCheckout for an archive written without a merge base: it holds head/ alone.
func ValidAttachmentID ¶
ValidAttachmentID reports whether id has the shape AttachmentID produces.
Types ¶
type Attachment ¶
type Attachment struct {
ID string `json:"id"`
Path string `json:"path"`
SourceURL string `json:"source_url"`
ContentType string `json:"content_type"`
// Alt and Heading, the nearest markdown heading above the image, are
// redacted and capped.
Alt string `json:"alt,omitempty"`
Heading string `json:"heading,omitempty"`
Position int `json:"position"`
Width int `json:"width"`
Height int `json:"height"`
SHA256 string `json:"sha256"`
}
Attachment is one stored description image. Its file is in the run directory at Path.
func DescriptionAttachments ¶
func DescriptionAttachments(body string, images []DescriptionImage) []Attachment
DescriptionAttachments lists the stored images for the bundle, each under the nearest heading above it in the untrimmed body.
type BlobFetcher ¶
BlobFetcher is the trusted blob accessor the loader reads one file through. It returns ErrNotFound, or an error wrapping it, for a commit or path that does not exist.
type Bundle ¶
type Bundle struct {
Repository string `json:"repository"`
PullRequest PullRequest `json:"pull_request"`
Diff []Hunk `json:"diff"`
Checks []Check `json:"checks"`
Conversation []ConversationItem `json:"conversation"`
// Threads are the pull request's review threads with their resolution,
// from the stored GitHub activity snapshot; empty when none was synced.
Threads []Thread `json:"threads"`
Sessions []Session `json:"sessions"`
References []Reference `json:"references"`
// Attachments are the stored description images, in description order.
// The byte fit counts them and never trims them.
Attachments []Attachment `json:"attachments,omitempty"`
ReviewConfig *ReviewConfig `json:"review_config,omitempty"`
Previous *PreviousVersion `json:"previous,omitempty"`
// Sources records which parts had data available, so an empty slot
// downstream reads as absent input rather than model omission.
Sources Sources `json:"sources"`
// Truncated is one plain-language generator.truncated note per cut.
Truncated []string `json:"truncated,omitempty"`
// MaskedSpanCount is not part of the encoded bundle a model reads: it is
// recorded with the stored version.
MaskedSpanCount int `json:"-"`
// FileComparisons preserve each stack member's path changes before hunk-ID
// deduplication, for derived links into the member's comparison base.
FileComparisons []FileComparison `json:"-"`
// Digest is the bundle digest, computed from the encoded, redacted,
// trimmed bundle, and stored with the version.
Digest string `json:"-"`
}
Bundle is the generation run's input: everything the model may cite, each with the identifier its anchor type resolves against.
func (*Bundle) DecisionIDs ¶
DecisionIDs returns, by root session ID, the DecisionID of each decision of each session that carries decisions, in the session's order; nil when no decision has one.
func (*Bundle) SetDecisionIDs ¶
SetDecisionIDs sets each session's decisions' DecisionID from ids, as DecisionIDs returned them for the same bundle. A session whose decisions do not number as many as its IDs gets none.
type Caps ¶
type Caps struct {
MaxSessions int
MaxPromptsPerSession int
MaxCommandEventsPerSession int
MaxComments int
MaxHunkPatchLines int
// MaxBytes bounds the encoded bundle apart from the diff index's hunk
// entries; patch text counts here. MaxDiffIndexBytes bounds those entries.
MaxBytes int
MaxDiffIndexBytes int
// MaxDiffFiles and MaxDiffPatchBytes bound what assembly reads for the
// diff index.
MaxDiffFiles int
MaxDiffPatchBytes int64
// MaxImageAltBytes bounds each description image's alt text and heading.
MaxImageAltBytes int
}
Caps are the configured count and byte ceilings applied to a bundle. ApplyCaps and Fit read the comment, session, patch, image and byte limits. MaxPromptsPerSession and MaxCommandEventsPerSession are applied by the source that collects sessions, and DiffLimits gives the limits diff assembly reads.
func (Caps) DiffLimits ¶
func (c Caps) DiffLimits() DiffLimits
DiffLimits returns the limits BuildDiffIndexWithin reads.
type Check ¶
type Check struct {
// HeadSHA identifies checks retained from a different revision during refresh.
HeadSHA string `json:"head_sha,omitempty"`
ID string `json:"id"`
Name string `json:"name"`
// Kind is "check_run" or "status".
Kind string `json:"kind"`
Conclusion string `json:"conclusion,omitempty"`
Status string `json:"status,omitempty"`
// Required is true or false from readable branch protection, and
// explicitly nil when the host cannot read it. Hosts that do not sync
// branch protection or rulesets always leave it nil.
Required *bool `json:"required"`
URL string `json:"url,omitempty"`
StartedAt *time.Time `json:"started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
}
Check is one check run or commit status for the head.
type CheckoutBuilder ¶
type CheckoutBuilder struct {
// Config bounds the checkout; the builder reads it on every export.
Config CheckoutConfig
}
CheckoutBuilder exports one run's isolated, budgeted code checkout.
func NewCheckoutBuilder ¶
func NewCheckoutBuilder(config CheckoutConfig) *CheckoutBuilder
func (*CheckoutBuilder) WriteArchive ¶
func (b *CheckoutBuilder) WriteArchive(ctx context.Context, pinned PinnedExport, head, mergeBase string, hunks []Hunk, output io.Writer) (omissions []CheckoutOmission, err error)
WriteArchive streams both trees from one pinned snapshot without checking them out; an empty mergeBase, which takes no hunks, writes the head tree alone. The compared paths go first, at the head and then at the merge base, and the rest of the head tree fills what the budget leaves: a file that does not fit is omitted with OmittedBudgetReason instead of failing the export, so the archive always stays within MaxTotalBytes and MaxTotalFiles. Binary files are omitted with OmittedBinaryReason.
A compared path the diff holds as text is never treated as binary: the archive applies working-tree-encoding, so a UTF-16 text file arrives with NUL bytes although git diffs its canonical content as text.
type CheckoutConfig ¶
type CheckoutConfig struct {
ScratchRoot string `json:"-"`
MaxFileBytes int64 `json:"max_file_bytes"`
MaxTotalBytes int64 `json:"max_total_bytes"`
MaxTotalFiles int `json:"max_total_files"`
}
CheckoutConfig bounds one run's checkout. MaxTotalBytes/MaxTotalFiles count only non-omitted content: a file omitted for exceeding MaxFileBytes, as binary or as submodule content, does not count toward either. WriteArchive omits files that would exceed them instead of failing; UnpackCheckout rejects an archive that exceeds them. ScratchRoot is local to each process and never crosses to a review agent.
A zero MaxTotalBytes or MaxTotalFiles means unlimited in WriteArchive but nothing allowed in UnpackCheckout; MaxFileBytes is always enforced, so zero omits or rejects every file.
func (CheckoutConfig) MaxArchiveBytes ¶
func (c CheckoutConfig) MaxArchiveBytes() int64
MaxArchiveBytes bounds a checkout archive within the configured caps: its content plus tar headers and gzip overhead.
type CheckoutOmission ¶
CheckoutOmission is one file the checkout left out of the tree.
type CommandEntry ¶
type CommandEntry struct {
Program string `json:"program"`
Category string `json:"category"`
Target string `json:"target,omitempty"`
}
CommandEntry is one simple command within a (possibly compound or piped) execute tool use.
func ParseCommandParaphrase ¶
func ParseCommandParaphrase(command string, knownPath func(string) bool) []CommandEntry
ParseCommandParaphrase extracts one entry per simple command from a possibly compound or piped command line. Raw command lines never survive past this function's return: it returns only program base name, category and an optional target. The target is the first argument that is path-shaped and, normalised, a path knownPath accepts: positive evidence it is a path of the repository, such as a changed file, a touched path or a file in the checkout. With a nil knownPath no entry has a target.
type CommandEvent ¶
type CommandEvent struct {
ID string `json:"id"`
Time *time.Time `json:"time,omitempty"`
// Outcome is "succeeded", "failed", "interrupted" or "unknown".
Outcome string `json:"outcome"`
Commands []CommandEntry `json:"commands"`
}
CommandEvent is one execute tool use. ID is the tool-use identifier the session_event anchor cites.
type Commit ¶
type Commit struct {
SHA string `json:"sha"`
Subject string `json:"subject"`
CommittedAt *time.Time `json:"committed_at,omitempty"`
Additions *int `json:"additions,omitempty"`
Deletions *int `json:"deletions,omitempty"`
// Parents are the commit's parent SHAs, which the host reads to choose
// the comparison for Additions and Deletions; not part of the encoded
// bundle.
Parents []string `json:"-"`
}
Commit is one synced commit of the pull request. Additions and Deletions are its change against its first parent, read only for commits made after the pull request was opened, and nil when the mirror cannot compare it; a merge commit carries zero, since what it brings in is not this pull request's change.
type CommitComparer ¶
type CommitComparer interface {
Compare(ctx context.Context, baseOID, headOID, mode string) (Comparison, error)
}
CommitComparer reads one commit's change against its parent.
type ComparedFile ¶
type ComparedFile struct {
Path string `json:"path"`
OldPath string `json:"old_path,omitempty"`
Change string `json:"change"`
}
ComparedFile records a file's names and presence across a comparison.
type Comparison ¶
type Comparison struct {
BaseOID string `json:"base_oid"`
HeadOID string `json:"head_oid"`
MergeBaseOID string `json:"merge_base_oid,omitempty"`
Files []FileChange `json:"files"`
}
Comparison is the list of files that differ between two commits.
type ConversationItem ¶
type ConversationItem struct {
ID string `json:"id"`
// Kind is "comment", "review" or "review_comment".
Kind string `json:"kind"`
AuthorLogin string `json:"author_login"`
AuthorAssociation string `json:"author_association,omitempty"`
// Bot is true when GitHub reports the author as a Bot actor.
Bot bool `json:"bot"`
// BotTool is the disclosed or recognised automation provider, set only
// when Bot is true or a disclosure was found in the body; the helpers run
// per contribution.
BotTool string `json:"bot_tool,omitempty"`
// BotReport is true for a bot-report marker from REVIEW.md's marker
// registry, which is not built, so it is always false for now. The
// host's own summary comment is not in the conversation at all.
BotReport bool `json:"bot_report,omitempty"`
Body string `json:"body"`
CreatedAt *time.Time `json:"created_at,omitempty"`
// State is the review verdict for a review item.
State string `json:"state,omitempty"`
// Path is set for a review comment.
Path string `json:"path,omitempty"`
// Commit is the head a review assessed.
Commit string `json:"commit,omitempty"`
// Review is the review a review comment was submitted with.
Review string `json:"review,omitempty"`
// Thread and Resolved place a review comment in its review thread when
// the activity snapshot holds it; ThreadRoot marks the thread's first
// comment.
Thread string `json:"thread,omitempty"`
ThreadRoot bool `json:"thread_root,omitempty"`
Resolved *bool `json:"resolved,omitempty"`
}
ConversationItem is one issue comment, review or review comment.
type DescriptionImage ¶
type DescriptionImage struct {
ID string
SourceURL string
// Alt is redacted.
Alt string
// Position is the image's 1-based place among the description's images.
Position int
State string
ContentType string
Size int64
Width int
Height int
SHA256 string
// ObjectKey is where the host stored the copy.
ObjectKey string
}
DescriptionImage is one image GitHub rendered from the description, in description order. Only a Stored image has its copy's fields set.
func WriteAttachments ¶
func WriteAttachments(ctx context.Context, images []DescriptionImage, archive io.Writer, open func(context.Context, DescriptionImage) (io.ReadCloser, error), skipped func(DescriptionImage, error)) ([]DescriptionImage, error)
WriteAttachments archives the stored copies as a plain tar of attachments/<id>.<ext> entries and returns the images it holds. open reads one stored copy. A copy that cannot be read or no longer matches its hash is left out of the archive, and so of the bundle: capture never fails assembly. skipped, when not nil, is told of each image left out and why.
type DiffLimits ¶
type DiffLimits struct {
// MaxFiles bounds the changed files, checked before any patch is read.
MaxFiles int
// MaxPatchBytes bounds the patch bytes read across every file.
MaxPatchBytes int64
// MaxHunkLines is the per-hunk line cap Fit applies, with its note,
// after redaction. Parsing keeps each hunk's leading MaxHunkLines
// lines and up to redactionMargin bytes past them: the cap and its note
// behave as on the full text, and redaction reads a secret the cap runs
// through whole. A file whose hunk other than its last is cut keeps its
// whole patch until Redact, which reads each file's hunks as one text;
// MaxPatchBytes bounds what is kept.
MaxHunkLines int
}
DiffLimits bound the diff index assembly reads. A zero field is unlimited.
type FileChange ¶
type FileChange struct {
OldPath string `json:"old_path,omitempty"`
NewPath string `json:"new_path,omitempty"`
Status string `json:"status"`
OldMode string `json:"old_mode,omitempty"`
NewMode string `json:"new_mode,omitempty"`
OldOID string `json:"old_oid,omitempty"`
NewOID string `json:"new_oid,omitempty"`
PatchHash string `json:"patch_hash,omitempty"`
Additions *int64 `json:"additions,omitempty"`
Deletions *int64 `json:"deletions,omitempty"`
}
FileChange is one file of a Comparison.
type FileComparison ¶
type FileComparison struct {
BaseRevision string `json:"base_revision"`
Changes []ComparedFile `json:"changes"`
}
FileComparison is one stack member's file changes, in member order.
type Hunk ¶
type Hunk struct {
// ID hashes the file path and normalised hunk content, so it survives a
// context shift and a rebase.
ID string `json:"id"`
Path string `json:"path"`
OldPath string `json:"old_path,omitempty"`
// Change is "added", "modified", "removed" or "renamed".
Change string `json:"change"`
// Role is one of code, test, generated, migration, docs, config,
// vendored.
Role string `json:"role"`
StartLine int `json:"start_line,omitempty"`
LineCount int `json:"line_count,omitempty"`
Additions int `json:"additions"`
Deletions int `json:"deletions"`
DiffURL string `json:"diff_url"`
// Patch is empty for a textless hunk: binary, unreadable, or omitted by
// the checkout budget; the host sets TextlessReason for its omissions.
Patch string `json:"patch,omitempty"`
Textless bool `json:"textless,omitempty"`
TextlessReason string `json:"textless_reason,omitempty"`
// contains filtered or unexported fields
}
Hunk is one entry of the diff index.
func BuildDiffIndex ¶
func BuildDiffIndex(comparison Comparison, fetch PatchFetcher, roleFor func(path string) string) ([]Hunk, error)
BuildDiffIndex splits every compared file into hunks, in Comparison.Files order, assigning content-addressed IDs and roles.
Hunk IDs hash the file path and a normalised form of the hunk's changed lines (the "+"/"-" lines only, not the "@@" line numbers and not unchanged context): this is what makes an ID survive a context shift (the same change, with different surrounding context after a nearby edit) and a rebase (the same change against a different base). Two hunks in the same file whose changed lines are byte-identical (e.g. two blank-line-only hunks) hash equally; ordinal suffixes disambiguate them in file order.
func BuildDiffIndexWithin ¶
func BuildDiffIndexWithin(comparison Comparison, fetch PatchFetcher, roleFor func(path string) string, limits DiffLimits) ([]Hunk, []string, error)
BuildDiffIndexWithin is buildDiffIndex within limits. Exceeding a file or byte limit fails with the checkout budget reason naming it.
type PatchFetcher ¶
PatchFetcher returns the unified diff patch text for one file of a comparison, or nil for a binary or unreadable change. An ErrOutputTooLarge or ErrPatchUnreadable error makes that file textless. paths holds the old and new path of a rename so git can pair them; otherwise the one path.
type PinnedExport ¶
type PinnedExport interface {
ExportCommit(ctx context.Context, commitOID string) (io.ReadCloser, error)
ExportCommitPath(ctx context.Context, commitOID, path string) (io.ReadCloser, error)
}
PinnedExport is one pinned snapshot's worth of exports: every call through it, for as long as the checkout that holds it runs, reads the same physical copy of the repository, so a rebuild cannot mix trees. A missing commit or path returns ErrNotFound or an error wrapping it.
type PreviousSection ¶
type PreviousVersion ¶
type PreviousVersion struct {
Version int `json:"version"`
Sections []PreviousSection `json:"sections"`
// HunkRanges is each hunk's right side in the previous version, by hunk
// ID: its first line and line count. The host uses it to move the
// sections' hunk anchors to where the same hunk sits now. It is never
// part of the bundle.
HunkRanges map[string][2]int `json:"-"`
}
PreviousVersion is the current version's sections, for regeneration to partition against.
type Prompt ¶
type Prompt struct {
At *time.Time `json:"at,omitempty"`
Index int `json:"index"`
ID string `json:"id"`
Text string `json:"text"`
Reply string `json:"reply,omitempty"`
TouchedPaths []string `json:"touched_paths,omitempty"`
}
Prompt is one human prompt. Index is the prompt's position among the session's human prompts; ID is its stored identifier, the prompt anchor.
type PullRequest ¶
type PullRequest struct {
Number int `json:"number"`
State string `json:"state"`
Draft bool `json:"draft"`
Title string `json:"title"`
Body string `json:"body"`
AuthorLogin string `json:"author_login"`
AuthorAssociation string `json:"author_association"`
AuthorBot bool `json:"author_bot"`
BaseRef string `json:"base_ref"`
BaseSHA string `json:"base_sha"`
// HeadRef is the pull request's own branch name — where a contributor
// actually puts ticket keys and other references, unlike BaseRef (almost
// always the default branch).
HeadRef string `json:"head_ref"`
HeadSHA string `json:"head_sha"`
MergeBaseSHA string `json:"merge_base_sha"`
MergedSHA string `json:"merged_sha,omitempty"`
RequestedReviewers []string `json:"requested_reviewers"`
// OpenedAt is when GitHub reports the pull request was opened.
OpenedAt *time.Time `json:"opened_at,omitempty"`
Commits []Commit `json:"commits"`
}
type Redactor ¶
type Redactor struct {
// contains filtered or unexported fields
}
Redactor masks bundle text with the redact package's engine, the one redaction configuration baum uses for input, output and logs. It is safe for concurrent use.
func (*Redactor) Find ¶
Find returns the spans RedactString masks in s, one per finding, so two secrets written side by side are told apart.
func (*Redactor) RedactLines ¶
RedactLines redacts lines that read as one text, such as a code excerpt's lines, as their newline-joined text, so a secret written across several of them is found as a whole. It returns as many lines as it was given, each masked in place, and the spans masked in the joined text. A line may hold a newline itself: each is cut back out at its own offsets. Should the mask ever change the text's length, every line is masked whole instead.
func (*Redactor) RedactString ¶
RedactString masks every secret and e-mail address in s and returns the result with the number of spans masked, which the bundle reports as its masked-span count. Secrets are found over the whole text, so a key that spans lines is caught, and the result keeps the length and the lines of s: a patch keeps its line numbers. Mentions are left as written; a code host is protected from them where text is published, not here.
type Reference ¶
type Reference struct {
// Kind is one of: issue_key, spec, spec_assertion, cherry_pick,
// stacked_on, supersedes, includes, follow_up, image, video,
// authorship_disclosure.
Kind string `json:"kind"`
Value string `json:"value"`
// Source names where the reference was found: "body", "commit_subject",
// "branch", or "comment:<id>".
Source string `json:"source"`
}
Reference is one extracted reference, extracted before redaction and trimming so a reference inside cut text still survives.
func CollectReferences ¶
CollectReferences extracts the references of a bundle's pull request description, head branch, commit subjects and conversation, de-duplicated and ordered. It reads untrimmed text, so call it before caps and trimming.
func ExtractReferences ¶
ExtractReferences finds every recognised reference in text, tagging each with source.
type RenderedImage ¶
type RenderedImage struct {
ID, SourceURL, Alt string
// FetchURL is the signed rendered source; it is never stored or logged.
FetchURL string
// State is preset for an image that is not downloaded.
State string
}
RenderedImage is one image found in a rendered description.
func RenderedImages ¶
func RenderedImages(bodyHTML string, uploads map[string]string) []RenderedImage
RenderedImages walks the img elements of body_html. GitHub renders none from HTML comments or code fences, so those are left out. A repeated image is listed once.
type ReviewConfig ¶
type ReviewConfig struct {
Present bool `json:"present"`
Digest string `json:"digest,omitempty"`
Content string `json:"content,omitempty"`
// ChangedInPullRequest is true when the diff index touches REVIEW.md.
// The head version in the checkout is then a proposal, not the policy
// this review applies.
ChangedInPullRequest bool `json:"changed_in_pull_request,omitempty"`
}
ReviewConfig is REVIEW.md at the pull request's base commit, the target branch's policy. Present is false when the file is absent there, in which case defaults apply and only ChangedInPullRequest can be set. Content is REVIEW.md's own text, verbatim and unredacted (it has no audience but the review agent, which can read the same file unredacted off the checkout anyway), given to generation up front rather than requiring it to browse for the file itself; it is empty when the file is absent, not valid UTF-8, or was capped by the host's size limit. Location, syntax and override acceptance are still shaping: the text is visible as context but is not parsed, no roles or markers are extracted, and overrides are not accepted.
func LoadReviewConfig ¶
func LoadReviewConfig(ctx context.Context, fetcher BlobFetcher, commitSHA string) (*ReviewConfig, error)
LoadReviewConfig loads REVIEW.md at commitSHA, which the builder passes as the pull request's base commit, or reports it absent. Content carries the file's own committed text, verbatim and unredacted (see Redact), so generation sees it up front instead of needing to browse for it. Binary or non-UTF-8 content is reported present, with a digest, but no content — the same "cannot fabricate text" rule an unreadable diff hunk follows.
type ReviewThreadComment ¶
ReviewThreadComment is a review comment's conversation ID (its GitHub database ID) and URL.
type ReviewThreadInput ¶
type ReviewThreadInput struct {
ID string
Path string
Side string
Line *int
Resolved bool
Outdated bool
Comments []ReviewThreadComment
}
ReviewThreadInput is one review thread as GitHub reports it. Side is the diff side of Line ("LEFT" or "RIGHT"); Comments are the thread's comments in thread order.
type Session ¶
type Session struct {
ValidationEvents []SessionEvent `json:"validation_events,omitempty"`
RootSessionID string `json:"id"`
Vendor string `json:"vendor"`
Restricted bool `json:"restricted"`
Models []string `json:"models,omitempty"`
Title string `json:"title,omitempty"`
Branch string `json:"branch,omitempty"`
StartedAt *time.Time `json:"started_at,omitempty"`
EndedAt *time.Time `json:"ended_at,omitempty"`
Outcome string `json:"outcome,omitempty"`
Prompts []Prompt `json:"prompts,omitempty"`
CommandEvents []CommandEvent `json:"command_events,omitempty"`
// Decisions are the decisions a host extracted from the session's
// transcript, in the host's order. Nil means none were extracted (off,
// failed or skipped); a non-nil empty list means the session was
// extracted and made none. A restricted session never carries them.
Decisions *[]SessionDecision `json:"decisions,omitempty"`
// Nil means extraction did not run; an empty list means it found no checks.
Validations *[]SessionValidation `json:"validations,omitempty"`
NotVerified []ValidationGap `json:"not_verified,omitempty"`
SetAside []ValidationSetAside `json:"set_aside,omitempty"`
// Confidence, HasStartedAt and StartedAtValue are the sort keys used when
// capping and ordering sessions; not part of the encoded bundle.
Confidence float64 `json:"-"`
HasStartedAt bool `json:"-"`
StartedAtValue time.Time `json:"-"`
// AuthoritativeLink is the host's: whether the session is linked to the
// pull request by more than a heuristic. Not part of the encoded bundle.
AuthoritativeLink bool `json:"-"`
}
Session is one linked session. Restricted is true for a session of which the pull request's repository is not a connected member: only RootSessionID and Vendor are populated, everywhere in the bundle.
type SessionDecision ¶
type SessionDecision struct {
Title string `json:"title,omitempty"`
Summary string `json:"summary"`
Who string `json:"who"`
Category string `json:"category"`
Trigger string `json:"trigger,omitempty"`
Rationale string `json:"rationale,omitempty"`
RejectedAlternative string `json:"rejected_alternative,omitempty"`
Superseded bool `json:"superseded,omitempty"`
Turns []int `json:"turns"`
DecidedTurn int `json:"decided_turn,omitempty"`
Evidence string `json:"evidence,omitempty"`
EvidenceTurn int `json:"evidence_turn,omitempty"`
Files []string `json:"files,omitempty"`
DecisionID string `json:"-"`
}
SessionDecision is one decision extracted from a session: a choice between plausible alternatives that shaped the repository. Who is "human", "agent" or "agent_proposed_human_approved"; Superseded marks a choice a later decision of the session reversed or replaced. Turns are prompt indexes of the session, the turns where it was proposed, made or implemented; Files are repository-relative paths edited in those turns. Trigger is what prompted it (request, review, failure, finding or initiative), Rationale why as the session states it, DecidedTurn the turn the choice was made, and Evidence a verbatim quote from EvidenceTurn showing it; each is empty when not extracted. DecisionID is the host's stable ID of the decision, empty when it has none; it is not part of the encoded bundle, so the model never reads it, and a host that needs it after decoding a bundle sets it again (SetDecisionIDs).
type SessionEvent ¶
type SessionEvent struct {
ID string `json:"id"`
Time *time.Time `json:"time,omitempty"`
Verb string `json:"verb"`
Summary string `json:"summary"`
}
SessionEvent is a cited non-command tool event retained for anchor resolution.
type SessionValidation ¶
type SessionValidation struct {
ID string `json:"id"`
Method string `json:"method"`
Checked string `json:"checked"`
Outcome string `json:"outcome"`
EvidenceClass string `json:"evidence_class"`
Caveats string `json:"caveats,omitempty"`
CommitLabel ValidationCommitLabel `json:"commit_label"`
EventIDs []string `json:"event_ids"`
}
SessionValidation is a cited check, with deterministic coverage of the reviewed head.
type Thread ¶
type Thread struct {
ID string `json:"id"`
Path string `json:"path"`
Line *int `json:"line"`
Resolved bool `json:"resolved"`
Outdated bool `json:"outdated"`
URL string `json:"url,omitempty"`
}
Thread is one review thread. Line is the current new-side line, null once outdated.