gitrun

package
v1.0.0-rc.2 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: AGPL-3.0, AGPL-3.0-or-later Imports: 17 Imported by: 0

Documentation

Overview

Package gitrun executes bounded, contained Git child processes for the CEM seams. Every failure is typed: cancellation, per-operation timeout, budget exhaustion, output-bound excess, start failure, and non-zero exit each carry a distinct registered code and are never collapsed into one another.

Containment: on Unix the child runs in its own process group. On every abnormal path (cancel, timeout, output excess) the whole group is killed BEFORE the child is reaped, so the group ID cannot be recycled while descendants are signalled. On the normal-exit path the group is swept immediately after the reap; the theoretical group-ID-reuse window there is accepted because the sweep is immediate and hostile same-UID interference is outside the approved trust boundary. Windows containment is deliberately not claimed here: Windows native execution is a separate unpromoted lane, and the stub kills only the direct child.

Index

Constants

View Source
const (
	DefaultOperations   = 1024
	DefaultTotalBudget  = 30 * time.Minute
	DefaultPerOpTimeout = 10 * time.Second
	DefaultStderrLimit  = 64 << 10
)

Frozen operational bounds.

View Source
const EmergencyAllowance = 10 * time.Second

EmergencyAllowance is the single, non-renewable retirement allowance that starts at the first caller cancellation or outer expiry.

View Source
const ProcessContainment = "unsupported-process-containment"

ProcessContainment is the code of a refusal caused by process ownership or cleanup that was not proven. It is never retried or downgraded.

Variables

This section is empty.

Functions

func PinBinary added in v0.8.0

func PinBinary(path string)

PinBinary makes every later spawn with an empty Options.Binary run path, so a Git placed on PATH after a host started never runs (MCPV0-016). The caller passes an absolute path it already resolved; the CLI never pins.

func Run

func Run(ctx context.Context, budget *Budget, options Options, args ...string) ([]byte, error)

Run executes one bounded Git operation and returns its stdout bytes.

func RunReservation

func RunReservation(ctx context.Context, budget *Budget, reservation Reservation, options Options, args ...string) ([]byte, error)

RunReservation replays one already reserved logical operation of a stable budget as a one-shot child. It charges nothing and keeps the deadline.

func RunReserved

func RunReserved(ctx context.Context, perOp time.Duration, options Options, args ...string) ([]byte, error)

RunReserved executes one bounded Git operation whose budget operation the caller already reserved, with perOp as its timeout. A Session request that must be replayed as its original one-shot invocation uses it, so the logical operation is charged exactly once.

func RunStream

func RunStream(ctx context.Context, budget *Budget, options Options, consumer io.Writer, args ...string) error

RunStream sends stdout to a trusted, synchronous, nonblocking consumer. The consumer owns stdout's memory and framing bounds; StdoutLimit and StdoutSizeHint apply only to Run. All other process bounds remain in force. Consumer state is provisional until this call and its framing check succeed.

func WithInheritedWorkerGroup

func WithInheritedWorkerGroup(ctx context.Context) context.Context

func WithOperationBudget

func WithOperationBudget(ctx context.Context, budget *OperationBudget) context.Context

Types

type Budget

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

Budget bounds one verification's Git usage: an operation count and a total wall deadline shared across operations.

func NewBudget

func NewBudget(ops int, total time.Duration) *Budget

NewBudget returns a budget of ops operations within total wall time.

func NewDefaultBudget

func NewDefaultBudget() *Budget

NewDefaultBudget returns the frozen 1,024-operation, 30-minute budget.

func NewStableBudget

func NewStableBudget(ops int, deadline time.Time, expire func(), seam Seam) *Budget

NewStableBudget returns a budget whose every child is run by the owned runner under one clock: ops logical operations before the absolute outer deadline. expire is called once when the budget first observes that deadline passed. Only the Stable verifier constructs one.

func (*Budget) AnchorEmergency

func (b *Budget) AnchorEmergency()

AnchorEmergency anchors the emergency allowance at a caller cancellation. Only the first terminal event anchors it.

func (*Budget) Held

func (b *Budget) Held() bool

Held reports whether any owned process reached HOLD under this budget.

func (*Budget) NewSession

func (b *Budget) NewSession() *Session

NewSession returns a session whose child is owned by a groupreap.Owner and bounded by this stable budget's one clock.

func (*Budget) Notify

func (b *Budget) Notify(name string)

Notify emits one verifier-level seam event.

func (*Budget) Now

func (b *Budget) Now() time.Time

Now reads the budget's clock.

func (*Budget) OuterExpired

func (b *Budget) OuterExpired() bool

OuterExpired samples the outer deadline, calling expire on first expiry.

func (*Budget) Reserve

func (b *Budget) Reserve() (Reservation, error)

Reserve charges one logical operation of a stable budget. A held budget refuses before any spawn; the count bound precedes the outer deadline.

func (*Budget) ReserveOperation

func (b *Budget) ReserveOperation(perOp time.Duration) (time.Duration, error)

ReserveOperation charges one logical operation using the same count and wall bounds as Run. Immutable request memo hits consume this budget without a child.

func (*Budget) Stable

func (b *Budget) Stable() bool

Stable reports whether the budget routes to the owned runner.

type Event

type Event struct {
	// Name is one of: reserved, op-start, retire-started, cause-committed,
	// released, hold, session-close-start, refused-before-spawn.
	// cause-committed is the commitment point: the outer cause is sampled
	// immediately before it and a later outer expiry does not replace the
	// committed cause.
	Name    string
	Ordinal int
	Session bool
	Replay  bool
}

Event is one synchronous lifecycle notification of a stable budget.

type OperationBudget

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

OperationBudget is opt-in aggregate accounting. Unlike the legacy logical Budget, it charges at the physical spawn boundary, including RunReserved. ALO-V0-017: nested NewDefaultBudget calls cannot replenish this context budget.

func NewOperationBudget

func NewOperationBudget(limit int, deadline time.Time, inheritedGroup bool) (*OperationBudget, error)

func OperationBudgetFrom

func OperationBudgetFrom(ctx context.Context) *OperationBudget

func (*OperationBudget) Deadline

func (budget *OperationBudget) Deadline() time.Time

func (*OperationBudget) Delegate

func (budget *OperationBudget) Delegate(keep int) (int, time.Duration, error)

Delegate leaves keep admissions for the parent closing identity checks. An unused quota is not a physical spawn; only a verified consumed count settles it.

func (*OperationBudget) Settle

func (budget *OperationBudget) Settle(consumed int) error

func (*OperationBudget) Used

func (budget *OperationBudget) Used() int

type OperationOutputFailure

type OperationOutputFailure struct {
	Stream string
	Cause  error
}

OperationOutputFailure preserves the overflowing stream for callers adapting the shared executor to an existing error contract. The legacy typed cause is still available through errors.As/Unwrap.

func (*OperationOutputFailure) Error

func (e *OperationOutputFailure) Error() string

func (*OperationOutputFailure) Unwrap

func (e *OperationOutputFailure) Unwrap() error

type Options

type Options struct {
	Binary      string // test seam; empty means the pinned Git, else "git"
	Dir         string
	Env         []string // complete child environment; nil means empty
	Stdin       []byte
	StdoutLimit int
	// StdoutSizeHint, when > 0, preallocates stdout's backing capacity to
	// min(StdoutSizeHint, StdoutLimit) instead of growing it off nil capacity
	// through Go's append growth ladder (roughly 5x the eventual payload).
	// Set it only when the caller can compute the exact expected output size
	// (e.g. a `git cat-file --batch` over blobs of known sizes); leave it
	// zero when StdoutLimit is a generic ceiling unrelated to the actual
	// output size, or preallocation would itself become the huge allocation.
	StdoutSizeHint int
	StderrLimit    int           // 0 means DefaultStderrLimit
	PerOpTimeout   time.Duration // 0 means DefaultPerOpTimeout
}

Options configure one bounded Git invocation.

type Reservation

type Reservation struct {
	Ordinal  int
	Deadline time.Time
}

Reservation is one charged logical operation: its ordinal and its absolute deadline. A replay of the same logical operation reuses it unchanged.

type Seam

type Seam struct {
	Now        func() time.Time
	Event      func(Event)
	Command    func(ordinal int, replay bool, binary string, args []string) (string, []string)
	Primitives func(ordinal int, session bool) groupreap.Primitives
}

Seam is the test seam of a stable budget. The zero value is production.

type Session

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

Session is one caller-scoped `git cat-file --batch` co-process answering requests in order. Its child starts on the first Read and ends at Close, so no process outlives the pass that owns the session. It charges no budget: the caller reserves one operation per request. A request the session cannot answer as one admitted record returns ok=false with the child already reaped; the caller then replays its original one-shot invocation, which alone classifies that failure. Only the per-operation timeout and cancellation are classified here, with Run's codes and messages.

func (*Session) Close

func (s *Session) Close()

Close ends the session: the child sees EOF on stdin and exits; a child that does not exit within DefaultPerOpTimeout is killed with its group.

func (*Session) CloseContext

func (s *Session) CloseContext(ctx context.Context) error

CloseContext ends a stable session and reports whether its cleanup was observed. The child sees EOF on stdin and may finish within ten seconds of remaining outer time; its still-owned group is then retired and reaped. A caller cancellation or outer expiry moves the close to the single emergency allowance. A legacy session has no cleanup status and returns nil.

func (*Session) Read

func (s *Session) Read(ctx context.Context, perOp time.Duration, options Options, args []string, request string, admit func(header string, fields []string, size int) bool) (string, []byte, bool, error)

Read writes request as one batch line and returns the record's header line and body when admit accepts the header line, its fields and the body size. A request holding LF or NUL is never written, so the stream cannot desynchronize.

func (*Session) ReadReserved

func (s *Session) ReadReserved(ctx context.Context, reservation Reservation, options Options, args []string, request string, admit func(header string, fields []string, size int) bool) (string, []byte, bool, error)

ReadReserved is Read for a stable session. The request runs under the absolute deadline of its reservation. ok=false with a nil error means the owned child was retired with observed cleanup and the caller replays the same reservation as a one-shot child; a failed cleanup is an error.

Jump to

Keyboard shortcuts

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