Documentation
¶
Overview ¶
Package knight implements the background auto-evolution agent. Knight runs during idle time in daemon mode, analyzing sessions, creating and validating skills, generating tests, and maintaining project health.
Index ¶
- Constants
- Variables
- func CheckDuplicate(entry *SkillEntry, existing []*SkillEntry) bool
- func FormatLockMessage(pid int) string
- func FormatSkillRefForDisplay(scope, name string) string
- func LockHeldBy(projDir string) (int, error)
- type ABReplayResult
- type AgentFactory
- type AgentRunner
- type AnalysisResult
- type AutoPolicy
- type AutoPromoteEvalLogEntry
- type Budget
- type CandidateQueue
- type EmitSeverity
- type Emitter
- type EventSink
- type FuncSink
- type Knight
- func (k *Knight) ApproveProposal(id, note string) (ProjectImprovementProposal, error)
- func (k *Knight) AutoPolicies() []AutoPolicy
- func (k *Knight) BudgetStatus() (used int, remaining int, limit int)
- func (k *Knight) CanPerformTask() bool
- func (k *Knight) ClearRejectFeedback() error
- func (k *Knight) ClearSkillScenarios() error
- func (k *Knight) DeleteSkill(name string) error
- func (k *Knight) FindActiveSkill(ref string) (*SkillEntry, error)
- func (k *Knight) FindStagingSkill(ref string) (*SkillEntry, error)
- func (k *Knight) GenerateProjectImprovementProposal(ctx context.Context, goal string) (ProjectImprovementProposal, TaskResult, error)
- func (k *Knight) Index() *SkillIndex
- func (k *Knight) NotifyActivity()
- func (k *Knight) PerformSkillAnalysis(ctx context.Context) error
- func (k *Knight) PerformSkillValidation(ctx context.Context) ([]ValidationResult, error)
- func (k *Knight) PromoteStaging(skillName string) error
- func (k *Knight) PromoteStagingByPath(path string) error
- func (k *Knight) Queue() *CandidateQueue
- func (k *Knight) ReadProjectImprovementProposal(id string) (ProjectImprovementProposal, string, error)
- func (k *Knight) RecentAutoPromoteEvals(limit int) ([]AutoPromoteEvalLogEntry, error)
- func (k *Knight) RecentAutoPromoteEvalsForSkill(scope, name string, limit int) ([]AutoPromoteEvalLogEntry, error)
- func (k *Knight) RecentProjectImprovementProposals(limit int) ([]ProjectImprovementProposal, error)
- func (k *Knight) RecentRejectFeedback(limit int) []string
- func (k *Knight) RecentSemanticMemory(limit int) ([]SemanticMemoryEntry, error)
- func (k *Knight) RecentSkillScenarios(limit int) ([]SkillScenarioLogEntry, error)
- func (k *Knight) RecordPromptSkillOutcome(refs []string, success bool)
- func (k *Knight) RecordPromptSkillScenario(refs []string, content []provider.ContentBlock, success bool, runErr error) error
- func (k *Knight) RecordSemanticMemory(kind, summary string, refs []string, source string) error
- func (k *Knight) RecordSkillEffectiveness(ref string, score int)
- func (k *Knight) RecordSkillPromptExposure(refs []string)
- func (k *Knight) RecordSkillUse(ref string)
- func (k *Knight) RejectProposal(id, note string) (ProjectImprovementProposal, error)
- func (k *Knight) RejectStaging(skillName string) error
- func (k *Knight) RejectStagingByPath(path string) error
- func (k *Knight) RollbackSkill(name string) error
- func (k *Knight) RunAdhocTask(ctx context.Context, goal string) (TaskResult, error)
- func (k *Knight) RunGovernanceAudit(window time.Duration) (SkillGovernanceAudit, error)
- func (k *Knight) RunSelfReflection(_ context.Context, window time.Duration) (SelfReflectionReport, error)
- func (k *Knight) RunTask(ctx context.Context, taskName, prompt string, factory AgentFactory) TaskResult
- func (k *Knight) RunTaskWithTurns(ctx context.Context, taskName, prompt string, factory AgentFactory, ...) TaskResult
- func (k *Knight) Running() bool
- func (k *Knight) SetEmitter(e Emitter)
- func (k *Knight) SetEventSink(s EventSink)
- func (k *Knight) SetFactory(f AgentFactory)
- func (k *Knight) SetSkillFrozen(name string, frozen bool) error
- func (k *Knight) SkillFeedback(ref string) (avgScore float64, samples int)
- func (k *Knight) SkillPromptExposure(ref string) (count int, lastExposed time.Time)
- func (k *Knight) SkillPromptOutcome(ref string) (successes int, failures int)
- func (k *Knight) SkillUsage(ref string) (count int, lastUsed time.Time, avgScore float64)
- func (k *Knight) Start(ctx context.Context) error
- func (k *Knight) Status() string
- func (k *Knight) Stop()
- type ProjectImprovementProposal
- type Promoter
- type SelfReflectionReport
- type SemanticMemoryEntry
- type SessionAnalyzer
- func (sa *SessionAnalyzer) AnalyzeRecent(ctx context.Context) (*AnalysisResult, error)
- func (sa *SessionAnalyzer) CollectProjectConventions() string
- func (sa *SessionAnalyzer) GenerateSkillFromAnalysis(ctx context.Context, candidate SkillCandidate, factory AgentFactory) (string, error)
- func (sa *SessionAnalyzer) RecordUsage(usage provider.TokenUsage)
- type SkillActionRecommendation
- type SkillCandidate
- type SkillEntry
- type SkillGovernanceAudit
- type SkillIndex
- func (si *SkillIndex) ActiveSkills() ([]*SkillEntry, error)
- func (si *SkillIndex) Directories() []string
- func (si *SkillIndex) FindActiveByName(name string) *SkillEntry
- func (si *SkillIndex) Invalidate()
- func (si *SkillIndex) LooseActiveSkillFiles() ([]*SkillEntry, error)
- func (si *SkillIndex) Scan() ([]*SkillEntry, error)
- func (si *SkillIndex) StagingSkills() ([]*SkillEntry, error)
- type SkillMeta
- type SkillScenarioLogEntry
- type TaskResult
- type UsageTracker
- func (ut *UsageTracker) AllUsage() map[string]skillUsage
- func (ut *UsageTracker) EnsureDir() error
- func (ut *UsageTracker) Flush()
- func (ut *UsageTracker) GetFeedback(name string) (avgScore float64, samples int)
- func (ut *UsageTracker) GetPromptExposure(name string) (count int, lastExposed time.Time)
- func (ut *UsageTracker) GetPromptOutcome(name string) (successes int, failures int)
- func (ut *UsageTracker) GetUsage(name string) (count int, lastUsed time.Time, avgScore float64)
- func (ut *UsageTracker) IsStale(name string, threshold time.Duration) bool
- func (ut *UsageTracker) RecordEffectiveness(name string, score int)
- func (ut *UsageTracker) RecordPromptExposure(name string)
- func (ut *UsageTracker) RecordPromptOutcome(name string, success bool)
- func (ut *UsageTracker) RecordUse(name string)
- func (ut *UsageTracker) Snapshot(name string) (skillUsage, bool)
- type ValidationResult
Constants ¶
const ( BudgetBucketAnalysis budgetBucket = "analysis" BudgetBucketEval budgetBucket = "eval" BudgetBucketMaintenance budgetBucket = "maintenance" BudgetBucketProposal budgetBucket = "proposal" BudgetBucketSkillTuning budgetBucket = "skill_tuning" BudgetBucketAdhoc budgetBucket = "adhoc" )
Variables ¶
var ErrLockConflict = fmt.Errorf("knight: another instance already running in this workspace")
ErrLockConflict is returned by Start when another ggcode instance in the same project directory already holds the Knight lock. Callers can check this to show a user-facing hint without treating it as a real error.
Functions ¶
func CheckDuplicate ¶
func CheckDuplicate(entry *SkillEntry, existing []*SkillEntry) bool
CheckDuplicate returns true if a skill with similar name already exists.
func FormatLockMessage ¶ added in v1.1.57
FormatLockMessage returns a human-readable message about why Knight didn't start.
func FormatSkillRefForDisplay ¶
FormatSkillRefForDisplay returns the canonical scope-qualified skill reference.
func LockHeldBy ¶ added in v1.1.57
LockHeldBy returns the PID of the process holding the Knight lock for the given project directory, or 0 if the lock is not held.
Types ¶
type ABReplayResult ¶ added in v1.1.84
type ABReplayResult struct {
ScenariosConsidered int
CandidateScore float64
BaselineScore float64
Delta float64
TopMatchedTasks []string
}
ABReplayResult captures a deterministic, LLM-free relevance score between a candidate skill body and a set of recently observed prompt scenarios.
The intuition: if Knight stages a candidate skill that does not actually resemble any task users have asked the agent to do recently, promoting it adds noise to the prompt without any payoff. Conversely, candidates that strongly overlap with real recent scenarios are more likely to improve agent behavior when promoted.
CandidateScore and BaselineScore are normalized in [0,1]. Delta is CandidateScore - BaselineScore (range [-1,1]); positive Delta means the candidate covers a wider/more frequent slice of recent reality than the baseline (e.g., the active skill it would replace).
type AgentFactory ¶
type AgentFactory func(systemPrompt string, maxTurns int, onUsage func(provider.TokenUsage)) (AgentRunner, error)
AgentFactory creates a Knight agent with restricted tools. The onUsage callback receives token usage after each LLM call.
type AgentRunner ¶
type AgentRunner interface {
RunStream(ctx context.Context, prompt string, onEvent func(provider.StreamEvent)) error
}
AgentRunner is the interface Knight uses to run LLM-powered tasks. It mirrors subagent.AgentRunner for compatibility.
type AnalysisResult ¶
type AnalysisResult struct {
SessionsAnalyzed int
SkillCandidates []SkillCandidate
}
AnalysisResult holds the outcome of a session analysis.
type AutoPolicy ¶ added in v1.1.84
type AutoPolicy struct {
Name string
Mode string
Description string
Guardrail string
// Effective is true if this policy is currently active given the running
// trust level and capability set. Disabled policies still appear so users
// can audit what Knight could do under a different config.
Effective bool
Reason string
}
type AutoPromoteEvalLogEntry ¶ added in v1.1.84
type AutoPromoteEvalLogEntry struct {
Time time.Time `json:"time"`
Skill string `json:"skill"`
Scope string `json:"scope"`
Path string `json:"path"`
Allowed bool `json:"allowed"`
Promote bool `json:"promote"`
ReplayPass bool `json:"replay_pass"`
SavedReplayRequired bool `json:"saved_replay_required,omitempty"`
SavedReplayStatus string `json:"saved_replay_status,omitempty"`
FalsePositiveCount int `json:"false_positive_count,omitempty"`
FalseNegativeCount int `json:"false_negative_count,omitempty"`
BaselineReplayRequired bool `json:"baseline_replay_required,omitempty"`
BaselineReplayStatus string `json:"baseline_replay_status,omitempty"`
OverlapCount int `json:"overlap_count,omitempty"`
RuleOverlap bool `json:"rule_overlap,omitempty"`
RuleOverlapJaccard float64 `json:"rule_overlap_jaccard,omitempty"`
RuleOverlapWith string `json:"rule_overlap_with,omitempty"`
ReplayCandidateScore float64 `json:"replay_candidate_score,omitempty"`
ReplayBaselineScore float64 `json:"replay_baseline_score,omitempty"`
ReplayDelta float64 `json:"replay_delta,omitempty"`
ReplayVerdict string `json:"replay_verdict,omitempty"`
ReplayScenarios int `json:"replay_scenarios,omitempty"`
Rationale string `json:"rationale,omitempty"`
RawOutput string `json:"raw_output,omitempty"`
FailureMode string `json:"failure_mode,omitempty"`
}
type Budget ¶
type Budget struct {
// contains filtered or unexported fields
}
Budget tracks daily token consumption for Knight.
func NewBudget ¶
func NewBudget(dir string, cfg config.KnightConfig) *Budget
NewBudget creates a Budget tracker. Data is stored under dir/knight/.
func (*Budget) CanSpend ¶
CanSpend returns true if Knight has enough remaining budget to start a task.
func (*Budget) DailyLimit ¶
DailyLimit returns the configured daily budget.
type CandidateQueue ¶
type CandidateQueue struct {
// contains filtered or unexported fields
}
CandidateQueue persists deferred high-value skill candidates between runs.
func NewCandidateQueue ¶
func NewCandidateQueue(path string) *CandidateQueue
NewCandidateQueue creates a queue backed by the given JSON file path.
func (*CandidateQueue) EnsureDir ¶
func (q *CandidateQueue) EnsureDir() error
EnsureDir creates the parent directory for the queue file.
func (*CandidateQueue) List ¶
func (q *CandidateQueue) List() ([]SkillCandidate, error)
List returns the current deferred candidates sorted by priority.
func (*CandidateQueue) Remove ¶
func (q *CandidateQueue) Remove(candidate SkillCandidate) error
Remove deletes a candidate from the queue if present.
func (*CandidateQueue) Upsert ¶
func (q *CandidateQueue) Upsert(candidate SkillCandidate) error
Upsert stores or updates a deferred candidate.
type EmitSeverity ¶ added in v1.1.84
type EmitSeverity int
EmitSeverity tags an outbound Knight report so downstream consumers (IM, EventSink, future filters) can decide what to do with it.
const ( EmitSeverityInfo EmitSeverity = iota EmitSeverityNotice EmitSeverityActionRequired EmitSeverityError )
func (EmitSeverity) String ¶ added in v1.1.84
func (s EmitSeverity) String() string
type EventSink ¶ added in v1.1.53
type EventSink interface {
// OnTaskStart is called when a Knight task begins.
OnTaskStart(taskName string)
// OnTaskComplete is called when a Knight task finishes with a detailed report.
OnTaskComplete(taskName string, report string, duration time.Duration)
}
EventSink receives Knight task lifecycle events for display in TUI/daemon.
type FuncSink ¶ added in v1.1.53
type FuncSink struct {
OnStart func(taskName string)
OnComplete func(taskName string, report string, duration time.Duration)
}
FuncSink is an EventSink that delegates to callback functions.
func (*FuncSink) OnTaskComplete ¶ added in v1.1.53
func (*FuncSink) OnTaskStart ¶ added in v1.1.53
type Knight ¶
type Knight struct {
// contains filtered or unexported fields
}
Knight is the background auto-evolution agent. It runs scheduled tasks during idle time, analyzes sessions, creates and validates skills.
func (*Knight) ApproveProposal ¶ added in v1.1.84
func (k *Knight) ApproveProposal(id, note string) (ProjectImprovementProposal, error)
ApproveProposal marks a stored proposal as user-approved. Knight does not implement approved proposals on its own; the user runs implementation as a separate normal agent task. Approved proposals also seed semantic memory so future Knight runs remember the lesson across sessions.
func (*Knight) AutoPolicies ¶ added in v1.1.84
func (k *Knight) AutoPolicies() []AutoPolicy
func (*Knight) BudgetStatus ¶
BudgetStatus returns current Knight token usage counters.
func (*Knight) CanPerformTask ¶
CanPerformTask checks if Knight has budget and is allowed to run.
func (*Knight) ClearRejectFeedback ¶ added in v1.1.84
ClearRejectFeedback wipes the reject feedback log; rejected candidates may then be re-staged on the next analysis tick.
func (*Knight) ClearSkillScenarios ¶ added in v1.1.84
ClearSkillScenarios removes the saved scenario log entirely. Returns nil if no log exists. Safe to call any time.
func (*Knight) DeleteSkill ¶ added in v1.1.85
DeleteSkill removes an active skill by deleting its file and directory.
func (*Knight) FindActiveSkill ¶
func (k *Knight) FindActiveSkill(ref string) (*SkillEntry, error)
FindActiveSkill resolves an active skill reference, optionally scoped as project:name or global:name.
func (*Knight) FindStagingSkill ¶
func (k *Knight) FindStagingSkill(ref string) (*SkillEntry, error)
FindStagingSkill resolves a staging skill reference, optionally scoped as project:name or global:name.
func (*Knight) GenerateProjectImprovementProposal ¶ added in v1.1.84
func (k *Knight) GenerateProjectImprovementProposal(ctx context.Context, goal string) (ProjectImprovementProposal, TaskResult, error)
func (*Knight) Index ¶
func (k *Knight) Index() *SkillIndex
Index returns the skill index for external access.
func (*Knight) NotifyActivity ¶
func (k *Knight) NotifyActivity()
NotifyActivity is called when the user sends a message, resetting the idle timer.
func (*Knight) PerformSkillAnalysis ¶
PerformSkillAnalysis triggers an immediate skill analysis task.
func (*Knight) PerformSkillValidation ¶
func (k *Knight) PerformSkillValidation(ctx context.Context) ([]ValidationResult, error)
PerformSkillValidation validates all active skills.
func (*Knight) PromoteStaging ¶
PromoteStaging promotes a staging skill to active after validation.
func (*Knight) PromoteStagingByPath ¶ added in v1.1.85
PromoteStagingByPath promotes a staging skill by its file path. Use this when multiple staging skills share the same name/scope.
func (*Knight) Queue ¶ added in v1.1.54
func (k *Knight) Queue() *CandidateQueue
Queue returns the candidate queue for external queries.
func (*Knight) ReadProjectImprovementProposal ¶ added in v1.1.84
func (k *Knight) ReadProjectImprovementProposal(id string) (ProjectImprovementProposal, string, error)
func (*Knight) RecentAutoPromoteEvals ¶ added in v1.1.84
func (k *Knight) RecentAutoPromoteEvals(limit int) ([]AutoPromoteEvalLogEntry, error)
func (*Knight) RecentAutoPromoteEvalsForSkill ¶ added in v1.1.84
func (k *Knight) RecentAutoPromoteEvalsForSkill(scope, name string, limit int) ([]AutoPromoteEvalLogEntry, error)
func (*Knight) RecentProjectImprovementProposals ¶ added in v1.1.84
func (k *Knight) RecentProjectImprovementProposals(limit int) ([]ProjectImprovementProposal, error)
func (*Knight) RecentRejectFeedback ¶ added in v1.1.84
RecentRejectFeedback returns at most limit recent reject/rollback entries (newest first) formatted as human-readable strings.
func (*Knight) RecentSemanticMemory ¶ added in v1.1.84
func (k *Knight) RecentSemanticMemory(limit int) ([]SemanticMemoryEntry, error)
RecentSemanticMemory returns the most recent semantic memory entries.
func (*Knight) RecentSkillScenarios ¶ added in v1.1.84
func (k *Knight) RecentSkillScenarios(limit int) ([]SkillScenarioLogEntry, error)
func (*Knight) RecordPromptSkillOutcome ¶ added in v1.1.84
RecordPromptSkillOutcome records a weak task-level outcome for prompt-visible skills. It should be used only as a soft signal because prompt visibility does not prove the skill caused the outcome.
func (*Knight) RecordPromptSkillScenario ¶ added in v1.1.84
func (*Knight) RecordSemanticMemory ¶ added in v1.1.84
RecordSemanticMemory persists a cross-session lesson. Safe to call with a nil Knight (no-op).
func (*Knight) RecordSkillEffectiveness ¶
RecordSkillEffectiveness records a 1-5 effectiveness score for a skill.
func (*Knight) RecordSkillPromptExposure ¶ added in v1.1.84
RecordSkillPromptExposure records that one or more active skills were visible to the model in the system prompt. This is a weak signal, separate from actual skill invocation, and helps distinguish "never shown" from "shown but ignored".
func (*Knight) RecordSkillUse ¶
RecordSkillUse increments the usage counter for a skill. Called from the skill tool when a Knight-managed skill is loaded.
func (*Knight) RejectProposal ¶ added in v1.1.84
func (k *Knight) RejectProposal(id, note string) (ProjectImprovementProposal, error)
RejectProposal marks a stored proposal as user-rejected and prevents future proposal listings from showing it as still pending.
func (*Knight) RejectStaging ¶
RejectStaging removes a staging skill.
func (*Knight) RejectStagingByPath ¶ added in v1.1.85
RejectStagingByPath rejects a staging skill by its file path. Use this when multiple staging skills share the same name/scope.
func (*Knight) RollbackSkill ¶
RollbackSkill restores the latest snapshot for an active skill.
func (*Knight) RunAdhocTask ¶
RunAdhocTask executes a user-directed Knight task using the configured agent factory.
func (*Knight) RunGovernanceAudit ¶ added in v1.1.84
func (k *Knight) RunGovernanceAudit(window time.Duration) (SkillGovernanceAudit, error)
RunGovernanceAudit generates a read-only governance summary. Unlike RunSelfReflection, it does not write back to semantic memory.
func (*Knight) RunSelfReflection ¶ added in v1.1.84
func (k *Knight) RunSelfReflection(_ context.Context, window time.Duration) (SelfReflectionReport, error)
RunSelfReflection inspects Knight's own recent decisions and produces a short summary. It is a low-cost, deterministic pass — no LLM call. The summary is also appended to semantic memory as a meta-lesson so future analyzer + eval prompts see how earlier Knight decisions actually turned out.
func (*Knight) RunTask ¶
func (k *Knight) RunTask(ctx context.Context, taskName, prompt string, factory AgentFactory) TaskResult
RunTask executes a single Knight task with budget tracking and default maxTurns=10. Token usage is tracked via the onUsage callback wired into the agent.
func (*Knight) RunTaskWithTurns ¶ added in v1.1.53
func (k *Knight) RunTaskWithTurns(ctx context.Context, taskName, prompt string, factory AgentFactory, maxTurns int) TaskResult
RunTaskWithTurns executes a single Knight task with a custom maxTurns limit.
func (*Knight) SetEmitter ¶
SetEmitter sets the IM emitter for Knight notifications.
func (*Knight) SetEventSink ¶ added in v1.1.53
SetEventSink sets the event sink for task lifecycle notifications.
func (*Knight) SetFactory ¶
func (k *Knight) SetFactory(f AgentFactory)
SetFactory sets the agent factory for LLM-powered tasks.
func (*Knight) SetSkillFrozen ¶
SetSkillFrozen updates an active skill's frozen flag.
func (*Knight) SkillFeedback ¶
SkillFeedback returns runtime feedback stats for a skill.
func (*Knight) SkillPromptExposure ¶ added in v1.1.84
SkillPromptExposure returns how often a skill has been visible in the prompt.
func (*Knight) SkillPromptOutcome ¶ added in v1.1.84
SkillPromptOutcome returns weak success/failure counts from runs where a skill was visible in the prompt.
func (*Knight) SkillUsage ¶
SkillUsage returns runtime usage stats for a skill.
type ProjectImprovementProposal ¶ added in v1.1.84
type ProjectImprovementProposal struct {
ID string `json:"id"`
Time time.Time `json:"time"`
Goal string `json:"goal"`
Title string `json:"title"`
Summary string `json:"summary,omitempty"`
Path string `json:"path"`
CreatedBy string `json:"created_by"`
// Lifecycle
Status string `json:"status,omitempty"` // proposed | approved | rejected
StatusNote string `json:"status_note,omitempty"`
StatusBy string `json:"status_by,omitempty"`
StatusAt time.Time `json:"status_at,omitempty"`
}
type Promoter ¶
type Promoter struct {
// contains filtered or unexported fields
}
Promoter handles moving skills from staging to active directories.
func NewPromoter ¶
NewPromoter creates a skill promoter.
func (*Promoter) MigrateLooseActive ¶ added in v1.1.84
func (p *Promoter) MigrateLooseActive(entry *SkillEntry) error
MigrateLooseActive moves a legacy active top-level *.md skill into the standard <name>/SKILL.md layout used by the ggcode skill loader.
func (*Promoter) Promote ¶
func (p *Promoter) Promote(entry *SkillEntry) error
Promote moves a skill from staging to the active skills directory. It creates a snapshot of any existing skill with the same name for rollback.
func (*Promoter) Reject ¶
func (p *Promoter) Reject(entry *SkillEntry) error
Reject removes a skill from staging.
func (*Promoter) Rollback ¶
func (p *Promoter) Rollback(entry *SkillEntry) error
Rollback restores the most recent snapshot for an active skill.
type SelfReflectionReport ¶ added in v1.1.84
type SelfReflectionReport struct {
Window time.Duration
ActiveSkills int
StagingSkills int
UnusedActive []string
HighUsageActive []string
RecentRejects []string
RecentPromotions []string
Recommendations []SkillActionRecommendation
GeneratedAt time.Time
}
SelfReflectionReport summarizes Knight's recent activity for human-visible output and for appending a meta-lesson to semantic memory.
func (SelfReflectionReport) FormatHuman ¶ added in v1.1.84
func (r SelfReflectionReport) FormatHuman() string
FormatHuman returns a multi-line human-readable rendering of the report.
func (SelfReflectionReport) MetaLesson ¶ added in v1.1.84
func (r SelfReflectionReport) MetaLesson() string
MetaLesson renders the report as a single short summary suitable for recording back into semantic memory.
type SemanticMemoryEntry ¶ added in v1.1.84
type SemanticMemoryEntry struct {
ID string `json:"id"`
Time time.Time `json:"time"`
Kind string `json:"kind"`
Summary string `json:"summary"`
Refs []string `json:"refs,omitempty"`
Source string `json:"source,omitempty"`
SessionID string `json:"session,omitempty"`
}
SemanticMemoryEntry is a long-form lesson Knight has accumulated across sessions: an approved proposal, a successfully promoted skill, a recurring resolved bug pattern, etc. The intent is to give later prompts (and Knight itself) cross-session continuity beyond what the active skill set captures.
type SessionAnalyzer ¶
type SessionAnalyzer struct {
// contains filtered or unexported fields
}
SessionAnalyzer analyzes session history to discover reusable patterns.
func NewSessionAnalyzer ¶
func NewSessionAnalyzer(k *Knight) *SessionAnalyzer
NewSessionAnalyzer creates a session analyzer.
func (*SessionAnalyzer) AnalyzeRecent ¶
func (sa *SessionAnalyzer) AnalyzeRecent(ctx context.Context) (*AnalysisResult, error)
AnalyzeRecent scans recent sessions for high-value learning signals.
Filtering and priority:
- Only sessions matching the current project workspace are analyzed.
- Sessions already analyzed in previous ticks are skipped (dedup).
- Sessions are prioritized: corrections/failure-fixes first, then recency.
- Up to `limit` sessions are analyzed per tick.
func (*SessionAnalyzer) CollectProjectConventions ¶
func (sa *SessionAnalyzer) CollectProjectConventions() string
CollectProjectConventions reads well-known project config files for context.
func (*SessionAnalyzer) GenerateSkillFromAnalysis ¶
func (sa *SessionAnalyzer) GenerateSkillFromAnalysis(ctx context.Context, candidate SkillCandidate, factory AgentFactory) (string, error)
GenerateSkillFromAnalysis uses LLM to create a skill from a high-value candidate. The skill is a behavioral guideline that teaches the AI what to do (or not do) based on real user interactions.
func (*SessionAnalyzer) RecordUsage ¶
func (sa *SessionAnalyzer) RecordUsage(usage provider.TokenUsage)
RecordUsage records token usage for session analysis tasks.
type SkillActionRecommendation ¶ added in v1.1.84
type SkillActionRecommendation struct {
Ref string
Action string
Priority string
Reason string
Command string
}
SkillActionRecommendation is a deterministic governance suggestion Knight can surface to the operator without taking any destructive action on its own.
type SkillCandidate ¶
type SkillCandidate struct {
Name string
Description string
Scope string // "global" or "project"
Score float64
Reason string
EvidenceCount int
SourceSessions []string
// Evidence holds the key conversation excerpts that justify this skill.
// For corrections: [0]=what AI did wrong, [1]=what user said instead.
// For failure-fix: [0]=error message, [1]=how it was fixed.
Evidence []string
// Category classifies the skill source for LLM context.
Category string // "correction", "failure-fix", "convention"
// GenFailCount tracks consecutive LLM generation failures; abandon after knightMaxGenFailures.
GenFailCount int `json:",omitempty"`
// Queue metadata is persisted for deferred candidates so Knight can make
// less myopic prioritization decisions across later analysis ticks.
FirstQueuedAt time.Time `json:"first_queued_at,omitempty"`
LastQueuedAt time.Time `json:"last_queued_at,omitempty"`
QueueTouchCount int `json:"queue_touch_count,omitempty"`
QueuePriority float64 `json:"queue_priority,omitempty"`
QueuePriorityReason string `json:"queue_priority_reason,omitempty"`
}
SkillCandidate is a potential skill discovered from session analysis.
type SkillEntry ¶
type SkillEntry struct {
Name string
Meta SkillMeta
Path string // full path to the skill file
Scope string // "global" or "project"
Staging bool // true if in staging directory
LoadedAt time.Time
}
SkillEntry is a discovered skill with its metadata and file location.
type SkillGovernanceAudit ¶ added in v1.1.84
type SkillGovernanceAudit struct {
Window time.Duration
GeneratedAt time.Time
ActiveSkills int
ProjectSkills int
GlobalSkills int
FrozenSkills int
StagingSkills int
GlobalStagingSkills int
StaleGlobalSkills []string
RecentGlobalEvents []string
Recommendations []SkillActionRecommendation
}
SkillGovernanceAudit summarizes active/staging scope health and the strongest operator-facing recommendations for pruning or tightening the skill set.
func (SkillGovernanceAudit) FormatHuman ¶ added in v1.1.84
func (a SkillGovernanceAudit) FormatHuman() string
type SkillIndex ¶
type SkillIndex struct {
// contains filtered or unexported fields
}
SkillIndex scans and indexes skills from both global and project directories. Results are cached with a TTL to avoid repeated disk reads.
func NewSkillIndex ¶
func NewSkillIndex(homeDir, projectDir string) *SkillIndex
NewSkillIndex creates a skill index for the given home and project dirs.
func (*SkillIndex) ActiveSkills ¶
func (si *SkillIndex) ActiveSkills() ([]*SkillEntry, error)
ActiveSkills returns only active (non-staging) skills.
func (*SkillIndex) Directories ¶
func (si *SkillIndex) Directories() []string
Directories returns all skill directories for display purposes.
func (*SkillIndex) FindActiveByName ¶
func (si *SkillIndex) FindActiveByName(name string) *SkillEntry
FindActiveByName finds an active skill by name.
func (*SkillIndex) Invalidate ¶
func (si *SkillIndex) Invalidate()
Invalidate clears the cache, forcing a fresh scan on next access.
func (*SkillIndex) LooseActiveSkillFiles ¶ added in v1.1.84
func (si *SkillIndex) LooseActiveSkillFiles() ([]*SkillEntry, error)
LooseActiveSkillFiles returns legacy/non-standard top-level *.md files under active skill directories. These files look like skills but are not loaded by ggcode's standard skill loader, which only accepts <name>/SKILL.md.
func (*SkillIndex) Scan ¶
func (si *SkillIndex) Scan() ([]*SkillEntry, error)
Scan returns all discovered skills (active + staging), using cache when fresh.
func (*SkillIndex) StagingSkills ¶
func (si *SkillIndex) StagingSkills() ([]*SkillEntry, error)
StagingSkills returns only staging skills.
type SkillMeta ¶
type SkillMeta struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Scope string `yaml:"scope"` // "global" or "project"
Platforms []string `yaml:"platforms"`
Requires []string `yaml:"requires"`
CreatedBy string `yaml:"created_by"` // "user", "knight", "agent"
CreatedFrom string `yaml:"created_from"` // source session ID
CreatedAt string `yaml:"created_at"`
UpdatedAt string `yaml:"updated_at"`
UsageCount int `yaml:"usage_count"`
LastUsed string `yaml:"last_used"`
PromptExposureCount int `yaml:"prompt_exposure_count"`
LastPromptExposure string `yaml:"last_prompt_exposure"`
PromptSuccessCount int `yaml:"prompt_success_count"`
PromptFailureCount int `yaml:"prompt_failure_count"`
EffectivenessScores []int `yaml:"effectiveness_scores"`
Frozen bool `yaml:"frozen"`
}
SkillMeta is the parsed frontmatter from a SKILL.md or staging skill file.
type SkillScenarioLogEntry ¶ added in v1.1.84
type TaskResult ¶
type TaskResult struct {
TaskName string
Output string
Tokens provider.TokenUsage
Duration time.Duration
Error error
}
TaskResult holds the outcome of a Knight task execution.
type UsageTracker ¶
type UsageTracker struct {
// contains filtered or unexported fields
}
UsageTracker tracks skill usage for Knight's lifecycle management. Persists to a JSON file in the project's .ggcode/ directory. Uses a dirty flag to batch disk writes — only saves when data changed and at most once per writeInterval.
func NewUsageTracker ¶
func NewUsageTracker(path string) *UsageTracker
NewUsageTracker creates a usage tracker that persists to the given path.
func (*UsageTracker) AllUsage ¶
func (ut *UsageTracker) AllUsage() map[string]skillUsage
AllUsage returns a snapshot of all usage data.
func (*UsageTracker) EnsureDir ¶
func (ut *UsageTracker) EnsureDir() error
EnsureDir creates the parent directory for the usage file.
func (*UsageTracker) Flush ¶
func (ut *UsageTracker) Flush()
Flush persists dirty data to disk. Called periodically by the scheduler.
func (*UsageTracker) GetFeedback ¶
func (ut *UsageTracker) GetFeedback(name string) (avgScore float64, samples int)
GetFeedback returns the average effectiveness score and sample count.
func (*UsageTracker) GetPromptExposure ¶ added in v1.1.84
func (ut *UsageTracker) GetPromptExposure(name string) (count int, lastExposed time.Time)
GetPromptExposure returns prompt exposure data for a skill.
func (*UsageTracker) GetPromptOutcome ¶ added in v1.1.84
func (ut *UsageTracker) GetPromptOutcome(name string) (successes int, failures int)
GetPromptOutcome returns weak task-level outcome counts for prompt-visible use. The returned counts are the time-decayed values consumed by Knight's prompt-tuning gates: a stale historical failure no longer dominates the recent signal. Callers wanting raw lifetime counts should read PromptSuccessCount/PromptFailureCount via Snapshot.
func (*UsageTracker) IsStale ¶
func (ut *UsageTracker) IsStale(name string, threshold time.Duration) bool
IsStale returns true if a skill hasn't been used for the given duration.
func (*UsageTracker) RecordEffectiveness ¶
func (ut *UsageTracker) RecordEffectiveness(name string, score int)
RecordEffectiveness adds an effectiveness score (1-5) for a skill.
func (*UsageTracker) RecordPromptExposure ¶ added in v1.1.84
func (ut *UsageTracker) RecordPromptExposure(name string)
RecordPromptExposure increments the count of times a skill was listed in the system prompt. Exposure is not the same as use; it only proves the model could see the skill when deciding whether to invoke it.
func (*UsageTracker) RecordPromptOutcome ¶ added in v1.1.84
func (ut *UsageTracker) RecordPromptOutcome(name string, success bool)
RecordPromptOutcome records a weak task-level outcome for a skill that was visible in the prompt during a run. It is attribution, not proof of causality.
func (*UsageTracker) RecordUse ¶
func (ut *UsageTracker) RecordUse(name string)
RecordUse increments the usage count and updates last_used for a skill.
func (*UsageTracker) Snapshot ¶
func (ut *UsageTracker) Snapshot(name string) (skillUsage, bool)
type ValidationResult ¶
type ValidationResult struct {
Valid bool `json:"valid"`
Errors []string `json:"errors,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
ValidationResult contains the outcome of skill validation.
func ValidateSkill ¶
func ValidateSkill(entry *SkillEntry) ValidationResult
ValidateSkill runs all validation checks on a skill entry.
Source Files
¶
- ab_replay.go
- analyzer.go
- auto_policy.go
- auto_promote_eval_log.go
- budget.go
- budget_buckets.go
- candidate_name.go
- candidate_queue.go
- emit_throttle.go
- governance.go
- lock_unix.go
- overlap.go
- project_proposal.go
- reject_feedback.go
- runner.go
- scenario_sanitize.go
- scheduler.go
- scope_arbiter.go
- self_reflection.go
- semantic_memory.go
- similarity.go
- skill_index.go
- skill_promoter.go
- skill_scenario_log.go
- skill_validator.go
- usage_tracker.go