knight

package
v1.2.13 Latest Latest
Warning

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

Go to latest
Published: May 12, 2026 License: MIT Imports: 23 Imported by: 0

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

View Source
const (
	BudgetBucketAnalysis    budgetBucket = "analysis"
	BudgetBucketEval        budgetBucket = "eval"
	BudgetBucketMaintenance budgetBucket = "maintenance"
	BudgetBucketProposal    budgetBucket = "proposal"
	BudgetBucketSkillTuning budgetBucket = "skill_tuning"
	BudgetBucketAdhoc       budgetBucket = "adhoc"
)

Variables

View Source
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

func FormatLockMessage(pid int) string

FormatLockMessage returns a human-readable message about why Knight didn't start.

func FormatSkillRefForDisplay

func FormatSkillRefForDisplay(scope, name string) string

FormatSkillRefForDisplay returns the canonical scope-qualified skill reference.

func LockHeldBy added in v1.1.57

func LockHeldBy(projDir string) (int, error)

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

func (b *Budget) CanSpend() bool

CanSpend returns true if Knight has enough remaining budget to start a task.

func (*Budget) DailyLimit

func (b *Budget) DailyLimit() int

DailyLimit returns the configured daily budget.

func (*Budget) EnsureDir

func (b *Budget) EnsureDir() error

EnsureDir creates the knight data directory if needed.

func (*Budget) Record

func (b *Budget) Record(task string, inputTokens, outputTokens int) error

Record adds a token usage entry to today's log.

func (*Budget) Remaining

func (b *Budget) Remaining() int

Remaining returns how many tokens are left in today's budget.

func (*Budget) Used

func (b *Budget) Used() int

Used returns today's total token consumption.

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 Emitter

type Emitter interface {
	EmitKnightReport(report string)
	HasTargets() bool
}

Emitter is the interface Knight uses to send IM notifications.

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 (s *FuncSink) OnTaskComplete(taskName string, report string, duration time.Duration)

func (*FuncSink) OnTaskStart added in v1.1.53

func (s *FuncSink) OnTaskStart(taskName string)

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 New

func New(cfg config.KnightConfig, homeDir, projDir string, store session.Store) *Knight

New creates a new Knight instance.

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

func (k *Knight) BudgetStatus() (used int, remaining int, limit int)

BudgetStatus returns current Knight token usage counters.

func (*Knight) CanPerformTask

func (k *Knight) CanPerformTask() bool

CanPerformTask checks if Knight has budget and is allowed to run.

func (*Knight) ClearRejectFeedback added in v1.1.84

func (k *Knight) ClearRejectFeedback() error

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

func (k *Knight) ClearSkillScenarios() error

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

func (k *Knight) DeleteSkill(name string) error

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

func (k *Knight) PerformSkillAnalysis(ctx context.Context) error

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

func (k *Knight) PromoteStaging(skillName string) error

PromoteStaging promotes a staging skill to active after validation.

func (*Knight) PromoteStagingByPath added in v1.1.85

func (k *Knight) PromoteStagingByPath(path string) error

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

func (k *Knight) RecentRejectFeedback(limit int) []string

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

func (k *Knight) RecordPromptSkillOutcome(refs []string, success bool)

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 (k *Knight) RecordPromptSkillScenario(refs []string, content []provider.ContentBlock, success bool, runErr error) error

func (*Knight) RecordSemanticMemory added in v1.1.84

func (k *Knight) RecordSemanticMemory(kind, summary string, refs []string, source string) error

RecordSemanticMemory persists a cross-session lesson. Safe to call with a nil Knight (no-op).

func (*Knight) RecordSkillEffectiveness

func (k *Knight) RecordSkillEffectiveness(ref string, score int)

RecordSkillEffectiveness records a 1-5 effectiveness score for a skill.

func (*Knight) RecordSkillPromptExposure added in v1.1.84

func (k *Knight) RecordSkillPromptExposure(refs []string)

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

func (k *Knight) RecordSkillUse(ref string)

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

func (k *Knight) RejectStaging(skillName string) error

RejectStaging removes a staging skill.

func (*Knight) RejectStagingByPath added in v1.1.85

func (k *Knight) RejectStagingByPath(path string) error

RejectStagingByPath rejects a staging skill by its file path. Use this when multiple staging skills share the same name/scope.

func (*Knight) RollbackSkill

func (k *Knight) RollbackSkill(name string) error

RollbackSkill restores the latest snapshot for an active skill.

func (*Knight) RunAdhocTask

func (k *Knight) RunAdhocTask(ctx context.Context, goal string) (TaskResult, error)

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) Running

func (k *Knight) Running() bool

Running returns whether Knight is currently active.

func (*Knight) SetEmitter

func (k *Knight) SetEmitter(e Emitter)

SetEmitter sets the IM emitter for Knight notifications.

func (*Knight) SetEventSink added in v1.1.53

func (k *Knight) SetEventSink(s EventSink)

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

func (k *Knight) SetSkillFrozen(name string, frozen bool) error

SetSkillFrozen updates an active skill's frozen flag.

func (*Knight) SkillFeedback

func (k *Knight) SkillFeedback(ref string) (avgScore float64, samples int)

SkillFeedback returns runtime feedback stats for a skill.

func (*Knight) SkillPromptExposure added in v1.1.84

func (k *Knight) SkillPromptExposure(ref string) (count int, lastExposed time.Time)

SkillPromptExposure returns how often a skill has been visible in the prompt.

func (*Knight) SkillPromptOutcome added in v1.1.84

func (k *Knight) SkillPromptOutcome(ref string) (successes int, failures int)

SkillPromptOutcome returns weak success/failure counts from runs where a skill was visible in the prompt.

func (*Knight) SkillUsage

func (k *Knight) SkillUsage(ref string) (count int, lastUsed time.Time, avgScore float64)

SkillUsage returns runtime usage stats for a skill.

func (*Knight) Start

func (k *Knight) Start(ctx context.Context) error

Start begins the Knight background loop.

func (*Knight) Status

func (k *Knight) Status() string

Status returns a human-readable status string.

func (*Knight) Stop

func (k *Knight) Stop()

Stop gracefully shuts down Knight.

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

func NewPromoter(homeDir, projectDir string) *Promoter

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.

func (*Promoter) WriteStaging

func (p *Promoter) WriteStaging(name, scope, content string) (string, error)

WriteStaging writes a new skill to the appropriate staging directory.

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:

  1. Only sessions matching the current project workspace are analyzed.
  2. Sessions already analyzed in previous ticks are skipped (dedup).
  3. Sessions are prioritized: corrections/failure-fixes first, then recency.
  4. 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 SkillScenarioLogEntry struct {
	Time      time.Time `json:"time"`
	Task      string    `json:"task"`
	SkillRefs []string  `json:"skill_refs"`
	Success   bool      `json:"success"`
	Error     string    `json:"error,omitempty"`
}

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) GetUsage

func (ut *UsageTracker) GetUsage(name string) (count int, lastUsed time.Time, avgScore float64)

GetUsage returns usage data for a skill.

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.

Jump to

Keyboard shortcuts

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