Documentation
¶
Overview ¶
Package evolution — Gap 4: Evolution Control Protocol (ECP).
ECP is the protocol for cross-instance knowledge sharing. It defines the message types, serialization, and aggregation primitives that enable multiple agent instances to share learned skills and patterns. Without ECP, evolution is siloed to a single device. With ECP, the agent's knowledge compounds across every user and every session.
Protocol layers:
ECP/1.0 — Core types and serialization (this file) ECP/1.1 — Federation and trust model ECP/1.2 — Peer discovery and synchronization
This file implements ECP/1.0: the type system and transport-neutral message definitions. The actual transport (HTTP, WebSocket, gRPC) is implemented by the caller.
Package evolution automatically extracts experiences from agent turns and generates skill candidates. This is OK's self-evolution engine.
Architecture:
OnTurnComplete hook (called from agent.Run after each turn) → saveEpisodicMemory() — save turn summary as memory → detectPatterns() — scan recent memory for repeatable patterns → saveSkillCandidate() — when pattern repeats, propose skill
Efficiency: episodic memories are buffered in memory and flushed to disk only every 3 turns, reducing I/O by ~66%.
Package evolution — P2: Automated forgetting mechanism.
Low-value memories decay over time. The forgetter periodically:
- Ages episodic memories: deletes entries older than maxAge
- Ages candidates: marks old pending-review candidates as "stale"
- Limits total episodic count: keeps only the most recent N entries
Package evolution — kernel.Learn interface implementation.
This file makes evolution.Engine implement kernel.Learn, unifying the two previously separate evolution paths:
- learnAdapter (adapters.go) — called by LLM via the "learn" tool
- evolution.Engine — called by OnTurnComplete hook automatically
After this unification, learnAdapter delegates to evolution.Engine, so both manual (LLM) and automatic (hook) evolution share one engine.
Package evolution — Gap 3: Sandbox execution validation.
Replaces the weak validatePattern (episodic memory keyword check) with layered skill validation:
Layer 0 — Structural validation (zero-LLM, always available):
Checks skill body completeness: frontmatter, required sections.
Stricter than skill.ValidateStructure — requires evolution-specific
sections ("## When to Use", "## Steps", "## Verification").
Layer 1 — Safety pattern scanning:
Delegates to skill.ValidateSafety — the canonical implementation
shared with Store.parse() so hand-written skills are also checked.
Layer 2 — LLM safety review (Learn tool path, provider available).
This file is referenced by learn_interface.go as the P1 smart closure component of the self-evolution engine.
Package evolution — P2: Active forgetting via usage-based scoring.
Replaces the pure time-decay model with a weighted scoring system. Candidates are scored on two axes using file metadata and content heuristics:
recency — how recently was the candidate modified? (weight 0.5) activity — how many times has the pattern recurred? (weight 0.5)
Items scoring below the retention threshold are candidates for forgetting.
Package evolution — Gap 1: Semantic pattern recognition.
Replaces the pure keyword-frequency approach (findPatterns) with a layered detection system:
Layer 0 — Workflow signatures (zero-LLM, always available):
Pre-defined workflow patterns matched against tool sequences + context
hints. Catches "TDD workflow", "search-then-edit", "audit-before-deploy"
etc. without any LLM call.
Layer 1 — Semantic analysis (LLM-driven, via Learn tool path):
When a provider is available, the episodic corpus is analyzed by the
LLM to extract abstract patterns ("user prefers incremental commits",
"security review always precedes deployment"). This is the Learn
interface's Extract path.
Layer 2 — Cross-turn narrative patterns (zero-LLM):
Aggregates tool frequency + sequence + temporal proximity into a
"workflow fingerprint" that captures more signal than isolated counts.
Package evolution — Gap 2: Intelligent skill synthesis.
Replaces the template-based generateSkillBody with a layered approach:
Layer 0 (automatic hook path, zero-LLM):
generateSkillBody produces structured playbooks from detected patterns.
This is the existing function, now enhanced with workflow-aware
descriptions.
Layer 1 (Learn tool path, LLM-driven):
SynthesizeSkill sends patterns + episodic context to the LLM and
receives a high-quality skill prompt that captures:
- When to invoke the skill
- Step-by-step workflow
- Expected outcomes and verification steps
- Common pitfalls and edge cases
The resulting skill is usable immediately — not just a skeleton, but a real instruction set the agent can follow.
Package evolution — ECP/1.1: Federation transport layer.
ECP/1.0 defined types and serialization. ECP/1.1 adds the ability for agent instances to discover each other, exchange knowledge updates, and merge learned skills — turning single-device evolution into a federated learning network.
This file implements:
- ECPTransport: transport-agnostic interface for push/pull
- HTTPPeer: HTTP-based peer client (the reference implementation)
- Federator: orchestrates peer sync on a schedule
Package evolution — P1: Skill auto-validation and auto-merging.
Index ¶
- func BuildSafetyReviewPrompt(req SafetyReviewRequest) string
- func DefaultAcceptPolicy(p ECPSkillPacket) bool
- func KnownTools() []string
- func MarshalPatternsForLLM(patterns []string) string
- func ServeECP(mux *http.ServeMux, eng *Engine)deprecated
- func ServeECPWithSecret(mux *http.ServeMux, eng *Engine, sharedSecret string)
- func SynthesizeBody(req SynthesisRequest) string
- func SynthesizePrompt(req SynthesisRequest) string
- func ValidateSkill(body string, knownTools []string) error
- func ValidateSkillReferences(body string, knownTools []string) error
- func ValidateSkillSafety(body string) error
- func ValidateSkillStructure(body string) error
- type AnalyzeRequest
- type ECPKnowledgeUpdate
- type ECPManifest
- type ECPMergeResult
- type ECPPeerStats
- type ECPSkillPacket
- type ECPTransport
- type Engine
- func (e *Engine) Extract(_ context.Context, task kernel.TaskRecord) ([]kernel.Pattern, error)
- func (e *Engine) Generate(_ context.Context, patterns []kernel.Pattern) (kernel.Skill, error)
- func (e *Engine) OnTurnComplete(ctx context.Context, input, output string)
- func (e *Engine) Publish(_ context.Context, skill kernel.Skill) error
- func (e *Engine) Stats(_ context.Context) kernel.LearnStats
- func (e *Engine) Validate(_ context.Context, skill kernel.Skill) error
- type Federator
- type FederatorConfig
- type HTTPPeer
- type SafetyReviewRequest
- type SafetyReviewResult
- type SemanticInsight
- type SkillInfo
- type SkillInstaller
- type SynthesisRequest
- type SynthesisResult
- type WorkflowSignature
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildSafetyReviewPrompt ¶
func BuildSafetyReviewPrompt(req SafetyReviewRequest) string
BuildSafetyReviewPrompt creates the LLM prompt for safety review.
func DefaultAcceptPolicy ¶
func DefaultAcceptPolicy(p ECPSkillPacket) bool
DefaultAcceptPolicy accepts skills with confidence >= 0.6 and no dangerous patterns in the body.
func KnownTools ¶
func KnownTools() []string
KnownTools returns the canonical set of tool names a skill may reference. Delegates to skill.KnownTools.
func MarshalPatternsForLLM ¶
MarshalPatternsForLLM serializes patterns to a JSON string suitable for the LLM context. Used by the Learn tool path.
func ServeECP
deprecated
ServeECP registers ECP endpoints on an HTTP mux. The evolution engine provides the knowledge to serve; the skill store receives pushed skills.
Usage:
mux := http.NewServeMux() ecp.ServeECP(mux, engine, skillStore)
Deprecated: use ServeECPWithSecret to enable peer authentication.
func ServeECPWithSecret ¶
ServeECPWithSecret registers ECP endpoints on an HTTP mux with peer authentication via HMAC shared secret. When sharedSecret is empty, HMAC verification is disabled (open federation).
func SynthesizeBody ¶
func SynthesizeBody(req SynthesisRequest) string
SynthesizeBody generates a skill body from patterns using the LLM. The provider argument is optional — when nil, falls back to enhanced template generation (Layer 0).
This is the Layer 1 path, called via the Learn tool when a provider is available.
func SynthesizePrompt ¶
func SynthesizePrompt(req SynthesisRequest) string
SynthesizePrompt returns the prompt to send to the LLM. The response should be the full skill body.
func ValidateSkill ¶
ValidateSkill runs all validation layers against a skill.
func ValidateSkillReferences ¶
ValidateSkillReferences checks that the skill body only references known tool names. Delegates to skill.ValidateReferences.
func ValidateSkillSafety ¶
ValidateSkillSafety scans the skill body for dangerous shell patterns. Delegates to skill.ValidateSafety.
func ValidateSkillStructure ¶
ValidateSkillStructure checks a skill body for structural completeness. Stricter than the skill-package version: requires evolution-generated sections ("## When to Use", "## Steps", "## Verification").
Types ¶
type AnalyzeRequest ¶
type AnalyzeRequest struct {
Entries []string `json:"entries"` // recent episodic memory entries
MaxN int `json:"maxN"` // max insights to return
}
AnalyzeRequest is the input to LLM-driven semantic analysis.
type ECPKnowledgeUpdate ¶
type ECPKnowledgeUpdate struct {
ID string `json:"id"`
PeerInstance string `json:"peerInstance"`
GeneratedAt time.Time `json:"generatedAt"`
Skills []ECPSkillPacket `json:"skills"`
Stats ECPPeerStats `json:"stats"`
SequenceNum int64 `json:"sequenceNum"` // monotonic update counter
}
ECPKnowledgeUpdate is an aggregated knowledge snapshot from a peer instance. It carries multiple skill packets and usage statistics.
func UnmarshalKnowledgeUpdate ¶
func UnmarshalKnowledgeUpdate(data []byte) (ECPKnowledgeUpdate, error)
UnmarshalKnowledgeUpdate deserializes a knowledge update.
func (ECPKnowledgeUpdate) Marshal ¶
func (u ECPKnowledgeUpdate) Marshal() ([]byte, error)
MarshalKnowledgeUpdate serializes a knowledge update.
type ECPManifest ¶
type ECPManifest struct {
Instance string `json:"instance"`
Version string `json:"version"`
GeneratedAt time.Time `json:"generatedAt"`
SequenceNum int64 `json:"sequenceNum"`
SkillCount int `json:"skillCount"`
SkillNames []string `json:"skillNames"` // for lightweight discovery
TopTags []string `json:"topTags"` // for topic-based filtering
LastUpdate time.Time `json:"lastUpdate"`
}
ECPManifest describes what knowledge a peer has available for sharing. Used during peer discovery to decide what to sync.
func (ECPManifest) Marshal ¶
func (m ECPManifest) Marshal() ([]byte, error)
MarshalManifest serializes a manifest.
type ECPMergeResult ¶
type ECPMergeResult struct {
NewSkills int `json:"newSkills"` // skills installed for the first time
UpdatedSkills int `json:"updatedSkills"` // skills that were refreshed
RejectedSkills int `json:"rejectedSkills"` // skills rejected (unsafe, duplicate, etc.)
Conflicts []string `json:"conflicts"` // skills that conflicted with local versions
}
ECPMergeResult describes the outcome of merging knowledge from a peer.
func MergeKnowledge ¶
func MergeKnowledge( update ECPKnowledgeUpdate, existingNames map[string]bool, acceptFn func(ECPSkillPacket) bool, installFn func(ECPSkillPacket) error, ) ECPMergeResult
MergeKnowledge aggregates skills from a peer update into a local skill set. Returns the merge result describing what was installed/updated/rejected.
acceptFn is called for each skill before installation. If it returns false, the skill is rejected. This allows the caller to enforce acceptance policies (e.g., only accept skills with confidence >= 0.7, only from trusted peers).
type ECPPeerStats ¶
type ECPPeerStats struct {
TotalSkills int `json:"totalSkills"`
TotalExtractions int64 `json:"totalExtractions"`
AvgConfidence float64 `json:"avgConfidence"`
UptimeHours float64 `json:"uptimeHours"`
TopWorkflows []string `json:"topWorkflows"` // most frequent workflow names
}
ECPPeerStats carries aggregate statistics about a peer's evolution.
type ECPSkillPacket ¶
type ECPSkillPacket struct {
// Header — routing and integrity.
ID string `json:"id"` // unique packet ID (SHA-256 of body)
Version string `json:"version"` // ECP protocol version ("1.0")
CreatedAt time.Time `json:"createdAt"` // when this packet was created
// Origin — where the skill came from.
OriginInstance string `json:"originInstance"` // agent instance identifier
OriginUserHash string `json:"originUserHash"` // SHA-256 of user ID (privacy-preserving)
OriginOS string `json:"originOS"` // "windows/amd64", "linux/arm64"
OriginVersion string `json:"originVersion"` // agent version that generated this
// Payload — the skill itself.
SkillName string `json:"skillName"`
SkillDescription string `json:"skillDescription"`
SkillBody string `json:"skillBody"`
Patterns []string `json:"patterns"` // detected patterns that triggered generation
Confidence float64 `json:"confidence"` // 0.0–1.0, how confident the generator was
// Integrity.
IntegrityHash string `json:"integrityHash"` // SHA-256 of the skill body
// Privacy flags.
Tags []string `json:"tags"` // categorization tags
Deprecated bool `json:"deprecated"` // true when superseded by a newer version
}
ECPSkillPacket is a skill packaged for transmission between agent instances. It carries the skill body, metadata, and integrity proof.
func NewECPSkillPacket ¶
func NewECPSkillPacket( instance, userID, osArch, agentVersion string, name, description, body string, patterns []string, confidence float64, ) ECPSkillPacket
NewECPSkillPacket creates a new skill packet ready for transmission. The originUserHash is a SHA-256 of the user ID — the raw ID never leaves the local instance.
func UnmarshalECPPacket ¶
func UnmarshalECPPacket(data []byte) (ECPSkillPacket, error)
UnmarshalECPPacket deserializes a skill packet from JSON.
func (ECPSkillPacket) Marshal ¶
func (p ECPSkillPacket) Marshal() ([]byte, error)
Marshal serializes a skill packet to JSON.
func (ECPSkillPacket) Verify ¶
func (p ECPSkillPacket) Verify() error
Verify checks the packet's integrity hash against its skill body.
type ECPTransport ¶
type ECPTransport interface {
// Push sends a knowledge update to a peer. The peer may accept, reject,
// or merge the update at its discretion. Returns the peer's response
// describing what was done.
Push(ctx context.Context, peerURL string, update ECPKnowledgeUpdate) (ECPMergeResult, error)
// Pull fetches a peer's knowledge manifest and (optionally) the full
// update. When manifestOnly is true, only the lightweight manifest is
// returned — useful for discovery. Otherwise, the full update is fetched.
Pull(ctx context.Context, peerURL string) (ECPKnowledgeUpdate, error)
// PullManifest fetches only the lightweight manifest from a peer.
// Used during discovery to decide whether a full pull is worthwhile.
PullManifest(ctx context.Context, peerURL string) (ECPManifest, error)
}
ECPTransport abstracts how knowledge updates move between agent instances. Implementations can use HTTP, gRPC, WebSocket, or even file-based sync.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is the self-evolution engine. Zero value is safe (no-op).
func (*Engine) Extract ¶
Extract analyzes a completed task and returns patterns. Satisfies kernel.Learn.Extract.
func (*Engine) Generate ¶
Generate creates a candidate skill from successful patterns using the enhanced synthesis pipeline (Gap 2). When pattern context is available, it produces a rich playbook; otherwise falls back to template generation. Satisfies kernel.Learn.Generate.
func (*Engine) OnTurnComplete ¶
OnTurnComplete is called by the agent after each completed turn. Episodic data is buffered in memory and flushed to disk every 3 turns.
func (*Engine) Publish ¶
Publish makes a validated skill available to the agent's skill store. Satisfies kernel.Learn.Publish.
func (*Engine) Stats ¶
func (e *Engine) Stats(_ context.Context) kernel.LearnStats
Stats returns learning metrics. Satisfies kernel.Learn.Stats.
type Federator ¶
type Federator struct {
// contains filtered or unexported fields
}
Federator orchestrates knowledge exchange with a set of peer instances. It periodically pulls from configured peers, merges their knowledge, and makes the local skill set available for others to pull.
The zero value is safe — Start is a no-op when no peers are configured.
func NewFederator ¶
func NewFederator(cfg FederatorConfig) *Federator
NewFederator creates a federator. Pass nil transport to use the default HTTP transport with 30s timeout.
func (*Federator) Start ¶
func (f *Federator) Start()
Start begins periodic federation. Runs the first sync immediately, then every interval. Call Stop to shut down.
type FederatorConfig ¶
type FederatorConfig struct {
Transport ECPTransport
Peers []string
Interval time.Duration // sync interval; default 1h
InstanceID string
SkillStore SkillInstaller
ExistingSkills func() []string
}
FederatorConfig configures the federation loop.
type HTTPPeer ¶
type HTTPPeer struct {
// contains filtered or unexported fields
}
HTTPPeer implements ECPTransport over plain HTTP. It is the reference transport for ECP/1.1.
Endpoints (on the peer server):
GET /ecp/manifest → ECPManifest GET /ecp/skills → ECPKnowledgeUpdate POST /ecp/skills → accept ECPKnowledgeUpdate, return ECPMergeResult
When SharedSecret is non-empty, requests include an X-ECP-HMAC header computed as HMAC-SHA256 of the request body (or URL path for GET requests) so the peer can authenticate the caller.
func NewHTTPPeer ¶
NewHTTPPeer creates an HTTP transport with the given timeout.
func (*HTTPPeer) PullManifest ¶
func (*HTTPPeer) Push ¶
func (h *HTTPPeer) Push(ctx context.Context, peerURL string, update ECPKnowledgeUpdate) (ECPMergeResult, error)
type SafetyReviewRequest ¶
type SafetyReviewRequest struct {
SkillName string `json:"skillName"`
SkillBody string `json:"skillBody"`
}
SafetyReviewRequest is the input for LLM-based skill safety review.
type SafetyReviewResult ¶
type SafetyReviewResult struct {
Safe bool `json:"safe"`
Issues []string `json:"issues,omitempty"`
Summary string `json:"summary"`
}
SafetyReviewResult is the LLM's verdict on skill safety.
type SemanticInsight ¶
type SemanticInsight struct {
Pattern string `json:"pattern"` // e.g. "incremental-commit"
Description string `json:"description"` // e.g. "User commits after every file edit"
Confidence float64 `json:"confidence"` // 0.0–1.0
Evidence string `json:"evidence"` // supporting episodic entries
}
SemanticInsight is a high-level pattern extracted by LLM analysis of episodic memory. Unlike raw tool counts, these carry human-readable descriptions of abstract workflows.
type SkillInstaller ¶
SkillInstaller abstracts skill installation so the federator doesn't depend on the concrete skill.Store.
type SynthesisRequest ¶
type SynthesisRequest struct {
Name string `json:"name"` // proposed skill name
Patterns []string `json:"patterns"` // detected patterns
Context []string `json:"context"` // recent episodic entries for context
Workflows []string `json:"workflows"` // detected workflow names
ToolNames []string `json:"toolNames"` // tools involved
}
SynthesisRequest is the input to LLM-driven skill synthesis.
type SynthesisResult ¶
type SynthesisResult struct {
Name string `json:"name"`
Description string `json:"description"`
Body string `json:"body"` // full skill markdown body
}
SynthesisResult is the output of LLM-driven skill synthesis.
func DecodeSynthesisResult ¶
func DecodeSynthesisResult(response string) SynthesisResult
DecodeSynthesisResult parses an LLM response into a SynthesisResult. The response is expected to be a markdown skill body; we extract the frontmatter to populate Name and Description.
type WorkflowSignature ¶
type WorkflowSignature struct {
Name string // e.g. "tdd", "search-then-edit"
Description string // human-readable explanation
Tools []string // ordered tools that must appear in sequence
MinHits int // minimum occurrences to trigger (default 2)
}
WorkflowSignature describes a named, repeatable workflow pattern. Signatures are matched against tool call sequences across episodic entries. This is Layer 0 — zero LLM cost, always active.