agency

package
v0.0.0-...-dac94cf Latest Latest
Warning

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

Go to latest
Published: May 10, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Index

Constants

View Source
const CausalGraphProtocolVersion = 1

CausalGraphProtocolVersion is the wire version for the typed causal graph payload exchanged between the GIST Python subprocess and the Go runtime. Bump when CausalGraph or CausalNode shapes change in a non-additive way.

View Source
const ConvergenceProtocolVersion = 1

ConvergenceProtocolVersion is the wire version for ConvergenceReport. Bump on any non-additive change so downstream consumers can refuse to interpret reports they don't understand.

View Source
const DefaultConvergenceThreshold = 0.66

DefaultConvergenceThreshold is the default quorum required for the 'converged' tier. 0.66 means at least two-thirds of agents must share the same Merkle root.

View Source
const DisputeProtocolVersion = 1

DisputeProtocolVersion is the wire version for persisted DisputeRecord payloads. Bump on shape-breaking changes.

View Source
const DyadProtocolVersion = 1

DyadProtocolVersion is the wire version for DyadDelta payloads. Bump on non-additive changes to the delta shape.

View Source
const GISTInspectorBundleProtocolVersion = 1

GISTInspectorBundleProtocolVersion is bumped when the persisted inspector envelope shape changes in a non-additive way. Additive changes (new optional fields) do NOT need a bump.

View Source
const MerkleAttestProtocolVersion = 1

MerkleAttestProtocolVersion is the wire version for MerkleAttestation payloads. Bump if the leaf preimage or tree shape changes; persisted attestations from older versions must be rehydrated, not silently reinterpreted, since identical graphs can produce different roots across versions.

View Source
const PearlLoopProtocolVersion = 1

PearlLoopProtocolVersion is the wire version for PearlPlan payloads embedded in a GISTVerdict. Bump on shape-breaking changes.

View Source
const ReconciliationProtocolVersion = 1

ReconciliationProtocolVersion is the wire version for ReconciliationReport. Bump on non-additive shape changes.

View Source
const SpeculativeBundleProtocolVersion = 1

SpeculativeBundleProtocolVersion is the wire-format version of the persisted speculative envelope. Bumped on non-additive changes only.

Variables

View Source
var ErrDisputeMalformed = errors.New("dispute malformed")

ErrDisputeMalformed is returned by EvaluateDispute when a dispute references a target node that doesn't exist or is missing a required field. Callers can choose to surface the validation error to the reviewer or downgrade the report to DisputeStatusNoted via Adjudicate.

View Source
var ErrTraceNotFound = errors.New("gist trace not found")

ErrTraceNotFound is the sentinel a GISTTraceFetcher returns when the requested trace id has no row in storage. The lattice inspector translates this into a 404.

View Source
var KokoroVoiceMap = map[string]string{
	"coordinator": "am_adam",
	"architect":   "bm_daniel",
	"developer":   "am_michael",
	"analyst":     "bf_emma",
	"scheduler":   "af_bella",
	"reviewer":    "bm_george",
	"default":     "af_heart",
}

KokoroVoiceMap maps agent role archetypes to Kokoro voice IDs.

Functions

func ActorChannel

func ActorChannel(actorID string) string

func ApprovalChannel

func ApprovalChannel(organizationID string) string

func BulletinChannel

func BulletinChannel(organizationID string) string

BulletinChannel returns the pub/sub channel name for an organization's bulletin.

func DyadCompress

func DyadCompress(verdicts []LabeledVerdict) ([]LabeledVerdict, DyadCompressionReport)

DyadCompress greedily pairs Hamming-1-related verdicts into base + delta records. Returns the compressed (base-only) verdict slice plus a report containing the deltas needed to rehydrate the original set.

Pairing is greedy and stable: verdicts are sorted by ID, then for each unpaired verdict we scan later IDs for a Hamming-1 partner. Each verdict participates in at most one dyad — this is deliberate (see PHASE5_DESIGN.md Open Q5: transitive collapse can degrade to "everything looks the same").

func GISTScriptPath

func GISTScriptPath(baseDir string) string

GISTScriptPath returns the conventional path to the GIST subprocess script.

func IPCSocketPath

func IPCSocketPath(baseDir, orgID string) string

IPCSocketPath returns the conventional socket path for an organization.

func KokoroProsodyRate

func KokoroProsodyRate(signalKind string) string

KokoroProsodyRate returns the speech rate multiplier for a given signal kind.

func MarshalInspectorBundle

func MarshalInspectorBundle(verdict GISTVerdict) (string, error)

MarshalInspectorBundle serialises a GISTVerdict into the JSON blob persisted in agency_gist_traces.inspector_json. A nil/empty verdict returns "{}" so the column constraint (NOT NULL) is satisfied.

func MarshalSpeculativeBundle

func MarshalSpeculativeBundle(b *SpeculativeBundle) (string, error)

MarshalSpeculativeBundle serialises a bundle into the JSON blob persisted in agency_gist_traces.speculative_json. nil → "{}".

func OrganizationChannel

func OrganizationChannel(organizationID string) string

func ParseScheduleInterval

func ParseScheduleInterval(expr string) (time.Duration, error)

ParseScheduleInterval parses a schedule expression and returns its firing interval.

func PlatformTTSCommand

func PlatformTTSCommand(baseDir string) (command string, args []string, available bool)

PlatformTTSCommand returns the best available TTS command for the current platform. Priority: Kokoro Python wrapper > macOS say fallback.

func PublishPerformance

func PublishPerformance(ctx context.Context, bus EventBus, rec PerformanceRecord) error

PublishPerformance serialises a PerformanceRecord into a WakeSignal and publishes it to the organization's bulletin channel.

func RunActorDaemon

func RunActorDaemon(ctx context.Context, cfg ActorDaemonConfig) error

func SortDisputeReports

func SortDisputeReports(reports []DisputeReport)

SortDisputeReports orders reports by adjudication-relevant signal: recommendation flips first, then largest |ΔConfidence|, then top-Shapley changes, then ID for stability. Used by the adversarial reviewer to surface the strongest disputes first.

func TTSNotInstalledMsg

func TTSNotInstalledMsg() string

TTSNotInstalledMsg returns the install hint message.

func VoiceIDForRole

func VoiceIDForRole(role string) string

VoiceIDForRole returns the Kokoro voice ID for a given agent role name.

Types

type ActionCandidate

type ActionCandidate struct {
	NodeID      NodeID  `json:"nodeId"`
	Label       string  `json:"label"`
	Score       float64 `json:"score"`
	Risk        float64 `json:"risk"`
	Recommended bool    `json:"recommended"`
}

ActionCandidate scores a single do(x) intervention against the abduced hypothesis. Higher Score = better expected outcome under the current graph; positive Score means evidence outweighs confounder + risk.

func EnumerateActions

func EnumerateActions(graph *CausalGraph, h Hypothesis) []ActionCandidate

EnumerateActions scores every intervention node in the graph against the abduced hypothesis. Score is sigmoid(evidence - 2*confounder + 0.5*self), which is the same value function used by AttributeNecessity so action scores and attribution agree.

type ActionIntent

type ActionIntent struct {
	TaskType        string   `json:"taskType"`
	Complexity      float64  `json:"complexity"`
	LatencyBudgetMs int64    `json:"latencyBudgetMs"`
	PrivacyLevel    string   `json:"privacyLevel"`
	CostCeilingUsd  float64  `json:"costCeilingUsd"`
	RequiredTools   []string `json:"requiredTools,omitempty"`
}

ActionIntent carries model routing requirements derived from a GISTVerdict.

type ActionProposal

type ActionProposal struct {
	ID             string         `json:"id"`
	ActorID        string         `json:"actorId"`
	OrganizationID string         `json:"organizationId"`
	Type           ActionType     `json:"type"`
	Target         string         `json:"target,omitempty"`
	Payload        map[string]any `json:"payload,omitempty"`
	ObservedAt     int64          `json:"observedAt,omitempty"`
	ProposedAt     int64          `json:"proposedAt"`
}

type ActionType

type ActionType string
const (
	ActionWriteCode       ActionType = "write_code"
	ActionRunTest         ActionType = "run_test"
	ActionPingPeer        ActionType = "ping_peer"
	ActionUpdateTask      ActionType = "update_task"
	ActionRequestReview   ActionType = "request_review"
	ActionBroadcast       ActionType = "broadcast"
	ActionSpawnAgent      ActionType = "spawn_agent"
	ActionPublishArtifact ActionType = "publish_artifact"
	ActionHandoffShift    ActionType = "handoff_shift"
)

type Actor

type Actor interface {
	Identity() AgentIdentity
	Capabilities() CapabilityPack
	Handle(context.Context, ObservationSnapshot, WakeSignal) ([]ActionProposal, error)
}

type ActorDaemonConfig

type ActorDaemonConfig struct {
	BaseDir         string
	SharedWorkplace string
	Redis           *RedisConfig
	Constitution    AgencyConstitution
	SpecPath        string
	// LatticeStore persists GIST lattice state across wake cycles.
	// If nil, lattice state is not persisted (in-memory only).
	LatticeStore LatticeStore
	// RoutingLog persists model routing decisions. Optional.
	RoutingLog RoutingLog
	// GISTTraceStore persists replayable GIST trace/proof packets. Optional.
	GISTTraceStore GISTTraceStore
	// ExecutionPolicy constrains model selection. Zero value = permissive.
	ExecutionPolicy ExecutionPolicy
}

type ActorLLMConfig

type ActorLLMConfig struct {
	ModelID   string
	MaxTokens int
	APIKey    string
	BaseURL   string
}

ActorLLMConfig holds configuration for LLM-backed action generation.

func DefaultActorLLMConfig

func DefaultActorLLMConfig() ActorLLMConfig

DefaultActorLLMConfig reads config from environment variables.

type ActorRuntimeSpec

type ActorRuntimeSpec struct {
	Identity        AgentIdentity  `json:"identity"`
	Capabilities    CapabilityPack `json:"capabilities"`
	SharedWorkplace string         `json:"sharedWorkplace,omitempty"`
	OrganizationID  string         `json:"organizationId,omitempty"`
	RegisteredAt    int64          `json:"registeredAt"`
	RuntimeMode     RuntimeMode    `json:"runtimeMode,omitempty"`
	Metadata        map[string]any `json:"metadata,omitempty"`
}

type Adjudication

type Adjudication struct {
	Status     DisputeStatus `json:"status"`
	Reason     string        `json:"reason,omitempty"`
	SwingScore float64       `json:"swingScore"`
	Mechanical bool          `json:"mechanical"`
}

Adjudication is the deterministic ruling on a single dispute. It is derived purely from the DisputeReport — no clocks, no randomness, no LLM in the loop — so any reviewer (human or agent) can replay the same report and arrive at the same status.

func Adjudicate

func Adjudicate(report DisputeReport) Adjudication

Adjudicate produces a deterministic Adjudication for a single DisputeReport. The decision tree is read top-down; first match wins:

  1. Non-mechanism reports (Applied=false, e.g. narrative or malformed claim) → Noted. Mechanical=false.
  2. Recommendation flipped OR BlockedByConfounder flipped → Upheld.
  3. |ΔConfidence| ≥ upholdConfidenceThreshold → Upheld.
  4. |ΔConfidence| ≥ notedConfidenceThreshold OR top-Shapley changed → Noted.
  5. Otherwise → Rejected.

func AdjudicateBatch

func AdjudicateBatch(reports []DisputeReport) []Adjudication

AdjudicateBatch is a convenience wrapper that adjudicates a slice of reports in order. Used by the adversarial reviewer agent (next commit) and by any caller that wants per-batch ruling without hand-rolling a loop.

type AdversarialReviewer

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

AdversarialReviewer is the Phase 4 reviewer agent. It does not call any LLM; instead, it hunts for mechanism-level fault lines in a GISTVerdict (negative-Shapley "evidence", lone interventions, thin confounder coverage, lopsidedly-heavy evidence) and emits plausible Disputes for each. Each dispute is then evaluated by EvaluateDispute and adjudicated by Adjudicate, producing a sorted slice of DisputeRecords.

The reviewer is deterministic: same verdict in, same record set out (modulo the dispute IDs, which are derived from a hash of reviewer-id + verdict-id + heuristic-name).

It is intentionally not a daemon — it is composed into the GIST verdict pipeline (or surfaced via /api/verdict/review). A daemon wrapper is a follow-up if desired.

func NewAdversarialReviewer

func NewAdversarialReviewer(cfg AdversarialReviewerConfig) *AdversarialReviewer

NewAdversarialReviewer builds a reviewer from config. Zero-value fields are populated with defaults so callers can override only the knobs they care about.

func (*AdversarialReviewer) Review

func (a *AdversarialReviewer) Review(verdict GISTVerdict) []DisputeRecord

Review hunts plausible disputes against a verdict and returns the resulting sorted DisputeRecords. The verdict is treated as immutable input.

Heuristics, in order:

  1. mislabeled-role: any evidence node with negative Shapley φ (the supposedly-supportive node is actually pulling confidence down) gets a "is this a confounder?" probe.

  2. action-blocked: every Pearl-recommended action gets a "what if this is infeasible?" probe.

  3. missing-confounder: when projected confidence is high and the existing confounder count is sparse, a synthetic confounder is appended to test robustness.

  4. evidence-stale: heavy evidence nodes (weight ≥ floor) get a "what if this is stale?" probe.

The reviewer never proposes narrative-only disputes; those exist for human reviewers.

type AdversarialReviewerConfig

type AdversarialReviewerConfig struct {
	// ReviewerID stamps every Dispute.ReviewerID this reviewer
	// emits. Defaults to "adversarial-reviewer".
	ReviewerID string

	// MaxDisputes caps the number of records returned (after
	// sorting). Zero means "no cap".
	MaxDisputes int

	// MinAbsSwingForKeep drops reports whose |ΔConfidence| is below
	// the threshold AND that did not flip recommendation /
	// blocking / top-Shapley. 0 keeps everything. Default 0.0
	// (keep everything; let Adjudicate sort upheld vs rejected).
	MinAbsSwingForKeep float64

	// HighConfidenceProbeFloor is the projected-confidence above
	// which we synthesise a "missing-confounder" probe to test
	// robustness. Default 0.7.
	HighConfidenceProbeFloor float64

	// HeavyEvidenceWeightFloor is the per-node weight at which an
	// evidence node becomes a candidate for an evidence-stale
	// probe. Default 0.8.
	HeavyEvidenceWeightFloor float64
}

AdversarialReviewerConfig tunes reviewer aggression. Defaults are returned by DefaultAdversarialReviewerConfig and tuned for "useful without spammy."

func DefaultAdversarialReviewerConfig

func DefaultAdversarialReviewerConfig() AdversarialReviewerConfig

DefaultAdversarialReviewerConfig returns the deployment-default reviewer config. All fields can be overridden individually.

type AgencyConstitution

type AgencyConstitution struct {
	ID             string              `json:"id"`
	Name           string              `json:"name"`
	Description    string              `json:"description,omitempty"`
	OrganizationID string              `json:"organizationId"`
	GovernanceMode GovernanceMode      `json:"governanceMode"`
	Roles          map[string]RoleSpec `json:"roles"`
	Metadata       map[string]string   `json:"metadata,omitempty"`
}

func ConstitutionFromConfig

func ConstitutionFromConfig(cfg *projectconfig.Config, preferred string) (AgencyConstitution, error)

type AgentDaemon

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

func NewAgentDaemon

func NewAgentDaemon(cfg RuntimeConfig, constitution AgencyConstitution, actor Actor) *AgentDaemon

func (*AgentDaemon) Run

func (d *AgentDaemon) Run(ctx context.Context) error

type AgentIdentity

type AgentIdentity struct {
	ID             string            `json:"id"`
	Name           string            `json:"name"`
	Role           string            `json:"role"`
	OrganizationID string            `json:"organizationId"`
	ParentID       string            `json:"parentId,omitempty"`
	AvatarPrompt   string            `json:"avatarPrompt,omitempty"`
	Metadata       map[string]string `json:"metadata,omitempty"`
}

type AgentSchedule

type AgentSchedule struct {
	ID                string            `json:"id"`
	ActorID           string            `json:"actorId"`
	Expression        string            `json:"expression"`
	Timezone          string            `json:"timezone,omitempty"`
	Enabled           bool              `json:"enabled"`
	DefaultSignalKind SignalKind        `json:"defaultSignalKind"`
	Metadata          map[string]string `json:"metadata,omitempty"`
}

type AnthropicAdapter

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

func NewAnthropicAdapter

func NewAnthropicAdapter() *AnthropicAdapter

func (*AnthropicAdapter) Available

func (a *AnthropicAdapter) Available(_ context.Context) bool

func (*AnthropicAdapter) Execute

func (*AnthropicAdapter) ModelID

func (a *AnthropicAdapter) ModelID() string

func (*AnthropicAdapter) Name

func (a *AnthropicAdapter) Name() string

type Bootstrap

type Bootstrap struct {
	Config       Config
	Constitution AgencyConstitution
}

func LoadBootstrap

func LoadBootstrap(workingDir string, constitutionOverride string, runtimeMode RuntimeMode, actorBinary string) (Bootstrap, error)

type CapabilityPack

type CapabilityPack struct {
	Skills            []string          `json:"skills,omitempty"`
	Tools             []string          `json:"tools,omitempty"`
	ActionConstraints []ActionType      `json:"actionConstraints,omitempty"`
	ContextScopes     []string          `json:"contextScopes,omitempty"`
	Metadata          map[string]string `json:"metadata,omitempty"`
}

type CathedralPayload

type CathedralPayload struct {
	TraceID  string             `json:"traceId"`
	Source   string             `json:"source"` // "persisted" | "demo" | "none"
	Bundle   *SpeculativeBundle `json:"bundle,omitempty"`
	Headline string             `json:"headline,omitempty"`
	Note     string             `json:"note,omitempty"`
}

CathedralPayload is the JSON payload served at /lattice/spec/{id}/data and embedded inline by the HTML route. It carries the SpeculativeBundle plus a small amount of header metadata the renderer uses for the status pill and breadcrumb.

type CausalGraph

type CausalGraph struct {
	ProtocolVersion int          `json:"protocolVersion"`
	Nodes           []CausalNode `json:"nodes"`
}

CausalGraph is the typed representation of a GIST verdict's reasoning chain. It is the long-lived shape; the legacy GISTVerdict.CausalChain []string is derived from it via FlatChain().

func ApplyDisputeClaim

func ApplyDisputeClaim(graph *CausalGraph, d Dispute) (*CausalGraph, bool, []string)

ApplyDisputeClaim materialises a Dispute against a CausalGraph, returning a deep clone with the claim applied (or the original graph when the claim is a no-op).

Returned tuple:

  • *CausalGraph — clone with claim applied (never nil for non-nil input)
  • bool — whether a non-trivial mutation happened
  • []string — diagnostic notes describing what changed (or why the claim was a no-op).

The original graph is never mutated.

func HydrateLegacyCausalChain

func HydrateLegacyCausalChain(chain []string) *CausalGraph

HydrateLegacyCausalChain converts a legacy []string causal chain into a minimal CausalGraph so older callers and persisted traces continue to flow through Pearl-aware code paths. Each entry becomes a single node with a content-hashed ID; weights are assigned in descending rank order so FlatChain round-trips back to the original ordering.

Entries with a "role: text" prefix (e.g. "evidence: foo bar") get the matching typed role; everything else is parked under NodeRoleUnknown.

func (*CausalGraph) Clone

func (g *CausalGraph) Clone() *CausalGraph

Clone returns a deep copy so downstream mutations (filtering, ablation, reweighting) never alias shared state across actors.

func (*CausalGraph) CountByRole

func (g *CausalGraph) CountByRole() map[NodeRole]int

CountByRole returns the number of nodes for each known role. Useful for quick health checks ("did we get any interventions?") and metrics export.

func (*CausalGraph) FilterByRole

func (g *CausalGraph) FilterByRole(roles ...NodeRole) *CausalGraph

FilterByRole returns a copy of the graph keeping only nodes whose Role matches one of the supplied roles. Returns nil if the graph is nil or no roles match. Useful for Pearl-loop ablation, e.g. drop confounders before running a counterfactual prediction.

func (*CausalGraph) FlatChain

func (g *CausalGraph) FlatChain() []string

FlatChain returns a deterministic, human-readable []string view of the graph suitable for legacy callers that consumed CausalChain. The ordering is:

  1. Outcomes first (an action plan reads top-down to its conclusion).
  2. Then interventions.
  3. Then evidence (highest weight first).
  4. Then confounders.
  5. Then unknowns (which carry no role prefix).

Within each role bucket nodes are ordered by descending weight, then by ID, so the output is stable across runs and across machines.

type CausalNode

type CausalNode struct {
	ID       NodeID            `json:"id"`
	Role     NodeRole          `json:"role"`
	Summary  string            `json:"summary"`
	Parents  []NodeID          `json:"parents,omitempty"`
	AtomRefs []string          `json:"atomRefs,omitempty"`
	Weight   float64           `json:"weight,omitempty"`
	Meta     map[string]string `json:"meta,omitempty"`
}

CausalNode is a single vertex in the typed causal graph emitted by the GIST kernel. It carries enough metadata to drive Pearl-style abduction -> action -> prediction loops, role-specific filtering, and Shapley/PSE attribution downstream.

type CodexCLIAdapter

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

CodexCLIAdapter runs inference via the Codex CLI (`codex exec`) using the ChatGPT OAuth credentials stored at ~/.codex/auth.json. No API key required — authentication is handled by `codex login` before first use.

func NewCodexCLIAdapter

func NewCodexCLIAdapter() *CodexCLIAdapter

func (*CodexCLIAdapter) Available

func (c *CodexCLIAdapter) Available(_ context.Context) bool

Available returns true when the codex binary is present and auth.json has an access token from a prior `codex login`.

func (*CodexCLIAdapter) Execute

Execute runs `codex exec --json` in a read-only sandbox by default and parses the resulting newline-delimited JSON event stream.

func (*CodexCLIAdapter) ModelID

func (c *CodexCLIAdapter) ModelID() string

func (*CodexCLIAdapter) Name

func (c *CodexCLIAdapter) Name() string

type CommitCertificate

type CommitCertificate struct {
	EntryID     string            `json:"entryId"`
	Sequence    int64             `json:"sequence"`
	Hash        string            `json:"hash"`
	CommittedAt int64             `json:"committedAt"`
	QuorumSize  int               `json:"quorumSize"`
	Status      LedgerEntryStatus `json:"status,omitempty"`
	Approvals   int               `json:"approvals,omitempty"`
	Rejections  int               `json:"rejections,omitempty"`
}

type Config

type Config struct {
	BaseDir          string
	SharedWorkplace  string
	WorkingDir       string
	RuntimeMode      RuntimeMode
	ActorBinaryPath  string
	WakeOnOfficeOpen bool
	Redis            *RedisConfig
	Voice            *VoiceGatewayConfig
}

type ConsensusRequirement

type ConsensusRequirement struct {
	Strategy          ConsensusStrategy `json:"strategy,omitempty"`
	QuorumKey         string            `json:"quorumKey,omitempty"`
	RequiredApprovals int               `json:"requiredApprovals,omitempty"`
	EligibleVoters    []string          `json:"eligibleVoters,omitempty"`
	AutoFinalize      bool              `json:"autoFinalize,omitempty"`
}

type ConsensusStrategy

type ConsensusStrategy string
const (
	ConsensusStrategyDirect ConsensusStrategy = "direct"
	ConsensusStrategyQuorum ConsensusStrategy = "quorum"
)

type ConsensusVote

type ConsensusVote struct {
	VoterID  string `json:"voterId"`
	EntryID  string `json:"entryId"`
	Approved bool   `json:"approved"`
	Reason   string `json:"reason,omitempty"`
	VotedAt  int64  `json:"votedAt"`
}

type ContextSnapshot

type ContextSnapshot struct {
	OrganizationID string              `json:"organizationId"`
	LedgerSequence int64               `json:"ledgerSequence"`
	Actors         []AgentIdentity     `json:"actors,omitempty"`
	Publications   []PublicationRecord `json:"publications,omitempty"`
	LastSignal     *WakeSignal         `json:"lastSignal,omitempty"`
	VoiceRooms     []VoiceRoomState    `json:"voiceRooms,omitempty"`
	LastVoiceEvent *VoiceEvent         `json:"lastVoiceEvent,omitempty"`
	OpenSchedules  []AgentSchedule     `json:"openSchedules,omitempty"`
	UpdatedAt      int64               `json:"updatedAt"`
	Metadata       map[string]string   `json:"metadata,omitempty"`
}

type ConvergenceReport

type ConvergenceReport struct {
	ProtocolVersion int                 `json:"protocolVersion"`
	Status          ConvergenceStatus   `json:"status"`
	ConsensusRoot   string              `json:"consensusRoot,omitempty"`
	Threshold       float64             `json:"threshold"`
	Quorum          float64             `json:"quorum"`
	AgentCount      int                 `json:"agentCount"`
	RootHistogram   map[string]int      `json:"rootHistogram"`
	BucketAgents    map[string][]string `json:"bucketAgents,omitempty"`
	DivergenceLoci  []DivergenceLocus   `json:"divergenceLoci,omitempty"`
	Notes           []string            `json:"notes,omitempty"`
}

ConvergenceReport is the full output of MerkleConverge. It is the gate signal: status determines whether downstream stages may run, ConsensusRoot identifies the consensus bucket, RootHistogram exposes the full distribution for diagnostic UIs, and DivergenceLoci names the leaves that broke unanimity.

func MerkleConverge

func MerkleConverge(peers []PeerAttestation) ConvergenceReport

MerkleConverge runs the gate over a slice of peer attestations using the default threshold. Empty input is an explicit divergence — there is no honest 'converged' answer over zero agents.

func MerkleConvergeWithThreshold

func MerkleConvergeWithThreshold(peers []PeerAttestation, threshold float64) ConvergenceReport

MerkleConvergeWithThreshold lets the caller override the quorum threshold (e.g. require unanimity by passing 1.0). Threshold values outside (0,1] fall back to the default.

func (ConvergenceReport) ConsensusBucketAgents

func (r ConvergenceReport) ConsensusBucketAgents() []string

ConsensusBucketAgents returns the agent IDs in the consensus root's bucket — the cohort whose verdicts the downstream stages may reconcile or compress over. Returns nil when there is no consensus.

func (ConvergenceReport) IsGateOpen

func (r ConvergenceReport) IsGateOpen() bool

IsGateOpen reports whether downstream speculative-tier stages may proceed. Converged: yes. Partial: yes with caveats. Divergent: no.

type ConvergenceStatus

type ConvergenceStatus string

ConvergenceStatus is the three-tier ladder for cohort agreement.

converged - quorum >= threshold on a single root; downstream stages may run
partial   - plurality root exists but below threshold; downstream stages run with caveats
divergent - no plurality OR no agents; downstream stages MUST refuse

Hard tie at the top (multiple roots tied for plurality) collapses to divergent because there's no defensible consensus to propagate.

const (
	ConvergenceStatusConverged ConvergenceStatus = "converged"
	ConvergenceStatusPartial   ConvergenceStatus = "partial"
	ConvergenceStatusDivergent ConvergenceStatus = "divergent"
)

type CorrectionSignal

type CorrectionSignal struct {
	Code          string `json:"code"`
	Message       string `json:"message"`
	TargetActorID string `json:"targetActorId,omitempty"`
	CreatedAt     int64  `json:"createdAt"`
}

type CredentialBroker

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

CredentialBroker loads and validates provider credentials from environment.

func NewCredentialBroker

func NewCredentialBroker() *CredentialBroker

NewCredentialBroker probes the environment for known provider API keys.

func (*CredentialBroker) Handle

func (b *CredentialBroker) Handle(provider string) (CredentialHandle, bool)

Handle returns the credential handle for the given provider name.

func (*CredentialBroker) ValidHandles

func (b *CredentialBroker) ValidHandles() []CredentialHandle

ValidHandles returns only handles whose status is "valid".

type CredentialHandle

type CredentialHandle struct {
	Provider string `json:"provider"`
	KeyRef   string `json:"keyRef"`  // env var name
	Status   string `json:"status"`  // "valid", "missing", "expired"
	ModelID  string `json:"modelId"` // default model for this credential
}

CredentialHandle represents a validated provider credential.

type DirectorAgent

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

func NewDirectorAgent

func NewDirectorAgent(organizationID string) *DirectorAgent

func (*DirectorAgent) Capabilities

func (a *DirectorAgent) Capabilities() CapabilityPack

func (*DirectorAgent) Handle

func (*DirectorAgent) Identity

func (a *DirectorAgent) Identity() AgentIdentity

type DirectorConfig

type DirectorConfig struct {
	BaseDir         string
	OrganizationID  string
	SharedWorkplace string
	Ledger          *LedgerService
	Bus             EventBus
	Router          *ModelRouter
	Policy          DirectorPolicy
}

type DirectorEvent

type DirectorEvent struct {
	ID             string            `json:"id"`
	OrganizationID string            `json:"organizationId"`
	TicketID       string            `json:"ticketId,omitempty"`
	Kind           string            `json:"kind"`
	Message        string            `json:"message"`
	Metadata       map[string]string `json:"metadata,omitempty"`
	CreatedAt      int64             `json:"createdAt"`
}

type DirectorHTTPConfig

type DirectorHTTPConfig struct {
	Addr  string
	Token string
}

type DirectorHTTPServer

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

func NewDirectorHTTPServer

func NewDirectorHTTPServer(cfg DirectorHTTPConfig, director *DirectorService) *DirectorHTTPServer

func (*DirectorHTTPServer) Handler

func (s *DirectorHTTPServer) Handler() http.Handler

Handler returns the underlying http.Handler the server dispatches from. Exposed so callers (notably the Phase 6 end-to-end test) can drive the same routing surface that production traffic flows through without spinning up a real listener. The returned handler still includes requireAuth, so tests must either set Token to "" or pass the configured token via header / query string.

func (*DirectorHTTPServer) Serve

func (s *DirectorHTTPServer) Serve(ctx context.Context) error

func (*DirectorHTTPServer) URL

func (s *DirectorHTTPServer) URL() string

type DirectorPolicy

type DirectorPolicy struct {
	AutoDispatchRisks         []DirectorRisk     `json:"autoDispatchRisks"`
	AutoDispatchPriorities    []DirectorPriority `json:"autoDispatchPriorities"`
	RequireApprovalRisks      []DirectorRisk     `json:"requireApprovalRisks"`
	RequireApprovalPriorities []DirectorPriority `json:"requireApprovalPriorities"`
	PauseWhenApprovalsPending bool               `json:"pauseWhenApprovalsPending"`
}

func DefaultDirectorPolicy

func DefaultDirectorPolicy() DirectorPolicy

func (DirectorPolicy) AllowsAutoDispatch

func (p DirectorPolicy) AllowsAutoDispatch(ticket DirectorTicket) (bool, string)

type DirectorPriority

type DirectorPriority string
const (
	DirectorPriorityLow    DirectorPriority = "low"
	DirectorPriorityNormal DirectorPriority = "normal"
	DirectorPriorityHigh   DirectorPriority = "high"
	DirectorPriorityUrgent DirectorPriority = "urgent"
)

type DirectorRisk

type DirectorRisk string
const (
	DirectorRiskLow     DirectorRisk = "low"
	DirectorRiskMedium  DirectorRisk = "medium"
	DirectorRiskHigh    DirectorRisk = "high"
	DirectorRiskUnknown DirectorRisk = "unknown"
)

type DirectorService

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

func NewDirectorService

func NewDirectorService(cfg DirectorConfig) (*DirectorService, error)

func (*DirectorService) Agent

func (d *DirectorService) Agent() *DirectorAgent

func (*DirectorService) AutoDispatchOpenTickets

func (d *DirectorService) AutoDispatchOpenTickets(ctx context.Context, source string) (int, error)

func (*DirectorService) AutoDispatchTicket

func (d *DirectorService) AutoDispatchTicket(ctx context.Context, ticketID string, source string) (DirectorTicket, error)

func (*DirectorService) DispatchTicket

func (d *DirectorService) DispatchTicket(ctx context.Context, ticketID string) (DirectorTicket, error)

func (*DirectorService) ListEvents

func (d *DirectorService) ListEvents() ([]DirectorEvent, error)

func (*DirectorService) ListTickets

func (d *DirectorService) ListTickets() ([]DirectorTicket, error)

func (*DirectorService) Monitor

func (d *DirectorService) Monitor(ctx context.Context) (DirectorStatus, error)

func (*DirectorService) Policy

func (d *DirectorService) Policy() DirectorPolicy

func (*DirectorService) SetTraceFetcher

func (d *DirectorService) SetTraceFetcher(f GISTTraceFetcher)

SetTraceFetcher attaches a fetcher to the DirectorService. May be called at most once during construction; later calls are silently ignored to avoid mid-flight swaps.

func (*DirectorService) Status

func (*DirectorService) SubmitTicket

func (*DirectorService) TraceFetcher

func (d *DirectorService) TraceFetcher() GISTTraceFetcher

TraceFetcher returns the registered fetcher or nil if none is wired. The HTTP handlers gate inspector routes on a non-nil fetcher.

type DirectorStatus

type DirectorStatus struct {
	Agent            AgentIdentity  `json:"agent"`
	BaseDir          string         `json:"baseDir"`
	OrganizationID   string         `json:"organizationId"`
	SharedWorkplace  string         `json:"sharedWorkplace"`
	OpenTickets      int            `json:"openTickets"`
	Dispatched       int            `json:"dispatched"`
	ClosedTickets    int            `json:"closedTickets"`
	LedgerSequence   int64          `json:"ledgerSequence"`
	PendingApprovals int            `json:"pendingApprovals"`
	LastSignal       *WakeSignal    `json:"lastSignal,omitempty"`
	LastEvent        *DirectorEvent `json:"lastEvent,omitempty"`
	UpdatedAt        int64          `json:"updatedAt"`
}

type DirectorTicket

type DirectorTicket struct {
	ID             string               `json:"id"`
	OrganizationID string               `json:"organizationId"`
	Title          string               `json:"title"`
	Body           string               `json:"body"`
	Source         string               `json:"source"`
	Priority       string               `json:"priority,omitempty"`
	Risk           string               `json:"risk,omitempty"`
	Status         DirectorTicketStatus `json:"status"`
	AssignedRole   string               `json:"assignedRole,omitempty"`
	CreatedAt      int64                `json:"createdAt"`
	UpdatedAt      int64                `json:"updatedAt"`
	DispatchedAt   int64                `json:"dispatchedAt,omitempty"`
	LastSummary    string               `json:"lastSummary,omitempty"`
}

type DirectorTicketRequest

type DirectorTicketRequest struct {
	Title        string `json:"title"`
	Body         string `json:"body"`
	Source       string `json:"source"`
	Priority     string `json:"priority,omitempty"`
	Risk         string `json:"risk,omitempty"`
	AssignedRole string `json:"assignedRole,omitempty"`
	AutoDispatch bool   `json:"autoDispatch,omitempty"`
}

type DirectorTicketStatus

type DirectorTicketStatus string
const (
	DirectorTicketOpen       DirectorTicketStatus = "open"
	DirectorTicketDispatched DirectorTicketStatus = "dispatched"
	DirectorTicketClosed     DirectorTicketStatus = "closed"
)

type Dispute

type Dispute struct {
	ID           string        `json:"id,omitempty"`
	ReviewerID   string        `json:"reviewerId,omitempty"`
	Ground       DisputeGround `json:"ground"`
	TargetNode   NodeID        `json:"targetNode,omitempty"`
	NewRole      NodeRole      `json:"newRole,omitempty"`
	AddedSummary string        `json:"addedSummary,omitempty"`
	AddedWeight  float64       `json:"addedWeight,omitempty"`
	StaleFactor  float64       `json:"staleFactor,omitempty"`
	Narrative    string        `json:"narrative,omitempty"`
	CreatedAt    time.Time     `json:"createdAt,omitempty"`
}

Dispute is the input lodged by an adversarial reviewer agent. It is a claim about a specific GISTVerdict; together with that verdict it can be evaluated mechanically by EvaluateDispute.

Field usage by ground:

  • mislabeled-role — TargetNode + NewRole are required.
  • missing-confounder — AddedSummary required; AddedWeight optional (defaults to defaultAddedConfounderWeight).
  • action-blocked — TargetNode required; node is removed from the graph so it no longer shows up as an intervention candidate.
  • evidence-stale — TargetNode required; StaleFactor is the multiplier applied to the node's weight (defaults to defaultStaleFactor when zero or out of range).
  • narrative — Narrative required; graph is unchanged.

CreatedAt is recorded so the persisted DisputeRecord on the inspector bundle has a stable timestamp; if zero, EvaluateDispute stamps now().

type DisputeGround

type DisputeGround string

DisputeGround enumerates the mechanism-level grounds on which an adversarial reviewer can dispute a verdict. Each ground (except the narrative carve-out) maps to a deterministic transformation of the typed CausalGraph; the dispute's evidentiary force is then the counterfactual swing between the original verdict and the verdict that results from re-running the Pearl loop on the transformed graph.

Grounds are intentionally narrow and Pearl-shaped:

  • mislabeled-role — claim a node's role is wrong (e.g. an "evidence" atom is actually a confounder).
  • missing-confounder — claim the graph omits a confounder that, if added, would change action selection.
  • action-blocked — claim a recommended intervention is infeasible / disallowed and must be removed from the candidate space.
  • evidence-stale — claim an evidence node's weight should be down-rated because it has decayed in relevance.
  • narrative — a non-mechanism reviewer concern. No graph mutation. Always routes to DisputeStatusNoted.
const (
	DisputeGroundMislabeledRole    DisputeGround = "mislabeled-role"
	DisputeGroundMissingConfounder DisputeGround = "missing-confounder"
	DisputeGroundActionBlocked     DisputeGround = "action-blocked"
	DisputeGroundEvidenceStale     DisputeGround = "evidence-stale"
	DisputeGroundNarrative         DisputeGround = "narrative"
)

type DisputeRecord

type DisputeRecord struct {
	ProtocolVersion int           `json:"protocolVersion"`
	Report          DisputeReport `json:"report"`
	Adjudication    Adjudication  `json:"adjudication"`
}

DisputeRecord packages a Dispute, its DisputeReport, and the resulting Adjudication into a single persistable unit. It is the shape carried on the inspector bundle (commit 4) and surfaced to the lattice inspector UI.

ProtocolVersion is bumped when the carrier shape changes; the inner Report and Adjudication carry their own implicit versions through the protocol constants on Dispute and DisputeStatus.

func NewDisputeRecord

func NewDisputeRecord(report DisputeReport) DisputeRecord

NewDisputeRecord materialises a DisputeRecord from a fully-populated DisputeReport (i.e. the output of EvaluateDispute) by adjudicating the report and stamping the protocol version.

func (DisputeRecord) IsUpheld

func (r DisputeRecord) IsUpheld() bool

IsUpheld returns true iff the record's adjudication is upheld. Convenience for filters in the inspector and for action-policy code that should refuse to act when any dispute is upheld.

type DisputeReport

type DisputeReport struct {
	Dispute Dispute `json:"dispute"`

	OriginalVerdict             string  `json:"originalVerdict,omitempty"`
	OriginalConfidence          float64 `json:"originalConfidence"`
	OriginalRecommendation      NodeID  `json:"originalRecommendation,omitempty"`
	OriginalTopShapley          NodeID  `json:"originalTopShapley,omitempty"`
	OriginalBlockedByConfounder bool    `json:"originalBlockedByConfounder,omitempty"`

	CounterfactualPlan           *PearlPlan        `json:"counterfactualPlan,omitempty"`
	CounterfactualAttribution    []NodeAttribution `json:"counterfactualAttribution,omitempty"`
	CounterfactualConfidence     float64           `json:"counterfactualConfidence"`
	CounterfactualRecommendation NodeID            `json:"counterfactualRecommendation,omitempty"`
	CounterfactualTopShapley     NodeID            `json:"counterfactualTopShapley,omitempty"`
	CounterfactualBlocked        bool              `json:"counterfactualBlocked,omitempty"`

	DeltaConfidence            float64 `json:"deltaConfidence"`
	RecommendationFlipped      bool    `json:"recommendationFlipped,omitempty"`
	TopShapleyChanged          bool    `json:"topShapleyChanged,omitempty"`
	BlockedByConfounderFlipped bool    `json:"blockedByConfounderFlipped,omitempty"`

	Applied bool     `json:"applied"`
	Notes   []string `json:"notes,omitempty"`
}

DisputeReport is the output of EvaluateDispute. It preserves the pre-dispute "world" (Original*) and the counterfactual world that results from applying the claim and re-running the Pearl loop + Shapley attribution. The Delta* fields are convenience computations the inspector and Adjudicate consume directly.

Applied=false means the claim was a no-op (typically narrative or referenced a node that doesn't exist); Adjudicate routes such reports to DisputeStatusNoted rather than rejected, since the reviewer's concern is still on record.

func EvaluateDispute

func EvaluateDispute(verdict GISTVerdict, d Dispute) DisputeReport

EvaluateDispute is the heart of Phase 4: it takes a verdict and a dispute, applies the dispute claim to a clone of the verdict's typed causal graph, re-runs the Pearl loop and Shapley attribution on the counterfactual graph, and returns a DisputeReport carrying both the original and counterfactual states plus the deltas that adjudication keys off.

The verdict is treated as immutable input; nothing on the verdict is mutated. The dispute's CreatedAt is stamped if zero.

func (DisputeReport) AbsConfidenceSwing

func (r DisputeReport) AbsConfidenceSwing() float64

AbsConfidenceSwing returns the magnitude of the counterfactual confidence shift, clamped to [0,1]. Convenience for adjudication and inspector display.

type DisputeStatus

type DisputeStatus string

DisputeStatus is the deterministic verdict on a dispute itself, produced by Adjudicate(report). It is mechanism-faithful: a dispute is upheld iff applying its claim materially shifts the counterfactual world (action swap, confidence past threshold, or blocking flag flipped), not because of social weight.

const (
	// DisputeStatusUpheld means the counterfactual swing was large
	// enough to materially change the verdict's behaviour: a
	// recommendation flipped, the BlockedByConfounder flag flipped,
	// or |ΔConfidence| crossed the upholdConfidenceThreshold.
	DisputeStatusUpheld DisputeStatus = "upheld"

	// DisputeStatusNoted means the dispute produced a measurable but
	// sub-threshold swing, OR it was a non-mechanism concern
	// (narrative ground / no-op claim). The dispute stays on record
	// and is surfaced in the inspector, but the verdict is not
	// invalidated.
	DisputeStatusNoted DisputeStatus = "noted"

	// DisputeStatusRejected means the claim transformed the graph
	// but the resulting counterfactual was indistinguishable from
	// the original (no detectable swing in confidence, top-Shapley
	// rank, recommendation, or blocking flag).
	DisputeStatusRejected DisputeStatus = "rejected"
)

type DivergenceLocus

type DivergenceLocus struct {
	LeafHash  string   `json:"leafHash"`
	Severity  string   `json:"severity"`
	Inclusion []string `json:"inclusion,omitempty"`
	Exclusion []string `json:"exclusion,omitempty"`
}

DivergenceLocus reports a leaf that the cohort disagrees about, naming the agents on each side. Severity 'extra' means the leaf is in the inclusion set but not the consensus; 'missing' means the reverse. This lets a reviewer point at the specific node IDs (via leaf hash) the minority is wrong about — without ever shipping the full graphs.

type DyadCompressionReport

type DyadCompressionReport struct {
	ProtocolVersion int         `json:"protocolVersion"`
	SlotsBefore     int         `json:"slotsBefore"`
	SlotsAfter      int         `json:"slotsAfter"`
	Deltas          []DyadDelta `json:"deltas"`
	UnpairedIDs     []string    `json:"unpairedIds,omitempty"`
	Notes           []string    `json:"notes,omitempty"`
}

DyadCompressionReport is the audit trail for one DyadCompress run. SlotsBefore/SlotsAfter let callers verify the storage win.

type DyadDelta

type DyadDelta struct {
	ProtocolVersion  int         `json:"protocolVersion"`
	BaseVerdictID    string      `json:"baseVerdictId"`
	SiblingVerdictID string      `json:"siblingVerdictId"`
	LeafReplaced     string      `json:"leafReplaced,omitempty"`
	LeafIntroduced   string      `json:"leafIntroduced,omitempty"`
	NodeMutation     *NodeDiff   `json:"nodeMutation,omitempty"`
	NodeAdded        *CausalNode `json:"nodeAdded,omitempty"`
	NodeRemoved      *NodeID     `json:"nodeRemoved,omitempty"`
}

DyadDelta encodes the Hamming-1 difference between a base verdict and its sibling. Exactly one of the three mutation forms is set:

NodeMutation - a node was renamed/re-roled/re-weighted in place
NodeAdded    - sibling carries one more node than base
NodeRemoved  - sibling carries one fewer node than base

LeafReplaced and LeafIntroduced are the canonical leaf hashes of the dropped/gained leaves. They are redundant given the typed mutation, but ship them anyway so a verifier can confirm the delta matches the Merkle attestations without rehydrating.

type ElasticBudget

type ElasticBudget struct {
	RecallThreshold float64 `json:"recallThreshold"`
	MaxTTLMs        int64   `json:"maxTtlMs"`
	StretchFactor   float64 `json:"stretchFactor,omitempty"`
}

ElasticBudget controls how much GIST elastic stretch is allowed per wake cycle.

func DefaultGISTBudget

func DefaultGISTBudget() ElasticBudget

DefaultGISTBudget reads elastic budget settings from environment variables.

type EventBus

type EventBus interface {
	Publish(context.Context, WakeSignal) error
	Subscribe(context.Context, string) (<-chan WakeSignal, error)
	Close(context.Context) error
}

type ExecProcessSpawner

type ExecProcessSpawner struct {
	BinaryPath       string
	WorkingDirectory string
	BaseDir          string
	SharedWorkplace  string
	Redis            *RedisConfig
	ConstitutionName string
}

func (*ExecProcessSpawner) Spawn

type ExecutionPolicy

type ExecutionPolicy struct {
	AllowedProviders []string `json:"allowedProviders,omitempty"`
	PreferLocal      bool     `json:"preferLocal"`
	MaxCostUsd       float64  `json:"maxCostUsd,omitempty"`
	MaxLatencyMs     int64    `json:"maxLatencyMs,omitempty"`
	PrivacyLevel     string   `json:"privacyLevel,omitempty"` // "local", "cloud", "any"
}

ExecutionPolicy constrains which providers the ModelRouter may select.

type GISTAgentCore

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

GISTAgentCore manages the per-agent GIST Python subprocess. It provides causal compression of observations into GISTVerdict values that are used to prefix LLM calls.

If the subprocess is unavailable the core degrades gracefully, returning a low-confidence verdict so the actor can still act.

func NewGISTAgentCore

func NewGISTAgentCore(agentID, scriptPath string, budget ElasticBudget) *GISTAgentCore

NewGISTAgentCore creates a new core for the given agent. scriptPath should point to the gist Python entry-point (e.g. scripts/gist_subprocess.py). If the script does not exist the core will return degraded verdicts on every call.

func (*GISTAgentCore) BuildAtoms

func (g *GISTAgentCore) BuildAtoms(obs ObservationSnapshot, signal WakeSignal) []gistAtom

BuildAtoms converts an observation snapshot and wake signal into GIST atoms.

func (*GISTAgentCore) Compress

func (g *GISTAgentCore) Compress(ctx context.Context, atoms []gistAtom) (GISTVerdict, string, error)

Compress sends atoms to the GIST Python subprocess and returns a verdict. Degrades gracefully if the subprocess is unavailable or errors.

func (*GISTAgentCore) ElasticStretch

func (g *GISTAgentCore) ElasticStretch(verdict GISTVerdict, lastWakeMs int64) GISTVerdict

ElasticStretch adjusts verdict confidence based on the elastic budget TTL. If the previous lattice is fresh enough, it boosts confidence; otherwise it returns the verdict unchanged.

func (*GISTAgentCore) LatticeJSON

func (g *GISTAgentCore) LatticeJSON() string

LatticeJSON returns the current lattice JSON (to be persisted to DB after wake).

func (*GISTAgentCore) SetLattice

func (g *GISTAgentCore) SetLattice(latticeJSON string)

SetLattice updates the persisted lattice state (loaded from DB before each wake).

type GISTAtom

type GISTAtom struct {
	ID         string            `json:"id"`
	Kind       string            `json:"kind"`
	Content    string            `json:"content,omitempty"`
	Scope      string            `json:"scope,omitempty"`
	SubjectID  string            `json:"subjectId,omitempty"`
	Predicate  string            `json:"predicate,omitempty"`
	ObjectID   string            `json:"objectId,omitempty"`
	Value      string            `json:"value,omitempty"`
	Weight     float64           `json:"weight,omitempty"`
	Confidence float64           `json:"confidence,omitempty"`
	SlotHint   string            `json:"slotHint,omitempty"`
	SourceRefs []string          `json:"sourceRefs,omitempty"`
	Meta       map[string]string `json:"meta,omitempty"`
}

type GISTClosure

type GISTClosure struct {
	ID            string   `json:"id"`
	Kind          string   `json:"kind,omitempty"`
	Arity         int      `json:"arity,omitempty"`
	Relation      string   `json:"relation,omitempty"`
	SlotIDs       []string `json:"slotIds,omitempty"`
	InputSlotIDs  []string `json:"inputSlotIds,omitempty"`
	AtomRefs      []string `json:"atomRefs,omitempty"`
	InputAtomRefs []string `json:"inputAtomRefs,omitempty"`
	OutputSlotID  string   `json:"outputSlotId,omitempty"`
	Summary       string   `json:"summary,omitempty"`
	Weight        float64  `json:"weight,omitempty"`
	Score         float64  `json:"score,omitempty"`
	Selected      bool     `json:"selected,omitempty"`
}

type GISTContradiction

type GISTContradiction struct {
	ID             string   `json:"id"`
	Kind           string   `json:"kind,omitempty"`
	Summary        string   `json:"summary"`
	Severity       string   `json:"severity"`
	Status         string   `json:"status,omitempty"`
	Atoms          []string `json:"atoms,omitempty"`
	AtomRefs       []string `json:"atomRefs,omitempty"`
	SlotIDs        []string `json:"slotIds,omitempty"`
	EvidenceNeeded []string `json:"evidenceNeeded,omitempty"`
	Blocking       bool     `json:"blocking,omitempty"`
}

type GISTCounterfactual

type GISTCounterfactual struct {
	ID              string   `json:"id"`
	InterventionID  string   `json:"interventionId,omitempty"`
	BranchKind      string   `json:"branchKind,omitempty"`
	If              string   `json:"if"`
	Then            string   `json:"then"`
	Risk            string   `json:"risk,omitempty"`
	RiskLevel       string   `json:"riskLevel,omitempty"`
	ExpectedUtility float64  `json:"expectedUtility,omitempty"`
	Unknowns        []string `json:"unknowns,omitempty"`
	EvidenceNeeded  []string `json:"evidenceNeeded,omitempty"`
	Tests           []string `json:"tests,omitempty"`
}

type GISTInspectorBundle

type GISTInspectorBundle struct {
	ProtocolVersion int      `json:"protocolVersion"`
	Verdict         string   `json:"verdict,omitempty"`
	RiskLevel       string   `json:"riskLevel,omitempty"`
	Confidence      float64  `json:"confidence,omitempty"`
	Degraded        bool     `json:"degraded,omitempty"`
	DegradedReason  string   `json:"degradedReason,omitempty"`
	ExecutionIntent string   `json:"executionIntent,omitempty"`
	OpenQuestions   []string `json:"openQuestions,omitempty"`

	// Number of contradictions reported by the kernel. Stored as a count
	// rather than the full slice so the inspector blob stays compact;
	// the full contradiction objects live in the lattice JSON.
	ContradictionCount int `json:"contradictionCount,omitempty"`
	InterventionCount  int `json:"interventionCount,omitempty"`

	// CausalGraph is the typed Pearl DAG. May be nil for legacy or
	// degraded verdicts; in that case FlatChain is still populated from
	// the legacy []string causal chain.
	CausalGraph *CausalGraph `json:"causalGraph,omitempty"`
	// FlatChain is the deterministic flattening of CausalGraph (or the
	// raw legacy chain when CausalGraph is nil). Inspector renders it as
	// the "Reasoning chain" tab.
	FlatChain []string `json:"flatChain,omitempty"`

	// PearlPlan is the abduction / action / prediction triple from
	// RunPearlLoop. nil if the loop was skipped (degraded verdicts).
	PearlPlan *PearlPlan `json:"pearlPlan,omitempty"`
	// Attribution is the Shapley necessity ranking from
	// AttributeNecessity. Empty if the graph had no players.
	Attribution []NodeAttribution `json:"attribution,omitempty"`

	// Disputes is the adversarial-review record set attached to this
	// verdict. Each entry pairs a Dispute with its DisputeReport
	// (counterfactual swing) and Adjudication (status). Empty for
	// verdicts that have not been routed through the reviewer.
	Disputes []DisputeRecord `json:"disputes,omitempty"`
}

GISTInspectorBundle is the persisted projection of a GISTVerdict that the lattice inspector renders. It is deliberately a denormalised, self-contained JSON envelope so the inspector can render a trace without re-running the kernel, and so old traces (missing the bundle) degrade gracefully.

The bundle is written into the agency_gist_traces.inspector_json column at trace-store time, alongside the existing legacy blobs (trace_json, proof_json, lattice_json). It captures everything Phases 1-2 added on top of GISTVerdict that the inspector route needs:

  • CausalGraph (the typed Pearl-shaped DAG, protocol v1)
  • PearlPlan (abduce / act / predict triple with scores)
  • Attribution (Shapley necessity ranking)
  • FlatChain (legacy ordering, retained for tooling that wants a list)
  • Verdict / RiskLevel / Confidence headline metadata
  • OpenQuestions / Contradictions counts (for hover summaries)

func BuildInspectorBundle

func BuildInspectorBundle(verdict GISTVerdict) *GISTInspectorBundle

BuildInspectorBundle builds an inspector bundle from a GISTVerdict. The returned bundle is safe to mutate independently of the verdict.

The verdict's CausalChain/CausalGraph relationship is reconciled via SyncCausalChain so the bundle's FlatChain agrees with CausalGraph.

func HydrateInspectorBundleFromLegacy

func HydrateInspectorBundleFromLegacy(traceJSON string) *GISTInspectorBundle

HydrateInspectorBundleFromLegacy synthesises a best-effort inspector bundle for a trace that was persisted before this column existed. It uses the legacy trace_json (a GISTTrace) to recover SelectedChain and SelectedVerdict; the typed graph is hydrated from the chain via HydrateLegacyCausalChain, but PearlPlan and Attribution will be nil (they were never computed for that trace).

Returns nil if the legacy trace blob is empty or unparseable; the caller should display "no inspector data available" in that case.

func ParseInspectorBundle

func ParseInspectorBundle(raw string) (*GISTInspectorBundle, error)

ParseInspectorBundle parses a persisted inspector_json blob. Empty or "{}" blobs return (nil, nil) so callers can distinguish "no bundle stored" from a parse error and fall back to legacy reconstruction.

If the blob is non-empty but parses cleanly with protocolVersion == 0, it's treated as a legacy/empty record and (nil, nil) is also returned.

type GISTIntervention

type GISTIntervention struct {
	ID              string   `json:"id"`
	Label           string   `json:"label,omitempty"`
	ActionAtomRef   string   `json:"actionAtomRef,omitempty"`
	Do              string   `json:"do"`
	Assumptions     []string `json:"assumptions,omitempty"`
	ExpectedEffects []string `json:"expectedEffects,omitempty"`
	Risks           []string `json:"risks,omitempty"`
	Confidence      float64  `json:"confidence,omitempty"`
}

type GISTLattice

type GISTLattice struct {
	Version           string       `json:"version"`
	Scope             GISTScopeRef `json:"scope"`
	CanonicalSlots    int          `json:"canonicalSlots"`
	Slots             []GISTSlot   `json:"slots"`
	ActiveSlots       []string     `json:"activeSlots,omitempty"`
	ParentLatticeHash string       `json:"parentLatticeHash,omitempty"`
	LastTraceID       string       `json:"lastTraceId,omitempty"`
	UpdatedAt         int64        `json:"updatedAt"`
}

GISTLattice is the canonical 64-slot causal lattice. Runtime activation may be sparse, but the 4x4x4 geometry is always present in the state contract.

type GISTLatticeDiff

type GISTLatticeDiff struct {
	ActivatedSlots   []string        `json:"activatedSlots,omitempty"`
	DeactivatedSlots []string        `json:"deactivatedSlots,omitempty"`
	UpdatedSlots     []GISTSlotDelta `json:"updatedSlots,omitempty"`
}

type GISTProofPacket

type GISTProofPacket struct {
	Version             string             `json:"version"`
	TraceID             string             `json:"traceId"`
	Verdict             string             `json:"verdict"`
	Confidence          float64            `json:"confidence"`
	InputHash           string             `json:"inputHash"`
	PrevLatticeHash     string             `json:"prevLatticeHash,omitempty"`
	NextLatticeHash     string             `json:"nextLatticeHash,omitempty"`
	LatticeDiff         *GISTLatticeDiff   `json:"latticeDiff,omitempty"`
	ContradictionIDs    []string           `json:"contradictionIds,omitempty"`
	InterventionIDs     []string           `json:"interventionIds,omitempty"`
	CounterfactualIDs   []string           `json:"counterfactualIds,omitempty"`
	ConfidenceBreakdown map[string]float64 `json:"confidenceBreakdown,omitempty"`
}

type GISTScopeRef

type GISTScopeRef struct {
	Kind           string `json:"kind"`
	OrganizationID string `json:"organizationId"`
	AgentID        string `json:"agentId,omitempty"`
	ParentKind     string `json:"parentKind,omitempty"`
	ParentID       string `json:"parentId,omitempty"`
}

type GISTSlot

type GISTSlot struct {
	ID               string             `json:"id"`
	Index            int                `json:"index"`
	Temporal         string             `json:"temporal"`
	Abstraction      string             `json:"abstraction"`
	Evidence         string             `json:"evidence"`
	Bits             string             `json:"bits"`
	Active           bool               `json:"active"`
	Summary          string             `json:"summary,omitempty"`
	AtomRefs         []string           `json:"atomRefs,omitempty"`
	ContradictionIDs []string           `json:"contradictionIds,omitempty"`
	Weight           float64            `json:"weight,omitempty"`
	Metrics          map[string]float64 `json:"metrics,omitempty"`
}

type GISTSlotDelta

type GISTSlotDelta struct {
	SlotID          string             `json:"slotId"`
	AddedAtomRefs   []string           `json:"addedAtomRefs,omitempty"`
	RemovedAtomRefs []string           `json:"removedAtomRefs,omitempty"`
	WeightDelta     float64            `json:"weightDelta,omitempty"`
	MetricDelta     map[string]float64 `json:"metricDelta,omitempty"`
}

type GISTTrace

type GISTTrace struct {
	ID                  string             `json:"id"`
	AgentID             string             `json:"agentId"`
	OrganizationID      string             `json:"organizationId"`
	Scope               GISTScopeRef       `json:"scope"`
	SignalID            string             `json:"signalId,omitempty"`
	LedgerSequence      int64              `json:"ledgerSequence,omitempty"`
	Atoms               []GISTAtom         `json:"atoms,omitempty"`
	AtomCount           int                `json:"atomCount"`
	InputHash           string             `json:"inputHash"`
	PrevLatticeHash     string             `json:"prevLatticeHash,omitempty"`
	NextLatticeHash     string             `json:"nextLatticeHash,omitempty"`
	LatticeHash         string             `json:"latticeHash,omitempty"`
	ActiveSlots         []string           `json:"activeSlots,omitempty"`
	TriadClosures       []GISTClosure      `json:"triadClosures,omitempty"`
	DyadClosures        []GISTClosure      `json:"dyadClosures,omitempty"`
	ContradictionIDs    []string           `json:"contradictionIds,omitempty"`
	InterventionIDs     []string           `json:"interventionIds,omitempty"`
	CounterfactualIDs   []string           `json:"counterfactualIds,omitempty"`
	LatticeDiff         *GISTLatticeDiff   `json:"latticeDiff,omitempty"`
	SelectedChain       []string           `json:"selectedChain,omitempty"`
	SelectedVerdict     string             `json:"selectedVerdict,omitempty"`
	ConfidenceBreakdown map[string]float64 `json:"confidenceBreakdown,omitempty"`
	ReplayHandle        string             `json:"replayHandle,omitempty"`
	CreatedAt           int64              `json:"createdAt"`
}

GISTTrace is the replayable packet emitted by each causal compression wake.

type GISTTraceFetcher

type GISTTraceFetcher interface {
	GetInspectorTrace(ctx context.Context, traceID string) (*InspectorTraceView, error)
	ListInspectorTraces(ctx context.Context, officeID string, limit int) ([]InspectorTraceSummary, error)
}

GISTTraceFetcher is the read-only side door the lattice inspector uses to load persisted traces. Implementations live alongside the DB (see internal/agency/cmd/director-daemon/trace_fetcher.go) so the inspector can render /lattice/<trace_id> without coupling DirectorService to the database layer.

type GISTTraceStore

type GISTTraceStore interface {
	StoreTrace(ctx context.Context, organizationID, agentID, latticeJSON string, verdict GISTVerdict) error
}

type GISTVerdict

type GISTVerdict struct {
	Verdict             string               `json:"verdict"`
	Confidence          float64              `json:"confidence"`
	CausalChain         []string             `json:"causalChain,omitempty"`
	CausalGraph         *CausalGraph         `json:"causalGraph,omitempty"`
	OpenQuestions       []string             `json:"openQuestions,omitempty"`
	ExecutionIntent     string               `json:"executionIntent"`
	Intent              *ActionIntent        `json:"intent,omitempty"`
	RiskLevel           string               `json:"riskLevel,omitempty"`
	RequiredTools       []string             `json:"requiredTools,omitempty"`
	Lattice             *GISTLattice         `json:"lattice,omitempty"`
	Trace               *GISTTrace           `json:"trace,omitempty"`
	Proof               *GISTProofPacket     `json:"proof,omitempty"`
	Contradictions      []GISTContradiction  `json:"contradictions,omitempty"`
	Interventions       []GISTIntervention   `json:"interventions,omitempty"`
	Counterfactuals     []GISTCounterfactual `json:"counterfactuals,omitempty"`
	ConfidenceBreakdown map[string]float64   `json:"confidenceBreakdown,omitempty"`
	Degraded            bool                 `json:"degraded,omitempty"`
	DegradedReason      string               `json:"degradedReason,omitempty"`
	PearlPlan           *PearlPlan           `json:"pearlPlan,omitempty"`
	Attribution         []NodeAttribution    `json:"attribution,omitempty"`
	Disputes            []DisputeRecord      `json:"disputes,omitempty"`
}

GISTVerdict is the output of the GIST causal compression step.

The legacy CausalChain []string field is kept for backward compatibility with all existing call sites; the typed CausalGraph is the new source of truth for Pearl-style abduction/action/prediction reasoning. Use SyncCausalChain to keep the two views aligned after mutating either.

func (*GISTVerdict) SyncCausalChain

func (v *GISTVerdict) SyncCausalChain()

SyncCausalChain reconciles the typed CausalGraph and the legacy CausalChain []string fields on the verdict. Precedence:

  • If CausalGraph has nodes, CausalChain is overwritten with graph.FlatChain() so legacy consumers see a deterministic view.
  • Otherwise, if CausalChain is non-empty and CausalGraph is nil, CausalGraph is hydrated from the chain via HydrateLegacyCausalChain so Pearl-aware consumers always see a graph.

Calling SyncCausalChain repeatedly is safe and idempotent.

type GeminiAdapter

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

func NewGeminiAdapter

func NewGeminiAdapter() *GeminiAdapter

func (*GeminiAdapter) Available

func (g *GeminiAdapter) Available(_ context.Context) bool

func (*GeminiAdapter) Execute

func (*GeminiAdapter) ModelID

func (g *GeminiAdapter) ModelID() string

func (*GeminiAdapter) Name

func (g *GeminiAdapter) Name() string

type GenesisManufacturingInput

type GenesisManufacturingInput struct {
	Intent           string
	Domain           string
	TimeHorizon      string
	WorkingStyle     string
	Governance       string
	GoalShape        string
	ConstitutionName string
	Constitution     config.AgencyConstitution
	Template         config.TeamTemplate
	RequestedRoles   []string
	DefaultCadence   string
	Timezone         string
	SharedWorkplace  string
	RedisAddress     string
	LedgerPath       string
}

type GenesisPlan

type GenesisPlan struct {
	Intent               OrgIntent           `json:"intent"`
	Summary              string              `json:"summary"`
	ConstitutionName     string              `json:"constitutionName"`
	Blueprint            string              `json:"blueprint,omitempty"`
	TeamTemplate         string              `json:"teamTemplate,omitempty"`
	Topology             string              `json:"topology,omitempty"`
	RoleBundles          []GenesisRoleBundle `json:"roleBundles,omitempty"`
	SocialThread         []string            `json:"socialThread,omitempty"`
	ManufacturingSignals []string            `json:"manufacturingSignals,omitempty"`
}

func ManufactureGenesis

func ManufactureGenesis(input GenesisManufacturingInput) GenesisPlan

type GenesisRoleBundle

type GenesisRoleBundle struct {
	RoleName            string            `json:"roleName"`
	DisplayName         string            `json:"displayName"`
	Profile             string            `json:"profile,omitempty"`
	ReportsTo           string            `json:"reportsTo,omitempty"`
	Archetype           string            `json:"archetype,omitempty"`
	Mission             string            `json:"mission"`
	WorkingPosture      string            `json:"workingPosture,omitempty"`
	Personality         string            `json:"personality,omitempty"`
	OfficePresence      string            `json:"officePresence,omitempty"`
	AvatarPrompt        string            `json:"avatarPrompt,omitempty"`
	SystemPrompt        string            `json:"systemPrompt,omitempty"`
	Skills              []string          `json:"skills,omitempty"`
	Tools               []string          `json:"tools,omitempty"`
	AllowedActions      []ActionType      `json:"allowedActions,omitempty"`
	ObservationScopes   []string          `json:"observationScopes,omitempty"`
	PeerRouting         map[string]string `json:"peerRouting,omitempty"`
	CapabilityPack      CapabilityPack    `json:"capabilityPack"`
	RecommendedSchedule AgentSchedule     `json:"recommendedSchedule"`
	SpawnOrder          int               `json:"spawnOrder"`
	CanSpawnAgents      bool              `json:"canSpawnAgents"`
}

type GovernanceMode

type GovernanceMode string
const (
	GovernanceHierarchical GovernanceMode = "hierarchical"
	GovernancePeer         GovernanceMode = "peer"
	GovernanceFederated    GovernanceMode = "federated"
	GovernanceFlat         GovernanceMode = "flat"
	GovernanceHybrid       GovernanceMode = "hybrid"
)

type Hypothesis

type Hypothesis struct {
	Evidence       []NodeID `json:"evidence,omitempty"`
	Confounders    []NodeID `json:"confounders,omitempty"`
	EvidenceWeight float64  `json:"evidenceWeight"`
	ConfounderLoad float64  `json:"confounderLoad"`
}

Hypothesis ranks the evidence and confounder nodes that make the verdict plausible. Evidence supports the verdict; confounders are flagged so the agent can decide whether to seek tie-breaking observations before acting.

func Abduce

func Abduce(graph *CausalGraph) Hypothesis

Abduce projects a CausalGraph onto its evidence + confounder atoms, returning a Hypothesis that ranks them by contribution. The graph is not mutated.

type IPCApprovalPayload

type IPCApprovalPayload struct {
	ProposalID  string `json:"proposalId"`
	ActorID     string `json:"actorId"`
	ActionType  string `json:"actionType"`
	Target      string `json:"target"`
	GISTVerdict string `json:"gistVerdict,omitempty"`
	GISTRisk    string `json:"gistRisk,omitempty"`
	GISTTraceID string `json:"gistTraceId,omitempty"`
	GISTReason  string `json:"gistReason,omitempty"`
	CreatedAt   int64  `json:"createdAt"`
}

IPCApprovalPayload carries a pending action proposal.

type IPCBroadcastPayload

type IPCBroadcastPayload struct {
	ActorID   string `json:"actorId"`
	Message   string `json:"message"`
	CreatedAt int64  `json:"createdAt"`
}

IPCBroadcastPayload carries a live agent message.

type IPCBulletinPayload

type IPCBulletinPayload struct {
	ActorID   string  `json:"actorId"`
	Directive string  `json:"directive"`
	Output    string  `json:"output"`
	Score     float64 `json:"score"`
	Provider  string  `json:"provider"`
	ModelID   string  `json:"modelId"`
	CreatedAt int64   `json:"createdAt"`
}

IPCBulletinPayload carries a performance record.

type IPCHandshake

type IPCHandshake struct {
	OrgID      string `json:"orgId"`
	ClientType string `json:"clientType"` // "desktop", "cli", "web"
}

IPCHandshake is the first message a client sends after connecting.

type IPCMessage

type IPCMessage struct {
	Type    IPCMessageType  `json:"type"`
	Payload json.RawMessage `json:"payload,omitempty"`
}

IPCMessage is the newline-delimited JSON envelope exchanged over the socket.

type IPCMessageType

type IPCMessageType string

IPCMessageType identifies the kind of event sent over the socket.

const (
	IPCTypeBroadcast IPCMessageType = "broadcast"
	IPCTypeApproval  IPCMessageType = "approval"
	IPCTypeBulletin  IPCMessageType = "bulletin"
	IPCTypeVote      IPCMessageType = "vote"
	IPCTypeHandshake IPCMessageType = "handshake"
	IPCTypePing      IPCMessageType = "ping"
	IPCTypePong      IPCMessageType = "pong"
)

type IPCServer

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

IPCServer listens on a Unix socket and fans out office events to connected clients. Clients subscribe by sending a handshake; they can send votes back.

func NewIPCServer

func NewIPCServer(socketPath string, bus EventBus) *IPCServer

NewIPCServer creates an IPC server that will listen on socketPath.

func (*IPCServer) Broadcast

func (s *IPCServer) Broadcast(orgID string, msg IPCMessage)

Broadcast sends a message directly to all connected clients for an org. Used for server-initiated notifications (e.g. office boot/stop).

func (*IPCServer) Serve

func (s *IPCServer) Serve(ctx context.Context) error

Serve starts accepting connections. Blocks until ctx is cancelled.

type IPCVote

type IPCVote struct {
	ProposalID string `json:"proposalId"`
	Approved   bool   `json:"approved"`
}

IPCVote is sent by a client to approve or reject a pending proposal.

type InferenceRequest

type InferenceRequest struct {
	System      string       `json:"system"`
	UserMessage string       `json:"userMessage"`
	Intent      ActionIntent `json:"intent"`
	AgentID     string       `json:"agentId"`
	OrgID       string       `json:"orgId"`
}

InferenceRequest is the input to the ModelRouter.

type InferenceResult

type InferenceResult struct {
	Text       string `json:"text"`
	Provider   string `json:"provider"`
	ModelID    string `json:"modelId"`
	LatencyMs  int64  `json:"latencyMs"`
	TokensUsed int    `json:"tokensUsed,omitempty"`
}

InferenceResult is the output from a ProviderAdapter.

type InspectorTraceSummary

type InspectorTraceSummary struct {
	ID         string  `json:"id"`
	OfficeID   string  `json:"officeId"`
	AgentID    string  `json:"agentId"`
	Verdict    string  `json:"verdict"`
	RiskLevel  string  `json:"riskLevel,omitempty"`
	Confidence float64 `json:"confidence"`
	CreatedAt  int64   `json:"createdAt"`
	HasBundle  bool    `json:"hasBundle"`
}

InspectorTraceSummary is the headline list-row for the inspector index page. Cheap to serialise, used by the picker UI.

type InspectorTraceView

type InspectorTraceView struct {
	Summary       InspectorTraceSummary `json:"summary"`
	Bundle        *GISTInspectorBundle  `json:"bundle,omitempty"`
	BundleSource  string                `json:"bundleSource"`
	LatticeJSON   string                `json:"latticeJson,omitempty"`
	TraceJSON     string                `json:"traceJson,omitempty"`
	ProofJSON     string                `json:"proofJson,omitempty"`
	InspectorJSON string                `json:"inspectorJson,omitempty"`
}

InspectorTraceView is the full payload rendered at /lattice/<trace_id>. It composes the persisted blobs (lattice JSON, raw trace, proof) with the typed Inspector bundle so the HTML template can render any of them without further parsing.

type Kernel

type Kernel struct{}

func NewKernel

func NewKernel() *Kernel

func (*Kernel) ValidateAction

func (k *Kernel) ValidateAction(constitution AgencyConstitution, actor AgentIdentity, proposal ActionProposal) KernelDecision

func (*Kernel) ValidateObservation

func (k *Kernel) ValidateObservation(constitution AgencyConstitution, observation ObservationSnapshot) KernelDecision

type KernelDecision

type KernelDecision struct {
	Accepted      bool               `json:"accepted"`
	Reason        string             `json:"reason,omitempty"`
	Corrections   []CorrectionSignal `json:"corrections,omitempty"`
	ValidatedAt   int64              `json:"validatedAt"`
	CommitAllowed bool               `json:"commitAllowed"`
}

type LLMActorProposer

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

LLMActorProposer generates action proposals via LLM for a given observation.

func NewLLMActorProposer

func NewLLMActorProposer(cfg ActorLLMConfig) *LLMActorProposer

NewLLMActorProposer creates a new proposer.

func (*LLMActorProposer) BuildSystemPrompt

func (p *LLMActorProposer) BuildSystemPrompt(obs ObservationSnapshot, role RoleSpec) string

BuildSystemPrompt returns the system prompt for the given observation and role.

func (*LLMActorProposer) BuildUserMessage

func (p *LLMActorProposer) BuildUserMessage(obs ObservationSnapshot, signal WakeSignal) string

BuildUserMessage returns the user message for the given observation and signal.

func (*LLMActorProposer) Propose

Propose generates action proposals for the given observation and signal. If the API key is not configured, returns a safe default proposal.

func (*LLMActorProposer) SetGISTContext

func (p *LLMActorProposer) SetGISTContext(verdict GISTVerdict)

SetGISTContext attaches a GIST verdict whose Verdict string is prepended to the LLM system prompt and whose ExecutionIntent is stored on each proposal.

type LabeledVerdict

type LabeledVerdict struct {
	ID      string      `json:"id"`
	Verdict GISTVerdict `json:"verdict"`
}

LabeledVerdict pairs a verdict with a stable identifier so dyad deltas can name their base/sibling verdicts. ID is opaque from the dyad layer's point of view — callers pick whatever ID scheme makes sense for their lattice slot store.

func DyadHydrate

func DyadHydrate(base LabeledVerdict, delta DyadDelta) (LabeledVerdict, error)

DyadHydrate is the inverse of DyadCompress for one (base, delta) pair. Returns the rehydrated sibling verdict.

By construction DyadHydrate(base, DyadCompress(base, sibling).delta) equals sibling modulo float-rounding at canonical 6-decimal precision.

type LatticeStore

type LatticeStore interface {
	GetLattice(ctx context.Context, agentID string) (string, error)
	SetLattice(ctx context.Context, agentID, latticeJSON string) error
}

LatticeStore is the persistence interface for per-agent GIST lattice state. Implementations may be DB-backed or no-op.

type LedgerEntry

type LedgerEntry struct {
	Sequence       int64                 `json:"sequence"`
	ID             string                `json:"id"`
	OrganizationID string                `json:"organizationId"`
	Kind           LedgerEntryKind       `json:"kind"`
	Status         LedgerEntryStatus     `json:"status,omitempty"`
	ActorID        string                `json:"actorId,omitempty"`
	Action         *ActionProposal       `json:"action,omitempty"`
	Decision       *KernelDecision       `json:"decision,omitempty"`
	Snapshot       *ContextSnapshot      `json:"snapshot,omitempty"`
	Signal         *WakeSignal           `json:"signal,omitempty"`
	Publication    *PublicationRecord    `json:"publication,omitempty"`
	Voice          *VoiceEvent           `json:"voice,omitempty"`
	Consensus      *ConsensusRequirement `json:"consensus,omitempty"`
	Quorum         *QuorumState          `json:"quorum,omitempty"`
	Certificate    *CommitCertificate    `json:"certificate,omitempty"`
	Votes          []ConsensusVote       `json:"votes,omitempty"`
	ProposedAt     int64                 `json:"proposedAt,omitempty"`
	CommittedAt    int64                 `json:"committedAt"`
	FinalizedAt    int64                 `json:"finalizedAt,omitempty"`
	RejectedAt     int64                 `json:"rejectedAt,omitempty"`
}

type LedgerEntryKind

type LedgerEntryKind string
const (
	LedgerEntryAction      LedgerEntryKind = "action"
	LedgerEntrySignal      LedgerEntryKind = "signal"
	LedgerEntrySnapshot    LedgerEntryKind = "snapshot"
	LedgerEntrySchedule    LedgerEntryKind = "schedule"
	LedgerEntryPublication LedgerEntryKind = "publication"
	LedgerEntryVoice       LedgerEntryKind = "voice"
)

type LedgerEntryStatus

type LedgerEntryStatus string
const (
	LedgerEntryStatusProposed  LedgerEntryStatus = "proposed"
	LedgerEntryStatusPending   LedgerEntryStatus = "pending"
	LedgerEntryStatusFinalized LedgerEntryStatus = "finalized"
	LedgerEntryStatusRejected  LedgerEntryStatus = "rejected"
)

type LedgerService

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

func NewLedgerService

func NewLedgerService(baseDir string) (*LedgerService, error)

func (*LedgerService) Append

func (*LedgerService) AppendSchedule

func (l *LedgerService) AppendSchedule(ctx context.Context, schedule AgentSchedule, signal WakeSignal) (CommitCertificate, error)

func (*LedgerService) AppendSignal

func (l *LedgerService) AppendSignal(ctx context.Context, signal WakeSignal) (CommitCertificate, error)

func (*LedgerService) AppendSnapshot

func (l *LedgerService) AppendSnapshot(ctx context.Context, snapshot ContextSnapshot) (CommitCertificate, error)

func (*LedgerService) AppendVoiceEvent

func (l *LedgerService) AppendVoiceEvent(ctx context.Context, event VoiceEvent) (CommitCertificate, error)

func (*LedgerService) Finalize

func (l *LedgerService) Finalize(ctx context.Context, entryID string) (CommitCertificate, error)

func (*LedgerService) LatestSnapshot

func (l *LedgerService) LatestSnapshot(ctx context.Context, organizationID string) (*ContextSnapshot, error)

func (*LedgerService) Pending

func (l *LedgerService) Pending(ctx context.Context, organizationID string) ([]LedgerEntry, error)

func (*LedgerService) Propose

func (l *LedgerService) Propose(ctx context.Context, entry LedgerEntry) (LedgerEntry, error)

func (*LedgerService) Replay

func (l *LedgerService) Replay(ctx context.Context) ([]LedgerEntry, error)

func (*LedgerService) Vote

func (l *LedgerService) Vote(ctx context.Context, entryID string, vote ConsensusVote) (QuorumState, error)

type MemoryEventBus

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

func NewMemoryEventBus

func NewMemoryEventBus() *MemoryEventBus

func (*MemoryEventBus) Close

func (b *MemoryEventBus) Close(ctx context.Context) error

func (*MemoryEventBus) Publish

func (b *MemoryEventBus) Publish(ctx context.Context, signal WakeSignal) error

func (*MemoryEventBus) Subscribe

func (b *MemoryEventBus) Subscribe(ctx context.Context, channel string) (<-chan WakeSignal, error)

type MerkleAttestConfig

type MerkleAttestConfig struct {
	// IncludeLeafHashes controls whether the attestation carries the
	// per-leaf hashes. Defaults to true via NewMerkleAttestConfig.
	IncludeLeafHashes bool
	// AttestedAt overrides the timestamp; zero means time.Now().UTC().
	AttestedAt time.Time
}

MerkleAttestConfig tunes optional knobs on the leaf canonicalisation. The zero value is a sensible default: lowercase + whitespace-collapse summary normalisation, 6-decimal-place weight rounding, no leaf hashes hidden.

func NewMerkleAttestConfig

func NewMerkleAttestConfig() MerkleAttestConfig

NewMerkleAttestConfig returns the default configuration: leaf hashes included, timestamp set at attest time.

type MerkleAttestation

type MerkleAttestation struct {
	ProtocolVersion int       `json:"protocolVersion"`
	Root            string    `json:"root"`
	LeafCount       int       `json:"leafCount"`
	LeafHashes      []string  `json:"leafHashes,omitempty"`
	GraphSize       int       `json:"graphSize"`
	AttestedAt      time.Time `json:"attestedAt"`
}

MerkleAttestation is a content-addressed, ordering-invariant summary of a CausalGraph. Two attestations share a Root iff, after canonicalisation, the underlying graphs have identical typed causal structure (nodes, roles, weights to 6 decimal places, parents, summaries modulo whitespace/case). Root equality is therefore a mechanism-faithful equivalence relation, not a textual one.

LeafHashes is optional but recommended: it is what allows MerkleConverge to localise divergence, pointing reviewers at the specific leaves a minority of peers disagree about rather than just emitting "graphs differ".

func MerkleAttest

func MerkleAttest(graph *CausalGraph) MerkleAttestation

MerkleAttest computes the Merkle attestation for a CausalGraph using default config. A nil or empty graph produces an attestation with LeafCount=0 and a fixed sentinel Root so the empty case is still distinguishable from "never attested".

func MerkleAttestWithConfig

func MerkleAttestWithConfig(graph *CausalGraph, cfg MerkleAttestConfig) MerkleAttestation

MerkleAttestWithConfig is the configurable form of MerkleAttest.

func (MerkleAttestation) LeafSet

func (a MerkleAttestation) LeafSet() map[string]struct{}

LeafSet returns the leaf hashes as a set for divergence comparison. Returns nil for attestations that didn't carry leaf hashes.

type ModelRouter

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

ModelRouter performs deterministic provider selection. Hard gates are applied in order: capability → auth → privacy → tools → budget. Remaining candidates are soft-scored and the highest scorer is returned.

func NewModelRouter

func NewModelRouter(adapters []ProviderAdapter, broker *CredentialBroker, policy ExecutionPolicy) *ModelRouter

NewModelRouter creates a router with the given adapters and policy.

func (*ModelRouter) Route

Route selects the best available adapter for the inference request. Returns an error only if no adapter passes all hard gates.

type NestedScheduler

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

NestedScheduler wraps Scheduler to support a tree of schedule nodes. Each node may carry a prompt_injection directive that is embedded in the fired WakeSignal payload and consumed by the actor daemon as a high-weight GIST directive atom.

func NewNestedScheduler

func NewNestedScheduler(bus EventBus) *NestedScheduler

NewNestedScheduler creates a NestedScheduler backed by the given event bus.

func (*NestedScheduler) Nodes

func (n *NestedScheduler) Nodes() []ScheduleNode

Nodes returns a snapshot of all registered schedule nodes.

func (*NestedScheduler) RegisterNode

func (n *NestedScheduler) RegisterNode(ctx context.Context, node ScheduleNode) error

RegisterNode adds a node to the schedule tree and starts its cron ticker. The node's PromptInjection (if set) is embedded in every WakeSignal fired.

func (*NestedScheduler) SetPublisher

func (n *NestedScheduler) SetPublisher(fn func(context.Context, AgentSchedule, WakeSignal) error)

SetPublisher delegates to the inner Scheduler's SetPublisher.

func (*NestedScheduler) Stop

func (n *NestedScheduler) Stop()

Stop cancels all running schedule tickers.

type NodeAttribution

type NodeAttribution struct {
	NodeID      NodeID   `json:"nodeId"`
	Role        NodeRole `json:"role"`
	Phi         float64  `json:"phi"`
	Rank        int      `json:"rank"`
	Approximate bool     `json:"approximate,omitempty"`
}

NodeAttribution is the per-node Shapley/PSE value answering "how much did this node contribute to the verdict's confidence?". Phi is the Shapley value over the same value function used by the Pearl loop:

v(S) = sigmoid( sum_{n in S} roleWeight(n.Role) * n.Weight )

Positive Phi means the node pushed confidence up; negative means it pulled confidence down (typical of confounders).

func AttributeNecessity

func AttributeNecessity(graph *CausalGraph) []NodeAttribution

AttributeNecessity computes per-node Shapley values over the typed CausalGraph and returns them ranked by absolute contribution. The outcome node is excluded from the player set since it is the target, not a contributor.

For graphs up to exactShapleyMaxPlayers nodes the result is exact; for larger graphs the result is a Monte Carlo estimate flagged via NodeAttribution.Approximate = true.

type NodeDiff

type NodeDiff struct {
	NodeID     NodeID   `json:"nodeId"`
	OldRole    NodeRole `json:"oldRole,omitempty"`
	NewRole    NodeRole `json:"newRole,omitempty"`
	OldWeight  *float64 `json:"oldWeight,omitempty"`
	NewWeight  *float64 `json:"newWeight,omitempty"`
	OldSummary string   `json:"oldSummary,omitempty"`
	NewSummary string   `json:"newSummary,omitempty"`
}

NodeDiff captures the typed mutation between a base node and its sibling. Pointer-typed weight fields distinguish "no change" from "changed to zero". Empty role/summary fields mean "unchanged".

type NodeID

type NodeID string

NodeID is a stable, content-addressable identifier for a CausalNode.

type NodeReconciliation

type NodeReconciliation struct {
	NodeID          NodeID   `json:"nodeId"`
	PeerSupport     float64  `json:"peerSupport"`
	RoleAgreement   float64  `json:"roleAgreement"`
	WeightDelta     float64  `json:"weightDelta"`
	SupportingPeers []string `json:"supportingPeers,omitempty"`
}

NodeReconciliation is the per-meta-node faithfulness probe. It does NOT measure text overlap; it measures *typed structural support*: canonical leaf-hash equality first, then a relaxed (role + normalized summary + weight-within-tolerance) match for cases where peers rounded weights differently or attached extra metadata.

type NodeRole

type NodeRole string

NodeRole tags the causal function each node plays.

The four canonical roles mirror Pearl's structural causal model vocabulary:

evidence     - observation that supports or constrains the outcome
confounder   - common-cause-style atom that creates spurious dependence
intervention - do(x) action node the agent could take
outcome      - the verdict / target the chain explains

Unknown is a transitional bucket used when legacy []string causal chains are hydrated without explicit role hints. Downstream code should treat unknown as "evidence-shaped but not yet classified".

const (
	NodeRoleEvidence     NodeRole = "evidence"
	NodeRoleConfounder   NodeRole = "confounder"
	NodeRoleIntervention NodeRole = "intervention"
	NodeRoleOutcome      NodeRole = "outcome"
	NodeRoleUnknown      NodeRole = "unknown"
)

type ObservationSnapshot

type ObservationSnapshot struct {
	OrganizationID string            `json:"organizationId"`
	Actor          AgentIdentity     `json:"actor"`
	LedgerSequence int64             `json:"ledgerSequence"`
	PendingTasks   []TaskSummary     `json:"pendingTasks,omitempty"`
	RecentSignals  []WakeSignal      `json:"recentSignals,omitempty"`
	Resources      ResourceState     `json:"resources"`
	CurrentTime    time.Time         `json:"currentTime"`
	Metadata       map[string]string `json:"metadata,omitempty"`
}

type OfficeStatus

type OfficeStatus struct {
	BaseDir         string              `json:"baseDir"`
	SharedWorkplace string              `json:"sharedWorkplace"`
	RuntimeMode     RuntimeMode         `json:"runtimeMode"`
	OrganizationID  string              `json:"organizationId"`
	LedgerSequence  int64               `json:"ledgerSequence"`
	ActorCount      int                 `json:"actorCount"`
	ScheduleCount   int                 `json:"scheduleCount"`
	Running         bool                `json:"running"`
	BusBackend      string              `json:"busBackend"`
	LastSignal      *WakeSignal         `json:"lastSignal,omitempty"`
	Actors          []AgentIdentity     `json:"actors,omitempty"`
	Schedules       []AgentSchedule     `json:"schedules,omitempty"`
	Constitution    AgencyConstitution  `json:"constitution"`
	Voice           *VoiceGatewayStatus `json:"voice,omitempty"`
}

type OllamaAdapter

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

func NewOllamaAdapter

func NewOllamaAdapter() *OllamaAdapter

func (*OllamaAdapter) Available

func (o *OllamaAdapter) Available(ctx context.Context) bool

func (*OllamaAdapter) Execute

func (*OllamaAdapter) ModelID

func (o *OllamaAdapter) ModelID() string

func (*OllamaAdapter) Name

func (o *OllamaAdapter) Name() string

type OpenAIAdapter

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

func NewOpenAIAdapter

func NewOpenAIAdapter() *OpenAIAdapter

func (*OpenAIAdapter) Available

func (o *OpenAIAdapter) Available(_ context.Context) bool

func (*OpenAIAdapter) Execute

func (*OpenAIAdapter) ModelID

func (o *OpenAIAdapter) ModelID() string

func (*OpenAIAdapter) Name

func (o *OpenAIAdapter) Name() string

type OpenAICompatibleAdapter

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

func NewOpenAICompatibleAdapter

func NewOpenAICompatibleAdapter(profile ProviderProfile) *OpenAICompatibleAdapter

func (*OpenAICompatibleAdapter) Available

func (a *OpenAICompatibleAdapter) Available(ctx context.Context) bool

func (*OpenAICompatibleAdapter) Execute

func (*OpenAICompatibleAdapter) ModelID

func (a *OpenAICompatibleAdapter) ModelID() string

func (*OpenAICompatibleAdapter) Name

func (a *OpenAICompatibleAdapter) Name() string

type OrgIntent

type OrgIntent struct {
	ID           string            `json:"id"`
	Domain       string            `json:"domain"`
	TimeHorizon  string            `json:"timeHorizon"`
	WorkingStyle string            `json:"workingStyle"`
	GoalShape    string            `json:"goalShape"`
	Governance   GovernanceMode    `json:"governance"`
	Summary      string            `json:"summary"`
	Requirements []string          `json:"requirements,omitempty"`
	Metadata     map[string]string `json:"metadata,omitempty"`
}

type PearlPlan

type PearlPlan struct {
	ProtocolVersion int               `json:"protocolVersion"`
	Hypothesis      Hypothesis        `json:"hypothesis"`
	Actions         []ActionCandidate `json:"actions,omitempty"`
	Prediction      Prediction        `json:"prediction"`
}

PearlPlan packages an abduction -> action -> prediction trace produced by RunPearlLoop. It rides on GISTVerdict so downstream actors (model router, approval flow, lattice inspector) can read structured causal reasoning instead of re-deriving it from the flat causal chain.

func RunPearlLoop

func RunPearlLoop(graph *CausalGraph) *PearlPlan

RunPearlLoop orchestrates abduction -> action enumeration -> prediction over a typed CausalGraph and returns a structured PearlPlan. Returns nil for a nil or empty graph so callers can lift the result onto a verdict without a nil-check tax.

type PeerAttestation

type PeerAttestation struct {
	AgentID     string            `json:"agentId"`
	Attestation MerkleAttestation `json:"attestation"`
}

PeerAttestation pairs a per-agent attestation with the agent's ID so divergence loci can name agents.

type PeerGraph

type PeerGraph struct {
	AgentID string       `json:"agentId"`
	Graph   *CausalGraph `json:"graph"`
}

PeerGraph pairs an agent ID with that peer's typed causal graph. Used by MetaReconcile so reports can name the agents that supported each meta node.

type PerformanceRecord

type PerformanceRecord struct {
	ID             string  `json:"id"`
	OrganizationID string  `json:"organizationId"`
	ActorID        string  `json:"actorId"`
	Directive      string  `json:"directive"` // prompt_injection or signal summary
	Output         string  `json:"output"`    // LLM inference result text
	Score          float64 `json:"score"`     // GIST confidence as proxy score
	SignalID       string  `json:"signalId"`
	Provider       string  `json:"provider"`
	ModelID        string  `json:"modelId"`
	CreatedAt      int64   `json:"createdAt"`
}

PerformanceRecord captures a single directive→output→score cycle for an actor. Published to the bulletin channel so the TUI can display the timeline.

type Prediction

type Prediction struct {
	Recommended         NodeID   `json:"recommended,omitempty"`
	ProjectedConfidence float64  `json:"projectedConfidence"`
	Residual            []string `json:"residual,omitempty"`
	BlockedByConfounder bool     `json:"blockedByConfounder,omitempty"`
}

Prediction is the projected verdict-drift if Recommended is taken. ProjectedConfidence is the expected post-action confidence; Residual lists open questions that the action does NOT resolve.

func Predict

func Predict(graph *CausalGraph, h Hypothesis, candidates []ActionCandidate) Prediction

Predict produces a one-step projection of the verdict given the abduced hypothesis and the scored action candidates. If confounder load exceeds the block threshold no action is recommended and BlockedByConfounder is set so the approval surface can flag the situation.

type ProcessHandle

type ProcessHandle interface {
	PID() int
	Wait() error
	Stop(context.Context) error
}

type ProcessSpawner

type ProcessSpawner interface {
	Spawn(context.Context, ActorRuntimeSpec) (ProcessHandle, error)
}

type ProjectionDaemon

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

func NewProjectionDaemon

func NewProjectionDaemon(ledger *LedgerService, organizationID, outputPath string, interval time.Duration) *ProjectionDaemon

func (*ProjectionDaemon) Run

func (d *ProjectionDaemon) Run(ctx context.Context) error

type ProviderAdapter

type ProviderAdapter interface {
	// Name returns the provider identifier (e.g. "anthropic", "ollama").
	Name() string
	// ModelID returns the model this adapter will use.
	ModelID() string
	// Available returns true if the provider is reachable and credentials are valid.
	Available(ctx context.Context) bool
	// Execute runs a single inference and returns the result.
	Execute(ctx context.Context, req InferenceRequest) (InferenceResult, error)
}

ProviderAdapter is the interface all LLM provider adapters must implement.

func BuiltinProviderAdaptersForDirector

func BuiltinProviderAdaptersForDirector() []ProviderAdapter

type ProviderProfile

type ProviderProfile struct {
	Name           string `json:"name"`
	DisplayName    string `json:"displayName"`
	Kind           string `json:"kind"`
	Priority       string `json:"priority"`
	APIKeyEnv      string `json:"apiKeyEnv,omitempty"`
	BaseURLEnv     string `json:"baseUrlEnv,omitempty"`
	ModelEnv       string `json:"modelEnv,omitempty"`
	DefaultBaseURL string `json:"defaultBaseUrl,omitempty"`
	DefaultModel   string `json:"defaultModel"`
	Local          bool   `json:"local"`
	Adapter        bool   `json:"adapter,omitempty"`
	Notes          string `json:"notes,omitempty"`
}

func BuiltinProviderProfiles

func BuiltinProviderProfiles() []ProviderProfile

type PublicationRecord

type PublicationRecord struct {
	ID           string   `json:"id"`
	ActorID      string   `json:"actorId"`
	Target       string   `json:"target"`
	Status       string   `json:"status"`
	Summary      string   `json:"summary,omitempty"`
	ArtifactRefs []string `json:"artifactRefs,omitempty"`
	CreatedAt    int64    `json:"createdAt"`
}

type QuorumState

type QuorumState struct {
	QuorumKey         string   `json:"quorumKey,omitempty"`
	RequiredApprovals int      `json:"requiredApprovals"`
	EligibleVoters    []string `json:"eligibleVoters,omitempty"`
	Approvals         int      `json:"approvals"`
	Rejections        int      `json:"rejections"`
	MissingApprovals  int      `json:"missingApprovals,omitempty"`
	LastVoteAt        int64    `json:"lastVoteAt,omitempty"`
	Finalizable       bool     `json:"finalizable"`
	Finalized         bool     `json:"finalized"`
	Rejected          bool     `json:"rejected"`
}

type ReconciliationConfig

type ReconciliationConfig struct {
	FaithfulSupport    float64
	FaithfulCoverage   float64
	DriftThreshold     float64
	FabricatedSupport  float64
	MetaNodeMinSupport float64
	WeightTolerance    float64
}

ReconciliationConfig tunes the status thresholds. Zero values mean "use the documented default".

type ReconciliationReport

type ReconciliationReport struct {
	ProtocolVersion int                  `json:"protocolVersion"`
	Status          ReconciliationStatus `json:"status"`
	SupportScore    float64              `json:"supportScore"`
	CoverageScore   float64              `json:"coverageScore"`
	DriftScore      float64              `json:"driftScore"`
	NodeReports     []NodeReconciliation `json:"nodeReports"`
	UnsupportedIDs  []NodeID             `json:"unsupportedIDs,omitempty"`
	UncoveredIDs    []NodeID             `json:"uncoveredIDs,omitempty"`
	Notes           []string             `json:"notes,omitempty"`
}

ReconciliationReport is the output of MetaReconcile. SupportScore is the weighted mean of NodeSupport across meta nodes; CoverageScore is the fraction of peer nodes captured by the meta; DriftScore is the mean absolute weight delta. Status is derived from these via the configured thresholds.

func MetaReconcile

func MetaReconcile(meta *CausalGraph, peers []PeerGraph) ReconciliationReport

MetaReconcile compares a meta-agent's CausalGraph against the peer cohort it claims to summarize, producing a faithfulness report.

Composition: this function does NOT itself check Merkle convergence. Callers should run MerkleConverge over peers first and refuse to call MetaReconcile on a divergent cohort (asking 'did the meta faithfully summarize them?' is ill-posed when the cohort has no consensus).

func MetaReconcileWithConfig

func MetaReconcileWithConfig(meta *CausalGraph, peers []PeerGraph, cfg ReconciliationConfig) ReconciliationReport

MetaReconcileWithConfig is the configurable form. Zero-valued config fields fall back to documented defaults.

func (ReconciliationReport) IsAcceptable

func (r ReconciliationReport) IsAcceptable() bool

IsAcceptable reports whether the lattice may use this meta verdict. Faithful and drifted are acceptable (drifted with caveats); fabricated is not.

type ReconciliationStatus

type ReconciliationStatus string

ReconciliationStatus is the three-tier ladder for meta-vs-peers faithfulness:

faithful   - meta summary aligns with peer consensus
drifted    - supported but coverage is weak or weights have shifted
fabricated - at least one meta node has no peer support; lattice rejects

Lattice consumers MUST refuse to use a fabricated meta verdict and fall back to peer aggregation. Drifted is a warning, not a refusal.

const (
	ReconciliationStatusFaithful   ReconciliationStatus = "faithful"
	ReconciliationStatusDrifted    ReconciliationStatus = "drifted"
	ReconciliationStatusFabricated ReconciliationStatus = "fabricated"
)

type RedisConfig

type RedisConfig struct {
	Addr        string
	Password    string
	DB          int
	DialTimeout time.Duration
}

type RedisEventBus

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

func NewRedisEventBus

func NewRedisEventBus(cfg RedisConfig) *RedisEventBus

func (*RedisEventBus) Close

func (b *RedisEventBus) Close(ctx context.Context) error

func (*RedisEventBus) Publish

func (b *RedisEventBus) Publish(ctx context.Context, signal WakeSignal) error

func (*RedisEventBus) Subscribe

func (b *RedisEventBus) Subscribe(ctx context.Context, channel string) (<-chan WakeSignal, error)

type ResourceState

type ResourceState struct {
	SharedWorkplace string            `json:"sharedWorkplace"`
	AvailableTools  []string          `json:"availableTools,omitempty"`
	Metadata        map[string]string `json:"metadata,omitempty"`
}

type RoleSpec

type RoleSpec struct {
	Name              string            `json:"name"`
	Mission           string            `json:"mission"`
	Personality       string            `json:"personality,omitempty"`
	WorkingPosture    string            `json:"workingPosture,omitempty"`
	SystemPrompt      string            `json:"systemPrompt,omitempty"`
	AllowedActions    []ActionType      `json:"allowedActions,omitempty"`
	ObservationScopes []string          `json:"observationScopes,omitempty"`
	ToolBindings      []string          `json:"toolBindings,omitempty"`
	PeerRouting       map[string]string `json:"peerRouting,omitempty"`
	CanSpawnAgents    bool              `json:"canSpawnAgents"`
}

type RoutingDecision

type RoutingDecision struct {
	SelectedProvider string
	SelectedModel    string
	GateReason       string // empty = passed all gates
	RejectedOrder    []string
	ScoredAt         int64
}

RoutingDecision records why a provider was selected or rejected.

type RoutingLog

type RoutingLog interface {
	LogDecision(ctx context.Context, agentID, orgID string, result InferenceResult, decision RoutingDecision, intent ActionIntent) error
}

RoutingLog persists model routing decisions for audit. If nil, routing decisions are only logged to stderr.

type RuntimeConfig

type RuntimeConfig struct {
	BaseDir         string
	SharedWorkplace string
	Ledger          *LedgerService
	Bus             EventBus
	Kernel          *Kernel
	Mode            RuntimeMode
	Spawner         ProcessSpawner
}

type RuntimeManager

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

func NewRuntimeManager

func NewRuntimeManager(cfg RuntimeConfig) *RuntimeManager

func (*RuntimeManager) Actors

func (r *RuntimeManager) Actors() []AgentIdentity

func (*RuntimeManager) Register

func (r *RuntimeManager) Register(ctx context.Context, actor Actor) error

func (*RuntimeManager) RegisterSpec

func (r *RuntimeManager) RegisterSpec(ctx context.Context, spec ActorRuntimeSpec) error

func (*RuntimeManager) Running

func (r *RuntimeManager) Running() bool

func (*RuntimeManager) SetConstitution

func (r *RuntimeManager) SetConstitution(constitution AgencyConstitution)

func (*RuntimeManager) Specs

func (r *RuntimeManager) Specs() []ActorRuntimeSpec

func (*RuntimeManager) Start

func (r *RuntimeManager) Start(ctx context.Context) error

func (*RuntimeManager) Stop

func (r *RuntimeManager) Stop()

type RuntimeMode

type RuntimeMode string
const (
	RuntimeModeEmbedded   RuntimeMode = "embedded"
	RuntimeModeDaemonized RuntimeMode = "daemonized"
)

type ScheduleLayerConfig

type ScheduleLayerConfig struct {
	LayerDepth             int    `json:"layerDepth"`
	MaxNodes               int    `json:"maxNodes"`
	DefaultExpression      string `json:"defaultExpression"`
	InheritParentInjection bool   `json:"inheritParentInjection"`
}

ScheduleLayerConfig configures defaults for a depth level in the schedule tree.

type ScheduleNode

type ScheduleNode struct {
	ID              string            `json:"id"`
	OrganizationID  string            `json:"organizationId"`
	ActorID         string            `json:"actorId"`
	ParentID        string            `json:"parentId,omitempty"`
	Expression      string            `json:"expression"`
	PromptInjection string            `json:"promptInjection,omitempty"`
	Layer           int               `json:"layer"`
	Enabled         bool              `json:"enabled"`
	Metadata        map[string]string `json:"metadata,omitempty"`
	CreatedAt       int64             `json:"createdAt"`
	UpdatedAt       int64             `json:"updatedAt"`
}

ScheduleNode is a single node in the nested temporal schedule tree. Each node can carry a prompt_injection directive that is added as a high-weight GIST atom when the schedule fires.

type Scheduler

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

func NewScheduler

func NewScheduler(bus EventBus) *Scheduler

func (*Scheduler) Register

func (s *Scheduler) Register(ctx context.Context, schedule AgentSchedule, base WakeSignal) error

func (*Scheduler) Schedules

func (s *Scheduler) Schedules() []AgentSchedule

func (*Scheduler) SetPublisher

func (s *Scheduler) SetPublisher(fn func(context.Context, AgentSchedule, WakeSignal) error)

func (*Scheduler) Stop

func (s *Scheduler) Stop()

type Service

type Service struct {
	Ledger    *LedgerService
	Bus       EventBus
	Kernel    *Kernel
	Scheduler *Scheduler
	Runtime   *RuntimeManager
	Voice     *VoiceGateway
	// contains filtered or unexported fields
}

func NewService

func NewService(ctx context.Context, cfg Config) (*Service, error)

func (*Service) PublishSignal

func (s *Service) PublishSignal(ctx context.Context, signal WakeSignal) error

func (*Service) RegisterActor

func (s *Service) RegisterActor(ctx context.Context, actor Actor) error

func (*Service) RegisterSchedule

func (s *Service) RegisterSchedule(ctx context.Context, schedule AgentSchedule) error

func (*Service) Shutdown

func (s *Service) Shutdown(ctx context.Context) error

func (*Service) Snapshot

func (s *Service) Snapshot(ctx context.Context, organizationID string) (*ContextSnapshot, error)

func (*Service) StartCoordinator

func (s *Service) StartCoordinator(ctx context.Context, constitution AgencyConstitution) error

func (*Service) StartOffice

func (s *Service) StartOffice(ctx context.Context, constitution AgencyConstitution) error

func (*Service) StartRuntime

func (s *Service) StartRuntime(ctx context.Context, constitution AgencyConstitution) error

func (*Service) StartScheduler

func (s *Service) StartScheduler(ctx context.Context, organizationID string) error

func (*Service) Status

func (s *Service) Status(ctx context.Context, organizationID string) (OfficeStatus, error)

type ServiceRole

type ServiceRole string
const (
	ServiceRoleOfficeCoordinator ServiceRole = "office-coordinator"
	ServiceRoleRuntimeDaemon     ServiceRole = "runtime-daemon"
	ServiceRoleSchedulerDaemon   ServiceRole = "scheduler-daemon"
	ServiceRoleActorDaemon       ServiceRole = "actor-daemon"
)

type ShiftHandoff

type ShiftHandoff struct {
	ID          string   `json:"id"`
	FromActorID string   `json:"fromActorId"`
	ToActorID   string   `json:"toActorId"`
	Summary     string   `json:"summary"`
	OpenTasks   []string `json:"openTasks,omitempty"`
	CreatedAt   int64    `json:"createdAt"`
}

type SignalKind

type SignalKind string
const (
	SignalTick        SignalKind = "tick"
	SignalSchedule    SignalKind = "schedule"
	SignalPeerMessage SignalKind = "peer_message"
	SignalTaskChange  SignalKind = "task_change"
	SignalReview      SignalKind = "review"
	SignalCorrection  SignalKind = "correction"
	SignalBroadcast   SignalKind = "broadcast"
	SignalVoice       SignalKind = "voice"
	SignalProjection  SignalKind = "projection"
	SignalDirector    SignalKind = "director"
)

type SpawnLineage

type SpawnLineage struct {
	ParentActorID string `json:"parentActorId"`
	ChildActorID  string `json:"childActorId"`
	RootActorID   string `json:"rootActorId"`
	Depth         int    `json:"depth"`
	SpawnedAt     int64  `json:"spawnedAt"`
}

type SpeculativeBuildInput

type SpeculativeBuildInput struct {
	CohortID string
	Verdicts []LabeledVerdict
	Meta     *LabeledVerdict
}

SpeculativeBuildInput is the source data BuildSpeculativeBundle consumes. Verdicts is the cohort; Meta is optional. CohortID is a caller-supplied label; if empty, BuildSpeculativeBundle derives a stable hash of the cohort's Merkle roots so the same cohort always produces the same id.

type SpeculativeBundle

type SpeculativeBundle struct {
	ProtocolVersion int    `json:"protocolVersion"`
	CohortID        string `json:"cohortId,omitempty"`

	// Peers is the cohort under review, with each peer's typed
	// CausalGraph and Merkle attestation embedded so the cathedral
	// can render geometry without follow-up lookups.
	Peers []SpeculativePeer `json:"peers,omitempty"`

	// Meta is the aggregator graph (optional). When present the
	// cathedral renders a meta tile above the cohort floor.
	Meta *SpeculativeMeta `json:"meta,omitempty"`

	// Convergence is the cohort-level Merkle gate report. Required.
	Convergence *ConvergenceReport `json:"convergence,omitempty"`
	// Reconciliation is the meta-vs-peers fidelity report.
	// nil when there is no meta in the cohort.
	Reconciliation *ReconciliationReport `json:"reconciliation,omitempty"`
	// Dyads is the Hamming-1 compression report. Always present;
	// SlotsAfter==SlotsBefore means no pairs were eligible.
	Dyads *DyadCompressionReport `json:"dyads,omitempty"`
}

SpeculativeBundle is the persisted projection of a speculative-tier cohort review: peer attestations, optional meta graph, convergence, reconciliation, and dyad compression report. It is the geometry payload the Lattice Cathedral renders.

The bundle is denormalised on purpose so that the cathedral can be rendered from a single SELECT without re-running the kernel and so historic rows (missing the bundle) degrade gracefully.

func BuildSpeculativeBundle

func BuildSpeculativeBundle(in SpeculativeBuildInput) *SpeculativeBundle

BuildSpeculativeBundle composes a SpeculativeBundle from a cohort of LabeledVerdicts. It runs MerkleAttest on every graph, MerkleConverge on the cohort, MetaReconcile if a meta is supplied, and DyadCompress on the cohort. The returned bundle's Peers slice mirrors the input order; consensus-bucket membership is mirrored from the convergence report onto each peer's InCohort flag.

Returns nil if the cohort is empty.

func ParseSpeculativeBundle

func ParseSpeculativeBundle(raw string) (*SpeculativeBundle, error)

ParseSpeculativeBundle parses a persisted speculative_json blob. Empty / "{}" / "null" returns (nil, nil) so callers can distinguish "no bundle stored" from a parse error.

func (*SpeculativeBundle) CohortAgentIDs

func (b *SpeculativeBundle) CohortAgentIDs() []string

CohortAgentIDs returns the AgentIDs of the cohort in input order. Used by the cathedral renderer for tile layout.

func (*SpeculativeBundle) HeadlineStatus

func (b *SpeculativeBundle) HeadlineStatus() string

HeadlineStatus collapses the bundle's three signals into a single human label the inspector can render in a status pill. Order of precedence: convergence gate first (the cohort must agree before reconciliation matters), then reconciliation, then dyad savings.

type SpeculativeFetcher

type SpeculativeFetcher interface {
	GetSpeculativeBundle(ctx context.Context, traceID string) (*SpeculativeBundle, error)
}

SpeculativeFetcher is the optional capability the cathedral route requires from a GISTTraceFetcher: read the persisted SpeculativeBundle for a given trace id. It is split out so callers can implement GISTTraceFetcher without breaking the lattice inspector when they haven't wired speculative storage yet.

The cathedral handler type-asserts on this interface and falls back to an embedded demo cohort if either the assertion fails or the fetched bundle is nil.

type SpeculativeMeta

type SpeculativeMeta struct {
	AgentID     string            `json:"agentId"`
	Verdict     string            `json:"verdict,omitempty"`
	Confidence  float64           `json:"confidence,omitempty"`
	Graph       *CausalGraph      `json:"graph,omitempty"`
	Attestation MerkleAttestation `json:"attestation"`
}

SpeculativeMeta is the optional aggregator/director projection. Reconciliation is computed against this graph; geometry-wise it floats above the cohort tiles in the cathedral.

type SpeculativePeer

type SpeculativePeer struct {
	AgentID     string            `json:"agentId"`
	Verdict     string            `json:"verdict,omitempty"`
	Confidence  float64           `json:"confidence,omitempty"`
	Graph       *CausalGraph      `json:"graph,omitempty"`
	Attestation MerkleAttestation `json:"attestation"`
	InCohort    bool              `json:"inCohort"`
}

SpeculativePeer is one cohort member, ready to be drawn as a tile in the cathedral. InCohort marks consensus-bucket membership so the renderer can colour-code dissenters separately from the agreeing majority. Verdict / Confidence headline data is included so the JSON-only API can render without rehydrating the full GIST envelope.

type SpeechRuntimeConfig

type SpeechRuntimeConfig struct {
	Enabled     bool
	Command     string
	Args        []string
	InputMode   string
	OutputMode  string
	Language    string
	Voice       string
	AudioFormat string
	Timeout     time.Duration
}

type TaskSummary

type TaskSummary struct {
	ID       string `json:"id"`
	Title    string `json:"title"`
	Status   string `json:"status"`
	Assigned string `json:"assigned,omitempty"`
}

type VoiceEvent

type VoiceEvent struct {
	ID             string            `json:"id"`
	OrganizationID string            `json:"organizationId"`
	ActorID        string            `json:"actorId,omitempty"`
	RoomID         string            `json:"roomId,omitempty"`
	Kind           VoiceEventKind    `json:"kind"`
	CanonicalText  string            `json:"canonicalText,omitempty"`
	AudioInputRef  string            `json:"audioInputRef,omitempty"`
	AudioOutputRef string            `json:"audioOutputRef,omitempty"`
	Engine         string            `json:"engine,omitempty"`
	Projection     *VoiceRoomState   `json:"projection,omitempty"`
	Metadata       map[string]string `json:"metadata,omitempty"`
	CreatedAt      int64             `json:"createdAt"`
}

type VoiceEventKind

type VoiceEventKind string
const (
	VoiceEventTranscript VoiceEventKind = "transcript"
	VoiceEventSynthesis  VoiceEventKind = "synthesis"
	VoiceEventProjection VoiceEventKind = "projection"
)

type VoiceGateway

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

func NewVoiceGateway

func NewVoiceGateway(cfg VoiceGatewayConfig, ledger *LedgerService, bus EventBus) *VoiceGateway

func (*VoiceGateway) IngestTranscript

func (*VoiceGateway) Serve

func (g *VoiceGateway) Serve(ctx context.Context, organizationID string) error

func (*VoiceGateway) SetProjection

func (*VoiceGateway) Status

func (g *VoiceGateway) Status(ctx context.Context, organizationID string) (VoiceGatewayStatus, error)

func (*VoiceGateway) Synthesize

type VoiceGatewayConfig

type VoiceGatewayConfig struct {
	Enabled              bool
	Provider             string
	StatePath            string
	AssetDir             string
	ControlChannel       string
	SynthesisChannel     string
	MeetingTranscriptDir string
	DefaultRoom          string
	Projection           VoiceProjectionDefaults
	STT                  SpeechRuntimeConfig
	TTS                  SpeechRuntimeConfig
}

type VoiceGatewayStatus

type VoiceGatewayStatus struct {
	Enabled              bool             `json:"enabled"`
	Provider             string           `json:"provider,omitempty"`
	OrganizationID       string           `json:"organizationId"`
	StatePath            string           `json:"statePath"`
	AssetDir             string           `json:"assetDir"`
	ControlChannel       string           `json:"controlChannel"`
	SynthesisChannel     string           `json:"synthesisChannel"`
	MeetingTranscriptDir string           `json:"meetingTranscriptDir"`
	DefaultRoom          string           `json:"defaultRoom"`
	STTConfigured        bool             `json:"sttConfigured"`
	TTSConfigured        bool             `json:"ttsConfigured"`
	Rooms                []VoiceRoomState `json:"rooms,omitempty"`
	LastVoiceEvent       *VoiceEvent      `json:"lastVoiceEvent,omitempty"`
}

type VoiceProjectionDefaults

type VoiceProjectionDefaults struct {
	TranscriptProjection  bool
	AudioProjection       bool
	AutoProjectTranscript bool
	AutoProjectSynthesis  bool
}

type VoiceProjectionRequest

type VoiceProjectionRequest struct {
	OrganizationID       string
	RoomID               string
	ProjectionEnabled    bool
	TranscriptProjection *bool
	AudioProjection      *bool
	Metadata             map[string]string
}

type VoiceRoomState

type VoiceRoomState struct {
	RoomID               string            `json:"roomId"`
	ProjectionEnabled    bool              `json:"projectionEnabled"`
	TranscriptProjection bool              `json:"transcriptProjection"`
	AudioProjection      bool              `json:"audioProjection"`
	LastTranscriptID     string            `json:"lastTranscriptId,omitempty"`
	LastSynthesisID      string            `json:"lastSynthesisId,omitempty"`
	Metadata             map[string]string `json:"metadata,omitempty"`
	UpdatedAt            int64             `json:"updatedAt"`
}

type VoiceSynthesisRequest

type VoiceSynthesisRequest struct {
	OrganizationID string
	ActorID        string
	RoomID         string
	Text           string
	OutputPath     string
	Metadata       map[string]string
}

type VoiceSynthesisResult

type VoiceSynthesisResult struct {
	Event       VoiceEvent        `json:"event"`
	Certificate CommitCertificate `json:"certificate"`
	Room        VoiceRoomState    `json:"room"`
}

type VoiceTranscriptRequest

type VoiceTranscriptRequest struct {
	OrganizationID string
	ActorID        string
	RoomID         string
	Text           string
	AudioPath      string
	Metadata       map[string]string
}

type VoiceTranscriptResult

type VoiceTranscriptResult struct {
	Event       VoiceEvent        `json:"event"`
	Certificate CommitCertificate `json:"certificate"`
	Room        VoiceRoomState    `json:"room"`
}

type WakeSignal

type WakeSignal struct {
	ID             string            `json:"id"`
	OrganizationID string            `json:"organizationId"`
	ActorID        string            `json:"actorId,omitempty"`
	Channel        string            `json:"channel"`
	Kind           SignalKind        `json:"kind"`
	Payload        map[string]string `json:"payload,omitempty"`
	CreatedAt      int64             `json:"createdAt"`
}

Directories

Path Synopsis
cmd
actor-daemon command
director-daemon command
ipc-server command
office-daemon command
runtime-daemon command

Jump to

Keyboard shortcuts

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