tach
$
npx mdskill add anam-org/metaxy/tachEnforces module boundaries and dependencies in Python codebases
- Solves issues with circular dependencies and unauthorized imports
- Uses a configuration file and module dependency graph for analysis
- Checks imports against declared dependencies and layer rules
- Reports violations and enforces boundaries during testing and commits
SKILL.md
.github/skills/tachView on GitHub ↗
---
name: tach
description: This skill should be used when the user asks to "add a tach module", "configure tach layers", "define module boundaries", "set up interfaces", "run tach check", "check module boundaries", "tach sync", "tach show", "deprecate a dependency", "tach-ignore", "unchecked modules", "tach test", "skip tests with tach", "configure tach.toml", "source roots", "forbid circular dependencies", "enforce module boundaries", "set up architectural layers", or "tach init".
---
# Tach
Tach enforces module boundaries in Python codebases. It verifies that imports between modules respect declared dependencies and public interfaces, with no runtime impact.
For full documentation: https://docs.gauge.sh/
## How This Project Uses Tach
The project defines three architectural layers in `tach.toml`: `cli` > `ext` > `core`. Higher layers may import from lower layers without declaring dependencies. Same-layer imports require explicit `depends_on` declarations. Unlayered facade and primitive modules (e.g., `metaxy`, `metaxy._decorators`) sit outside the layer hierarchy.
Run `uv run tach check` to verify boundaries. The pre-commit hook runs this automatically on `src/` changes.
Run `uv run pytest --tach` to skip tests unaffected by changes (uses tach's module dependency graph for impact analysis).
## Core Commands
| Command | Purpose |
|---------|---------|
| `tach init` | Guided setup: walks through `tach mod`, `tach sync`, `tach show` |
| `tach mod` | Interactive terminal UI to mark module boundaries |
| `tach sync` | Sync `tach.toml` with actual imports (`--add` to only add) |
| `tach check` | Report boundary/interface violations (`--exact` for unused deps) |
| `tach check-external` | Validate 3rd-party imports match `pyproject.toml` |
| `tach show` | Visualize dependency graph (`--web`, `--mermaid`, `-o`) |
| `tach map` | JSON dependency map between files (`--closure` for transitives) |
| `tach report` | Dependencies/usages of a module (`--dependencies`, `--usages`) |
| `tach test` | Run only tests impacted by changes |
| `tach install` | Install as pre-commit hook |
Full command reference: https://docs.gauge.sh/usage/commands/
## Key Concepts
### Modules
A module is a Python package or file with dependencies configured in `tach.toml`. Identified by import path from the nearest source root (e.g., `metaxy.config` for `src/metaxy/config/`).
```toml
[[modules]]
path = "metaxy.config"
layer = "core"
depends_on = ["metaxy._decorators", "metaxy.models"]
```
Special attributes:
- `utility: true` — accessible to all modules without declaring dependency
- `unchecked: true` — no dependency restrictions (for incremental adoption)
- `visibility: []` — isolate module from external imports
- `cannot_depend_on` — forbidden dependencies (takes precedence over `depends_on`)
### Layers
Ordered architectural tiers. Higher layers may freely import from lower layers; lower layers may never import from higher layers. Same-layer imports require explicit `depends_on`.
```toml
layers = ["cli", "ext", "core"]
```
Set `layers_explicit_depends_on = true` to require all cross-layer dependencies be declared explicitly. Mark a layer as closed with `{ name = "commands", closed = true }` to force higher layers through the intermediary.
Full layers documentation: https://docs.gauge.sh/usage/layers/
### Interfaces
Define public APIs to prevent deep coupling. Only imports matching `expose` patterns are allowed.
```toml
[[interfaces]]
expose = ["get_data"]
from = ["core"]
```
Interfaces support `visibility` to restrict consumers and `exclusive: true` to override other interfaces.
Full interfaces documentation: https://docs.gauge.sh/usage/interfaces/
### Deprecation
Mark dependencies as deprecated to surface usage without failing checks:
```toml
depends_on = [{ path = "core", deprecated = true }]
```
### tach-ignore
Suppress specific violations with inline comments:
```python
# tach-ignore
from core.main import private_function
from core.api import priv, pub # tach-ignore priv
```
Add reasons: `# tach-ignore(reason here) member_name`
## Common Tasks
### Add a New Module
1. Add the module definition to `tach.toml` with `path`, `layer`, and `depends_on`
2. Run `tach sync --add` to discover any additional dependencies
3. Run `tach check` to verify
### Move a Module Between Layers
1. Update the `layer` field in `tach.toml`
2. Adjust `depends_on` based on new layer relationships
3. Run `tach check` to verify no violations
### Debug Boundary Violations
Error format: `file.py[L8]: Cannot import 'foo.bar'. Module 'baz' cannot depend on 'foo'.`
Options:
1. Add the dependency to `depends_on` in `tach.toml`
2. Mark dependency as `deprecated` to track without blocking
3. Use `# tach-ignore` for exceptions
4. Restructure imports to go through public interfaces
## Configuration Reference
Full configuration documentation: https://docs.gauge.sh/usage/configuration/
More from anam-org/metaxy
- claude-improve-configSelf-reflect on the current session to identify mistakes and propose improvements to .claude configuration (CLAUDE.md, hooks, skills).
- docs-page-frontmatterWrite YAML front matter for documentation pages with appropriate titles and descriptions for social cards.
- hypothesisUse Hypothesis for property-based testing to automatically generate comprehensive test cases, find edge cases, and write more robust tests with minimal example shrinking. Includes Polars parametric testing integration.
- metaxyThis skill should be used when the user asks to "define a feature", "create a BaseFeature class", "track feature versions", "set up metadata store", "field-level lineage", "FieldSpec", "FeatureDep", "run metaxy CLI", "metaxy migrations", "metaxy lock", "lock features", "external features", "multi-environment", "monorepo features", "enable Map datatype", "enable_map_datatype", or needs guidance on metaxy feature definitions, versioning, metadata stores, CLI commands, testing patterns, feature locking, Map datatype configuration, or multi-environment configuration.
- narwhalsEffectively use Narwhals to write dataframe-agnostic code that works seamlessly across multiple Python dataframe libraries. Write correct type annotations for code using Narwhals.
- sybilUse Sybil for testing code examples in documentation and docstrings. Covers pytest integration, parsers, skip directives, and namespace management.
- syrupyUse syrupy for pytest snapshot testing to ensure the immutability of computed results, manage snapshots, customize serialization, and handle complex data structures with built-in matchers and filters.