Extract clm.runtime and clm.agents; keep session core vendor-free; inject describe_live_event into the outer loop; enforce import boundaries and mirror unit tests by package.
7.8 KiB
AGENTS.md — CLM map for coding agents
CLM (Context Lifecycle Management) is a framework-agnostic outer control loop over an executing coding agent. It measures tokens/context, decides CONTINUE / COMPACT / HANDOFF, persists memory, and emits audit-friendly handoff manifests.
| Field | Value |
|---|---|
| Package | clm (src/clm/) |
| Runtime home | .clm/ (never commit) |
| Python / tests | always .venv/bin/python and .venv/bin/pytest |
| Session continuity | HANDOFF.md |
| Architecture | docs/architecture.md |
| Coding agents | docs/coding-agents.md |
| Module pages | docs/modules/ |
Module map
| Package | Responsibility | Primary paths | Tests |
|---|---|---|---|
clm.models |
Pydantic domain types & config | src/clm/models/ |
tests/unit/models/ (test_config_thresholds.py); manifest tests in tests/unit/handoff/ |
clm.session |
Working session, Agent protocol, pure factory registry | src/clm/session/ |
tests/unit/session/ (test_tracking_session.py, test_live_event_capable.py) |
clm.agents |
Vendor / coding-agent adapters + builtin registration | src/clm/agents/ (simulated, openai_compatible, grok/) |
tests/unit/agents/ (simulated, openai, grok_*, factory, settings) |
clm.loop |
Outer control loop + live progress | src/clm/loop/ |
tests/unit/loop/ |
clm.decision |
CONTINUE/COMPACT/HANDOFF rules + policies | src/clm/decision/ |
tests/unit/decision/ |
clm.memory |
MemoryStore protocol, backends, backup | src/clm/memory/ |
tests/unit/memory/ (incl. multi-agent + ab_memory) |
clm.compaction |
Verified compaction pipeline | src/clm/compaction/ |
tests/unit/compaction/ |
clm.handoff |
Manifest + seed context pipeline | src/clm/handoff/ |
tests/unit/handoff/ |
clm.metrics |
Token monitor, estimators, cost | src/clm/metrics/ |
tests/unit/metrics/ (monitor, export, calibration) |
clm.cli |
Typer CLI (clm …) |
src/clm/cli/ |
tests/unit/cli/ |
clm.logging |
Audit JSONL + structured logs | src/clm/logging/ |
covered via tests/unit/production/, loop/metrics |
clm.export |
Metrics export (csv/json/html) | src/clm/export/ |
tests/unit/metrics/test_export_metrics.py |
clm.calibration |
Soft/hard threshold suggestions | src/clm/calibration/ |
tests/unit/metrics/test_calibration.py |
clm.experiments |
Offline A/B memory runner | src/clm/experiments/ |
tests/unit/memory/test_ab_memory.py |
clm.runtime |
Composition helpers (paths, config, script load) | src/clm/runtime/ |
tests/unit/runtime/ |
Also under unit: tests/unit/architecture/ (import boundaries), tests/unit/support/ (fakes smoke), tests/unit/production/ (cross-cutting P4), tests/unit/test_version.py.
Integration: tests/integration/test_outer_loop_*.py, test_resume_run.py.
Layout (modularization step 9): unit tests live under tests/unit/<package>/ matching source domains. clm.agents holds vendor adapters; clm.session is vendor-free core + pure registry.
Hard boundaries (do-not)
-
clm.loopmust not import vendor Grok modules
Goal: loop talks only toAgent+ capability protocols (LiveEventCapable,ExternalSessionCapable).
Livedoing=labels: injectdescribe_live_eventat the composition root (CLI wiresclm.agents.grok.stream.describe_stream_eventfor grok-build).
Known violations: EMPTY — noloop → clm.agents.grok*/ legacyclm.session.grok_*imports (import-boundary test). -
clm.experimentsmust not importclm.cli
Goal: experiment runners use library APIs / shared helpers only.
Fixed (step 4): shared helpers live inclm.runtime;ab_memoryimportsclm.runtimeonly.
Known violations: EMPTY — noexperiments → clipackage edge. -
Session core vs vendor adapters
- Core (vendor-free,
clm.session):agent.py,capabilities.py,working.py,tracking.py,factory.py(registry only — no vendor imports). - Adapters (
clm.agents):simulated.py,openai_compatible.py,grok/agent.py,grok/cli.py,grok/stream.py; builtins viaregister_builtin_agents()(also onimport clm.agents). - Loop/decision/compaction/handoff/metrics must not
isinstanceconcrete adapters. sessionmust not importagents(adapters depend on session protocols, not the reverse).
- Core (vendor-free,
-
Never commit
.clm/— runtime artifacts only (sessions, memory, manifests, backups, exports). -
Always use the project venv
.venv/bin/python … .venv/bin/pytest …System Python (e.g. 3.9) breaks typing / suite assumptions.
-
Do not branch the outer loop on
agent_kindor vendor names — use registry + capabilities.
Import-boundary guard: tests/unit/architecture/test_import_boundaries.py — KNOWN_PACKAGE_VIOLATIONS and KNOWN_MODULE_VIOLATIONS are empty sets; do not re-grow them.
Task routing (where to edit)
| Task | Start here | Also touch | Tests |
|---|---|---|---|
| Stream parse (NDJSON / ACP session updates) | agents/grok/stream.py |
agents/grok/cli.py, agents/grok/agent.py |
tests/unit/agents/test_grok_stream.py, test_grok_streaming_runner.py |
| Decision rule (thresholds, phase, policies) | decision/rules.py, decision/engine.py |
decision/policy.py, models/config.py, models/decision.py |
tests/unit/decision/, tests/unit/models/test_config_thresholds.py |
| Progress format (human-readable STATUS lines) | loop/progress.py |
loop/control.py (emit sites), cli/run.py (callback) |
tests/unit/loop/ |
| New agent adapter | agents/<name>.py + agents/register.py / register_agent |
models/config.py (AgentSettings.options), docs coding-agents.md |
tests/unit/agents/ + optional tests/integration/test_outer_loop_pluggable_agent.py |
| Verified compaction | compaction/pipeline.py, verify.py, summary.py |
memory/*, loop wire-up |
tests/unit/compaction/ |
| Handoff / manifest | handoff/pipeline.py, handoff/seed.py |
models/manifest.py, schema schemas/handoff_manifest.schema.json |
tests/unit/handoff/ |
| CLI flag / command | cli/app.py + command module (run.py, …) |
cli/common.py |
tests/unit/cli/ |
| Memory backend | memory/base.py, factory.py, store impl |
models/config.py (memory_backend) |
tests/unit/memory/ |
Verify commands
# Full suite (quiet)
.venv/bin/pytest -q
# Scoped by package folder
.venv/bin/pytest -q tests/unit/loop/
.venv/bin/pytest -q tests/unit/decision/
.venv/bin/pytest -q tests/unit/agents/test_grok_stream.py tests/unit/agents/test_grok_streaming_runner.py
.venv/bin/pytest -q tests/integration/
Prefer scoped runs while iterating; full suite before handoff/commit.
Further reading
| Doc | Use when |
|---|---|
docs/modules/*.md |
Module responsibility, API, deps, minimal file set |
docs/architecture.md |
Dataflow, layers, artifact layout |
docs/coding-agents.md |
Pluggable agents, Grok Build, CLI flags |
docs/getting-started.md |
Offline Simulated walkthrough |
docs/manifest-schema.md |
Handoff manifest fields |
docs/metrics.md |
Token/cost observability |
HANDOFF.md |
Branch tip, next safe action, open work |
Conventions (short)
- English identifiers and docstrings in code; German OK in ops/handoff notes.
- Typed Python; package is typed (
py.typed). - Tests use fixtures under
tests/fixtures/; inject fakes (e.g.FakeGrokCliRunner) — no live Grok in CI. - Keep module docs in
docs/modules/short; put deep design indocs/architecture.md/ superpowers specs.