trunk

package
v0.29.0 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package trunk reads entity ids visible in git refs for the allocator's cross-branch view. Its primary surface, Read, scans the configured trunk ref's tree, applying the policy from id-allocation.md:

  • Not a git repository at all → skip. Tooling that legitimately runs outside a repo (test fixtures, exploratory invocations on plain directories) has no cross-branch surface to police.

  • Configured trunk ref resolves → return the (kind, id, path) triples found under work/ and docs/adr/ in that ref's tree.

  • Trunk ref missing AND was explicitly set in aiwf.yaml → hard error. The user named a specific ref; if it doesn't exist they should fix the typo or fetch it. Silent degradation would defeat their explicit intent.

  • Trunk ref missing AND was the default (no allocate.trunk in aiwf.yaml) AND no refs/remotes/* tracking refs exist → skip. Covers "no remote configured" (sandbox repos), "remote configured but never fetched" (transient setup), and "freshly cloned an empty bare" (canonical first-push setup, where the bare has no branches so the clone has none either). None has anything to collide with.

  • Trunk ref missing AND was the default AND tracking refs DO exist → hard error. The remote has been populated; an unresolvable default trunk is a real misconfiguration (the team's trunk is named something other than main, or the consumer hasn't fetched it). Setting allocate.trunk in aiwf.yaml fixes it.

LocalRefIDs is the second surface: it widens that view to every local branch ref (refs/heads/*) for the allocator only — never the ids-unique check — so a sibling worktree's freshly-committed id is seen at allocation time (M-0212).

LocalRefHits/RemoteRefHits and detectCollisions (M-0259) widen this further into a second consumer beyond the allocator: the per-id path/ref view they carry, plus blob-content comparison across refs, feed the check layer's cross-branch-pending/cross-branch-collision classification (ADR-0030) — so the package's scope is no longer "for the allocator" alone, but every read-only consumer of "what ids are visible where, across every locally-knowable ref."

The package is read-only and has no per-process cache; callers invoke once per verb run.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DistinctRefs added in v0.27.0

func DistinctRefs(hits []RefHit) []string

DistinctRefs returns the distinct ref names carried by hits, in first-seen order — the candidate-ref list a caller surfaces when hits disagree (M-0259/AC-3's cross-branch-collision finding, M-0260/AC-3's aiwf show/list refusal to arbitrate between them).

func HitIDStrings added in v0.27.0

func HitIDStrings(hits []RefHit) []string

HitIDStrings returns just the id strings from hits, in order. Convenience for LocalRefIDs/RemoteRefIDs, which only need id values.

func LocalRefIDs added in v0.20.0

func LocalRefIDs(ctx context.Context, workdir string) []string

LocalRefIDs returns the entity id strings reachable from every local branch ref (refs/heads/*) in workdir's repository. It is the allocator's broadened cross-branch view (M-0212): a sibling git worktree's freshly-committed entity already lives in the shared local refs, so unioning these ids into the allocator's max keeps the next allocation from colliding with it (G-0272 class 1).

Best-effort and read-only: it never returns an error. On any odd repo state — not a git repository, no local branches, or a ref that lists but fails to read — it degrades to the ids it could collect (down to none), never blocking or failing the caller's allocation (M-0212/AC-2). The scan narrows the collision window; it is not a correctness gate, and the irreducible cross-machine race stays `aiwf reallocate`'s to cure.

Unlike Read, the result feeds the allocator ONLY — never the ids-unique trunk-collision check, which keeps its working-tree-vs- trunk basis. Folding every sibling branch into the uniqueness comparison would false-flag the same entity present on two branches (e.g. a feature branch forked from main); E-0052's decision is to take only the prevention half here.

Cost is one `git ls-tree` per local branch — O(local branches) subprocesses per call. Trivial at the solo / handful-of-branches scale this targets; it grows linearly, so a repo carrying hundreds of stale local branches would pay for them on every allocation.

Derived from LocalRefHits (M-0259/AC-1) by dropping path/ref — additive widening only, this function's shape and behavior are unchanged from before AC-1.

func RemoteRefIDs added in v0.20.0

func RemoteRefIDs(ctx context.Context, workdir string) []string

RemoteRefIDs returns the entity id strings reachable from every remote-tracking ref (refs/remotes/*) in workdir's repository — the remote-side mirror of LocalRefIDs (M-0214). An entity pushed to any remote branch (a teammate's not-yet-merged work, a CI checkout) is visible in the local remote-tracking refs, so unioning these ids into the allocator's max keeps the next allocation from colliding with it (G-0316).

Same best-effort, allocation-only contract as LocalRefIDs: it never returns an error, degrades to nil on odd repo states, and feeds the allocator ONLY — never the ids-unique check, which keeps its working-tree-vs-trunk basis.

Derived from RemoteRefHits (M-0259/AC-1) by dropping path/ref — additive widening only.

Types

type CrossBranchScan added in v0.27.0

type CrossBranchScan struct {
	// LocalHits is every entity-id hit on a local branch ref
	// (refs/heads/*) — the allocator's LocalRefIDs view (M-0212).
	LocalHits []RefHit
	// RemoteHits is every hit on a remote-tracking ref (refs/remotes/*)
	// — the allocator's RemoteRefIDs view (M-0214).
	RemoteHits []RefHit
	// Hits is LocalHits followed by RemoteHits: the cross-branch union
	// the read-side resolver (crossBranchIndex / show / list) groups by
	// id on a local-tree miss (ADR-0030).
	Hits []RefHit
	// Collisions is the canonicalized-id set whose hits carry divergent
	// blob content across refs (detectCollisions, G-0415), consulted on
	// a local-tree miss to escalate cross-branch-pending to
	// cross-branch-collision (D-0036). Domain bound: only ids ABSENT from
	// the local tree (per ScanCrossBranch's presentLocally) can appear
	// here — a locally-present diverging id is deliberately omitted by the
	// lazy filter, so a bare Collisions[id] lookup returns false even for
	// a genuinely diverging present id. Read it only after a local-tree
	// miss (as every consumer does).
	Collisions map[string]bool
}

CrossBranchScan is the outcome of one cross-branch ref scan: the per-ref-class hit slices the allocator's id view needs (LocalHits / RemoteHits), their union (Hits — the cross-branch read-side index), and the divergent-content id set among them (Collisions). Composed once by ScanCrossBranch so no consumer re-derives the union or re-runs detectCollisions (E-0067, G-0418).

func ScanCrossBranch added in v0.27.0

func ScanCrossBranch(ctx context.Context, workdir string, presentLocally func(canonicalID string) bool) CrossBranchScan

ScanCrossBranch composes the local + remote ref-hit union once and detects content collisions among them, returning both the union (for the cross-branch read-side index) and its per-ref-class halves (for the allocator's id view). It is the single composition point for the cross-branch scan E-0060 shipped copied across three call sites (cliutil.LoadTreeWithTrunk, list.crossBranchListRows, show.buildCrossBranchShowView); consolidating it here keeps the "hits scanned equal the hits handed to detectCollisions" coupling in one place (G-0418).

Collision detection is lazy: only hits whose id is absent from the local tree (presentLocally reports false) are handed to detectCollisions, so the O(entities×refs) blob-stat pass shrinks to the locally-absent id set — nothing in the common all-merged state, where every id resolves locally. This is behavior-preserving because every consumer reads a collision result only after a local-tree miss (ADR-0030): a locally-present id's collision entry is never observed, so declining to compute it changes no output. A nil presentLocally disables the filter (every id treated as absent, collisions computed over the full union) — nil-safety for absentHits, not a mode any production caller uses; all three callers pass a real predicate.

Best-effort and read-only, inheriting LocalRefHits/RemoteRefHits/ detectCollisions' contract: it never errors, degrading to empty slices and an empty collision map on odd repo state.

type ID

type ID struct {
	Kind entity.Kind
	ID   string
	Path string
}

ID names one entity that exists in the trunk ref's tree, by kind, id string, and the repo-relative path the trunk has it at.

type RefHit added in v0.27.0

type RefHit struct {
	Kind entity.Kind
	ID   string
	Path string
	Ref  string
}

RefHit names one entity id visible on a specific local or remote-tracking git ref (M-0259/AC-1): the same (kind, id, path) triple as trunk.ID, tagged with the originating ref name. Widens LocalRefIDs/RemoteRefIDs' bare-id view so a consumer beyond the allocator (the check-side cross-branch-pending tier, the read-side show/list resolver) can tell WHICH ref and path a hit came from, not just that the id exists somewhere.

func LocalRefHits added in v0.27.0

func LocalRefHits(ctx context.Context, workdir string) []RefHit

LocalRefHits is LocalRefIDs' widened form (M-0259/AC-1): every hit on every local branch ref, carrying kind/path/ref alongside the id. Same best-effort, read-only, allocation-plus-check-consumer contract as LocalRefIDs — never errors, degrades to nil on odd repo states.

func RemoteRefHits added in v0.27.0

func RemoteRefHits(ctx context.Context, workdir string) []RefHit

RemoteRefHits is RemoteRefIDs' widened form (M-0259/AC-1): every hit on every remote-tracking ref, carrying kind/path/ref alongside the id. Same best-effort, read-only contract as RemoteRefIDs.

type Result

type Result struct {
	IDs     []ID
	Skipped bool
}

Result carries the trunk ids visible to the allocator and the cross-tree check. Skipped is true when the repo has no remotes and the trunk read was deliberately bypassed.

func Read

func Read(ctx context.Context, workdir string, cfg *config.Config) (Result, error)

Read returns the entity ids in cfg's configured trunk ref, following the policy in this package's doc comment.

cfg may be nil — in which case the default trunk ref is used. Callers pass workdir as the consumer repo root.

func (Result) IDStrings

func (r Result) IDStrings() []string

IDStrings returns just the id strings from r, in the order they appear in r.IDs. Convenience for AllocateID, which only needs the id values.

Jump to

Keyboard shortcuts

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