- Add docs/modules/git-worktree-sandbox.md: full module guide for GitWorktreeSandbox (lifecycle, state machine, API, errors, apply summary, fallback) - Add docs/api/acms.md: context_tier_hydrator API reference (hydrate_tiers_for_plan/from_project, limits, metadata, structured logs) - Update docs/architecture.md: add Git Worktree Sandbox section and expand ACMS hydrator coverage - Update mkdocs.yml: surface new docs in Modules and API navigation groups - Update docs/api/index.md: add ACMS Services entry to API index - Update CHANGELOG.md: restructure Unreleased entries with Added/Changed/Fixed summary plus existing bug IDs - Correct Introduced versions and remove duplicate changelog entry for ACMS fix, clarify hydrator parameter types ISSUES CLOSED: #6837
6.1 KiB
cleveragents.application.services — ACMS Services
This page documents the Advanced Context Management System (ACMS) application services, including the context tier hydrator that bridges the resource registry with the in-memory context tier service.
For the ACMS architecture overview, see Architecture — Context Management. For the ADR, see ADR-014 Context Management (ACMS).
context_tier_hydrator — ACMS Indexing Pipeline
Module: cleveragents.application.services.context_tier_hydrator
Introduced: v3.4.0 — fixes bug #1028
Problem Solved
Without this module, ContextTierService starts empty on every CLI process
invocation. The LLM receives zero file context during plan execution because
the tier service is never populated from the project's linked resources.
context_tier_hydrator bridges the gap: it reads files from the resource
registry and stores them as TieredFragment objects in the tier service,
so the LLM always has project context available.
Functions
hydrate_tiers_for_plan
def hydrate_tiers_for_plan(
tier_service: ContextTierService,
project_names: list[str],
project_repository: Any,
resource_registry: Any,
) -> int:
High-level entry point. Hydrates tiers for all projects linked to a plan.
Called automatically by LLMExecuteActor.execute() before context assembly.
Parameters:
| Parameter | Type | Description |
|---|---|---|
tier_service |
ContextTierService |
The service to populate with fragments |
project_names |
list[str] |
Namespaced project names (e.g. ["local/my-project"]) |
project_repository |
NamespacedProjectRepository |
Provides project → linked resource lookup |
resource_registry |
ResourceRegistryService |
Provides resource location and type |
Returns: Total number of TieredFragment objects stored across all projects.
!!! note "Implementation detail"
The production implementation annotates project_repository and
resource_registry as Any to accommodate dependency-injection wiring.
At runtime these parameters are instances of NamespacedProjectRepository
and ResourceRegistryService respectively. Future refactors will tighten
the function signature once the container exposes stable protocols.
Example:
from cleveragents.application.services.context_tier_hydrator import (
hydrate_tiers_for_plan,
)
count = hydrate_tiers_for_plan(
tier_service=container.context_tier_service(),
project_names=["local/my-project"],
project_repository=container.project_repository(),
resource_registry=container.resource_registry(),
)
print(f"Hydrated {count} fragments")
hydrate_tiers_from_project
def hydrate_tiers_from_project(
tier_service: ContextTierService,
project_name: str,
resource_id: str,
resource_location: str,
resource_type: str = "git-checkout",
) -> int:
Lower-level function. Reads files from a single resource directory and stores
them as TieredFragment objects in ContextTier.HOT.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
tier_service |
ContextTierService |
— | Service to populate |
project_name |
str |
— | Namespaced project name |
resource_id |
str |
— | ULID of the resource |
resource_location |
str |
— | Filesystem path to the resource root |
resource_type |
str |
"git-checkout" |
Affects file listing strategy |
Returns: Number of fragments stored.
File listing strategy:
- For
git-checkout/gitresources: usesgit ls-files --cached --others --exclude-standard - For all other resource types: falls back to
os.walk
Limits and Filters
| Limit | Value | Description |
|---|---|---|
| Max file size | 256 KB | Files larger than this are skipped |
| Max total bytes | 10 MB | Hydration stops when this budget is reached |
| Binary extensions | .pyc, .so, .png, .pdf, .zip, etc. |
Skipped entirely |
| Skip directories | .git, __pycache__, node_modules, .venv, dist, build, etc. |
Not traversed |
Fragment Metadata
Each TieredFragment stored by the hydrator has the following metadata:
metadata = {
"path": "src/cleveragents/foo.py", # relative path within resource
"detail_depth": "1", # string (Pydantic requirement)
"relevance_score": "0.5", # string (Pydantic requirement)
}
!!! note "String metadata types"
detail_depth and relevance_score must be strings, not int/float.
Using numeric types causes a Pydantic validation error during context
assembly (bug #1028).
Automatic Invocation
hydrate_tiers_for_plan is called automatically by LLMExecuteActor.execute()
before context assembly. No manual invocation is required in normal usage.
LLMExecuteActor.execute()
│
├─ hydrate_tiers_for_plan(...) ← populates ContextTierService
│
└─ ContextAssembler.assemble() ← now has file context available
Structured Log Events
The hydrator emits structured log events at DEBUG and INFO levels:
| Event | Level | Description |
|---|---|---|
context_hydrator.skip_missing_location |
WARNING |
Resource location does not exist |
context_hydrator.project_not_found |
DEBUG |
Project not found in repository |
context_hydrator.no_linked_resources |
DEBUG |
Project has no linked resources |
context_hydrator.resource_not_found |
DEBUG |
Resource not found in registry |
context_hydrator.store_failed |
DEBUG |
Failed to store a fragment |
context_hydrator.hydrated |
INFO |
Hydration complete — includes fragments_stored and total_bytes |