- docs/reference/context_strategies.md: update Built-in Strategies table to document real retrieval logic for all 6 strategies (SimpleKeyword, SemanticEmbedding, BreadthDepthNavigator, ARCE, TemporalArchaeology, PlanDecisionContext); add note about v1 character-frequency embedding approximation; note SpecStrategyAdapter registration (#3500) - docs/reference/checkpointing.md: add Automatic Checkpoint Triggers section documenting the 4 triggers (on_tool_write, on_tool_write_complete, on_subplan_spawn, on_error), configuration via core.checkpoints.auto_create_on, and wiring into ToolRunner/SubplanExecutionService/PlanExecutor (#3439)
5.8 KiB
Context Strategy Registry
The Context Strategy Registry manages pluggable retrieval strategies for the
ACMS Context Assembly Pipeline. Strategies implement the ContextStrategy
protocol and are registered via TOML configuration or programmatic API.
Architecture
ContextRequest
┌─── StrategySelector ────┐
│ can_handle() polling │
└──────────┬──────────────┘
v
┌─── BudgetAllocator ─────┐
│ proportional alloc │
└──────────┬──────────────┘
v
┌─── StrategyExecutor ────┐
│ parallel w/ timeout │
│ circuit breaker │
└──────────┬──────────────┘
v
ContextFragment[]
ContextStrategy Protocol
Every strategy implements:
| Member | Type | Description |
|---|---|---|
name |
property -> str |
Unique strategy name |
capabilities |
property -> StrategyCapabilities |
Backend requirements and quality score |
can_handle(request, backends) |
-> float |
0.0-1.0 confidence for this request |
assemble(request, backends, budget, plan_context) |
-> list[ContextFragment] |
Execute and return fragments; must respect budget |
explain() |
-> str |
Human-readable description |
StrategyCapabilities
| Field | Type | Default | Description |
|---|---|---|---|
uses_text |
bool |
False |
Requires TextBackend |
uses_vector |
bool |
False |
Requires VectorBackend |
uses_graph |
bool |
False |
Requires GraphBackend |
uses_temporal |
bool |
False |
Requires temporal/cold-tier data |
resource_types |
tuple[str, ...] |
() |
Supported resource types (empty = all) |
quality_score |
float |
0.5 |
Intrinsic quality score (0.0-1.0) |
supports_depth_breadth |
bool |
False |
Supports depth/breadth projection |
supports_plan_hierarchy |
bool |
False |
Supports plan hierarchy traversal |
supports_temporal |
bool |
False |
Supports temporal archaeology queries |
Built-in Strategies
All six built-in strategies now implement real backend-driven retrieval logic
(v3.8.0+, issue #3500). Previously they were no-op stubs that returned empty
fragment lists. The SpecStrategyAdapter bridges each strategy into the
ACMSPipeline at construction time.
| Strategy | Quality | Backends | Retrieval Logic |
|---|---|---|---|
simple-keyword |
0.3 | Text | TextBackend.search() using keywords extracted from the ContextRequest; results packed greedily into token budget |
semantic-embedding |
0.6 | Vector | VectorBackend.similarity_search() using a character-frequency embedding as a v1 approximation; budget-aware packing |
breadth-depth-navigator |
0.85 | Graph | GraphBackend traversal from focus nodes declared in the ContextRequest, expanding outward by request.breadth hops |
arce |
0.95 | All | Multi-modal pipeline: text search (40% budget) + vector similarity (40%) + graph traversal (20%); results merged and deduplicated |
temporal-archaeology |
0.5 | Graph + Cold | Two-phase: TemporalBackend.query_by_tier() for cold-tier historical nodes, then GraphBackend traversal from those nodes |
plan-decision-context |
0.7 | Warm/Cold | TemporalBackend-driven lookup walking parent and ancestor plan hierarchy, retrieving decision records from warm/cold tiers |
Default enabled (spec context.strategies.enabled):
["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]
Note: The
SemanticEmbeddingStrategyuses a character-frequency embedding as a v1 approximation of semantic similarity. A real embedding model integration is planned for a future milestone.
Configuration
Global (config.toml)
[context.strategies]
enabled = ["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]
[context.strategies.custom]
"my-strategy" = "my_package.strategies:MyStrategy"
Per-strategy settings
| Key | Type | Default | Description |
|---|---|---|---|
timeout_seconds |
int | 30 | Per-strategy assembly timeout |
max_fragments |
int | 100 | Maximum fragments per call |
max_workers |
int | 4 | Parallel workers for executor |
circuit_breaker_threshold |
int | 3 | Failures before circuit opens |
enabled |
bool | true |
Whether the strategy is active |
Per-project overrides
Projects can override the global enabled list using:
agents project context set --strategy simple-keyword --strategy semantic-embedding
This replaces the global context.strategies.enabled list for that project.
ContextStrategyResult
Output of a single strategy execution:
| Field | Type | Description |
|---|---|---|
strategy_name |
str |
Name of the producing strategy |
fragments |
tuple[ContextFragment, ...] |
Deterministically ordered fragments |
total_fragments |
int |
Total fragments before limits |
tokens_used |
int |
Total tokens across fragments |
execution_time_ms |
float |
Execution wall-clock time (ms) |
errors |
tuple[str, ...] |
Error messages |
stats |
dict[str, Any] |
Strategy-specific statistics |
Fragment ordering: (relevance_score DESC, uko_node ASC).
Registry Validation
The registry validates that:
- Every enabled strategy is actually registered.
- Every strategy declares at least one backend capability.
- Every strategy declares supported resource types.
Fallback Degradation Path
When backends are unavailable, the system degrades gracefully:
arce(requires all) → 2.breadth-depth-navigator(graph) →semantic-embedding(vector) → 4.simple-keyword(text only)
This ensures context is always produced.