ant

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package ant is the population side of the colony: the card contract, the prompt assembly, and the runner that puts the agent loop behind the core's TurnRunner seam. M0 ships exactly one ant, the pi-shaped worker; everything here is written so a second ant is a row of data, never a new type (D3, D4).

Index

Constants

View Source
const SystemPromptBudget = 2000

SystemPromptBudget is the D7 ceiling for block one: two thousand tokens, pi-style. A prompt that creeps over it fails the build via TestSystemPromptBudget, not a code review.

Variables

This section is empty.

Functions

func BlockTwo

func BlockTwo(c Context) provider.Message

BlockTwo renders the pinned index, project memory, skills, and git status as one synthetic system-reminder user message, the D21 treatment of project memory. Its last block carries the second cache breakpoint; it changes only at folding boundaries, which in M0 means never within a session (D14).

func PromptTokens

func PromptTokens(blocks []provider.Block) int

PromptTokens reports the estimated token count of a rendered block one, for the D7 budget gate.

func SystemPrompt

func SystemPrompt(env Env) []provider.Block

SystemPrompt renders block one of the cache-aligned prompt: identity plus the session-stable environment facts, as one system block. The first cache breakpoint is not here; it lands after the tools array (doc 03 section 8), which the loop marks when it renders tool defs.

Types

type Asker

type Asker interface {
	Wait(ctx context.Context, s core.SessionID, request string) (core.RespondRequest, error)
}

Asker is how a blocked Ask reaches the client and the answer comes back. The colony's Asks registry implements it; a headless run leaves it nil and the Ask stands as a refusal (doc 05 section 3).

type Card

type Card struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	Glyph  string `json:"glyph"`  // one rune for the TUI accent, D18
	Accent string `json:"accent"` // semantic palette key, D18

	State     StateSpec     `json:"state"`
	Commands  CommandSpec   `json:"commands"`
	Inspect   InspectSpec   `json:"inspect"`
	Render    RenderSpec    `json:"render"`
	Verify    VerifySpec    `json:"verify"`
	Discovery DiscoverySpec `json:"discovery"`

	Tier  ModelTier `json:"tier"`
	Tools []string  `json:"tools"` // allowlist, subset of the D7 six

	Status  CardStatus `json:"status"`
	Born    time.Time  `json:"born,omitzero"`
	Revised time.Time  `json:"revised,omitzero"`
}

Card is an ant's S/C/I/R/V/D contract (D4). It is data the queen routes on, a document a human reads, and a fixture the eval harness runs (D23). At rest it is a row; awake it parameterizes one goroutine holding one context window (doc 01 section 2.2).

func WorkerCard

func WorkerCard() Card

WorkerCard is the one built-in ant M0 ships: the pi-shaped generalist that reads, edits, runs, and verifies inside one repository.

func (Card) Validate

func (c Card) Validate() error

Validate enforces the D4 floor: every letter of S/C/I/R/V/D must say something, and an ant with no verification story does not register.

type CardStats

type CardStats struct {
	Assigned         int       `json:"assigned"`
	Succeeded        int       `json:"succeeded"`
	Failed           int       `json:"failed"`
	TokensTotal      int64     `json:"tokens_total"`
	SuccessPerKToken float64   `json:"success_per_ktoken"`
	LastActive       time.Time `json:"last_active,omitzero"`
}

CardStats is a denormalized fitness snapshot, refreshed at folding boundaries. The trail table (doc 06 section 8) is the source of truth from M4 on; this is a render cache.

type CardStatus

type CardStatus string

CardStatus is the card's lifecycle position.

const (
	StatusProvisional CardStatus = "provisional"
	StatusActive      CardStatus = "active"
	StatusArchived    CardStatus = "archived"
)

type CommandSpec

type CommandSpec struct {
	Accepts  []string `json:"accepts"`
	Produces []string `json:"produces"`
}

CommandSpec is the C section: the typed handoff kinds this ant takes in and produces.

type Context

type Context struct {
	PinnedIndex   string // the ant's pinned memory index, "" until M2
	ProjectMemory string // ARI.md contents, "" when the file is absent
	Skills        string // installed skills, name plus one line, "" until their milestone
	GitStatus     string // git status --porcelain=v1 --branch at session start
	DeferredTools string // MCP tools announced by name only, "" when none configured
}

Context carries the session-stable inputs block two renders. Every field can be large or can change between sessions, which is exactly why none of them may ride block one (doc 03 section 8).

type DiscoverySpec

type DiscoverySpec struct {
	Summary string      `json:"summary"`
	Classes []TaskClass `json:"classes"`
	Signals []string    `json:"signals"`
	Prefers []TaskClass `json:"prefers,omitempty"`
}

DiscoverySpec is the D section, the routing-facing description. Summary is what gets embedded to SkillVec; Classes are the coarse prefilter; Signals are cheap string cues (globs, languages, symbols) the queen can match without an embedding call (doc 06 section 2.1).

type Env

type Env struct {
	Cwd      string // the workspace root
	Platform string // GOOS/GOARCH
	OS       string // OS version line, "" omits it
	Model    string // resolved model id for the session
}

Env is the small set of facts that are fixed for a session and so may live in block one without busting its cache (doc 03 section 8). Anything that can change mid-session belongs in block two instead.

type InspectSpec

type InspectSpec struct {
	Probes []string `json:"probes"`
}

InspectSpec is the I section: read-only probes. Probe-before-mutate (D4) is enforced here: an ant that mutates must list an inspection that shows what it would touch before it touches it.

type Memory

type Memory interface {
	// PinnedIndex renders the ant's pinned memory index as capped
	// markdown, one line per pin (D11, doc 07).
	PinnedIndex(ctx context.Context, namespace string) (string, error)
}

Memory is the store seam the ant holds and does not call in M0. M2's two-tier provenanced memory (D11) implements it; the ant's loop is untouched then, because block two already reserves the pinned index's slot and the runner already threads this interface (doc 01 section 2.1, plan/01 slice 9).

type ModelTier

type ModelTier string

ModelTier names a failover chain in the provider registry. A card carries a tier, never a model id, so a model swap is a config edit the card never sees (D17).

const (
	TierFrontier ModelTier = "frontier"
	TierMid      ModelTier = "mid"
	TierCheap    ModelTier = "cheap"
	TierLocal    ModelTier = "local"
)

type RenderSpec

type RenderSpec struct {
	Style string `json:"style"` // "markdown" for the worker
}

RenderSpec is the R section: how this ant presents results, for the TUI and the --json stream.

type Runner

type Runner struct {
	// Memory is the store seam the ant holds and does not call in M0
	// (doc 01 section 2.1). Nil renders the pinned index placeholder.
	Memory Memory

	// GitStatus overrides the git probe for deterministic tests. Nil
	// runs git against the workspace root.
	GitStatus func(root string) string

	// LSPClient overrides the language-server seam the tools read. Nil
	// uses the real service built at Bind. It exists so the demo replay
	// can drive the self-correcting edit loop against a deterministic
	// diagnostics source instead of a live gopls whose timing would make
	// a release gate flaky; the real adapter is proven by the LSP fixture
	// suite (plan 02 slices 5 and 6).
	LSPClient lsp.LSPClient
	// contains filtered or unexported fields
}

Runner puts the agent loop behind the core's TurnRunner seam. One runner serves the colony; it wakes one worker per session and keeps it awake for the colony's lifetime, because the worker owns that session's context window (doc 01 section 2.2).

func NewRunner

func NewRunner() *Runner

NewRunner builds an unbound runner. Pass it to core.Open via core.WithRunner, then Bind the opened colony:

r := ant.NewRunner()
c, err := core.Open(ctx, dir, core.WithRunner(r))
r.Bind(c)

Open takes the runner as an option before the colony exists, so binding is the second step.

func (*Runner) Bind

func (r *Runner) Bind(c *core.Colony)

Bind connects the runner to the opened colony's kernel: the provider registry for tier resolution, the ledger for metering, the config for the default permission mode, and the nest for paths.

func (*Runner) Close

func (r *Runner) Close() error

Close tears down the runner's background resources. The colony calls it on shutdown through the optional io.Closer seam, so a spawned language server and every MCP server child process end with the session rather than outliving it.

func (*Runner) Headless

func (r *Runner) Headless()

Headless swaps the interactive resolver for the resolver of last resort: every Ask that reaches the pipeline is claimed with a deny carrying KindHeadless, so the run never blocks on a prompt nobody can see and never runs a call nobody reviewed (doc 05 section 11). Call it after Bind and before Start.

func (*Runner) RunTurn

func (r *Runner) RunTurn(ctx context.Context, t *core.TurnHandle) error

RunTurn implements core.TurnRunner: it wakes or finds the session's worker and drives one turn through the loop.

type StateSpec

type StateSpec struct {
	Namespace string   `json:"namespace"`      // memory namespace, doc 07
	Disk      []string `json:"disk,omitempty"` // worklog, sidechain paths
}

StateSpec is the S section: the state this ant owns. Not global soup; a named memory namespace plus any on-disk working state.

type TaskClass

type TaskClass string

TaskClass is one coarse task class in the small controlled vocabulary the queen prefilters on before spending an embedding call (doc 06).

type VerifySpec

type VerifySpec struct {
	Fixtures []string `json:"fixtures"`
	Check    string   `json:"check"`
}

VerifySpec is the V section: the verification story. No ant is registered without one (D4). Fixtures are replay sets the eval harness runs; Check names what gates the ant's output.

Jump to

Keyboard shortcuts

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