Skip to content

Latest commit

 

History

History
68 lines (53 loc) · 3.98 KB

development.md

File metadata and controls

68 lines (53 loc) · 3.98 KB

Development guide

For the high-level pipeline, trust loop, and safety model, see architecture.md. This page is for people working in the code: the package map, naming, and the compatibility shim.

Setup

uv sync --extra dev --extra mcp
uv run --extra dev --extra mcp pytest   # full suite must stay green
uv run etch --help                      # the CLI
ruff check .                            # lint

Package map

The engine is a monorepo of single-purpose packages under packages/. Each directory packages/etchplan-<x>/ contains one importable module, etchplan_<x>:

Package Module Role
etchplan-core etchplan_core schemas (trace, pattern, plan, policy, manifest, audit), hashing, ids, paths
etchplan-ingest etchplan_ingest trace import (JSONL, Claude Code / Codex / opencode hooks, benchmark fixtures), normalization, redaction, slotting
etchplan-miner etchplan_miner gap-tolerant repeated-subsequence mining, parameter-flow + guard learning
etchplan-compiler etchplan_compiler plan synthesis, candidate ranking, code-routine distillation, serialization
etchplan-validator etchplan_validator executed-replay validation, static invariant checks, AST / osascript safety guards
etchplan-runtime etchplan_runtime the deterministic executor, registry, guards, gated mutations, model backends, audit
etchplan-store etchplan_store SQLite repository (traces, patterns, plans, shadow + plan stats)
etchplan-cli etchplan_cli the etch command
etchplan-mcp etchplan_mcp the etchplan-mcp MCP server
etchplan-actions etchplan_actions the toy refund sandbox + executed-plan corpus used by the examples
etchplan-evals etchplan_evals compile-safety reporting for the optional benchmark demo

Packages import each other by their absolute module name (e.g. from etchplan_core.schemas.plan import ExecutionPlan).

Naming and backward compatibility

The product, CLI, and import namespace are all etchplan / etch / etchplan_*. The packages were previously named aec_* (from the project's earlier name); a few compatibility shims keep older artifacts and integrations working through the rename:

  • Import paths: legacy aec_* imports (e.g. import aec_runtime.registry, or a --registry aec_runtime.registry:Registry spec) resolve to the renamed etchplan_* modules via a meta-path finder in etchplan_core/_compat.py, installed when etchplan_core is imported.
  • Plan format: ExecutionPlan.apiVersion is now etchplan/v1alpha1; the schema also accepts the legacy aec/v1alpha1 so plans saved by older builds still load.
  • Report format: benchmark schema_version tags are now etchplan.*; the importer canonicalizes the legacy aec.* prefix on read (see benchmark_importers.py).
  • Local state: new captures live under ~/.etchplan/; reads fall back to the legacy ~/.aec/, and a legacy aec_ts capture-timestamp field is still read.

These are temporary compatibility layers and will be removed in a future release. New code should use the etchplan_* names throughout.

Public API stability

etchplan is pre-1.0. Treat the import surface and the ExecutionPlan / report schemas as unstable until 1.0; the stable public contract today is the etch CLI and the documented --registry / --fallback module:attr integration seam.

Adding a new agent harness

The most common contribution. Trace ingestion has a single seam: build a raw-trace dict and call normalize_trace(raw, source="<harness>") (packages/etchplan-ingest/etchplan_ingest/normalizer.py), it handles redaction, slotting, fingerprinting, and validation. Model a new adapter on packages/etchplan-ingest/etchplan_ingest/claude_code_hook.py, and wire an etch import <harness> command in packages/etchplan-cli/etchplan_cli/main.py.