Split the monolithic docs/specification.md (48,071 lines, ~3.2MB) into a docs/specification/ directory with 10 logical sub-documents plus an index. - docs/specification/index.md — Root entry point with navigation table - docs/specification/overview.md — Overview, standards alignment, and glossary - docs/specification/cli.md — Complete CLI command reference (~18,000 lines) - docs/specification/core-concepts.md — Plan lifecycle, actors, tools, skills, resources, context - docs/specification/behavior.md — Automation profiles, guardrails, plan correction - docs/specification/tui.md — Text User Interface architecture and components - docs/specification/configuration.md — Configuration keys and file schemas - docs/specification/examples.md — End-to-end workflow examples - docs/specification/architecture.md — System architecture, ACMS, storage, security - docs/specification/milestones.md — Milestone delivery plan - docs/specification/acms.md — ACMS v1 detailed specification docs/specification.md replaced with a stub redirect pointing to docs/specification/index.md. mkdocs.yml updated with hierarchical navigation for the new sub-documents. CONTRIBUTING.md, docs/CONTRIBUTING.md, and all .opencode/ agent/skill references updated to point to docs/specification/ instead of docs/specification.md. ISSUES CLOSED: #4749
35 KiB
ACMS v1 — Advanced Context Management System (Milestone v3.4.0)
Overview
The Advanced Context Management System (ACMS) v1 is the context intelligence layer of CleverAgents. It provides a principled, scalable mechanism for indexing project knowledge, assembling budget-constrained context views, and delivering scoped context payloads to actors for LLM calls. ACMS v1 is the primary deliverable of milestone v3.4.0 — ACMS v1 + Context Scaling.
ACMS is built on two foundational subsystems:
- UKO (Unified Knowledge Ontology) — a layered RDF/Turtle ontology that indexes project files, symbols, relationships, and semantic concepts into a queryable knowledge graph.
- CRP (Context Request Protocol) — a structured protocol through which actors declare what information they need, at what level of detail, and with what scope, triggering a context assembly cycle in the ACMS pipeline.
Together, UKO and CRP power a 10-component context assembly pipeline that transforms raw retrieval results into a budget-constrained, coherently ordered context window for each actor.
Design goals for ACMS v1:
- Support projects with 10,000+ files without timeout or memory exhaustion.
- Respect hard token budget ceilings derived from the actor's model context window.
- Enable multiple complementary retrieval strategies (keyword, semantic, graph, LLM-driven).
- Provide tiered context lifecycle management (hot/warm/cold) with per-actor visibility.
- Expose a clean CLI interface for context inspection, simulation, and policy management.
Architecture
UKO — Unified Knowledge Ontology
UKO is the indexing layer. It transforms project resources into a queryable hierarchy of knowledge nodes, each with multiple detail depths enabling progressive disclosure.
Layer structure:
| Layer | Prefix(es) | IRI Namespace | Purpose |
|---|---|---|---|
| 0 | uko: |
https://cleveragents.ai/ontology/uko# |
Universal foundation — base information unit types and core relationships |
| 1 | uko-code:, uko-doc:, uko-data:, uko-infra: |
https://cleveragents.ai/ontology/uko/code# etc. |
General software — modules, callables, types, tests, imports |
| 2 | uko-oo:, uko-func:, uko-proc: |
https://cleveragents.ai/ontology/uko/oo# etc. |
Paradigm-specific — OO classes, interfaces, methods, attributes |
| 3 | uko-py:, uko-ts:, uko-rs:, uko-java: |
https://cleveragents.ai/ontology/uko/py# etc. |
Technology-specific — DetailLevelMap insertions |
Layer 0 root types:
InformationUnit— root of every UKO node; anything that can appear in an actor's context.Container— an information unit that contains other units (file, module, class, section).Atom— a leaf-level information unit (function body, paragraph, config value).Annotation— metadata attached to another unit (comment, docstring, attribute).Boundary— an interface point between containers (export, API endpoint, public method signature).
Core relationship properties:
contains— parent contains child.references— weak reference (e.g. a function mentions a type in a docstring).dependsOn— strong dependency (import, inheritance, call).
Detail depths enable progressive disclosure:
| Depth | Question Answered | What Gets Included |
|---|---|---|
| 0 | What exists? | Name/identifier only |
| 1 | How is it organized? | Names of immediate children |
| 2 | What are the key relationships? | Children + dependency/reference edges |
| 3 | What is each thing's purpose? | + Short descriptions/summaries |
| 4 | What is the structural shape? | + Type info, size/count metadata |
| 5-8 | How does it work? | Progressively more content |
| 9 | Everything. | Complete content — nothing omitted |
When context budget is tight, fragments are downgraded to shallower depths rather than omitted entirely (depth fallback).
Provenance properties on every UKO node:
sourceResource— the CleverAgents Resource (by ULID) this node was extracted from.sourcePath— file path within the resource.sourceRange— byte or line range within the source file (e.g.42:1-87:0).
Temporal properties support versioned knowledge:
validFrom,validUntil,isCurrent,isRevisionOf.
CRP — Context Request Protocol
CRP is the structured vocabulary through which actors declare context needs. Each
ContextRequest triggers a context assembly cycle in the ACMS pipeline.
ContextRequest fields:
| Field | Type | Default | Description |
|---|---|---|---|
query |
str | None |
None |
Natural language query |
entities |
list[str] |
[] |
Named entities to focus on |
uko_types |
list[str] |
[] |
UKO types to filter |
focus |
list[str] |
[] |
URIs or identifiers to focus on |
breadth |
int |
2 |
Dependency hops outward (>= 0) |
depth |
int | str |
3 |
Detail depth — integer or named level |
depth_gradient |
bool |
True |
Items closer to focus get more detail |
temporal |
TemporalScope |
CURRENT |
Temporal scope for retrieval |
max_tokens |
int | None |
None |
Maximum token budget (>= 0) |
preferred_strategies |
list[str] |
[] |
Preferred context strategies |
required_backends |
list[str] |
[] |
Required data backends |
priority |
float |
0.5 |
0.0 = background, 1.0 = critical |
purpose |
str |
"" |
Why this context is needed |
DetailLevelMap maps named detail levels to integer depths for a UKO domain. Inheritance allows child maps to include all entries from their parent map and insert additional levels.
Built-in named levels (universal Layer 0):
| Name | Depth |
|---|---|
MODULE_LISTING |
0 |
SIGNATURES |
4 |
FULL_SOURCE |
9 |
Context Pipeline
The ACMS pipeline transforms a ContextRequest into an AssembledContext through five
high-level stages:
-
Indexing — Project files are indexed into the UKO ontology by
RepoIndexingService. Language-specific analyzers extract structural elements (functions, classes, modules, types) into UKO nodes with multiple detail depths. The index is persisted in SQLite and refreshed incrementally on file changes. -
Assembly — A
ContextRequesttriggers the 10-component assembly pipeline. Strategies run in parallel; their results are fused, deduplicated, scored, and packed. -
Scoping — Context is filtered by the project's
ProjectContextPolicy. Each plan phase (default->strategize->execute->apply) may override the policy view, controlling which resources and file paths are visible. -
Budget Enforcement —
ContextBudgetEnforcerappliesmax_file_sizeandmax_total_sizeconstraints. The token budget is a hard ceiling:budget = model_context_window - response_reserve (4096) - tool_definitions - skeleton_allocationBudget refresh is triggered when available budget changes by more than
context.budget.refresh-threshold(default: 0.30). -
Delivery — The assembled
AssembledContext(orContextPayload) is delivered to the actor for its LLM call. Child plans inherit a compressed skeleton of their parent's context (default: 15% of child's budget viaSkeletonCompressor).
Storage Tiers
ACMS v1 manages context fragments across three storage tiers:
| Tier | Backend | Latency | Capacity | Actor Visibility |
|---|---|---|---|---|
| Hot | In-memory cache | Low | Token-budget (max_tokens_hot, default: 8,000) |
All roles |
| Warm | SQLite (fast disk) | Medium | Decision-count (max_decisions_warm, default: 500) |
Strategist, Executor |
| Cold | File archive (compressed) | High | Decision-count (max_decisions_cold, default: 5,000) |
Strategist only |
Actor roles and tier visibility:
| Role | Sees |
|---|---|
strategist |
hot + warm + cold |
executor |
hot + warm |
reviewer |
hot only |
Tier operations:
promote(fragment_id)— cold->warm or warm->hot.demote(fragment_id)— hot->warm or warm->cold (with optional summarisation).evict_lru(tier, count)— evict least-recently-used fragments from a tier.
v1 Note: In v1, tier labels on
ContextFragmentare sort-priority labels used for ranking during assembly (hot > warm > cold). Full storage-tier semantics with retention policies, promotion/demotion, and eviction are implemented inContextTierService.
Module Definitions
ACMS v1 follows the project's layered architecture (Domain -> Application -> Infrastructure -> Presentation).
Domain Layer
Domain models are pure Pydantic v2 frozen dataclasses with ULID identifiers and UTC datetimes. No infrastructure dependencies.
| Class | Module | Description |
|---|---|---|
ContextFragment |
cleveragents.domain.models.core.context_fragment |
Atomic unit of context with UKO node, content, depth, token count, relevance, provenance, and tier |
FragmentProvenance |
cleveragents.domain.models.core.context_fragment |
Links a fragment back to its originating resource and location |
ContextBudget |
cleveragents.domain.models.core.context_fragment |
Token budget with max and reserved tokens |
ContextPayload |
cleveragents.domain.models.core.context_fragment |
Assembled payload with fragments, token count, budget usage, context hash, and provenance map |
ContextView |
cleveragents.domain.models.core.context_policy |
Per-phase view controlling resource/path filters and size limits |
ProjectContextPolicy |
cleveragents.domain.models.core.context_policy |
Per-project policy with phase-based view inheritance |
ContextRequest |
cleveragents.domain.models.acms.crp |
Structured context request issued by an actor via CRP |
DetailLevelMap |
cleveragents.domain.models.acms.crp |
Maps named detail levels to integer depths for a UKO domain |
AssembledContext |
cleveragents.domain.models.acms.crp |
Fused, budget-respecting context payload delivered to an actor |
TieredFragment |
cleveragents.domain.models.acms.context_tiers |
Extends ContextFragment with tier placement and access tracking metadata |
TierBudget |
cleveragents.domain.models.acms.context_tiers |
Controls capacity per tier |
ActorContextView |
cleveragents.domain.models.acms.context_tiers |
Per-actor filtered view configuration with role-based default tiers |
TierMetrics |
cleveragents.domain.models.acms.context_tiers |
Hit/miss counters and population counts per tier |
FileRecord |
cleveragents.domain.models.acms.context_indexing |
Per-file metadata stored during indexing |
IndexMetadata |
cleveragents.domain.models.acms.context_indexing |
Summary record for a repository index |
RepoIndex |
cleveragents.domain.models.acms.context_indexing |
Composite object returned by index and refresh operations |
Application Layer
Application services orchestrate domain models and delegate to infrastructure adapters. They are registered as singletons in the DI container.
| Class | Module | Description |
|---|---|---|
ACMSPipeline |
cleveragents.application.services.acms_service |
Orchestrates the 10-component context assembly pipeline |
ContextTierService |
cleveragents.application.services.context_tiers |
Manages fragment lifecycle across hot/warm/cold tiers with LRU eviction |
RepoIndexingService |
cleveragents.application.services.context_indexing |
Scans repository resources and builds persistent file-level indexes |
ContextBudgetEnforcer |
cleveragents.application.services.acms_service |
Enforces max_file_size and max_total_size constraints on assembled context |
ContextStrategyRegistry |
cleveragents.application.services.context_strategies |
Manages pluggable retrieval strategies; validates capabilities and handles fallback degradation |
UKOLoader |
cleveragents.application.services.uko_loader |
Parses docs/ontology/uko.ttl into an in-memory ontology graph; resolves inheritance chains |
Infrastructure Layer
Infrastructure adapters implement persistence and external integrations.
| Class | Module | Description |
|---|---|---|
UKOStore |
cleveragents.infrastructure.acms.uko_store |
RDF storage adapter for UKO ontology nodes; supports query and index operations |
ContextTierManager |
cleveragents.infrastructure.acms.context_tier_manager |
Manages hot (in-memory), warm (SQLite), and cold (file) storage backends |
ContextPersistenceAdapter |
cleveragents.infrastructure.acms.context_persistence |
SQLAlchemy-backed persistence for repo_indexes and indexed_files tables |
TextBackend |
cleveragents.infrastructure.acms.backends |
Full-text search via Tantivy or SQLite FTS5 |
VectorBackend |
cleveragents.infrastructure.acms.backends |
Vector similarity search via FAISS or Qdrant |
GraphBackend |
cleveragents.infrastructure.acms.backends |
Graph traversal over UKO structural relationships |
TemporalBackend |
cleveragents.infrastructure.acms.backends |
Temporal/cold-tier data access for historical context |
Presentation Layer
CLI commands expose ACMS functionality to users.
| Class | Module | Description |
|---|---|---|
ContextCLI |
cleveragents.presentation.cli.context |
agents context list/add/show/clear commands |
ProjectContextCLI |
cleveragents.presentation.cli.project_context |
agents project context set/show/inspect/simulate commands |
Data Models
ContextFragment
The atomic unit of context returned by strategies and consumed by the assembly pipeline.
| Field | Type | Default | Description |
|---|---|---|---|
fragment_id |
str |
auto ULID | Stable unique identifier |
uko_node |
str |
required | UKO URI of the source node |
content |
str |
required | Rendered text content (max 1,000,000 chars) |
detail_depth |
int |
0 |
Resolved depth: 0 (MODULE_LISTING) through 9 (FULL_SOURCE) |
token_count |
int |
required | Actual token count of content (>= 0) |
relevance_score |
float |
0.5 |
Score from 0.0 to 1.0 |
provenance |
FragmentProvenance |
required | Provenance trace |
tier |
str |
"warm" |
Priority tier: "hot", "warm", "cold" |
metadata |
dict[str, str] |
{} |
Arbitrary key-value metadata (max 64 entries) |
created_at |
datetime |
auto UTC | Creation timestamp |
ContextBudget
| Field | Type | Default | Description |
|---|---|---|---|
max_tokens |
int |
4096 |
Maximum total tokens (>= 1) |
reserved_tokens |
int |
512 |
Tokens reserved for system prompt (>= 0, < max_tokens) |
available_tokens |
int |
computed | max_tokens - reserved_tokens |
ProjectContextPolicy
Controls what context is available during each ACMS phase via view inheritance:
default -> strategize -> execute -> apply
Each phase resolves to the first explicitly-set ContextView walking up the chain.
ContextView fields:
| Field | Type | Default | Description |
|---|---|---|---|
include_resources |
list[str] |
[] |
Resource names/patterns to include (empty = all) |
exclude_resources |
list[str] |
[] |
Resource names/patterns to exclude |
include_paths |
list[str] |
[] |
File path globs to include (empty = all) |
exclude_paths |
list[str] |
[] |
File path globs to exclude |
max_file_size |
int | None |
None |
Max file size in bytes (None = no limit) |
max_total_size |
int | None |
None |
Max total context size in bytes (None = no limit) |
Exclusions always take precedence over inclusions.
AssembledContext / ContextPayload
The fused, budget-respecting context payload delivered to an actor.
| Field | Type | Description |
|---|---|---|
payload_id |
str |
ULID identifier |
plan_id |
str |
Plan this payload was assembled for |
fragments |
tuple[ContextFragment, ...] |
Ordered context fragments |
total_tokens |
int |
Sum of fragment token_count values |
budget |
ContextBudget |
Budget used for assembly |
budget_used |
float |
Fraction of budget consumed (0.0-1.0) |
strategies_used |
tuple[str, ...] |
Strategy names that contributed |
context_hash |
str |
SHA-256 hash of assembled content |
preamble |
str | None |
Optional structure summary (max 200 tokens) |
provenance_map |
dict[str, Any] |
Fragment ID -> provenance mapping |
assembled_at |
datetime |
UTC timestamp |
Properties:
is_within_budget—Trueif total tokens do not exceed available budget.remaining_tokens— Tokens still available in the budget.
IndexMetadata
| Field | Type | Description |
|---|---|---|
index_id |
str |
ULID identifier for this index snapshot |
resource_id |
str |
ULID of the linked resource |
indexed_at |
datetime |
When indexing completed (UTC) |
file_count |
int |
Total files in the index |
token_estimate |
int |
Sum of all file token counts |
primary_language |
str |
Most common language by token count |
status |
IndexStatus |
pending, indexing, ready, stale, error |
error_message |
str | None |
Error details when status == error |
Key Interfaces
ContextAssemblyService (ACMSPipeline)
class ACMSPipeline:
def assemble(
self,
plan_id: str,
fragments: Sequence[ContextFragment],
budget: ContextBudget,
strategy: str = "relevance",
) -> ContextPayload: ...
def register_strategy(self, name: str, strategy: ContextStrategy) -> None: ...
The pipeline applies a named strategy to rank and filter fragments, then runs all 10
pipeline components to produce the final ContextPayload.
ContextBudgetEnforcer
class ContextBudgetEnforcer:
def enforce(
self,
view: ContextView,
policy: ContextPolicy,
) -> ContextView: ...
Applies max_file_size and max_total_size constraints from the policy to the assembled
view, excluding or summarising fragments that exceed limits.
UKOStore
class UKOStore:
def query(
self,
ontology: UKOOntology,
query: str,
) -> list[ContextFragment]: ...
def index(
self,
project: Project,
) -> UKOOntology: ...
RDF storage adapter for UKO ontology nodes. Supports SPARQL-like queries and full project indexing.
ContextTierService
class ContextTierService:
def store(self, fragment: TieredFragment) -> None: ...
def get(self, fragment_id: str) -> TieredFragment | None: ...
def promote(self, fragment_id: str) -> None: ... # cold->warm or warm->hot
def demote(self, fragment_id: str) -> None: ... # hot->warm or warm->cold
def evict_lru(self, tier: ContextTier, count: int) -> int: ...
def get_for_actor(
self,
role: ActorRole,
project_names: list[str],
) -> list[TieredFragment]: ...
def get_scoped_view(self, project_names: list[str]) -> ScopedBackendView: ...
def get_metrics(self) -> TierMetrics: ...
RepoIndexingService
class RepoIndexingService:
def index_resource(
self,
resource_id: str,
root_path: str | Path,
*,
include_globs: tuple[str, ...] = (),
exclude_globs: tuple[str, ...] = (),
max_file_size: int | None = None,
max_total_size: int | None = None,
) -> RepoIndex: ...
def refresh_index(self, resource_id: str, root_path: str | Path, **kwargs) -> RepoIndex: ...
def get_index(self, resource_id: str) -> RepoIndex | None: ...
def get_index_status(self, resource_id: str) -> IndexMetadata | None: ...
def remove_index(self, resource_id: str) -> bool: ...
def cleanup_stale_indexing(self) -> int: ...
10-Component Pipeline Architecture
The ACMS pipeline runs three phases, each containing specific components. All 10 components have explicit Protocol definitions and injectable Default implementations.
Phase 1 — Strategy Orchestration:
| # | Component | Responsibility |
|---|---|---|
| 1 | StrategySelector |
Decides which strategies to invoke and with what confidence. Polls can_handle() on each registered strategy. |
| 2 | BudgetAllocator |
Distributes the token budget across selected strategies proportionally. |
| 3 | StrategyExecutor |
Runs strategies in parallel with timeouts (default: 30s), circuit breakers (threshold: 3 failures), and configurable max workers (default: 4). |
Phase 2 — Fragment Fusion:
| # | Component | Responsibility |
|---|---|---|
| 4 | FragmentDeduplicator |
Removes duplicate fragments via content-hash, UKO-identity, or semantic similarity. |
| 5 | DetailDepthResolver |
Resolves conflicts when the same UKO node appears at different detail depths (keeps the most appropriate depth for the budget). |
| 6 | FragmentScorer |
Computes composite relevance scores using weighted factors: relevance (0.4), hierarchy position (0.3), strategy quality (0.2), recency (0.1). |
| 7 | BudgetPacker |
Fits scored fragments into the token budget using a greedy knapsack algorithm with depth fallback (steps: [9, 4, 2, 0]). Minimum fragment size: 10 tokens. |
| 8 | FragmentOrderer |
Orders packed fragments for optimal coherence in the context window. |
Phase 3 — Context Finalization:
| # | Component | Responsibility |
|---|---|---|
| 9 | PreambleGenerator |
Generates provenance summaries prepended to assembled context (max tokens: 200). |
| 10 | SkeletonCompressor |
Compresses parent plan context into skeleton form for child plan inheritance (budget ratio: context.budget.skeleton-ratio, default: 0.15). |
Each component is pluggable via context.pipeline.* configuration keys specifying
"module:ClassName". All 10 components must execute for every context assembly; components
may produce empty output but must not be skipped.
v1 defaults: Phase 1 uses single-strategy selection, full-budget allocation, and synchronous execution. Phase 2 components are pass-through stubs. Phase 3 components are no-op (no preamble, identity compression). Production implementations are planned for future milestones.
Context Strategies
Strategies implement the ContextStrategy protocol and are registered in the
ContextStrategyRegistry.
Built-in strategies:
| Strategy | Quality | Backends | Description |
|---|---|---|---|
simple-keyword |
0.3 | Text | Full-text search via Tantivy or SQLite FTS5 |
semantic-embedding |
0.6 | Vector | Vector similarity search via FAISS or Qdrant |
breadth-depth-navigator |
0.85 | Graph | Graph traversal from focus nodes, expanding by request.breadth hops |
arce |
0.95 | All | Multi-modal: text (40%) + vector (40%) + graph (20%); results merged and deduplicated |
temporal-archaeology |
0.5 | Graph + Cold | Two-phase: cold-tier historical nodes + graph traversal |
plan-decision-context |
0.7 | Warm/Cold | Walks parent/ancestor plan hierarchy, retrieving decision records |
Default enabled: ["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]
Fallback degradation path (when backends are unavailable):
arce -> breadth-depth-navigator -> semantic-embedding -> simple-keyword
StrategyCapabilities fields:
| 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 |
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 |
CLI Commands
agents context — Context Entry Management
| Command | Description |
|---|---|
agents context list |
List context entries for the current project |
agents context add |
Add a context entry |
agents context show <id> |
Show details of a specific context entry |
agents context clear |
Clear all context entries for the current project |
agents project context — Project Context Policy and ACMS Management
| Command | Description |
|---|---|
agents project context set PROJECT [OPTIONS] |
Persist a context policy view and ACMS pipeline configuration for a project |
agents project context show PROJECT [OPTIONS] |
Display the context policy and ACMS pipeline configuration |
agents project context inspect PROJECT [OPTIONS] |
Inspect the effective context state (tier metrics, fragment distribution, actor visibility) |
agents project context simulate PROJECT [OPTIONS] |
Run a dry-run context window assembly |
agents project context set key options:
| Option | Default | Description |
|---|---|---|
--view |
default |
Phase view: default, strategize, execute, apply |
--include-resource |
— | Resource pattern to include (repeatable) |
--exclude-resource |
— | Resource pattern to exclude (repeatable) |
--include-path |
— | File path glob to include (repeatable) |
--exclude-path |
— | File path glob to exclude (repeatable) |
--max-file-size |
None |
Max file size in bytes |
--max-total-size |
None |
Max total context size in bytes |
--hot-max-tokens |
8000 |
Max tokens for the hot tier context window |
--warm-max-decisions |
500 |
Max decisions for the warm tier |
--cold-max-decisions |
5000 |
Max decisions for the cold tier |
--strategy |
— | Preferred context strategy (repeatable) |
--default-breadth |
2 |
Default breadth for context retrieval |
--default-depth |
3 |
Default depth (integer or named level) |
--skeleton-ratio |
0.2 |
Skeleton compression ratio (0.0-1.0) |
--temporal-scope |
current |
Temporal scope: current, recent, or all |
--auto-refresh/--no-auto-refresh |
True |
Auto-refresh context on resource changes |
Integration Points
Plan Lifecycle Integration
Context assembly is triggered at each plan phase transition (see ADR-006). The ACMS pipeline runs before the actor's LLM call for each phase:
strategize— full context assembly withbreadth-depth-navigator+semantic-embedding.execute— focused context assembly scoped to the current task.apply— minimal context assembly; primarily hot-tier fragments.
Child plans inherit a compressed skeleton of their parent's context via SkeletonCompressor.
Resource System Integration
When a resource is linked to a project via agents project link-resource, the
RepoIndexingService is triggered to index the resource's filesystem tree. The index is
stored in SQLite and refreshed incrementally on file changes (see ADR-008).
Actor and Agent Integration
Actors consume assembled context via the builtin/context skill, which provides three tools:
| Tool | Description |
|---|---|
request_context |
Request specific context during reasoning |
query_history |
Query historical context about past decisions |
get_context_budget |
Check remaining context token budget |
Configuration System Integration
ACMS behaviour is controlled via config.toml under the [context] namespace (see ADR-024).
Key configuration keys:
| Key | Default | Description |
|---|---|---|
context.hot.max-tokens |
16000 |
Hot tier token budget |
context.warm.max-decisions |
100 |
Warm tier max decisions |
context.warm.retention-hours |
24 |
Warm tier retention period |
context.cold.max-decisions |
500 |
Cold tier max decisions |
context.cold.retention-days |
90 |
Cold tier retention period |
context.strategies.enabled |
["simple-keyword", "semantic-embedding", "breadth-depth-navigator"] |
Enabled strategies |
context.strategies.arce.max-rounds |
3 |
ARCE max refinement rounds |
context.strategies.breadth-depth-navigator.max-hops |
4 |
Max graph traversal hops |
context.query.min-relevance |
0.3 |
Minimum relevance score threshold |
context.file.max-size |
1048576 |
Max file size in bytes (1 MB) |
context.file.max-total-size |
52428800 |
Max total file size (50 MB) |
context.budget.refresh-threshold |
0.30 |
Budget change threshold for refresh |
context.budget.min-useful-budget |
500 |
Minimum useful budget (tokens) |
context.budget.skeleton-ratio |
0.15 |
Skeleton compression ratio |
context.pipeline.* |
— | Pluggable pipeline component overrides ("module:ClassName") |
DI Container Integration
All ACMS services are registered as singletons in the DI container:
from cleveragents.application.container import get_container
container = get_container()
acms_pipeline = container.acms_pipeline()
tier_service = container.context_tier_service()
indexing_service = container.repo_indexing_service()
Database Schema
ACMS v1 adds two tables to the SQLite database:
repo_indexes
| Column | Type | Constraints |
|---|---|---|
index_id |
String(26) |
PK |
resource_id |
String(26) |
NOT NULL, UNIQUE, INDEXED |
indexed_at |
String(40) |
NOT NULL (ISO-8601 UTC) |
file_count |
Integer |
NOT NULL, DEFAULT 0 |
token_estimate |
Integer |
NOT NULL, DEFAULT 0 |
primary_language |
String(50) |
NOT NULL, DEFAULT "unknown" |
status |
String(20) |
NOT NULL, CHECK IN (pending, indexing, ready, stale, error) |
error_message |
Text |
NULLABLE |
created_at |
String(40) |
NOT NULL (ISO-8601 UTC) |
indexed_files
| Column | Type | Constraints |
|---|---|---|
index_id |
String(26) |
PK (composite), FK -> repo_indexes.index_id ON DELETE CASCADE |
path |
String(1024) |
PK (composite) |
content_hash |
String(64) |
NOT NULL |
token_count |
Integer |
NOT NULL, DEFAULT 0 |
size_bytes |
Integer |
NOT NULL, DEFAULT 0 |
language |
String(50) |
NOT NULL, DEFAULT "unknown" |
last_modified |
String(40) |
NOT NULL |
v1 Known Limitations
The following are accepted deviations from the full specification in v1, with a planned path to spec conformance in future milestones:
| Area | v1 Behaviour | Spec Target | Planned |
|---|---|---|---|
| Pipeline components | All 10 Protocol + Default classes defined; defaults are pass-through stubs | Production implementations (parallel execution, dedup, scoring, compression) | Future milestone |
ContextStrategy signatures |
can_handle(request: dict), assemble(fragments, budget) |
can_handle(request: ContextRequest, backends: BackendSet), assemble(request, backends, budget, plan_context) |
M6 strategy registry |
StrategyCapabilities fields |
supports_semantic_search, supports_graph_navigation, max_fragments |
uses_text, uses_vector, uses_graph, uses_temporal, quality_score |
M6 strategy registry |
| Tiers | Sort-priority labels for ranking | Storage tiers with retention policies, promotion/demotion | ContextTierService future milestone |
SemanticEmbeddingStrategy |
Character-frequency embedding approximation | Real embedding model integration | Future milestone |
DetailDepthResolver.resolve() |
Missing budget parameter |
resolve(fragments, budget) |
Future milestone |
FragmentScorer.score() |
Missing plan_context param; returns Sequence[ContextFragment] |
Returns list[ScoredFragment] with plan_context |
Future milestone |
PreambleGenerator.generate() |
Missing strategies_used, budget_used, max_tokens params |
Full parameter set per spec | Future milestone |
provenance_map keying |
Keyed by fragment_id (ULID) |
Spec keys by uko_node (UKO URI) |
Under review |
Acceptance Criteria
The following criteria must be satisfied for ACMS v1 to be considered complete for milestone v3.4.0:
Indexing:
RepoIndexingService.index_resource()successfully indexes a repository with 10,000+ files without timeout (target: < 60 seconds on standard hardware).- Incremental
refresh_index()only re-processes changed files (verified by content hash comparison). - Language detection correctly identifies all supported languages.
- Index status transitions correctly through
pending -> indexing -> ready. cleanup_stale_indexing()removes orphanINDEXINGrows on startup.
Assembly:
ACMSPipeline.assemble()produces aContextPayloadthat never exceeds the declared token budget (is_within_budget == True).- All three built-in strategies (
relevance,recency,tiered) produce correctly ordered fragment sequences. - The pipeline runs all 10 components for every assembly call.
- Depth fallback correctly downgrades fragments to shallower depths when budget is tight.
ContextBudgetEnforcercorrectly appliesmax_file_sizeandmax_total_sizelimits.
Tiers:
ContextTierService.store()correctly places fragments in the specified tier.promote()anddemote()correctly move fragments between tiers.evict_lru()removes the correct number of least-recently-used fragments.- Actor role visibility is correctly enforced (reviewer sees hot only; executor sees hot + warm; strategist sees all).
- Project scoping correctly isolates fragments by
project_name.
Policy:
ProjectContextPolicy.resolve_view()correctly walks the inheritance chain.- Empty policy correctly includes all resources and paths.
- Exclusions take precedence over inclusions.
max_file_sizeandmax_total_sizevalidation rejects zero or negative values.
CLI:
agents context list/add/show/clearcommands function correctly.agents project context setpersists policy views and ACMS pipeline configuration.agents project context showdisplays resolved views and ACMS config.agents project context inspectdisplays tier metrics, fragment distribution, and actor visibility.agents project context simulateproduces a dry-runAssembledContextusing the project's ACMS configuration.
UKO:
UKOLoadercorrectly parsesdocs/ontology/uko.ttland resolves inheritance chains (including multi-parentrdfs:subClassOf).- All four layers (0-3) are correctly identified by prefix.
resolve_inheritance()returns the correct BFS-ordered chain foruko-oo:Class.
Testing:
- Budget constraint tests verify assembled context never exceeds declared token budget.
- Each of the 10 pipeline components has unit tests for edge cases (empty input, budget exhaustion, duplicate fragments).
- Each retrieval strategy has integration tests verifying correctly structured results.
- Depth fallback tests verify fragments are downgraded to shallower depths when budget is insufficient.
- Configuration tests verify custom pipeline components and strategy registrations are loaded and invoked correctly.
- Performance benchmark: index 10,000 files in < 60 seconds; assemble context in < 5 seconds.
Section added by [AUTO-ARCH-20] — Cycle 27 — Milestone v3.4.0 — ACMS v1 + Context Scaling