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

composition

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package composition combines the selected changes of every repository in a workspace scope. Each repository is pinned, combined and analyzed on its own with the integration engine; Git objects of different repositories are never mixed. It also derives the composition digest and keeps run records.

Index

Constants

View Source
const (
	SelectionAuto  = "auto: worktree"
	SelectionNamed = "named"
	SelectionBase  = "base only"
	BaseAuto       = "auto"
	BaseNamed      = "named"
	BaseTeam       = "team file"
)

Selection and base sources shown next to every repository.

View Source
const Algorithm = "radar-composition-v1"

Algorithm versions the combination model. It is part of the digest, so a change to how candidates are built changes every digest.

View Source
const KeepRuns = 50

KeepRuns is how many run records each workspace keeps.

View Source
const RecordVersion = 1

RecordVersion is the run-record format version.

View Source
const UnsupportedTree = "" /* 126-byte string literal not displayed */

UnsupportedTree is the guidance for repositories whose trees hold submodules or symlinks.

Variables

View Source
var ErrMoving = errors.New("refs kept moving while Radar pinned them; rerun when no agent is committing")

ErrMoving reports refs that moved during both collection rounds.

View Source
var ErrNoRun = errors.New("no recorded run")

ErrNoRun reports a store without the requested run.

Functions

func Digest

func Digest(results []Result, teams ...*Team) string

Digest identifies a composition by what was combined: repo IDs, base SHAs, ordered input SHAs, candidate trees (or conflicts) and the algorithm. It excludes paths, times and temporary directories, so the same selection has the same digest from any checkout, and a moved repository keeps it.

func Member

func Member(ctx context.Context) func(workspace.ScopeRepo, string) bool

Member reports whether a registered repository holds a team identity, independently of checkout paths and of the checked-out branch.

func StateDir

func StateDir() (string, error)

StateDir is RADAR_STATE_DIR, or <user cache dir>/radar. Run records are never written inside a repository.

func UnsupportedEntries

func UnsupportedEntries(ctx context.Context, root, ref string, limit int) ([]string, error)

UnsupportedEntries lists submodule and symlink paths in the tree at ref, at most limit of them, so they can be reported before a gate run.

Types

type Branch

type Branch struct {
	Ref     string   `json:"ref"`
	Commit  string   `json:"commit"`
	Source  string   `json:"source"`
	Changed []string `json:"changed"`
}

Branch is one pinned input of a repository.

type Detached

type Detached struct {
	Path   string `json:"path"`
	Commit string `json:"commit"`
}

Detached is a detached worktree whose commit was not selected.

type Dirty

type Dirty struct {
	Path            string   `json:"path"`
	Branch          string   `json:"branch,omitempty"`
	Selected        bool     `json:"selected"`
	Staged          []string `json:"staged"`
	Unstaged        []string `json:"unstaged"`
	Untracked       []string `json:"untracked"`
	InspectionError string   `json:"inspection_error,omitempty"`
}

Dirty is a worktree with uncommitted changes. Uncommitted changes never enter a candidate; Selected marks worktrees of selected branches.

func (Dirty) Count

func (d Dirty) Count() int

Count is the number of distinct uncommitted paths.

type FileSides

type FileSides struct {
	Base, Candidate       []byte
	BaseErr, CandidateErr error
}

FileSides caches only declarations and documents required for link checks. A nil data slice without an error means the path is absent from the tree.

type Link struct {
	contracts.LinkResult
	Producer     string   `json:"producer"`
	Consumer     string   `json:"consumer"`
	ProducerPath string   `json:"producer_path"`
	Pointer      string   `json:"pointer"`
	Direction    string   `json:"direction"`
	Warnings     []string `json:"warnings,omitempty"`
}
func CheckLinks(results []Result, team *Team) []Link

CheckLinks uses base declarations even when the candidate removes them.

type Record

type Record struct {
	Version   int                  `json:"version"`
	RunID     string               `json:"run_id"`
	CreatedAt string               `json:"created_at"`
	Workspace string               `json:"workspace"`
	Key       string               `json:"key"`
	Digest    string               `json:"digest"`
	Verdict   string               `json:"verdict"`
	Selection Selection            `json:"selection"`
	Repos     []RecordRepo         `json:"repos"`
	Team      *Team                `json:"team_file,omitempty"`
	TeamHome  *workspace.ScopeRepo `json:"team_home,omitempty"`
	Links     []Link               `json:"links,omitempty"`
}

Record is a run's snapshot: enough to repeat its selection (--again) or rebuild its exact commits (--replay).

func NewRecord

func NewRecord(scope workspace.Scope, selection Selection, results []Result, digest, verdict string, teams ...*Team) Record

NewRecord captures the pinned state of results. The caller adds the link results it reported, so they are not computed twice.

type RecordRepo

type RecordRepo struct {
	ID              string   `json:"id"`
	Path            string   `json:"path"`
	CommonDir       string   `json:"common_dir"`
	BaseRef         string   `json:"base_ref"`
	Base            string   `json:"base"`
	BaseSource      string   `json:"base_source"`
	Selection       string   `json:"selection_source"`
	Branches        []Branch `json:"branches"`
	CandidateCommit string   `json:"candidate_commit,omitempty"`
	CandidateTree   string   `json:"candidate_tree,omitempty"`
	Conflicts       []string `json:"conflicts,omitempty"`
	Error           string   `json:"error,omitempty"`
}

RecordRepo is the pinned state of one repository in a run.

type Repo

type Repo struct {
	workspace.ScopeRepo
	BaseRef                 string     `json:"base_ref"`
	Base                    string     `json:"base"`
	BaseSource              string     `json:"base_source"`
	Selection               string     `json:"selection_source"`
	Branches                []Branch   `json:"branches"`
	Skipped                 []string   `json:"skipped_branches,omitempty"`
	Detached                []Detached `json:"detached,omitempty"`
	Dirty                   []Dirty    `json:"dirty"`
	WorktreeInspectionError string     `json:"worktree_inspection_error,omitempty"`
	Error                   string     `json:"error,omitempty"`
	Next                    string     `json:"next,omitempty"`
	// contains filtered or unexported fields
}

Repo is the pinned selection of one repository. Error, with its next action, marks a repository that cannot be checked; other repositories are still checked.

func Collect

func Collect(ctx context.Context, req Request) ([]Repo, error)

Collect pins every repository's base and inputs to commit SHAs. When a ref moves while refs are being pinned, it pins again once; refs that move again are an error. Only then does it inspect worktrees and changes.

type Request

type Request struct {
	Scope  workspace.Scope
	Named  map[string][]string
	Bases  map[string]string
	Replay *Record
}

Request selects what Collect pins. Named maps repo IDs to refs in merge order; nil Named selects worktree branches automatically. Replay pins the exact commits of a recorded run instead of resolving refs.

type Result

type Result struct {
	Repo
	Report    *integration.Report  `json:"report,omitempty"`
	Files     map[string]FileSides `json:"-"`
	Discovery *discovery.Report    `json:"-"`
}

Result is a repository's pinned selection and, when it could be built, the integration report of its candidate.

func Build

func Build(ctx context.Context, repos []Repo, o integration.Options, teams ...*Team) []Result

Build combines and analyzes every repository that has no error, one at a time and each in its own private repository. A repository that fails to build gets an error; the others are still built. With a replayed selection the candidate must reproduce the recorded tree. A repository with no selected branch takes part at its base: nothing is combined there, so it is analyzed without execution and execution is not required of it.

type RunChange

type RunChange struct {
	PreviousRun string   `json:"previous_run"`
	Mode        string   `json:"mode"`
	Added       []string `json:"added"`
	Removed     []string `json:"removed"`
	Moved       []string `json:"moved"`
}

RunChange lists how a repeated selection differs from the previous run.

func CompareRun

func CompareRun(previous Record, results []Result) *RunChange

CompareRun reports which repository branches were added, removed or moved to another commit since the previous run.

type Selection

type Selection struct {
	// Mode is "auto" (worktree branches) or "named" (positional targets).
	Mode    string   `json:"mode"`
	Targets []string `json:"targets"`
	Bases   []string `json:"bases"`
	With    []string `json:"with"`
	Only    []string `json:"only"`
	// All lists every repo ID in scope before --only.
	All []string `json:"all"`
}

Selection is how a run chose its inputs, with every repo spelled out so a repeated run resolves it identically from any repository.

type Store

type Store struct{ Dir string }

Store holds the run records of one workspace key.

func OpenStore

func OpenStore(key string) (Store, error)

OpenStore returns the store for a workspace key.

func (Store) Load

func (s Store) Load(id string) (Record, error)

Load reads a run's record by run ID, or the newest kept run with "last". "last" is resolved from the run IDs rather than a pointer written by Save: with concurrent saves the run finishing last can start earliest, and prune may already have removed it.

func (Store) Recent

func (s Store) Recent(n int) []Record

Recent returns up to n records, newest first.

func (Store) Save

func (s Store) Save(rec *Record, report func() any) error

Save writes the record and report under a new run ID and keeps the newest KeepRuns runs. Each run is written to a private directory and renamed into place, so concurrent runs never overwrite each other and readers never see a partial run. report is called once the run ID is assigned, so the stored report can carry it.

type SuggestedLink struct {
	Producer  string              `json:"producer"`
	Consumer  string              `json:"consumer"`
	Candidate discovery.Candidate `json:"candidate"`
}

func Suggestions

func Suggestions(results []Result) []SuggestedLink

Suggestions proposes literal endpoint+method matches only for pairs where at least one repository has committed candidate changes. They are never authoritative links or verdict input.

type Team

type Team struct {
	File        *workspace.TeamFile `json:"-"`
	Home        string              `json:"home"`
	Path        string              `json:"path"`
	Blob        string              `json:"blob"`
	Base        string              `json:"base"`
	BaseRef     string              `json:"-"`
	Digest      string              `json:"digest"`
	Uncommitted bool                `json:"uncommitted"`
	// contains filtered or unexported fields
}

Team pins the authoritative team declaration to its home repository and blob.

func LoadTeam

func LoadTeam(ctx context.Context, scope workspace.Scope, home string, bases map[string]string, replay *Record) (*Team, error)

LoadTeam reads only committed declarations. With no saved home it accepts exactly one declaration among the registered base trees. Replay reads the recorded base and verifies its recorded blob, never the current branch.

Jump to

Keyboard shortcuts

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