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
- func BlockTwo(c Context) provider.Message
- func PromptTokens(blocks []provider.Block) int
- func SystemPrompt(env Env) []provider.Block
- type Asker
- type Card
- type CardStats
- type CardStatus
- type CommandSpec
- type Context
- type DiscoverySpec
- type Env
- type InspectSpec
- type Memory
- type ModelTier
- type RenderSpec
- type Runner
- type StateSpec
- type TaskClass
- type VerifySpec
Constants ¶
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 ¶
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 ¶
PromptTokens reports the estimated token count of a rendered block one, for the D7 budget gate.
func SystemPrompt ¶
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.
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 ¶
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).
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 ¶
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 ¶
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.
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 ¶
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.