autopilot

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 19, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package autopilot is the OPTIONAL auto-drive layer over the governed collaboration channel.

Base mnemon-harness integrates the channel into host agents and the human drives each agent by hand (prompting it). Engage the autopilot and that manual pacing is automated: it watches each participant's governed projection scope and, when a participant's scope changes, NUDGES it to take a turn — looping until the cluster is quiescent. Disengage and you are back to manual. Base never depends on this package; delete it and the channel still runs.

Like an aircraft autopilot, it flies the plane but does NOT navigate: the flight plan — who acts next / what to do — is decided elsewhere (a POC's governed assignment events, surfaced by the Control Tower). The autopilot is deliberately CONTENT-BLIND: it cannot tell a worker report from a routing assignment from a review; it only sees "this participant's scope changed, nudge it". That is the line that keeps this a governed cluster, not an orchestrator. Routing lives in the Agents, never here.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ItemStr

func ItemStr(item map[string]any, key string) string

ItemStr reads a string field from a coordination item.

func Observe

func Observe(eventType, externalID string, payload map[string]any) contract.ObservationEnvelope

Observe builds an observation envelope. Source is left empty: the server stamps the authenticated principal as Event.Actor on Ingest — a client never names its own identity.

func ProjectionHasKind

func ProjectionHasKind(proj projection.Projection, kind contract.ResourceKind) bool

ProjectionHasKind reports whether a resource of kind is present (materialized) in the view.

func ProjectionItems

func ProjectionItems(proj projection.Projection, kind contract.ResourceKind) []map[string]any

ProjectionItems returns the item list of the first resource of kind in the view. Coordination kinds (assignment, progress_digest, project_intent) carry their records under the "items" field.

Types

type Agent

type Agent interface {
	Principal() contract.ActorID
	Act(pkt TurnPacket) []contract.ObservationEnvelope
}

Agent is a participant the autopilot drives. When nudged it returns the observations it chooses to emit; it owns ALL understanding and routing, the autopilot owns none. A scripted agent (deterministic) and a real-LLM agent are both just Agents — swapping one for the other is an Agent change, never an autopilot change. Emissions MUST be idempotent via ExternalID so re-nudges on an unrelated scope change re-emit harmlessly and the loop reaches quiescence.

func Scripted

func Scripted(principal contract.ActorID, act func(pkt TurnPacket) []contract.ObservationEnvelope) Agent

Scripted wraps a closure as an Agent: deterministic understanding/routing instead of an LLM. It proves the plumbing of governed self-continuation without spending a real turn.

type Loop

type Loop struct {

	// Delay, when > 0, paces the loop one step at a time so a human can watch the cluster
	// self-continue in the UI. Zero (the test/CI default) runs at full speed.
	Delay time.Duration
	// contains filtered or unexported fields
}

Loop is the engaged autopilot. It drives the cluster to quiescence by nudging on scope change.

func NewLoop

func NewLoop(rt Runtime, bindings []channel.ChannelBinding, agents ...Agent) *Loop

NewLoop engages the autopilot over rt for the given agents. Each participant's subscription scope comes straight from its channel binding (the auditable ceiling); the autopilot never widens or narrows it — scope is the communication graph, configured at binding time, not here.

func (*Loop) Done

func (l *Loop) Done() bool

Done reports whether the autopilot has reached quiescence (or stopped).

func (*Loop) Nudges

func (l *Loop) Nudges() []Nudge

Nudges returns a copy of the nudge timeline for the UI/observability surface.

func (*Loop) Run

func (l *Loop) Run(maxSteps int) (int, error)

Run drives passes until quiescence (a full pass that produces no new accepted decision) or maxSteps (a runaway guard). It returns the total accepted decisions produced. Quiescence — not a fixed round count — is what "the cluster finished" means.

func (*Loop) RunContext

func (l *Loop) RunContext(ctx context.Context, maxSteps int) (int, error)

RunContext is Run with cancellation and optional per-step pacing (Delay) for the live UI.

type Nudge

type Nudge struct {
	Step      int
	Principal contract.ActorID
	Digest    string
	Emitted   int
	Accepted  int
}

Nudge records one nudge for the human-facing UI: which participant woke, on what digest, how much it emitted, and how many governed decisions that produced — the observability surface that makes the self-continuation legible.

type Runtime

type Runtime interface {
	PullProjection(principal contract.ActorID, sub contract.Subscription) (projection.Projection, error)
	Submit(principal contract.ActorID, env contract.ObservationEnvelope) (seq int64, dup bool, decisions []contract.Decision, err error)
	DecisionLedger() ([]contract.Decision, error)
}

Runtime is the autopilot's only seam to the governed channel: pull a participant's scoped projection, Submit (ingest + tick) the observations it emits, and read the decision ledger. The in-process runtime handle satisfies it; autopilot never imports the runtime package, and the channel core never imports autopilot — so the autopilot stays a deletable optional ring.

type TurnPacket

type TurnPacket struct {
	Principal  contract.ActorID
	Reason     string
	Projection projection.Projection
}

TurnPacket is what a nudged participant receives: its scoped projection and why it was woken. Reason is always "scope-changed" — the only nudge cause (content-blind).

Jump to

Keyboard shortcuts

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