verify

package
v0.5.2 Latest Latest
Warning

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

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

Documentation

Overview

Package verify boots a proposed manifest and repairs it when it fails.

This is what makes generated configuration trustworthy. Detection is imperfect and always will be: rules reach a useful majority of repositories and a model reaches further, but neither can be relied on to be right the first time. The developer does zero work not because detection is perfect, but because recovery from imperfect detection is automated.

The loop is: propose, validate, boot, probe. A failure at any stage is fed back with the evidence — which service, which stage, and what it actually printed — and a new proposal is attempted. Bounded, because a loop that tries forever is a loop that burns an afternoon producing nothing; after the last attempt the partial manifest and the final failure are handed to the human, who is usually four lines from a working file.

The airlock

A Patcher is untrusted. It reads repository content — READMEs, CI configs, dependency manifests, and now the error output of code from that repository — which is precisely the material an attacker can influence, and it produces something devbay is about to execute.

So every proposal crosses one checkpoint, in this package, before anything runs it:

  • It must parse and pass the full validator. A shell string where an argv array belongs fails structurally, before any rule runs.
  • `egress:` is stripped from every proposal, always. If content from a repository could widen the network policy, an injected instruction could widen the network policy, and the sandbox would be arguing with itself.
  • A proposal that fails validation is not retried blindly: the validation error is itself fed back, because a patcher that produced invalid YAML can usually fix it when told what was wrong.

Index

Constants

View Source
const AwaitingApproval = "a command in this manifest needs a human's approval before it can run"

AwaitingApproval marks a result that stopped for a human decision. The manifest may be perfectly good; it simply has not been agreed to.

View Source
const NoPatcher = "no patcher is configured, so the failure was not repaired"

NoPatcher marks a result that stopped because nothing could repair it. It is recorded on the result rather than returned as an error: the loop ran, and the answer -- with the failure and the container's logs -- is the useful part. Returning an error here made callers discard exactly that.

Variables

This section is empty.

Functions

func StripEgress

func StripEgress(m *manifest.Manifest)

StripEgress is the exported form, for callers admitting a manifest by hand.

Types

type Attempt

type Attempt struct {
	N        int           `json:"n"`
	Manifest []byte        `json:"-"`
	Failure  *Failure      `json:"failure,omitempty"`
	Took     time.Duration `json:"took"`
}

Attempt records one pass through the loop.

type Booter

type Booter interface {
	Boot(ctx context.Context, m *manifest.Manifest) *Failure
}

Booter brings a manifest up and reports whether it works.

Returning a *Failure rather than a bare error is the point: a patcher given "boot failed" can do nothing useful, and a patcher given the service, the stage and the container's own output usually can.

type BooterFunc

type BooterFunc func(context.Context, *manifest.Manifest) *Failure

BooterFunc adapts a function to Booter.

func (BooterFunc) Boot

type Failure

type Failure struct {
	Stage Stage `json:"stage"`
	// Service is the service that failed, when the failure belongs to one.
	Service string `json:"service,omitempty"`
	// Message is the error as devbay saw it.
	Message string `json:"message"`
	// Logs is the container's own output, which is usually where the real
	// cause is: a missing environment variable, a refused connection, a
	// migration that has not run.
	Logs string `json:"logs,omitempty"`
}

Failure describes why an attempt did not work, in the terms a patcher needs.

func (Failure) Error

func (f Failure) Error() string

type Loop

type Loop struct {
	// Boot brings a candidate up. Required.
	Boot Booter
	// Patch proposes a revision. When nil the loop validates and boots once,
	// which is the deterministic-only path.
	Patch Patcher
	// MaxAttempts bounds the work. Zero means three.
	MaxAttempts int
	// Log receives progress.
	Log func(format string, args ...any)
}

Loop repairs a proposed manifest until it boots.

func (*Loop) Run

func (l *Loop) Run(ctx context.Context, initial []byte) (*Result, error)

Run drives the loop over an initial proposal.

type Patcher

type Patcher interface {
	// Patch returns revised YAML, given the current file and why it failed.
	Patch(ctx context.Context, current []byte, f Failure) ([]byte, error)
}

Patcher proposes a revised manifest.

Implementations are untrusted by construction, including the ones that call a model. Nothing here trusts the result: see the package comment.

type PatcherFunc

type PatcherFunc func(context.Context, []byte, Failure) ([]byte, error)

PatcherFunc adapts a function to Patcher.

func (PatcherFunc) Patch

func (p PatcherFunc) Patch(ctx context.Context, cur []byte, f Failure) ([]byte, error)

type Result

type Result struct {
	// Manifest is the last proposal that was tried. On success it is the one
	// that worked; on failure it is the best available starting point, which
	// is far more useful to a human than nothing.
	Manifest []byte `json:"-"`
	// Parsed is the validated form of Manifest, when it validated.
	Parsed   *manifest.Manifest `json:"-"`
	Attempts []Attempt          `json:"attempts"`
	OK       bool               `json:"ok"`
	// Note explains why the loop stopped when that is not obvious from the
	// last failure, e.g. that no patcher was available.
	Note string `json:"note,omitempty"`
}

Result is the outcome of the loop.

func (*Result) LastFailure

func (r *Result) LastFailure() *Failure

LastFailure returns the failure that ended the loop, if any.

type Stage

type Stage string

Stage names where an attempt failed.

const (
	StageParse    Stage = "parse"
	StageValidate Stage = "validate"
	StageBoot     Stage = "boot"
	StagePatch    Stage = "patch"
	// StageApproval means the candidate is well-formed but runs a command no
	// human has agreed to. Distinct from the others because it is the one
	// failure a patcher must not try to fix: rewriting the command to get past
	// the gate is precisely what the gate is there to stop.
	StageApproval Stage = "approval"
)

Jump to

Keyboard shortcuts

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