routing

package
v0.5.6 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// IdentityMarker prevents double-injection of agent identity
	IdentityMarker    = "[AGENT IDENTITY - AUTO-INJECTED]"
	IdentityEndMarker = "[END AGENT IDENTITY]"

	// SessionMarker prevents double-injection of session context
	SessionMarker    = "[SESSION CONTEXT]"
	SessionEndMarker = "[END SESSION CONTEXT]"
)
View Source
const (
	// ConventionsMarker is used to detect if conventions were already injected
	ConventionsMarker    = "[CONVENTIONS - AUTO-INJECTED BY goyoke-validate]"
	ConventionsEndMarker = "[END CONVENTIONS]"
)
View Source
const (
	DecisionApprove = "approve" // Allow the tool to proceed
	DecisionBlock   = "block"   // Block the tool from executing

	// Legacy aliases (deprecated - use DecisionApprove/DecisionBlock)
	DecisionWarn = "approve" // Mapped to approve (warn not supported by Claude Code)
	DecisionPass = "approve" // Mapped to approve (pass not supported by Claude Code)
)

Decision values for hook responses Claude Code expects: "approve" | "block" (optional)

View Source
const (
	// MaxNestingDepth prevents runaway nesting
	MaxNestingDepth = 10

	// DefaultNestingLevel for fail-closed behavior
	DefaultNestingLevel = 1
)
View Source
const EXPECTED_AGENT_INDEX_VERSION = "2.8.0"

EXPECTED_AGENT_INDEX_VERSION is the version this code is built for.

View Source
const EXPECTED_SCHEMA_VERSION = "2.5.0"

EXPECTED_SCHEMA_VERSION is the version this code is built for.

Variables

This section is empty.

Functions

func AnalyzeToolDistribution

func AnalyzeToolDistribution(events []ToolEvent) map[string]int

AnalyzeToolDistribution counts tool usage across all events. Returns a map of tool names to usage counts.

Parameters:

  • events: slice of ToolEvent structs to analyze

Returns:

  • map[string]int: tool names mapped to occurrence counts

Edge cases:

  • nil slice: returns empty map (not nil)
  • empty slice: returns empty map
  • unknown tool names: counted like any other tool

Example output:

map[string]int{
    "Read":  30,
    "Edit":  10,
    "Write": 5,
    "Task":  2,
    "Bash":  8,
}

func BlockResponseForNesting

func BlockResponseForNesting(level int, model, reason string) map[string]interface{}

BlockResponseForNesting creates the standard block response for nesting violations. This is specifically for blocking Task(opus) at nesting levels 1+.

func BuildAugmentedPrompt

func BuildAugmentedPrompt(originalPrompt string, requirements *ContextRequirements, taskFiles []string) (string, error)

BuildAugmentedPrompt creates a new prompt with conventions prepended. It loads the required rules and conventions based on the agent's context_requirements and prepends them to the original prompt in a clearly marked section.

Parameters:

  • originalPrompt: The original Task prompt from the router
  • requirements: The agent's context requirements (rules and conventions)
  • taskFiles: File paths mentioned in the prompt (for conditional convention matching)

Returns the augmented prompt or the original if no requirements or already augmented.

func BuildFullAgentContext

func BuildFullAgentContext(agentID string, requirements *ContextRequirements, taskFiles []string, originalPrompt string) (string, error)

BuildFullAgentContext builds complete agent context: identity + rules + conventions. Unified entry point for both Task() (goyoke-validate) and team-run (envelope.go) paths.

Injection order:

  1. Agent identity (from ~/.claude/agents/{agentID}/{agentID}.md body)
  2. Rules (from context_requirements.rules → ~/.claude/rules/)
  3. Conventions (from context_requirements.conventions → ~/.claude/conventions/)
  4. Original prompt

Returns the augmented prompt with all context prepended. If no context is available, returns originalPrompt unchanged.

func CheckDelegationCeiling

func CheckDelegationCeiling(schema *Schema, ceiling *DelegationCeilingRuntime, requestedModel string) (bool, string)

CheckDelegationCeiling validates if requested model is within ceiling

func ClearAgentsIndexCache

func ClearAgentsIndexCache()

ClearAgentsIndexCache clears the cached agents index. Used by tests to force re-loading of modified index files.

func ClearConventionCache

func ClearConventionCache()

ClearConventionCache clears the convention cache. Useful for testing or when conventions might have changed.

func CountChildAgentsFromTranscript

func CountChildAgentsFromTranscript(transcriptPath string) (int, error)

CountChildAgentsFromTranscript counts Task() invocations in the transcript. Returns the number of child agents spawned by analyzing tool usage. Uses the existing ParseTranscript function which handles JSONL format.

func ExtractFilePath

func ExtractFilePath(event *PostToolEvent) string

ExtractFilePath extracts the target file from event Tries: file_path → command (first arg) → "unknown"

func ExtractFilesFromPrompt

func ExtractFilesFromPrompt(prompt string) []string

ExtractFilesFromPrompt attempts to extract file paths mentioned in a prompt. It looks for common patterns like "/path/to/file.go" or "in src/main.go". Returns a slice of detected file paths (may be empty).

func GetClaudeConfigDir deprecated

func GetClaudeConfigDir() (string, error)

GetClaudeConfigDir returns the path to ~/.claude directory. Uses CLAUDE_CONFIG_DIR env var if set, otherwise ~/.claude

Deprecated: use resolve.NewFromEnv() instead.

func GetCurrentTier

func GetCurrentTier() (string, error)

GetCurrentTier reads current-tier file, returns default if missing

func GetNestingLevel

func GetNestingLevel() int

GetNestingLevel returns the current nesting level from environment. If GOYOKE_NESTING_LEVEL is unset, checks CLAUDE_CODE_NESTING_LEVEL to distinguish root sessions (level 0) from unknown contexts (fail-closed to 1).

func GetSessionDir

func GetSessionDir() string

GetSessionDir reads the current session directory path. First checks GOYOKE_SESSION_DIR (set directly by team-run for spawned agents), then falls back to reading the current-session marker file using project dir resolution: GOYOKE_PROJECT_ROOT → GOYOKE_PROJECT_DIR → CLAUDE_PROJECT_DIR → os.Getwd(). Returns empty string if unavailable.

Note: Cannot import pkg/session (circular dependency via sharp_edge_utils.go), so env var resolution is inlined here.

func InjectCodebaseMapContext

func InjectCodebaseMapContext(agentID, prompt, projectRoot string) string

InjectCodebaseMapContext returns a context block for modules relevant to the prompt, or empty string when injection should be skipped.

Returns empty string when:

  • GOYOKE_CODEBASE_MAP_INJECT != "1"
  • agentID not in the injectable allowlist
  • graph.json missing or unreadable
  • no relevant modules identified from the prompt

func IsNestingLevelExplicit

func IsNestingLevelExplicit() bool

IsNestingLevelExplicit returns true if GOYOKE_NESTING_LEVEL was set explicitly. Used for telemetry to distinguish real Level 0 from assumed nesting.

func IsOrchestratorType

func IsOrchestratorType(metadata *ParsedAgentMetadata) bool

IsOrchestratorType returns true if the agent is orchestrator or architect. These agents require tier-specific follow-up prompts after completion.

Returns false for all other agent types, including unknown/empty agents.

func LoadAgentIdentity

func LoadAgentIdentity(agentID string) (string, error)

LoadAgentIdentity loads the markdown body (post-frontmatter) from ~/.claude/agents/{agentID}/{agentID}.md

Returns empty string without error if file doesn't exist. Results are cached in conventionCache with "identity:" prefix.

func LoadAndFormatSchemaSummary

func LoadAndFormatSchemaSummary() (string, error)

LoadAndFormatSchemaSummary loads routing schema and returns formatted summary. Returns a friendly message if schema file is missing (not an error). Returns actual errors only for JSON parsing or validation failures.

func LoadConventionContent

func LoadConventionContent(conventionName string) (string, error)

LoadConventionContent loads a convention file by name. Returns the file content as a string. Results are cached for the duration of the process.

func LoadMultipleConventions

func LoadMultipleConventions(conventionNames []string) (map[string]string, []error)

LoadMultipleConventions loads multiple convention files and returns them as a map. Continues loading remaining files even if one fails (logs warning).

func LoadRulesContent

func LoadRulesContent(rulesName string) (string, error)

LoadRulesContent loads a rules file by name. Returns the file content as a string.

func LogViolation

func LogViolation(v *Violation, projectDir string) error

LogViolation appends violation to BOTH: 1. Global XDG cache: ~/.cache/goyoke/routing-violations.jsonl (survives project deletion) 2. Project memory: <project>/.goyoke/memory/routing-violations.jsonl (session integration)

Timestamp is auto-populated in RFC3339 format. Project log failure does NOT fail the entire operation (graceful degradation).

func ReadStdin

func ReadStdin(r io.Reader, timeout time.Duration) ([]byte, error)

ReadStdin reads all data from reader with timeout protection. Returns error if no data received within timeout duration. This prevents hooks from hanging indefinitely (fixes M-6).

func StripConventionsFromPrompt

func StripConventionsFromPrompt(prompt string) string

StripConventionsFromPrompt removes the auto-injected conventions section. Useful for logging or displaying the original prompt without injected content.

func StripYAMLFrontmatter

func StripYAMLFrontmatter(content string) string

StripYAMLFrontmatter removes YAML frontmatter (between --- delimiters) from a markdown file, returning only the body content. No YAML parsing — pure string processing.

func TierNumber

func TierNumber(tier any) float64

TierNumber returns the numeric tier value for an agent tier field. Handles float64 (JSON default), int, and nil → 0.

func UpdateTierFromMetrics

func UpdateTierFromMetrics(projectDir string) error

UpdateTierFromMetrics reads scout metrics and updates current-tier file

func ValidateDelegationRequirement

func ValidateDelegationRequirement(agentID string, childCount int) error

ValidateDelegationRequirement checks if an agent met its delegation requirements. Returns error if agent must delegate but didn't spawn enough child agents. Returns nil if requirements are met or agent has no delegation requirement.

func ValidateHookOutput

func ValidateHookOutput(output interface{}) error

ValidateHookOutput validates output against schema (lightweight check)

func ValidateModelMatch

func ValidateModelMatch(agentName string, agentConfig *AgentConfig, requestedModel string) (bool, string)

ValidateModelMatch checks if Task model matches agent's expected model Warning messages are logged to violations.jsonl with type "model_mismatch_warning" and included in CLI output's additionalContext field

func ValidateTaskAtNestingLevel

func ValidateTaskAtNestingLevel(nestingLevel int, toolInput map[string]interface{}) map[string]interface{}

ValidateTaskAtNestingLevel checks if a Task() call is allowed at the given nesting level. Returns nil if allowed, or a block response map if blocked.

At nesting level 0 (Router), all models are allowed. At nesting level 1+ (sub-agents), only haiku and sonnet are allowed. Task(opus) is blocked at Level 1+ to prevent expensive delegation chains.

func ValidateTaskNestingLevel

func ValidateTaskNestingLevel() error

ValidateTaskNestingLevel checks if Task() is allowed at current nesting level. Returns nil if allowed, error with guidance if blocked.

Types

type Agent

type Agent struct {
	ID                        string               `json:"id"`
	Name                      string               `json:"name"`
	Model                     string               `json:"model"`
	Thinking                  bool                 `json:"thinking"`
	ThinkingBudget            int                  `json:"thinking_budget,omitempty"`
	ThinkingBudgetComplex     int                  `json:"thinking_budget_complex,omitempty"`
	EffortLevel               string               `json:"effortLevel,omitempty"`
	Tier                      any                  `json:"tier"` // Can be float64 (1.5) or string ("external")
	Category                  string               `json:"category"`
	Path                      string               `json:"path"`
	Triggers                  []string             `json:"triggers"`
	Tools                     []string             `json:"tools"`
	CliFlags                  *AgentCliFlags       `json:"cli_flags,omitempty"`
	AutoActivate              *AutoActivate        `json:"auto_activate"` // Can be null or object
	Inputs                    []string             `json:"inputs,omitempty"`
	Outputs                   []string             `json:"outputs,omitempty"`
	ConventionsRequired       []string             `json:"conventions_required,omitempty"`
	SharpEdgesCount           int                  `json:"sharp_edges_count,omitempty"`
	Description               string               `json:"description"`
	AutoFire                  []string             `json:"auto_fire,omitempty"`
	ScoutFirst                bool                 `json:"scout_first,omitempty"`
	MustDelegate              bool                 `json:"must_delegate,omitempty"`
	MinDelegations            int                  `json:"min_delegations,omitempty"`
	OutputArtifacts           *OutputArtifacts     `json:"output_artifacts,omitempty"`
	InputSources              []string             `json:"input_sources,omitempty"`
	Invocation                string               `json:"invocation,omitempty"`
	Protocols                 []string             `json:"protocols,omitempty"`
	StateFiles                *StateFiles          `json:"state_files,omitempty"`
	CostPerInvocation         string               `json:"cost_per_invocation,omitempty"`
	ParallelSafe              bool                 `json:"parallel_safe,omitempty"`
	SwarmCompatible           bool                 `json:"swarm_compatible,omitempty"`
	Interactive               bool                 `json:"interactive,omitempty"`
	OutputFormat              string               `json:"output_format,omitempty"`
	OutputFile                string               `json:"output_file,omitempty"`
	CostCeilingUSD            float64              `json:"cost_ceiling_usd,omitempty"`
	FallbackFor               string               `json:"fallback_for,omitempty"`
	SpawnedBy                 []string             `json:"spawned_by,omitempty"`
	CanSpawn                  []string             `json:"can_spawn,omitempty"`
	ContextRequirements       *ContextRequirements `json:"context_requirements,omitempty"`
	DefaultAcceptanceCriteria []string             `json:"default_acceptance_criteria,omitempty"`
}

Agent represents a single agent definition with complete v2.2.0 fields.

func (*Agent) GetAllowedTools

func (ag *Agent) GetAllowedTools() []string

GetAllowedTools returns CLI-permitted tools for this agent. Returns cli_flags.allowed_tools if configured, otherwise conservative read-only fallback.

func (*Agent) ValidateAgent

func (ag *Agent) ValidateAgent() error

ValidateAgent performs validation on individual agent configuration.

type AgentClass

type AgentClass string

AgentClass represents agent classification

const (
	ClassOrchestrator   AgentClass = "orchestrator"
	ClassImplementation AgentClass = "implementation"
	ClassSpecialist     AgentClass = "specialist"
	ClassCoordination   AgentClass = "coordination"
	ClassAnalysis       AgentClass = "analysis"
	ClassReview         AgentClass = "review"
	ClassUnknown        AgentClass = "unknown"
)

func GetAgentClass

func GetAgentClass(agentID string) AgentClass

GetAgentClass returns the class of agent based on agent_id. Orchestrator-class agents may spawn background tasks and need collection validation.

type AgentCliFlags

type AgentCliFlags struct {
	AllowedTools    []string `json:"allowed_tools"`
	AdditionalFlags []string `json:"additional_flags,omitempty"`
}

AgentCliFlags represents CLI spawning configuration for an agent.

type AgentConfig

type AgentConfig struct {
	Name                string               `json:"name"`
	Model               string               `json:"model"`
	SubagentType        string               `json:"subagent_type"`
	AllowedModels       []string             `json:"allowed_models,omitempty"`
	ContextRequirements *ContextRequirements `json:"context_requirements,omitempty"`
	CliFlags            *AgentCliFlags       `json:"cli_flags,omitempty"`
}

AgentConfig represents agent metadata from agents-index.json

type AgentDelegationConfig

type AgentDelegationConfig struct {
	MustDelegate   bool `json:"must_delegate"`
	MinDelegations int  `json:"min_delegations"`
}

AgentDelegationConfig holds delegation requirements for an agent. Matches must_delegate and min_delegations fields in agents-index.json.

func GetAgentDelegationConfig

func GetAgentDelegationConfig(agentID string) AgentDelegationConfig

GetAgentDelegationConfig retrieves delegation requirements for the specified agent. Returns zero-value config if agent not found or has no delegation requirements. This function never errors - unknown agents are treated as having no requirements.

type AgentIndex

type AgentIndex struct {
	Version         string          `json:"version"`
	GeneratedAt     string          `json:"generated_at"`
	Description     string          `json:"description"`
	Agents          []Agent         `json:"agents"`
	RoutingRules    RoutingRules    `json:"routing_rules"`
	StateManagement StateManagement `json:"state_management"`
}

AgentIndex represents the complete agents-index.json v2.2.0 structure. This defines the agent catalog for Claude Code routing and auto-activation.

func LoadAgentIndex

func LoadAgentIndex() (*AgentIndex, error)

LoadAgentIndex loads and validates agents-index.json. Priority: GOYOKE_AGENTS_INDEX env var (Tier 0) > resolve.Default() layered resolver. When both userFS and embedFS layers exist, agents are merged by ID (embedFS=base, userFS=override). Returns an error if file is missing, malformed, or version mismatch detected.

func LoadAgentsIndexCached

func LoadAgentsIndexCached() (*AgentIndex, error)

LoadAgentsIndexCached loads the agents index with caching. Subsequent calls return the cached index without re-reading the file. Thread-safe via RWMutex.

func (*AgentIndex) FindAgentByCategory

func (a *AgentIndex) FindAgentByCategory(category string) []*Agent

FindAgentByCategory returns all agents in the specified category. Returns empty slice if no matching agents found.

func (*AgentIndex) FindAgentByLanguage

func (a *AgentIndex) FindAgentByLanguage(language string) []*Agent

FindAgentByLanguage returns agents that auto-activate for the given language. Returns empty slice if no matching agents found.

func (*AgentIndex) FindAgentByPattern

func (a *AgentIndex) FindAgentByPattern(pattern string) []*Agent

FindAgentByPattern returns agents that auto-activate for the given pattern. Returns empty slice if no matching agents found.

func (*AgentIndex) FindAgentByTrigger

func (a *AgentIndex) FindAgentByTrigger(trigger string) []*Agent

FindAgentByTrigger returns agents with the specified trigger phrase. Returns empty slice if no matching agents found.

func (*AgentIndex) GetAgentByID

func (a *AgentIndex) GetAgentByID(agentID string) (*Agent, error)

GetAgentByID returns the agent with the specified ID. Returns an error if the agent does not exist.

func (*AgentIndex) GetAgentsByTier

func (a *AgentIndex) GetAgentsByTier(tierName string) ([]*Agent, error)

GetAgentsByTier returns all agents in the specified tier. Returns an error if the tier does not exist in model_tiers.

func (*AgentIndex) GetScoutAgents

func (a *AgentIndex) GetScoutAgents() []*Agent

GetScoutAgents returns all agents with scout_first=true or in scout protocols. Returns empty slice if no scout agents found.

func (*AgentIndex) GetTierForAgent

func (a *AgentIndex) GetTierForAgent(agentID string) (string, error)

GetTierForAgent returns the tier name for an agent by looking up model_tiers. Returns an error if the agent is not found in any tier.

func (*AgentIndex) GetToolsForAgent

func (a *AgentIndex) GetToolsForAgent(agentID string) ([]string, error)

GetToolsForAgent returns the tool list for the specified agent. Returns an error if the agent does not exist.

func (*AgentIndex) Validate

func (a *AgentIndex) Validate() error

Validate performs semantic validation on the loaded agent index. Checks version compatibility, agent ID uniqueness, and reference integrity.

func (*AgentIndex) ValidateDependencies

func (a *AgentIndex) ValidateDependencies() error

ValidateDependencies checks for circular dependencies in agent AutoActivate.Dependencies. Uses depth-first search to detect cycles in the dependency graph.

type AgentSubagentMapping

type AgentSubagentMapping struct {
	Description                  string               `json:"description"`
	CodebaseSearch               FlexibleSubagentType `json:"codebase-search"`
	HaikuScout                   FlexibleSubagentType `json:"haiku-scout"`
	CodeReviewer                 FlexibleSubagentType `json:"code-reviewer"`
	Librarian                    FlexibleSubagentType `json:"librarian"`
	TechDocsWriter               FlexibleSubagentType `json:"tech-docs-writer"`
	Scaffolder                   FlexibleSubagentType `json:"scaffolder"`
	MemoryArchivist              FlexibleSubagentType `json:"memory-archivist"`
	PythonPro                    FlexibleSubagentType `json:"python-pro"`
	PythonUX                     FlexibleSubagentType `json:"python-ux"`
	RPro                         FlexibleSubagentType `json:"r-pro"`
	RShinyPro                    FlexibleSubagentType `json:"r-shiny-pro"`
	GoPro                        FlexibleSubagentType `json:"go-pro"`
	GoCLI                        FlexibleSubagentType `json:"go-cli"`
	GoTUI                        FlexibleSubagentType `json:"go-tui"`
	GoAPI                        FlexibleSubagentType `json:"go-api"`
	GoConcurrent                 FlexibleSubagentType `json:"go-concurrent"`
	TypescriptPro                FlexibleSubagentType `json:"typescript-pro"`
	ReactPro                     FlexibleSubagentType `json:"react-pro"`
	BackendReviewer              FlexibleSubagentType `json:"backend-reviewer"`
	FrontendReviewer             FlexibleSubagentType `json:"frontend-reviewer"`
	StandardsReviewer            FlexibleSubagentType `json:"standards-reviewer"`
	ReviewOrchestrator           FlexibleSubagentType `json:"review-orchestrator"`
	ImplManager                  FlexibleSubagentType `json:"impl-manager"`
	Orchestrator                 FlexibleSubagentType `json:"orchestrator"`
	Architect                    FlexibleSubagentType `json:"architect"`
	Planner                      FlexibleSubagentType `json:"planner"`
	PythonArchitect              FlexibleSubagentType `json:"python-architect"`
	Einstein                     FlexibleSubagentType `json:"einstein"`
	Mozart                       FlexibleSubagentType `json:"mozart"`
	Beethoven                    FlexibleSubagentType `json:"beethoven"`
	StaffArchitectCriticalReview FlexibleSubagentType `json:"staff-architect-critical-review"`
	SchemaArchitect              FlexibleSubagentType `json:"schema-architect"`
}

AgentSubagentMapping maps each agent to its required subagent_type.

type AgentsIndex

type AgentsIndex struct {
	Agents map[string]AgentConfig `json:"agents"`
}

AgentsIndex represents the full agents-index.json structure

type AutoActivate

type AutoActivate struct {
	Languages    []string `json:"languages,omitempty"`
	Patterns     []string `json:"patterns,omitempty"`
	Dependencies []string `json:"dependencies,omitempty"`
	FilePatterns []string `json:"file_patterns,omitempty"`
}

AutoActivate defines conditions for agent auto-activation.

type BashBlockedBinary

type BashBlockedBinary struct {
	Reason   string `json:"reason"`
	Redirect string `json:"redirect"`
}

BashBlockedBinary defines a binary that must not be invoked directly via Bash.

type BashToolCall

type BashToolCall struct {
	Command         string `json:"command"`
	RunInBackground bool   `json:"run_in_background"`
}

BashToolCall represents a Bash tool call with run_in_background parameter.

type BlockedPattern

type BlockedPattern struct {
	Pattern     string `json:"pattern"`
	Reason      string `json:"reason"`
	Alternative string `json:"alternative"`
	CostImpact  string `json:"cost_impact"`
}

BlockedPattern represents a forbidden pattern with guidance.

type BlockedPatternsConfig

type BlockedPatternsConfig struct {
	Description string           `json:"description"`
	Patterns    []BlockedPattern `json:"patterns"`
}

BlockedPatternsConfig contains patterns that should never be used.

type Cleanup

type Cleanup struct {
	Trigger string `json:"trigger"`
	Action  string `json:"action"`
}

Cleanup defines state cleanup rules.

type ComplexityRouting

type ComplexityRouting struct {
	Description     string               `json:"description"`
	Calculator      string               `json:"calculator"`
	Thresholds      map[string]Threshold `json:"thresholds"`
	ForceExternalIf string               `json:"force_external_if"`
}

ComplexityRouting defines complexity-based tier selection.

type CompoundTriggers

type CompoundTriggers struct {
	Description string     `json:"description"`
	Examples    [][]string `json:"examples"`
	Action      string     `json:"action"`
}

CompoundTriggers defines multi-pattern escalation to orchestrator.

type ConditionalConvention

type ConditionalConvention struct {
	// Pattern is a glob pattern to match file paths in the task
	Pattern string `json:"pattern"`

	// Convention is the filename to load if pattern matches
	Convention string `json:"convention"`
}

ConditionalConvention represents a convention that's only loaded when the task involves files matching the pattern.

type ContextRequirements

type ContextRequirements struct {
	// Rules lists rules files to inject (e.g., "agent-guidelines.md")
	Rules []string `json:"rules,omitempty"`

	// Conventions specifies convention files to inject
	Conventions ConventionRequirements `json:"conventions,omitempty"`
}

ContextRequirements defines what context an agent needs at spawn time. This is used by goyoke-validate to inject conventions into Task prompts.

func (*ContextRequirements) GetAllConventions

func (c *ContextRequirements) GetAllConventions(taskFiles []string) []string

GetAllConventions returns all conventions that should be loaded, given a list of file paths mentioned in the task.

func (*ContextRequirements) HasContextRequirements

func (c *ContextRequirements) HasContextRequirements() bool

HasContextRequirements returns true if the agent has any context requirements.

type ConventionRequirements

type ConventionRequirements struct {
	// Base conventions always injected for this agent
	Base []string `json:"base,omitempty"`

	// Conditional conventions injected based on file path patterns
	Conditional []ConditionalConvention `json:"conditional,omitempty"`
}

ConventionRequirements specifies base and conditional conventions.

type CostThresholds

type CostThresholds struct {
	ScoutMaxCost       float64 `json:"scout_max_cost"`
	ExplorationMaxCost float64 `json:"exploration_max_cost"`
	Description        string  `json:"description"`
}

CostThresholds defines cost ceilings for pre-execution phases.

type DelegationCeiling

type DelegationCeiling struct {
	Description string            `json:"description"`
	File        string            `json:"file"`
	SetBy       string            `json:"set_by"`
	EnforcedBy  string            `json:"enforced_by"`
	Values      []string          `json:"values"`
	Note        string            `json:"note"`
	Override    string            `json:"override"`
	Calculation map[string]string `json:"calculation"`
}

DelegationCeiling controls which agents can be spawned via Task().

type DelegationCeilingRuntime

type DelegationCeilingRuntime struct {
	MaxTier string // e.g., "haiku", "sonnet"
}

DelegationCeilingRuntime represents max allowed delegation tier

func LoadDelegationCeiling

func LoadDelegationCeiling(projectDir string) (*DelegationCeilingRuntime, error)

LoadDelegationCeiling reads max_delegation file from project

type DelegationRules

type DelegationRules struct {
	Description                  string   `json:"description"`
	TaskAlwaysAllowed            bool     `json:"task_always_allowed"`
	TierRestrictionsApplyTo      []string `json:"tier_restrictions_apply_to"`
	TierRestrictionsDoNotApplyTo []string `json:"tier_restrictions_do_not_apply_to"`
	Rationale                    string   `json:"rationale"`
}

DelegationRules defines Task() tool permissions.

type DirectImplCheckConfig

type DirectImplCheckConfig struct {
	Description              string   `json:"description"`
	Enabled                  bool     `json:"enabled"`
	WriteThresholdLines      int      `json:"write_threshold_lines"`
	EditThresholdLines       int      `json:"edit_threshold_lines"`
	ImplementationExtensions []string `json:"implementation_extensions"`
	ImplementationPaths      []string `json:"implementation_paths"`
	ExcludedPatterns         []string `json:"excluded_patterns"`
}

DirectImplCheckConfig configures detection of direct implementation instead of delegation.

type DocumentationTheater

type DocumentationTheater struct {
	Description       string   `json:"description"`
	DetectionPatterns []string `json:"detection_patterns"`
	TargetFiles       []string `json:"target_files"`
	Enforcement       string   `json:"enforcement"`
	Guidance          string   `json:"guidance"`
}

DocumentationTheater defines detection of unenforceable imperatives.

type EscalationRules

type EscalationRules struct {
	HaikuToHaikuThinking []string         `json:"haiku_to_haiku_thinking"`
	HaikuToSonnet        []string         `json:"haiku_to_sonnet"`
	SonnetToOpus         SonnetToOpusRule `json:"sonnet_to_opus"`
}

EscalationRules defines tier-to-tier escalation triggers.

type FailureInfo

type FailureInfo struct {
	File       string `json:"file"`
	ErrorType  string `json:"error_type"`
	Timestamp  int64  `json:"timestamp"`
	Tool       string `json:"tool,omitempty"`
	ExitCode   int    `json:"exit_code,omitempty"`
	ErrorMatch string `json:"error_match,omitempty"` // The specific text that matched
}

FailureInfo captures detected failure information Compatible with session.SharpEdge struct for seamless integration

func DetectFailure

func DetectFailure(event *PostToolEvent) *FailureInfo

DetectFailure analyzes PostToolEvent for failure signals Returns nil if no failure detected

type FlexibleSubagentType

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

FlexibleSubagentType supports both string and []string JSON unmarshaling for backwards compatibility with routing-schema.json.

Accepts:

  • "codebase-search": "Explore" (single string, backwards compat)
  • "staff-architect-critical-review": ["Plan", "Explore"] (array, new multi-type)

func NewFlexibleSubagentType

func NewFlexibleSubagentType(types ...string) FlexibleSubagentType

NewFlexibleSubagentType creates a FlexibleSubagentType from one or more types. This is the recommended way to create FlexibleSubagentType in tests and code.

func (*FlexibleSubagentType) Contains

func (f *FlexibleSubagentType) Contains(subagentType string) bool

Contains checks if the given subagent_type is in the allowed list.

func (*FlexibleSubagentType) GetAll

func (f *FlexibleSubagentType) GetAll() []string

GetAll returns all allowed subagent_types. For single-type entries, returns a slice containing that one type.

func (*FlexibleSubagentType) Primary

func (f *FlexibleSubagentType) Primary() string

Primary returns the first/only subagent_type. Useful for error messages and single-type compatibility.

func (*FlexibleSubagentType) UnmarshalJSON

func (f *FlexibleSubagentType) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshals either a string or []string into FlexibleSubagentType. Tries string first, falls back to []string if that fails.

type HookResponse

type HookResponse struct {
	Decision           string                 `json:"decision,omitempty"`
	Reason             string                 `json:"reason,omitempty"`
	HookSpecificOutput map[string]interface{} `json:"hookSpecificOutput"`
}

HookResponse represents the JSON response structure for hooks. This is the canonical response format that all hooks must emit. Empty Decision/Reason fields are omitted from JSON output to avoid schema violations.

func AllowResponseForDelegation

func AllowResponseForDelegation(agentID string, required, actual int) *HookResponse

AllowResponseForDelegation creates a SubagentStop allow response for successful delegation. Includes telemetry-friendly structured output for ML analysis.

func BlockResponseForDelegation

func BlockResponseForDelegation(agentID string, required, actual int) *HookResponse

BlockResponseForDelegation creates a SubagentStop block response for delegation violations. Includes structured hook-specific output with required delegations and suggestions.

func NewBlockResponse

func NewBlockResponse(hookEventName, reason string) *HookResponse

NewBlockResponse creates a HookResponse with decision="block". hookEventName is automatically populated in hookSpecificOutput.

func NewModifyResponse

func NewModifyResponse(hookEventName string, updatedInput map[string]interface{}) *HookResponse

NewModifyResponse creates a HookResponse that modifies the tool input. This is used by PreToolUse hooks to inject conventions into Task prompts. The updatedInput map should contain the complete modified tool input. Uses permissionDecision: "allow" in hookSpecificOutput per Claude Code PreToolUse schema. Top-level decision is omitted (deprecated for PreToolUse events).

func NewPassResponse

func NewPassResponse(hookEventName string) *HookResponse

NewPassResponse creates a HookResponse with no decision/reason fields. This is used for context-only responses like additionalContext injection.

func NewWarnResponse

func NewWarnResponse(hookEventName, reason string) *HookResponse

NewWarnResponse creates a HookResponse with decision="warn". hookEventName is automatically populated in hookSpecificOutput.

func ValidateDelegationFromTranscript

func ValidateDelegationFromTranscript(transcriptPath string) (*HookResponse, error)

ValidateDelegationFromTranscript validates delegation requirements using transcript analysis. This is the primary entry point for the orchestrator-guard hook.

Process: 1. Parse agent metadata from transcript 2. Get delegation config for agent 3. Validate child count meets requirements 4. Return block/allow response

Fail-open behavior: If any step fails (parsing, config load), returns allow response.

func (*HookResponse) AddField

func (r *HookResponse) AddField(key string, value interface{})

AddField adds a custom field to hookSpecificOutput. This allows hooks to include tool-specific data in the response.

func (*HookResponse) GetDecision

func (r *HookResponse) GetDecision() string

GetDecision retrieves the decision field from the HookResponse.

func (*HookResponse) GetUpdatedInput

func (r *HookResponse) GetUpdatedInput() map[string]interface{}

GetUpdatedInput returns the updatedInput map if present, nil otherwise.

func (*HookResponse) HasUpdatedInput

func (r *HookResponse) HasUpdatedInput() bool

HasUpdatedInput returns true if this response modifies the tool input.

func (*HookResponse) Marshal

func (r *HookResponse) Marshal(w io.Writer) error

Marshal writes the HookResponse as indented JSON to the provided writer. Returns an error if JSON marshaling or writing fails.

func (*HookResponse) SetDecision

func (r *HookResponse) SetDecision(decision string)

SetDecision sets the decision field of the HookResponse. Use the Decision* constants for valid values.

func (*HookResponse) Validate

func (r *HookResponse) Validate() error

Validate checks that the HookResponse has valid decision values and required fields. Returns an error if validation fails.

type IntentGate

type IntentGate struct {
	Description string       `json:"description"`
	Types       []IntentType `json:"types"`
}

IntentGate defines pre-classification rules.

type IntentType

type IntentType struct {
	Type   string `json:"type"`
	Signal string `json:"signal"`
	Action string `json:"action"`
}

IntentType represents a message intent classification.

type MetaRules

type MetaRules struct {
	DocumentationTheater DocumentationTheater `json:"documentation_theater"`
}

MetaRules defines meta-enforcement rules.

type MetricsConfig

type MetricsConfig struct {
	TTLSeconds   int    // Default: 300 (5 minutes)
	FallbackTier string // Default: "sonnet"
}

MetricsConfig defines TTL and fallback behavior

func DefaultMetricsConfig

func DefaultMetricsConfig() *MetricsConfig

DefaultMetricsConfig returns standard config

type NestingLevelError

type NestingLevelError struct {
	Level   int
	Message string
}

NestingLevelError represents a Task() blocked due to nesting level.

func (*NestingLevelError) Error

func (e *NestingLevelError) Error() string

type OutputArtifacts

type OutputArtifacts struct {
	Required      []string `json:"required"`
	SpecsLocation string   `json:"specs_location,omitempty"`
}

OutputArtifacts defines required outputs for planning agents.

type Override

type Override struct {
	Flag        string   `json:"flag"`
	Description string   `json:"description"`
	ValidTiers  []string `json:"valid_tiers"`
	AuditLog    string   `json:"audit_log"`
}

Override defines user escape hatch for routing.

type OverrideFlags

type OverrideFlags struct {
	ForceTier       string // e.g., "haiku", "sonnet", "opus"
	ForceDelegation string // e.g., "haiku", "sonnet"
}

OverrideFlags represents parsed override flags from prompt

func ParseOverrides

func ParseOverrides(prompt string) *OverrideFlags

ParseOverrides extracts --force-* flags from Task prompt

func (*OverrideFlags) HasOverrides

func (o *OverrideFlags) HasOverrides() bool

HasOverrides returns true if any overrides are present

type ParsedAgentMetadata

type ParsedAgentMetadata struct {
	AgentID      string `json:"agent_id,omitempty"`      // e.g., "orchestrator", "python-pro"
	AgentModel   string `json:"agent_model,omitempty"`   // "haiku", "sonnet", "opus"
	Tier         string `json:"tier,omitempty"`          // Derived from model
	DurationMs   int    `json:"duration_ms,omitempty"`   // Calculated from transcript timestamps
	OutputTokens int    `json:"output_tokens,omitempty"` // From transcript if available
	ExitCode     int    `json:"exit_code,omitempty"`     // 0=success, derived from completion status
}

ParsedAgentMetadata contains agent information extracted from transcript file. All fields are optional as transcript parsing may fail.

func EnrichMetadataFromEvent

func EnrichMetadataFromEvent(event *SubagentStopEvent) (*ParsedAgentMetadata, error)

EnrichMetadataFromEvent populates agent metadata from direct event fields (v2.1.69+), falling back to transcript parsing when event fields are absent. Always parses transcript for duration, tokens, and exit code (not in event fields).

func ParseOrchestratorStopEvent

func ParseOrchestratorStopEvent(r io.Reader, timeout time.Duration) (*ParsedAgentMetadata, error)

ParseOrchestratorStopEvent parses SubagentStop event and extracts agent metadata. This function composes ParseSubagentStopEvent and ParseTranscriptForMetadata to provide orchestrator-guard with complete agent information in a single call.

Returns ParsedAgentMetadata (possibly partial on transcript errors) and any error encountered. Follows graceful degradation: returns partial metadata even when transcript parsing fails.

func ParseTranscriptForMetadata

func ParseTranscriptForMetadata(transcriptPath string) (*ParsedAgentMetadata, error)

ParseTranscriptForMetadata reads transcript file and extracts agent metadata. Returns partial metadata on parsing errors rather than failing completely (graceful degradation).

func (*ParsedAgentMetadata) IsSuccess

func (m *ParsedAgentMetadata) IsSuccess() bool

IsSuccess returns true if agent completed successfully (derived from metadata)

type PostToolEvent

type PostToolEvent struct {
	// Core fields (DO NOT MODIFY - backward compatibility)
	ToolName      string                 `json:"tool_name"`
	ToolInput     map[string]interface{} `json:"tool_input"`
	ToolResponse  map[string]interface{} `json:"tool_response"`
	SessionID     string                 `json:"session_id"`
	HookEventName string                 `json:"hook_event_name"`
	CapturedAt    int64                  `json:"captured_at"`

	// v2.1.69 common fields
	CWD            string `json:"cwd,omitempty"`
	PermissionMode string `json:"permission_mode,omitempty"`
	AgentID        string `json:"agent_id,omitempty"`
	AgentType      string `json:"agent_type,omitempty"`

	// Performance metrics
	DurationMs   int64 `json:"duration_ms,omitempty"`
	InputTokens  int   `json:"input_tokens,omitempty"`
	OutputTokens int   `json:"output_tokens,omitempty"`

	// Model context
	Model string `json:"model,omitempty"`
	Tier  string `json:"tier,omitempty"`

	// Outcome
	Success bool `json:"success,omitempty"`

	// Sequence tracking (GAP 4.2)
	SequenceIndex    int      `json:"sequence_index,omitempty"`
	PreviousTools    []string `json:"previous_tools,omitempty"`
	PreviousOutcomes []bool   `json:"previous_outcomes,omitempty"`

	// Task classification (GAP 4.4)
	TaskType   string `json:"task_type,omitempty"`
	TaskDomain string `json:"task_domain,omitempty"`

	// Routing info (for Task() events)
	SelectedTier  string `json:"selected_tier,omitempty"`
	SelectedAgent string `json:"selected_agent,omitempty"`

	// Correlation
	EventID string `json:"event_id,omitempty"`

	// Understanding context (Addendum A.4)
	TargetSize       int64   `json:"target_size,omitempty"`
	CoverageAchieved float64 `json:"coverage_achieved,omitempty"`
	EntitiesFound    int     `json:"entities_found,omitempty"`
}

PostToolEvent represents PostToolUse events with execution results. These events include both the input and the tool's response.

func ParsePostToolEvent

func ParsePostToolEvent(r io.Reader, timeout time.Duration) (*PostToolEvent, error)

ParsePostToolEvent reads and parses PostToolUse events. Returns an error if JSON parsing fails or required fields are missing. Uses ReadStdin for timeout protection.

type PreToolUseHookOutput

type PreToolUseHookOutput struct {
	HookEventName            string `json:"hookEventName"`
	PermissionDecision       string `json:"permissionDecision"` // "allow", "deny"
	PermissionDecisionReason string `json:"permissionDecisionReason,omitempty"`
	NestingLevel             int    `json:"nestingLevel,omitempty"`
	Suggestion               string `json:"suggestion,omitempty"`
}

type PreToolUseInput

type PreToolUseInput struct {
	HookEventName string                 `json:"hook_event_name"`
	SessionID     string                 `json:"session_id"`
	ToolName      string                 `json:"tool_name"`
	ToolInput     map[string]interface{} `json:"tool_input,omitempty"`
}

PreToolUseInput matches hook-io-schema.json#/definitions/PreToolUseInput

type PreToolUseOutput

type PreToolUseOutput struct {
	Decision           string                `json:"decision"` // "allow", "block", "modify"
	Reason             string                `json:"reason,omitempty"`
	HookSpecificOutput *PreToolUseHookOutput `json:"hookSpecificOutput,omitempty"`
}

PreToolUseOutput matches hook-io-schema.json#/definitions/PreToolUseOutput

type Protocol

type Protocol struct {
	Model  string `json:"model"`
	Output string `json:"output"`
}

Protocol defines external model protocol configuration.

type RoutingRules

type RoutingRules struct {
	IntentGate         IntentGate          `json:"intent_gate"`
	ScoutFirstProtocol ScoutFirstProtocol  `json:"scout_first_protocol"`
	ComplexityRouting  ComplexityRouting   `json:"complexity_routing"`
	AutoFire           map[string]string   `json:"auto_fire"`
	ModelTiers         map[string][]string `json:"model_tiers"`
}

RoutingRules defines routing behavior configuration.

type Schema

type Schema struct {
	SchemaVersion        string                       `json:"$schema"`
	Version              string                       `json:"version"`
	Description          string                       `json:"description"`
	Updated              string                       `json:"updated"`
	Tiers                map[string]TierConfig        `json:"tiers"`
	TierLevels           TierLevels                   `json:"tier_levels"`
	DelegationCeiling    DelegationCeiling            `json:"delegation_ceiling"`
	ScoutProtocol        ScoutProtocol                `json:"scout_protocol"`
	EscalationRules      EscalationRules              `json:"escalation_rules"`
	CompoundTriggers     CompoundTriggers             `json:"compound_triggers"`
	CostThresholds       CostThresholds               `json:"cost_thresholds"`
	Override             Override                     `json:"override"`
	SubagentTypesConfig  SubagentTypesConfig          `json:"subagent_types"`
	DelegationRules      DelegationRules              `json:"delegation_rules"`
	AgentSubagentMapping AgentSubagentMapping         `json:"agent_subagent_mapping"`
	BlockedPatterns      BlockedPatternsConfig        `json:"blocked_patterns"`
	DirectImplCheck      DirectImplCheckConfig        `json:"direct_impl_check"`
	MetaRules            MetaRules                    `json:"meta_rules"`
	BashBlockedBinaries  map[string]BashBlockedBinary `json:"bash_blocked_binaries"`
}

Schema represents the complete routing-schema.json v2.2.0 structure. This defines the tiered agent architecture for Claude Code.

func LoadSchema

func LoadSchema() (*Schema, error)

LoadSchema loads and validates routing-schema.json. Priority: GOYOKE_ROUTING_SCHEMA env var (Tier 0) > resolve.NewFromEnv() first-found. Returns an error if file is missing, malformed, or version mismatch detected.

func (*Schema) FormatTierSummary

func (s *Schema) FormatTierSummary() string

FormatTierSummary generates a concise routing tier summary for session context. Limits patterns to first 3 and tools to first 4 to prevent context bloat. Format:

ROUTING TIERS ACTIVE:
  • haiku: patterns=[...] → tools=[...]
  • sonnet: patterns=[...] → tools=[...]

DELEGATION CEILING: Set by {SetBy}

func (*Schema) GetAllowedSubagentTypes

func (s *Schema) GetAllowedSubagentTypes(agentName string) ([]string, error)

GetAllowedSubagentTypes returns all allowed subagent_types for an agent. For agents with multi-type support, returns all types. For single-type agents, returns a slice containing that one type. Returns an error if the agent is not in the mapping.

func (*Schema) GetSubagentType

func (s *Schema) GetSubagentType(category string) (*SubagentType, error)

GetSubagentType returns SubagentType configuration for an informational category. Returns an error if the category does not exist.

func (*Schema) GetSubagentTypeForAgent deprecated

func (s *Schema) GetSubagentTypeForAgent(agentName string) (string, error)

GetSubagentTypeForAgent returns the primary subagent_type for an agent. For backwards compatibility, this returns the first type in multi-type mappings.

Deprecated: Use GetAllowedSubagentTypes to get all allowed types. This function only returns the primary type and may not represent the full set of allowed types.

func (*Schema) GetTier

func (s *Schema) GetTier(tierName string) (*TierConfig, error)

GetTier returns TierConfig for the given tier name. Returns an error if the tier does not exist.

func (*Schema) GetTierLevel

func (s *Schema) GetTierLevel(tierName string) (int, error)

GetTierLevel returns numeric tier level for comparison. Returns an error if the tier does not exist in tier_levels.

func (*Schema) Validate

func (s *Schema) Validate() error

Validate performs semantic validation on the loaded schema. Checks version compatibility, tier name validity, and reference integrity.

func (*Schema) ValidateAgentSubagentPair

func (s *Schema) ValidateAgentSubagentPair(agentName, subagentType string) error

ValidateAgentSubagentPair checks if agent-subagent_type pairing is valid. Returns an error if the pairing violates the mapping in routing-schema.json.

type ScoutCriteria

type ScoutCriteria struct {
	MaxFiles  *int   `json:"max_files,omitempty"`
	MinFiles  *int   `json:"min_files,omitempty"`
	MaxTokens *int   `json:"max_tokens,omitempty"`
	MinTokens *int   `json:"min_tokens,omitempty"`
	Reason    string `json:"reason"`
}

ScoutCriteria defines selection criteria for scout type.

type ScoutFirstProtocol

type ScoutFirstProtocol struct {
	Description string   `json:"description"`
	Triggers    []string `json:"triggers"`
	SkipWhen    []string `json:"skip_when"`
	Primary     string   `json:"primary"`
	Fallback    string   `json:"fallback"`
	Output      string   `json:"output"`
}

ScoutFirstProtocol defines pre-routing reconnaissance configuration.

type ScoutMetrics

type ScoutMetrics struct {
	// Base fields (required by goYoke-013)
	FileCount       int      `json:"file_count"`
	TotalLines      int      `json:"total_lines"`
	ComplexityScore float64  `json:"complexity_score"`
	RecommendedTier string   `json:"recommended_tier"`
	Timestamp       int64    `json:"timestamp"`
	ScannedPaths    []string `json:"scanned_paths,omitempty"`

	// Future expansion fields (goYoke-014+)
	EstimatedTokens       int     `json:"estimated_tokens,omitempty"`
	Confidence            float64 `json:"confidence,omitempty"`
	ClarificationNeeded   bool    `json:"clarification_needed,omitempty"`
	ImportDensity         float64 `json:"import_density,omitempty"`
	CrossFileDependencies int     `json:"cross_file_dependencies,omitempty"`
}

ScoutMetrics represents output from haiku-scout agent. Contains file counts, LoC, complexity signals for routing decisions.

func LoadScoutMetrics

func LoadScoutMetrics(projectDir string) (*ScoutMetrics, error)

LoadScoutMetrics reads scout_metrics.json from project tmp directory. Returns nil (no error) when file doesn't exist (scout hasn't run yet). Validates required fields and tier name before returning.

func (*ScoutMetrics) Age

func (m *ScoutMetrics) Age() int64

Age returns metrics age in seconds. Returns -1 if metrics are nil (nil safety).

func (*ScoutMetrics) GetActiveTier

func (m *ScoutMetrics) GetActiveTier(config *MetricsConfig) string

GetActiveTier returns tier based on metrics freshness If fresh: returns recommended_tier from metrics If stale: returns fallback tier

func (*ScoutMetrics) IsFresh

func (m *ScoutMetrics) IsFresh(ttlSeconds int) bool

IsFresh returns true if metrics are less than ttlSeconds old. Returns false if metrics are nil (nil safety).

type ScoutOutputSchema

type ScoutOutputSchema struct {
	ScopeMetrics          []string `json:"scope_metrics"`
	ComplexitySignals     []string `json:"complexity_signals"`
	RoutingRecommendation []string `json:"routing_recommendation"`
}

ScoutOutputSchema defines expected scout output structure.

type ScoutProtocol

type ScoutProtocol struct {
	Description         string              `json:"description"`
	Primary             string              `json:"primary"`
	Fallback            string              `json:"fallback"`
	SelectionLogic      ScoutSelectionLogic `json:"selection_logic"`
	CostPerCallEstimate float64             `json:"cost_per_call_estimate"`
	Invocation          string              `json:"invocation"`
	OutputSchema        ScoutOutputSchema   `json:"output_schema"`
	WhenToUse           []string            `json:"when_to_use"`
	WhenToSkip          []string            `json:"when_to_skip"`
}

ScoutProtocol defines pre-routing reconnaissance configuration.

type ScoutSelectionLogic

type ScoutSelectionLogic struct {
	HaikuScout ScoutCriteria `json:"haiku_scout"`
}

ScoutSelectionLogic defines logic for choosing between scout types.

type SessionPhase

type SessionPhase struct {
	Phase     string // "discovery", "implementation", "debugging", "delegation", "mixed"
	StartTime int64
	Duration  int64
	ToolCount int
}

SessionPhase represents a detected work phase within a session

func DetectPhases

func DetectPhases(events []ToolEvent) []SessionPhase

DetectPhases identifies session work phases based on tool usage patterns Uses threshold heuristics: 70% for discovery/implementation/delegation, 50% for debugging

type SonnetToOpusRule

type SonnetToOpusRule struct {
	Triggers     []string `json:"triggers"`
	Action       string   `json:"action"`
	Protocol     string   `json:"protocol"`
	OutputPath   string   `json:"output_path"`
	Notification string   `json:"notification"`
}

SonnetToOpusRule defines special handling for Opus escalation.

type StateFile

type StateFile struct {
	WrittenBy  []string `json:"written_by"`
	ReadBy     []string `json:"read_by"`
	TTLMinutes *int     `json:"ttl_minutes"` // Can be null
	ArchivedTo string   `json:"archived_to,omitempty"`
}

StateFile defines state file metadata.

type StateFiles

type StateFiles struct {
	ScoutOutput     string `json:"scout_output,omitempty"`
	ComplexityScore string `json:"complexity_score,omitempty"`
}

StateFiles defines state file locations for external agents.

type StateManagement

type StateManagement struct {
	Description  string               `json:"description"`
	TmpDirectory string               `json:"tmp_directory"`
	Files        map[string]StateFile `json:"files"`
	Cleanup      Cleanup              `json:"cleanup"`
}

StateManagement defines file-based state passing.

type SubagentStopEvent

type SubagentStopEvent struct {
	HookEventName  string `json:"hook_event_name"` // Always "SubagentStop"
	SessionID      string `json:"session_id"`
	TranscriptPath string `json:"transcript_path"` // Session transcript path
	StopHookActive bool   `json:"stop_hook_active"`

	// v2.1.69 common + SubagentStop-specific fields
	AgentID              string `json:"agent_id,omitempty"`               // Unique subagent identifier
	AgentType            string `json:"agent_type,omitempty"`             // Agent name (e.g., "Explore", "GO Pro")
	AgentTranscriptPath  string `json:"agent_transcript_path,omitempty"`  // Subagent's own transcript (separate from session)
	LastAssistantMessage string `json:"last_assistant_message,omitempty"` // Final response text
	CWD                  string `json:"cwd,omitempty"`
	PermissionMode       string `json:"permission_mode,omitempty"`
}

SubagentStopEvent represents the Claude Code SubagentStop hook event. As of v2.1.69, agent metadata is available directly in event fields. For pre-v2.1.69 compatibility, metadata can also be extracted from transcript file. Schema validated via goYoke-063a research, updated goYoke-v2169.

func ParseSubagentStopEvent

func ParseSubagentStopEvent(r io.Reader, timeout time.Duration) (*SubagentStopEvent, error)

ParseSubagentStopEvent reads SubagentStop event from STDIN using ACTUAL schema

type SubagentType

type SubagentType struct {
	Description string   `json:"description"`
	Tools       []string `json:"tools"`
	AllowsWrite bool     `json:"allows_write"`
	Agents      []string `json:"agents"`
	Rationale   string   `json:"rationale"`
}

SubagentType defines tool capabilities for an agent category.

type SubagentTypeValidation

type SubagentTypeValidation struct {
	Valid         bool
	RequestedType string
	AllowedTypes  []string
	Agent         string
	ErrorMessage  string
}

SubagentTypeValidation represents result of subagent_type check

func ValidateSubagentType

func ValidateSubagentType(schema *Schema, targetAgent string, requestedType string, agentTaskNames map[string]string) *SubagentTypeValidation

ValidateSubagentType checks if Task uses correct subagent_type for agent

func (*SubagentTypeValidation) FormatSubagentTypeError

func (v *SubagentTypeValidation) FormatSubagentTypeError() string

FormatSubagentTypeError creates detailed error with fix suggestion

type SubagentTypesConfig

type SubagentTypesConfig struct {
	Description    string       `json:"description"`
	Exploration    SubagentType `json:"exploration"`
	Implementation SubagentType `json:"implementation"`
	Planning       SubagentType `json:"planning"`
	Analysis       SubagentType `json:"analysis"`
}

SubagentTypesConfig wraps the subagent_types configuration with its description. These are informational groupings — each agent uses its specific CC type name from agent_subagent_mapping rather than these generic categories.

type TaskInput

type TaskInput struct {
	Model           string `json:"model"`
	Prompt          string `json:"prompt"`
	SubagentType    string `json:"subagent_type"`
	Description     string `json:"description"`
	MaxTurns        int    `json:"max_turns,omitempty"`
	RunInBackground bool   `json:"run_in_background,omitempty"`
	Resume          string `json:"resume,omitempty"`
}

TaskInput represents Task tool_input structure. This is the specific structure for Task tool invocations.

func ParseTaskInput

func ParseTaskInput(toolInput map[string]interface{}) (*TaskInput, error)

ParseTaskInput extracts Task parameters from tool_input map. Returns an error if the prompt field is missing (required). Other fields are optional and may be empty strings.

type TaskOutputCall

type TaskOutputCall struct {
	TaskID string `json:"task_id"`
}

TaskOutputCall represents a TaskOutput tool call for collecting background tasks.

type TaskTracker

type TaskTracker struct {
	SpawnedIDs   map[string]bool // task_id → spawned
	CollectedIDs map[string]bool // task_id → collected
}

TaskTracker provides ID-based tracking of background task spawns and collections. Uses map-based tracking to support idempotent duplicate handling and precise state.

func NewTaskTracker

func NewTaskTracker() *TaskTracker

NewTaskTracker creates a new TaskTracker with initialized ID maps.

func (*TaskTracker) GetStats

func (t *TaskTracker) GetStats() (int, int, []string)

GetStats returns tracking statistics. Returns: spawned count, collected count, uncollected task IDs

func (*TaskTracker) GetUncollected

func (t *TaskTracker) GetUncollected() []string

GetUncollected returns a slice of task IDs that were spawned but not collected.

func (*TaskTracker) HasUncollected

func (t *TaskTracker) HasUncollected() bool

HasUncollected returns true if any spawned tasks have not been collected.

type TaskValidationResult

type TaskValidationResult struct {
	Allowed        bool
	BlockReason    string
	Violation      *Violation
	Recommendation string
}

TaskValidationResult represents result of Task tool validation

func ValidateTaskInvocation

func ValidateTaskInvocation(schema *Schema, taskInput map[string]interface{}, sessionID string) *TaskValidationResult

ValidateTaskInvocation checks if Task tool usage is allowed

type Threshold

type Threshold struct {
	MaxScore int `json:"max_score,omitempty"`
	MinScore int `json:"min_score,omitempty"`
}

Threshold defines tier selection thresholds.

type TierConfig

type TierConfig struct {
	Description             string              `json:"description"`
	Model                   string              `json:"model"`
	Thinking                bool                `json:"thinking"`
	MaxThinkingBudget       int                 `json:"max_thinking_budget"`
	CostPer1KTokens         float64             `json:"cost_per_1k_tokens"`
	Patterns                []string            `json:"patterns"`
	Tools                   []string            `json:"tools"`
	Invocation              string              `json:"invocation,omitempty"`
	TaskInvocationBlocked   bool                `json:"task_invocation_blocked,omitempty"`
	TaskInvocationAllowlist []string            `json:"task_invocation_allowlist,omitempty"`
	EscalationProtocol      string              `json:"escalation_protocol,omitempty"`
	Thresholds              TierThresholds      `json:"thresholds"`
	Agents                  []string            `json:"agents"`
	Protocols               map[string]Protocol `json:"protocols,omitempty"`
}

TierConfig defines configuration for each routing tier (haiku, sonnet, opus, etc.).

type TierLevels

type TierLevels struct {
	Description   string `json:"description"`
	Haiku         int    `json:"haiku"`
	HaikuThinking int    `json:"haiku_thinking"`
	Sonnet        int    `json:"sonnet"`
	Opus          int    `json:"opus"`
}

TierLevels defines numeric levels for tier comparison in delegation ceiling.

type TierThresholds

type TierThresholds struct {
	MaxFiles          *int `json:"max_files"`
	MaxLines          *int `json:"max_lines"`
	MaxTokensEstimate *int `json:"max_tokens_estimate"`
	MinFiles          *int `json:"min_files,omitempty"`
	MinLines          *int `json:"min_lines,omitempty"`
	MinTokensEstimate *int `json:"min_tokens_estimate,omitempty"`
}

TierThresholds defines limits for each tier.

type ToolEvent

type ToolEvent struct {
	ToolName      string                 `json:"tool_name"`
	ToolInput     map[string]interface{} `json:"tool_input"`
	SessionID     string                 `json:"session_id"`
	HookEventName string                 `json:"hook_event_name"`
	CapturedAt    int64                  `json:"captured_at"`

	// v2.1.69 common fields
	CWD            string `json:"cwd,omitempty"`
	PermissionMode string `json:"permission_mode,omitempty"`
	AgentID        string `json:"agent_id,omitempty"`
	AgentType      string `json:"agent_type,omitempty"`
	TranscriptPath string `json:"transcript_path,omitempty"`
}

ToolEvent represents PreToolUse events from Claude Code hooks. These events are emitted before a tool is invoked.

func ParseToolEvent

func ParseToolEvent(r io.Reader, timeout time.Duration) (*ToolEvent, error)

ParseToolEvent reads JSON from io.Reader and parses into ToolEvent. Returns an error if JSON parsing fails or required fields are missing. Uses ReadStdin for timeout protection.

func ParseTranscript

func ParseTranscript(transcriptPath string) ([]ToolEvent, error)

ParseTranscript reads a JSONL session transcript file and returns a slice of ToolEvent structs. Each line in the file should be a valid JSON object representing a ToolEvent.

Parameters:

  • transcriptPath: absolute path to the JSONL transcript file

Returns:

  • []ToolEvent: slice of parsed events (empty slice if file is empty)
  • error: nil on success, error with context on failure

Error cases:

  • File not found: returns descriptive error
  • Malformed JSON: returns error with line number
  • File read error: returns error with context

Empty lines are skipped silently.

func (*ToolEvent) ExtractFilePath

func (e *ToolEvent) ExtractFilePath() string

ExtractFilePath gets file_path from tool_input. Returns empty string if file_path is not present or not a string.

func (*ToolEvent) ExtractWriteContent

func (e *ToolEvent) ExtractWriteContent() string

ExtractWriteContent gets content for Write tool or new_string for Edit tool. Returns empty string if neither field is present or not a string.

func (*ToolEvent) IsClaudeMDFile

func (e *ToolEvent) IsClaudeMDFile() bool

IsClaudeMDFile checks if target is a CLAUDE.md file (or variant like CLAUDE.en.md). Returns false if file_path cannot be extracted.

func (*ToolEvent) IsWriteOperation

func (e *ToolEvent) IsWriteOperation() bool

IsWriteOperation checks if this is a Write or Edit operation.

type ToolPermission

type ToolPermission struct {
	Allowed         bool
	CurrentTier     string
	Tool            string
	AllowedTools    []string
	RecommendedTier string
}

ToolPermission represents the result of a tool permission check.

func CheckToolPermission

func CheckToolPermission(schema *Schema, currentTier string, toolName string) *ToolPermission

CheckToolPermission validates if a tool is allowed for the current tier. It checks the schema's tier configuration and returns detailed permission info.

Parameters:

  • schema: The routing schema containing tier configurations
  • currentTier: The tier to check permissions for (e.g., "haiku", "sonnet")
  • toolName: The tool being requested (e.g., "Read", "Write", "Task")

Returns:

  • ToolPermission with Allowed=true if tool is permitted
  • ToolPermission with Allowed=false and RecommendedTier if denied

func (*ToolPermission) FormatPermissionError

func (p *ToolPermission) FormatPermissionError() string

FormatPermissionError creates a formatted error message following the standard: "[component] What. Why. How to fix."

The error message includes:

  • Tool name and current tier
  • List of allowed tools for current tier
  • Recommended tier that allows the tool
  • Override suggestion using --force-tier flag

type TranscriptAnalyzer

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

TranscriptAnalyzer analyzes session transcripts for background task usage patterns.

func NewTranscriptAnalyzer

func NewTranscriptAnalyzer(transcriptPath string) *TranscriptAnalyzer

NewTranscriptAnalyzer creates a TranscriptAnalyzer for the given transcript file.

func (*TranscriptAnalyzer) Analyze

func (a *TranscriptAnalyzer) Analyze() error

Analyze parses the transcript and tracks background task spawns and collections. Uses both JSON parsing and regex fallback for robustness.

Returns:

  • error: nil on success, error with context on file read failure

Graceful handling:

  • Missing file: returns nil (assumes no tasks)
  • Malformed JSON: falls back to regex pattern matching
  • Duplicate IDs: idempotent (same ID can be spawned/collected multiple times)

func (*TranscriptAnalyzer) GetSummary

func (a *TranscriptAnalyzer) GetSummary() string

GetSummary returns a human-readable summary of background task tracking.

func (*TranscriptAnalyzer) GetUncollectedList

func (a *TranscriptAnalyzer) GetUncollectedList() string

GetUncollectedList returns a formatted list of uncollected task IDs. Returns empty string if all tasks collected.

func (*TranscriptAnalyzer) HasUncollectedTasks

func (a *TranscriptAnalyzer) HasUncollectedTasks() bool

HasUncollectedTasks returns true if any background tasks remain uncollected.

type ValidationOrchestrator

type ValidationOrchestrator struct {
	Schema         *Schema
	ProjectDir     string
	AgentsIndex    *AgentsIndex
	AgentTaskNames map[string]string
}

ValidationOrchestrator coordinates all Task validation checks

func NewValidationOrchestrator

func NewValidationOrchestrator(schema *Schema, projectDir string, agentsIndex *AgentsIndex, agentTaskNames map[string]string) *ValidationOrchestrator

NewValidationOrchestrator creates orchestrator with all dependencies loaded

func (*ValidationOrchestrator) ValidateTask

func (v *ValidationOrchestrator) ValidateTask(taskInput map[string]interface{}, sessionID string) *ValidationResult

ValidateTask runs all validation checks on Task invocation

type ValidationResult

type ValidationResult struct {
	Decision            string                  `json:"decision"` // "allow" or "block"
	Reason              string                  `json:"reason,omitempty"`
	EinsteinBlocked     *TaskValidationResult   `json:"einstein_blocked,omitempty"`
	ModelMismatch       string                  `json:"model_mismatch,omitempty"`
	CeilingViolation    string                  `json:"ceiling_violation,omitempty"`
	SubagentTypeInvalid *SubagentTypeValidation `json:"subagent_type_invalid,omitempty"`
	Violations          []*Violation            `json:"violations,omitempty"`
}

ValidationResult combines all validation outcomes

func (*ValidationResult) ToJSON

func (v *ValidationResult) ToJSON() (string, error)

ToJSON serializes validation result to JSON

type Violation

type Violation struct {
	// Existing fields from goYoke-011
	Timestamp     string `json:"timestamp"`
	SessionID     string `json:"session_id"`
	ViolationType string `json:"violation_type"`
	Agent         string `json:"agent,omitempty"`
	Model         string `json:"model,omitempty"`
	Tool          string `json:"tool,omitempty"`
	Reason        string `json:"reason"`
	Allowed       string `json:"allowed,omitempty"`
	Override      string `json:"override,omitempty"`

	// NEW: File context (critical for correlation with sharp edges)
	File string `json:"file,omitempty"`

	// NEW: Tier context (critical for pattern analysis)
	CurrentTier  string `json:"current_tier,omitempty"`
	RequiredTier string `json:"required_tier,omitempty"`

	// NEW: Task context (critical for understanding user intent)
	TaskDescription string `json:"task_description,omitempty"` // First 200 chars of prompt

	// NEW: Enforcement outcome (critical for effectiveness analysis)
	HookDecision string `json:"hook_decision,omitempty"` // "allow", "warn", "block"

	// NEW: Project context (enables cross-project pattern detection)
	ProjectDir string `json:"project_dir,omitempty"`
}

Violation represents a routing rule violation. Logged to both XDG cache (global) and .goyoke/memory/ (project-scoped).

Jump to

Keyboard shortcuts

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