|
| 1 | +# Agents |
| 2 | + |
| 3 | +Development context for AI agents working on this codebase. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Trailmark parses source code into directed graphs of functions, classes, |
| 8 | +calls, and semantic metadata for security analysis. It supports 16 |
| 9 | +languages via tree-sitter (plus a bundled Circom grammar) and uses |
| 10 | +rustworkx for graph traversal. |
| 11 | + |
| 12 | +## Architecture |
| 13 | + |
| 14 | +``` |
| 15 | +CodeGraph (data) -> GraphStore (indexed storage) -> QueryEngine (facade) |
| 16 | +``` |
| 17 | + |
| 18 | +- **CodeGraph** holds raw nodes, edges, annotations, entrypoints. Mutable. |
| 19 | +- **GraphStore** wraps CodeGraph in a rustworkx PyDiGraph. Validates |
| 20 | + node existence. Returns model objects. |
| 21 | +- **QueryEngine** resolves names to node IDs, delegates to GraphStore, |
| 22 | + returns plain dicts for JSON serialization. |
| 23 | + |
| 24 | +## Key Conventions |
| 25 | + |
| 26 | +- All public methods return `False` or `[]` for missing nodes. Never raise. |
| 27 | +- QueryEngine returns dicts; GraphStore returns model objects. |
| 28 | +- Node IDs follow `module:function`, `module:Class`, `module:Class.method`. |
| 29 | +- Edge confidence: `certain`, `inferred`, `uncertain`. |
| 30 | +- Annotation sources: `"llm"`, `"docstring"`, `"manual"`. |
| 31 | +- Frozen dataclasses for immutable data. `CodeGraph` is mutable. |
| 32 | +- No relative (`..`) imports. Use `from trailmark.*`. |
| 33 | + |
| 34 | +## File Layout |
| 35 | + |
| 36 | +``` |
| 37 | +src/trailmark/ |
| 38 | + models/ # Data classes: CodeUnit, CodeEdge, Annotation, CodeGraph |
| 39 | + graph.py # CodeGraph with add_annotation, clear_annotations, merge |
| 40 | + nodes.py # CodeUnit, Parameter, TypeRef, BranchInfo |
| 41 | + edges.py # CodeEdge, EdgeKind, EdgeConfidence |
| 42 | + annotations.py # Annotation, AnnotationKind, EntrypointTag |
| 43 | + parsers/ # Language-specific tree-sitter parsers |
| 44 | + base.py # BaseParser protocol |
| 45 | + _common.py # Shared parser utilities |
| 46 | + python/ # One subpackage per language |
| 47 | + javascript/ |
| 48 | + ... |
| 49 | + storage/ |
| 50 | + graph_store.py # GraphStore: rustworkx-backed indexed storage |
| 51 | + query/ |
| 52 | + api.py # QueryEngine: high-level facade |
| 53 | + cli.py # CLI entry point |
| 54 | +tests/ # pytest test suite |
| 55 | +``` |
| 56 | + |
| 57 | +## Running Checks |
| 58 | + |
| 59 | +```bash |
| 60 | +uv run ruff check --fix src/ tests/ |
| 61 | +uv run ruff format src/ tests/ |
| 62 | +uv run ty check |
| 63 | +pytest -q |
| 64 | +``` |
| 65 | + |
| 66 | +## Mutation Testing |
| 67 | + |
| 68 | +```bash |
| 69 | +uv run mutmut run |
| 70 | +uv run mutmut results |
| 71 | +``` |
| 72 | + |
| 73 | +### macOS Fork Safety |
| 74 | + |
| 75 | +mutmut uses `fork()` which segfaults with rustworkx on macOS. Set: |
| 76 | + |
| 77 | +```bash |
| 78 | +export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES |
| 79 | +``` |
| 80 | + |
| 81 | +This is not needed on Linux/CI (Ubuntu). |
| 82 | + |
| 83 | +## Adding Features |
| 84 | + |
| 85 | +- Follow the three-layer pattern: add to CodeGraph first, then GraphStore |
| 86 | + (with validation), then QueryEngine (with name resolution and dict |
| 87 | + conversion). |
| 88 | +- Add tests at each layer: `test_models.py`, `test_storage.py`, |
| 89 | + `test_query.py`. |
| 90 | +- Update `README.md` if adding user-facing API. |
0 commit comments