Trammel — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Trammel (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Trammel helps AI coding assistants plan, verify, and remember multi-step tasks.
Instead of letting your AI assistant wing it on complex changes, Trammel breaks goals into ordered steps, verifies each one works, learns from failures, and saves successful strategies for reuse. It works with Claude Code, Cursor, and any MCP-compatible editor — or standalone via Python and CLI.
Trammel is a tool for LLMs, not a tool that calls LLMs. It provides the planning discipline that coding assistants need to tackle multi-step tasks reliably.
Trammel Plan & Explore Demo
verify_step tool execute the real test suite in isolation; verify_step also returns static analysis, preflight syntax checks, and import-integrity results alongside the test outcome.15 languages supported: Python, TypeScript, JavaScript, Go, Rust, C/C++, Java/Kotlin, C#, Ruby, PHP, Swift, Dart, Zig
pip install trammel # core library (no dependencies beyond Python stdlib)
pip install trammel[mcp] # with MCP server for Claude Code / CursorOr from source:
git clone https://github.com/IronAdamant/Trammel.git
cd Trammel && pip install -e '.[mcp]'Add to your .claude/.mcp.json (Claude Code) or equivalent MCP config:
{
"mcpServers": {
"trammel": {
"command": "trammel-mcp",
"args": []
}
}
}Your AI assistant now has access to 31 planning tools — decompose goals, create plans, claim steps, verify work, save recipes, and prune stale plans. See SYSTEM_PROMPT.md for the full orchestration guide.
python -m trammel "refactor auth module" --root /path/to/project --beams 3
python -m trammel "fix tests" --test-cmd "pytest -x -q"
python -m trammel "explore auth" --dry-run # explore strategies without verification
python -m trammel "fix auth" --root /monorepo --scope services/authfrom trammel import plan_and_execute, explore, synthesize
# Full pipeline: decompose → plan → explore → verify → store recipe
result = plan_and_execute("your goal", "/path/to/project", num_beams=3)
# Explore only (no verification)
strategy = explore("refactor auth", "/path/to/project")
# Save a verified strategy as a reusable recipe
synthesize("refactor auth", verified_strategy)Trammel treats planning as a structured search problem:
All state lives in a local SQLite database (trammel.db) — plans, steps, constraints, recipes, and telemetry.
Trammel doesn't require MCP. The same capabilities are available through multiple surfaces:
| Surface | Best for |
|---|---|
MCP server (trammel-mcp) | Claude Code, Cursor, and other MCP-aware editors |
Python API (plan_and_execute, explore, etc.) | Scripts, CI pipelines, custom orchestrators |
CLI (python -m trammel) | Shell automation, quick one-off plans |
SQLite (trammel.db) | Direct queries, external dashboards, cross-process coordination |
When decomposing with a scaffold, Trammel returns DAG metrics for dispatching work across multiple agents:
| Metric | What it tells you |
|---|---|
max_parallelism | Peak number of agents you can run at once |
layer_widths | How many files can be worked on per round (e.g. [7, 12, 6, 10, 3, 2]) |
critical_path_length | The longest chain — your minimum number of rounds |
Agents coordinate via claim_step / release_step / available_steps. Claims auto-expire after 10 minutes for stale agent recovery.
Trammel works standalone. When co-installed with Stele (context retrieval) and Chisel (code analysis), all three cooperate through the MCP tool layer — no cross-dependencies between packages.
| Tool | Role |
|---|---|
| Stele | Persistent context retrieval and semantic indexing |
| Chisel | Code analysis, churn, coupling, risk mapping |
| Trammel | Planning, verification, failure learning, recipe memory |
Trammel has controls to keep plans accurate and sub-agents aligned:
high / medium / low relevance so prioritization is transparentOptional project config via pyproject.toml ([tool.trammel] section) or .trammel.json:
[tool.trammel]
default_scope = "src/"
focus_keywords = ["auth", "login"]
max_files = 50trammel/ Importable package
__init__.py Public API: plan_and_execute, explore, synthesize
core.py Planner: decomposition, constraints, step generation
store.py RecipeStore: SQLite persistence (8 tables), telemetry
store_recipes.py Recipe methods: save, retrieve, list, prune
strategies.py 9 built-in beam strategies
harness.py Execution harness: temp copies, test runner
analyzer_specs.py Declarative regex specs for 13 regex-based analyzers
analyzer_engine.py RegexAnalyzerEngine + import resolvers + backward-compat shims
analyzers.py Python + TypeScript analyzers, language detection
analyzers_ext.py Backward-compat shim (re-exports from analyzer_engine)
analyzers_ext2.py Backward-compat shim (re-exports from analyzer_engine)
project_config.py Config merging (pyproject.toml + .trammel.json)
utils.py Trigrams, cosine, failure extraction, shared helpers
cli.py CLI entry point
mcp_server.py MCP tool schemas and dispatch
mcp_stdio.py MCP stdio server entry point
plan_merge.py Plan merging engine: conflict detection + 4 resolution strategies
store_agents.py Multi-agent coordination: step claiming, availability, proximity warnings
tests/ 361 tests across 6 modules (stdlib unittest)
SYSTEM_PROMPT.md Reference orchestration guide for LLM clientstrammel.db)| Table | Purpose |
|---|---|
recipes | Successful strategies with pattern, constraints, success/failure counts |
recipe_trigrams | Inverted trigram index for fast recipe retrieval |
recipe_files | File paths for structural matching (Jaccard overlap) |
plans | Goals + strategy snapshots + scaffold with step progress |
steps | Work units with dependencies, rationale, verification results |
constraints | Failure records that prevent known-bad repetition |
trajectories | Run logs per beam: outcome, steps completed, failure reason |
failure_patterns | Historical failure signatures with resolution history |
usage_events | Telemetry: tool calls, recipe hit rates, strategy win rates |
Contributions welcome. Please open an issue first to discuss changes.
git checkout -b feature/your-feature)unittest only)python -m unittest discover -q -s tests -p 'test_*.py'Releases use Trusted Publishing (GitHub OIDC → PyPI). No API tokens needed.
version in pyproject.tomlmaingit tag -a vX.Y.Z -m "Release X.Y.Z" && git push origin vX.Y.Z<details> <summary><strong>Full Changelog</strong></summary>
No package-code changes — this release hardens the delivery pipeline ahead of GitHub's 2026-06-16 forced Node 24 switch and exercises it end-to-end.
actions/upload-artifact@v7 and actions/download-artifact@v8 (were @v5, which still ran on Node 20). Inputs unchanged across the majors.workflow_dispatch trigger plus a dispatch-only verify-artifacts job exercise the build → upload → download round-trip without touching PyPI; the publish job is guarded to release events.Patch release: one small MCP feature plus a documentation-accuracy pass verified against source.
trammel.db than the one the server was started with (list_plans(db_path="/abs/path/trammel.db")). The server's own database remains the default. New TestListPlansDbPath regression test covers both paths.verify_step was a static/heuristic check only — in fact it has run the real test suite in an isolated temp copy (alongside static analysis, preflight syntax, and import-integrity checks) via the shared ExecutionHarness. Docs now match the source.resume, update_plan_status, record_steps, prune_recipes, deactivate_constraint, prune_plans, estimate, resolve_failure were missing from one or both).CLAUDE.md documents the architecture layers, registry parity invariants (_TOOL_SCHEMAS/_DISPATCH, _LANGUAGES/analyzer registry), additive-only schema migrations, and repo conventions for AI-assisted development.Patch release closing the four critical gaps exposed by exhaustive 31/31-tool testing against the TrammelConstraintFailureRecoveryEngine corpus (26 adversarial near-identical structural scaffolds, 12 duplicate "phase15" plans, 13 constraints, 8 injected failures). The trammel_open.md findings document (RecipeLab_alt/MCP_Findings) has been renamed trammel_open_closed.md.
has_util + "util"/"utils" role support added to goal_fingerprint_from_text, strategy_fingerprint, structural_similarity (cosine + bonus), role vectors, and goal_scaffold_fingerprint_from_text. model+service+route+test vs model+service+util+test (and 1–2 token variants) now produce meaningfully different scores instead of max ~0.19. Near-identical goals saved via save_recipe/validate_recipes are now correctly preferred by decompose and the scaffold-recipe fallback path (0.15 threshold). _W_STRUCTURAL weighting and arch MinHash benefit.create_plan now performs an exact (goal + strategy JSON) match against existing pending plans and returns the prior ID instead of inserting duplicates. Eliminates the 12 identical + 49 total pending plan pollution observed with repeated create_plan calls on identical goals. prune_plans, merge_plans, list_plans, and usage_stats stay clean.resolve_failure_pattern, the MCP handler, and tool_schemas.py with optional plan_id/step_id parameters. When provided, the targeted step is moved from "running"/"pending" → "failed", any claim is released, and the resolution note is stored in the step's verification JSON. Fixes the 2/8 cases where injected failures left steps stuck after resolve_failure + failure_history._LAYER_PATTERNS (with test layers), src/utils + src/helpers to _FALLBACK_ROLE_DIRS, and "util"/"utils" to _ROLE_DIR_SUBSTRINGS. _creation_hints, _detect_layered_architecture, and _fallback_directories now emit ready-to-use scaffold entries (with depends_on DAGs and paired test files) for greenfield goals mentioning "util", "importer/exporter/registry", "model+service+util+test", etc. — even when existing_files is empty and no explicit paths are in the goal. explore and scaffold-less decompose produce useful new-file plans instead of full-repo or empty results.tool_schemas.py for the new optional resolve params. scripts/release.sh helper and Trusted Publishing flow unchanged. All 413 tests (and subtests) continue to pass with no regressions.These changes deliver the "40-70 step dependency-aware plan" capability and reliable recipe reuse for large refactors (Phase 16 campaign) that the original Phase 15 adversarial corpus was designed to validate.
Bug-fix follow-up to v3.12.0. No public API changes.
db_connect now uses isolation_level=None and transaction() is SAVEPOINT-aware, so create_plan, add_constraint, save_recipe, validate_recipes, and log_event no longer hit "cannot start a transaction within a transaction". The same root cause silently broke usage_stats / list_strategies telemetry — both now report real numbers.store_plans.py so resume and available_steps no longer 500 on a single bad row; instead the plan is returned with a _corrupted_fields marker._scaffold_matches_scope rejects scaffold-recipe matches whose files all live outside the queried scope — fixes the case where a low-threshold scaffold match overrode scope=X with a stored scaffold from elsewhere.(recipe_sig, file_path) and INSERT OR IGNORE in _insert_file_entries prevent the 320+ duplicate rows seen on legacy DBs.prune_recipes. Default targets pending plans older than 7 days; cascade-deletes their steps, trajectories, and constraints. Total MCP tools: 31.get_recipe ↔ near_match_recipes parity. When get_recipe finds nothing above threshold, it now also returns near_match_recipes so it agrees with explore`.decompose field instead of being buried inside analysis_meta.implicit_dependency_analysis.TestFindingsRegressions).Structural refactor with no public API changes. All existing from trammel... imports keep working; re-exports preserve legacy paths.
recipe_fingerprints.py, store_retrieval.py, store_scaffolds.py (extracted from store_recipes.py, which drops from 1223 → 373).store_plans.py, store_telemetry.py (extracted from store.py).tool_schemas.py (extracted from mcp_server.py).implicit_deps_engines.py, pattern_learner.py (extracted from implicit_deps.py).analyzer_resolvers.py (extracted from analyzer_engine.py).text_similarity.py, scaffold_validation.py (extracted from utils.py).language_detection.py (extracted from analyzers.py).scaffold_creation.py (extracted from scaffold_logic.py).planner_helpers.py (extracted from core.py).NAMING_CONVENTION_RULES, INFRASTRUCTURE_PATTERNS, file-role patterns, and goal-role patterns now live in trammel/data/patterns.json and are loaded via a new pattern_config.py. Edit the JSON to tune inference without code changes.tests/test_mcp_dispatch.py with 11 tests covering schema↔dispatch parity, category-registry sync, unknown-tool error shape, previously-uncovered handlers (record_steps, claim/release/available_steps, merge_plans, usage_stats, list_strategies, resolve_failure), and schema-driven int coercion.Planner (class + every method), ExecutionHarness (class + __init__), RecipeStore (class + context-manager lifecycle), every MCP _handle_*, the constraint/trajectory methods on the store, and all 11 language-analyzer subclasses.verify_step is static/heuristic). SYSTEM_PROMPT.md gains an explicit "decompose vs explore vs create_plan — which do I call?" decision block. pyproject.toml version bumped to 3.12.0 (closes the drift where README already documented a v3.11.3 entry but the package version still said 3.11.2).validate_scaffold treats >4 dependencies as a warning rather than a fatal error. Test files and facades with many dependencies no longer block decomposition.decompose now returns whatever steps can still be inferred from the scaffold instead of an empty plan.explore receives an empty or error result from decompose, it automatically retries with suppress_creation_hints=true and expand_repo=false to produce a usable strategy.complete_plan now logs a trajectory entry automatically, so list_strategies accumulates empirical success/failure data over time.strict_greenfield and suppress_creation_hints descriptions now explicitly mention test-heavy projects and refactor goals.UserService.js → RecipeService.js).merge_plans MCP tool with four strategies: sequential, interleave, priority, unified.claim_step now returns proximity warnings when other active plans have pending steps targeting the same file.decompose is called with a scaffold, the scaffold fingerprint is used for recipe comparison.auth → authentication, authorization, login, token, etc.).SyntaxError and possible undefined names before running tests.static_analysis heuristics: mixed indentation, TODO/FIXME density, empty files, duplicate symbol names.create_plan. Plans with cyclic step dependencies are rejected with a clear circular_dependency error instead of being persisted.ambiguity field in analysis_meta scores goals for vague phrasing (real-time, AI-powered, conflict resolution, etc.), scope words, and conjunction density. Helps flag underspecified goals before planning.static_analysis object with file-path convention checks and test-coverage heuristics (e.g., missing matching test files), surfacing warnings even when tests pass.retrieve_best_recipe and retrieve_near_matches now union candidates from both the TF-IDF inverted word index and the MinHash LSH index, improving recall for synonym/reordered goals.scoring.py, scaffold_logic.py, goal_nlp.py, constraints.py, scaffold_templates.py. Orchestrator reduced from ~1,700 LOC to ~570 LOC.recipe_index.py with zero-dep inverted word index (TF-IDF) and MinHash LSH for deduplication / approximate nearest neighbors. Schema extended with recipe_terms and recipe_signatures; integrated into store_recipes.py (trigram tables kept for transition safety).analyzer_specs.py + single RegexAnalyzerEngine in analyzer_engine.py. analyzers_ext.py / analyzers_ext2.py now backward-compat shims. All class names remain unchanged.max_parallelism, layer_widths, critical_path_length, and max_dependency_depth with usage guidance for parallel agent workflows.create_plan failed with "table plans has no column named scaffold" on existing databases. The schema migration was targeting the wrong table (steps instead of plans). Fixed in store.py.create_plan → claim_step → record_steps → complete_plan).suppress_creation_hints, scaffold_dag_metrics, skipped_existing_scaffold; refactor-verb guard for creation inference; summary_only surfaces DAG + skip blocks.tests/test_findings_checklist.py encodes validation matrix A–C (305 tests). Core remains stdlib-only (zero third-party runtime deps).SYSTEM_PROMPT.md tracked in repo (sub-agents without MCP).str(None) bug), missing created column in step queries, mixin stubs now raise NotImplementedError, _sql_in empty-input guard._is_ignored_dir import from analyzers_ext2.py.sqlite3.Row unpacking with named column access (8 sites). Pre-compiled Rust/Cargo/Maven regex patterns at module level._validate_registries() wrapper._extract_step_files, TYPE_CHECKING imports, private _cosine naming, KeyboardInterrupt handling in MCP stdio._STEP_COLUMNS + _step_to_dict() in store.py — eliminates duplicated step-dict construction in get_plan() and get_step().word_jaccard, cosine, _strip_php_comments in utils.py condensed (reduced total LOC).type() vs isinstance() inconsistency in PythonAnalyzer.collect_typed_symbols.ZeroDivisionError in explore_trajectories, ValueError with 0 beams, replaced fragile assert with RuntimeError in MCP server._default_beam_count, dead TYPE_CHECKING: pass block._sql_in() helper (deduplicates 8 sites), eliminated redundant dict copies, simplified confusing list-unpacking comprehension.asyncio.to_thread replaces run_in_executor, logger configured at module level for early error capture, lazy _get_analyzer_registry() replaces late inline imports.store_recipes.py, deduplicated Swift SPM scanning._count_importers uses Counter, set-based symbol deduplication, f-string continuation.sqlite3.Error, fixed type annotation, named constants for magic numbers._inject_orderings None-key dict comprehension, recipe mutation in decompose(), hardcoded DB path in synthesize(), missing claimed_by/claimed_at in get_step().RecipeStoreMixin and AgentStoreMixin for type-checker compatibility.claim_step rejects non-pending steps; parallel beam fallback narrowed to OSError only with debug logging.run_incremental optimized from O(K^2) to O(K) via persistent base copy.collect_typed_symbols tests (Rust, C++, Java, C#, Ruby, PHP, Swift, Dart, Zig).log_event bare commit, schema migration over-broad catch, inconsistent win-rate formulas, trigram_signature fingerprint type bug, Rust cargo relpath bug, Java import comment stripping, PHP grouped-use alias stripping.ExecutionHarness.run() alias._walk_project_sources shared generator, DEFAULT_DB_PATH constant consolidation._SUPPORTED_LANGUAGES derived from registry, language/analyzer sync assertion, mid-file imports moved to top, premature Python 3.14 classifier removed.record_failure_pattern and resolve_failure_pattern (wrapped in transactions). Fixed JavaAnalyzer.pick_test_cmd fallback to use system gradle instead of nonexistent ./gradlew._count_importers(), _is_claimed_by_other(), _try_resolve() helpers. run() now delegates to verify_step(). Removed redundant _collect_files wrappers. Merged two transactions in validate_recipes.or "", redundant assignment, ineffective deferred import.collections.abc.Callable/Generator imports, PEP 561 py.typed marker, get_analyzer added to __all__, .mypy_cache/.ruff_cache in .gitignore._split_active_skipped, defensive .get() for constraint descriptions, simplified test assertions._strip_js_comments and _strip_cpp_comments, all analyzers now use the shared _strip_c_comments from utils* to +), preventing duplicate symbol entries with the function patternif, for, while, etc.)detect_language extension counting now uses lambda k: counts[k] instead of counts.get_collect_* helpersPlanner.explore_trajectories (uses self.store)RecipeStore.get_status_summary() instead of raw SQL_TOOL_SCHEMAS and _DISPATCH keys stay in sync__del__, narrowed schema migration exception to sqlite3.OperationalError, fixed list_plans status filter, fixed get_strategy_stats return type, batch-fetched recipe files in list_recipes (N+1 fix)>= 0.9999 instead of == 1.0mcp_stdio.py now calls logging.basicConfig before server constructionif __name__ == "__main__" protectionclaim_step, release_step, and available_steps MCP tools (27 tools total). Agents claim steps before working on them — other agents see claimed steps and skip them. Claims auto-expire after 10 minutes (stale agent recovery). available_steps returns only steps whose dependencies are satisfied AND aren't claimed by another agent.AgentStoreMixin with claim_step(), release_step(), get_available_steps(). RecipeStore inherits from both RecipeStoreMixin and AgentStoreMixin.claimed_by and claimed_at columns (safe migration for existing databases).failure_patterns SQLite table (9 tables total) accumulates structured failure signatures across sessions. When a step fails with verification data, the file + error type + message are auto-recorded. Patterns track occurrence count, first/last seen timestamps, and resolution history.update_step with status="failed" automatically extracts failure analysis and records the pattern — no manual instrumentation needed.template<typename T, std::vector<int>>) instead of breaking at the first >. Also fixed in Rust impl<> and Java/Kotlin generic fun<> patterns.analyze_imports now resolves use super::, use self::, and workspace crate imports (reads Cargo.toml [workspace] members and member crate names). Previously only use crate:: was handled.use Foo\{Bar, Baz, Qux}; (PHP 7.0+) now correctly expanded and resolved. Previously only simple use Foo\Bar; was parsed.Sources/<Module>/ and Tests/<Module>/ directory structure for Swift Package Manager projects. Falls back to parent-directory mapping for non-SPM projects.package.json workspaces field (npm, yarn, pnpm patterns), discovers workspace packages, resolves bare imports (import { x } from '@scope/pkg') to workspace package entry points.usage_events SQLite table (8 tables total) with log_event() and get_usage_stats() methods on RecipeStore. Tool calls, recipe hit/miss rates, and strategy win rates tracked automatically. New usage_stats MCP tool (22 tools total) returns aggregated telemetry over a configurable time window.match/case in mcp_server.py with dispatch-dict pattern. Each tool has a dedicated handler function, looked up via _DISPATCH dict. Adding new tools now requires only: handler function + schema + dict entry.record keyword supported. Dart factory/named constructors detected._strip_c_comments (shared by Go, Rust, Java, C#, Swift, Dart, Zig), _strip_hash_comments (Ruby), and _strip_php_comments (PHP). Previously only Python (AST), TypeScript, and C/C++ stripped comments before symbol detection.sample_file_test/ for analyzer validation across all 15 supported languages.core.py into new strategies.py (~280 LOC). core.py reduced from 595 to 324 LOC, well under the 500 LOC limit._collect_symbols_regex and _collect_typed_symbols_regex helpers from analyzers.py to utils.py. Removed functools.cache lazy-import wrappers from analyzers_ext.py and analyzers_ext2.py (12 lines each), replaced with direct imports._*_SYMBOL_PATTERNS from _*_TYPED_PATTERNS via [p for p, _ in _*_TYPED_PATTERNS] for TypeScript, Rust, Java, C#, Ruby, PHP, Swift, and Dart (8 languages). Eliminates ~70 lines of duplicated regex definitions.PythonAnalyzer._iter_ast() generator, shared by both collect_symbols and collect_typed_symbols, eliminating duplicated file-walking and AST-parsing code.store_recipes.py (import os moved before local imports).analyzers.py reduced from 559 to 463 LOC. Total source: 3,876 to 3,771 LOC (105 lines net reduction through deduplication).collect_typed_symbols() method on all 15 analyzers returns symbols with type classification (function, class, interface, enum, struct, trait, etc.).leaf_first (zero-importer files first), hub_first (network hub files by in*out degree), test_adjacent (files with matching test files first)._init_schema() decomposed into class-level SQL constants.retrieve_best_recipe scoring bug where best_score was updated before JSON validation — corrupted entries could shadow valid recipes.total_files variable in estimate tool, redundant get_analyzer re-import.detect_language replaced 8 extension alias constants and 12-branch if/elif with data-driven loop. Lambda replaced with def in _detect_from_config. Redundant DartAnalyzer.pick_test_cmd branch removed._get_collect_symbols_regex. Moved _SUPPORTED to module-level _SUPPORTED_LANGUAGES frozenset. Simplified __main__.py.CSharpAnalyzer (.cs), RubyAnalyzer (.rb), PhpAnalyzer (.php), SwiftAnalyzer (.swift), DartAnalyzer (.dart), ZigAnalyzer (.zig) in new analyzers_ext2.py (~480 LOC). Total: 15 supported languages (Python, TypeScript, JavaScript, Go, Rust, C/C++, Java/Kotlin, C#, Ruby, PHP, Swift, Dart, Zig)..cs, .rb, .php, .swift, .dart, .zig all counted in detect_language fallback._ANALYZER_REGISTRY. MCP _LANGUAGES list updated to match.CSharpAnalyzer, DartAnalyzer, PhpAnalyzer, RubyAnalyzer, SwiftAnalyzer, ZigAnalyzer exported from __init__.py._ABBREVIATIONS dict in utils.py with ~40 common coding abbreviations (gc, db, auth, api, etc.). normalize_goal expands abbreviations before applying verb synonyms. Recipe matching that previously failed (e.g., "optimize GC" vs "optimize garbage collector") now works with 0.86+ similarity.decompose now returns analysis_meta in the response with language, scope, files_analyzed, dep_files, dep_edges, timing_s (symbols, imports, total), and optional warning for unsupported language fallbacks.language, matching_files, recommendation ("use scope" if >5000 files, "full analysis OK" otherwise). Helps LLMs decide whether to scope before analyzing large repos. 21 MCP tools total._longest depth computation to iterative stack-based DFS with cycle detection via in_stack set. Fixes stack overflow on deep dependency graphs (Guava's 1.66M-edge Java import graph was crashing).scope parameter on decompose, explore, plan_and_execute, CLI (--scope), and MCP tools. Limits analysis to a subdirectory while keeping the full project available for test execution. Example: --scope services/auth analyzes only services/auth/.get_plan_progress(plan_id) returns accumulated prior_edits from passed steps and remaining_steps for continuing failed plans. New resume MCP tool.validate_recipes(project_root) checks recipe file entries against current project, removes stale entries, prunes fully-stale recipes. New validate_recipes MCP tool.detect_language() now checks config files first (Cargo.toml, go.mod, tsconfig.json, package.json, build.gradle, CMakeLists.txt, pyproject.toml) before falling back to extension counting. Config detection takes priority._collect_project_files(root, extensions) in utils.py replaces duplicated os.walk patterns in TypeScriptAnalyzer, CppAnalyzer, RustAnalyzer.language parameter for auto-detecting test command and error patterns._split_active_skipped helper instead of reimplementing inline.Any from analyzers.py, json from analyzers_ext.py, ExecutionHarness/dumps_json from test_strategies.py). Replaced fragile lazy-import global in analyzers_ext.py with functools.cache (thread-safe, simpler). Fixed overly broad BaseException → Exception in transaction rollback (utils.py). Modernized conn.commit()/conn.rollback(). Optimized _order_cohesion set creation. Updated SYSTEM_PROMPT.md (tool count 17→18, added C/C++/Java/Kotlin to multi-language section).save_recipe, retrieve_best_recipe, list_recipes, prune_recipes, _rebuild_trigram_index, _backfill_files) into store_recipes.py as RecipeStoreMixin (~210 LOC). RecipeStore in store.py now inherits from it (~342 LOC, down from 540).CppAnalyzer with 5 targeted patterns: template functions, qualified functions (static/inline/constexpr), operator overloading, constructor/destructor detection, macro-prefixed functions (EXPORT_API etc).JavaAnalyzer._detect_source_roots(project_root) reads build.gradle/build.gradle.kts and pom.xml to find standard source directories (src/main/java, src/main/kotlin, etc). Falls back to project root. analyze_imports now walks detected source roots instead of project root.max_age_days and min_success_ratio parameters. 18 MCP tools total.plan_and_execute runs beams concurrently via concurrent.futures.ProcessPoolExecutor (stdlib). Falls back to sequential on systems where process spawning fails.CppAnalyzer (.c/.cpp/.cc/.cxx/.h/.hpp/.hxx, class/struct/namespace/enum/typedef/function symbols, #include "..." resolution) and JavaAnalyzer (.java/.kt/.kts, class/interface/enum/fun/object/@interface symbols, package-based import resolution) in analyzers_ext.py. MCP language enum expanded to 9 entries.analyzers.py split into analyzers.py (~370 LOC) + analyzers_ext.py (~400 LOC) to stay under 500 LOC per file. All existing imports preserved via re-export.RecipeStore.prune_recipes(max_age_days=90, min_success_ratio=0.1) removes stale, low-quality recipes with cascade deletes to recipe_trigrams and recipe_files.prepare_base(project_root) and run_from_base(edits, base_dir) create one filtered base copy; beams copy from it instead of re-filtering per beam.--dry-run runs explore() instead of plan_and_execute().core.py split into _parse_constraints, _mark_avoided, _inject_orderings, _mark_incompatible, _add_prerequisites.import sys from harness.py. Eliminated duplicate set(symbols) | set(dep_graph) computation in Planner.decompose (core.py). Added defensive json.loads error handling in retrieve_best_recipe (store.py). Made failure default explicit in get_strategy_stats (store.py). Fixed register_strategy parameter order in spec-project.md documentation.GoAnalyzer (regex-based, reads go.mod for module path, resolves internal imports) and RustAnalyzer (regex-based, resolves use crate:: and mod declarations). Shared _collect_symbols_regex helper for regex-based analyzers. detect_language expanded to count .go/.rs files. Registry now supports 5 languages._strip_c_comments for comment stripping before symbol/import detection. Namespace pattern added to _TS_SYMBOL_PATTERNS._order_bottom_up stable-sorts by ascending dependency count (files with fewer deps first). _order_top_down stable-sorts by descending dependency count (most consumer-facing files first). Both now genuinely use the dep_graph parameter.word_substring_score(a, b) for partial word matching. goal_similarity reweighted: 0.3 trigram cosine + 0.4 word Jaccard + 0.3 substring (was 0.4/0.6).save_recipe, list_plans, get_active_constraints. Composite scoring gains recency weighting (30-day half-life). New weights: text 0.4, files 0.25, success 0.15, recency 0.2. File trimmed from 534 to 516 lines._schema() and _prop() helpers reduce from 507 to 255 lines. Added "go" and "rust" to language enums._split_active_skipped helper in core.py, shared by all 6 beam strategy functions (eliminates duplicated active/skipped split pattern). Modernized _VERB_SYNONYMS in utils.py from imperative loop to dict comprehension (eliminates leaked module-level variables _canonical, _variants, _v).register_strategy parameter order in glossary ((name, description, fn) not (name, fn, description))._VERB_SYNONYMS (40+ verb variants to 9 canonical forms), normalize_goal, word_jaccard, and goal_similarity (0.4 trigram cosine + 0.6 word Jaccard on normalized text) in utils.py. save_recipe normalizes before trigram indexing. retrieve_best_recipe uses goal_similarity. _backfill_trigrams renamed to _rebuild_trigram_index (rebuilds with normalized text on init).critical_path (longest dependency chain first — bottleneck feedback), cohesion (flood-fill connected components, largest first, toposort within), minimal_change (fewest symbols first — quick wins)._TS_SYMBOL_PATTERNS list replacing single regex (interface, enum, const enum, type alias, abstract class, decorated class, function expression). Expanded import detection (re-exports, barrel exports, type re-exports, dynamic imports). New _TS_ALIAS_IMPORT_RE, _read_ts_path_aliases, _resolve_alias. Added .mts/.mjs extensions.json import from core.py. Eliminated duplicated error patterns between utils.py and PythonAnalyzer. Removed duplicated _pick_test_cmd from harness.py (falls back to PythonAnalyzer). Removed analyze_imports backward-compat wrapper from utils.py.SYSTEM_PROMPT.md providing a reference orchestration guide for LLM clients (plan-verify-store loop).update_plan_status (exposes existing store method), deactivate_constraint (exposes existing store method). status tool now includes tools count in response. Tool count 16 → 17.recipe_files table in SQLite schema (7 tables total) with indexes on both columns. save_recipe populates recipe_files with file paths from strategy steps. _backfill_files() auto-migrates existing databases.retrieve_best_recipe accepts optional context_files for composite scoring — text similarity (0.5), file overlap via Jaccard (0.3), success ratio (0.2). Without context_files, scoring is backward-compatible (text-only).Planner.decompose passes project file context to recipe retrieval (two-phase: text-only fast path, then structural).list_recipes (limit=20), get_recipe gains context_files parameter. Tool count 14 → 16.trammel/analyzers.py with LanguageAnalyzer protocol, PythonAnalyzer, TypeScriptAnalyzer (regex-based, stdlib-only), detect_language(), get_analyzer().Planner accepts optional analyzer parameter, auto-detects language. ExecutionHarness accepts optional analyzer for language-specific test commands and error patterns._collect_python_symbols removed from core.py (moved to PythonAnalyzer). analyze_imports in utils.py now a backward-compat wrapper delegating to PythonAnalyzer. ast import removed from utils.py.error_patterns parameter..next, .nuxt, coverage, .turbo, .parcel-cache.plan_and_execute, explore, and MCP decompose/explore tools.PythonAnalyzer, TypeScriptAnalyzer, detect_language from trammel.__init__.tests/test_analyzers.py).register_strategy() and get_strategies() API in core.py with StrategyFn and StrategyEntry types. Three built-in strategies (bottom_up, top_down, risk_first) auto-registered at module load. Strategy functions use unified signature (steps, dep_graph) -> steps.explore_trajectories accepts optional store for learning feedback. When provided, strategies sorted by historical success rate from trajectory data. plan_and_execute and explore pass store to enable learning.RecipeStore.get_strategy_stats() aggregates trajectory outcomes by variant (success/failure counts per strategy).list_strategies returns registered strategy names with success/failure stats. Tool count 13 → 14.register_strategy and get_strategies exported from trammel.__init__.tests/test_strategies.py with 8 strategy-focused tests. TestBeamStrategies moved from test_trammel_extra.py. Test count 62 → 70._collect_python_symbols returns symbol name strings instead of redundant dicts; unused file, type, line fields removed (only name was consumed downstream)._step_rationale no longer accepts unused filepath argument._BEAM_STRATEGIES module-level constant; descriptions inlined at usage site, eliminating fragile index-based coupling.spec-project.md.RecipeStore methods wrapped in explicit BEGIN IMMEDIATE transactions with exponential backoff retry on SQLITE_BUSY. Multi-statement operations like create_plan are now atomic. db_connect sets timeout=5.0.recipe_trigrams table with B-tree index). retrieve_best_recipe now queries candidate recipes by shared trigrams before computing exact cosine, avoiding full table scans. Existing databases auto-backfill on schema init._apply_constraints enforces active constraints during decomposition — avoid skips files, dependency injects ordering, incompatible marks conflict metadata, requires adds prerequisite steps. Strategy output now includes constraints_applied._order_bottom_up and _order_top_down place skipped steps at end. _order_risk_first isolates incompatible steps and batches by package directory. explore_trajectories excludes skipped steps from beam edits.close(), __enter__/__exit__, and __del__ safety net. All public API functions and MCP server use with RecipeStore(...).mcp_stdio.py to relative imports, matching the rest of the package.UnicodeDecodeError from _collect_python_symbols except clause (core.py). Files are opened with errors="replace", so the exception can never be raised..chisel to _IGNORED_DIRS in utils.py (tool cache directory, same category as .mypy_cache, .ruff_cache).explore, synthesize, analyze_imports, cosine, trigram_bag_cosine, trigram_signature). Removed dead goal_slice parameter from _collect_python_symbols — computed per symbol but never consumed downstream.rev.setdefault() call where keys are guaranteed to exist from pre-initialization.plan_and_execute API signature in spec now includes test_cmd parameter.__version__ now derived from importlib.metadata at runtime, eliminating version duplication between pyproject.toml and source code.dispatch_tool in mcp_server.py converted from 13-branch if/elif chain to Python 3.10+ match/case.ExecutionHarness accepts test_cmd parameter for custom test runners (e.g. pytest). Propagated through plan_and_execute, CLI (--test-cmd), and MCP verify_step tool.retrieve_best_recipe short-circuits on exact match (similarity 1.0).tests/__init__.py.advance_plan_step method from RecipeStore, unused json/os imports from mcp_server.py, unused json import from tests.harness.py with _IGNORED_DIRS from utils.py via new _is_ignored_dir helper. Fixed egg-info pattern that could never match actual *.egg-info directories.topological_sort uses collections.deque instead of list.pop(0) for O(1) queue operations.Planner.decompose with set union for all_files construction.bottom_up, top_down, risk_first -- instead of label variations.verify_step() and run_incremental().steps and constraints tables._collect_python_symbols collects async def and skips ignored directories.sys.executable; SQLite foreign_keys=ON.edits include path; JSON serialization centralized via dumps_json.__version__ and CLI --version.</details>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.