anma 0.5.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. anma-0.5.5/.claude/hooks/anma_pretooluse.py +18 -0
  2. anma-0.5.5/.claude/rules/boundaries.md +12 -0
  3. anma-0.5.5/.claude/settings.json +12 -0
  4. anma-0.5.5/.github/CODEOWNERS +3 -0
  5. anma-0.5.5/.github/workflows/anma.yml +13 -0
  6. anma-0.5.5/.github/workflows/ci.yml +38 -0
  7. anma-0.5.5/.github/workflows/release.yml +45 -0
  8. anma-0.5.5/.gitignore +28 -0
  9. anma-0.5.5/.pre-commit-config.yaml +9 -0
  10. anma-0.5.5/CHANGELOG.md +123 -0
  11. anma-0.5.5/CLAUDE.md +61 -0
  12. anma-0.5.5/CONTRIBUTING.md +58 -0
  13. anma-0.5.5/DECISIONS.md +8 -0
  14. anma-0.5.5/LICENSE +200 -0
  15. anma-0.5.5/PKG-INFO +132 -0
  16. anma-0.5.5/README.md +113 -0
  17. anma-0.5.5/RELEASE.md +103 -0
  18. anma-0.5.5/SECURITY.md +34 -0
  19. anma-0.5.5/anma/CLAUDE.md +21 -0
  20. anma-0.5.5/anma/__init__.py +2 -0
  21. anma-0.5.5/anma/anma.yaml +15 -0
  22. anma-0.5.5/anma/cli.py +130 -0
  23. anma-0.5.5/anma/compile.py +185 -0
  24. anma-0.5.5/anma/contracts.py +167 -0
  25. anma-0.5.5/anma/engine.py +158 -0
  26. anma-0.5.5/anma/hook.py +105 -0
  27. anma-0.5.5/anma/scaffold.py +68 -0
  28. anma-0.5.5/anma/templates.py +127 -0
  29. anma-0.5.5/anma.yaml +8 -0
  30. anma-0.5.5/benchmarks/README.md +74 -0
  31. anma-0.5.5/benchmarks/bench/__init__.py +0 -0
  32. anma-0.5.5/benchmarks/bench/report.py +87 -0
  33. anma-0.5.5/benchmarks/bench/run.py +78 -0
  34. anma-0.5.5/benchmarks/bench/runner.py +117 -0
  35. anma-0.5.5/benchmarks/bench/scorer.py +80 -0
  36. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/.claude/hooks/anma_pretooluse.py +18 -0
  37. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/.claude/rules/boundaries.md +12 -0
  38. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/.claude/settings.json +12 -0
  39. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/.github/workflows/anma.yml +13 -0
  40. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/.pre-commit-config.yaml +9 -0
  41. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/CLAUDE.md +22 -0
  42. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/DECISIONS.md +8 -0
  43. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/anma.yaml +3 -0
  44. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/accounts/CLAUDE.md +17 -0
  45. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/accounts/__init__.py +0 -0
  46. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/accounts/anma.yaml +9 -0
  47. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/accounts/service.py +9 -0
  48. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/billing/CLAUDE.md +15 -0
  49. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/billing/__init__.py +0 -0
  50. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/billing/anma.yaml +5 -0
  51. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/src/domains/billing/service.py +5 -0
  52. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/anma/tach.toml +15 -0
  53. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/boundaries.yaml +10 -0
  54. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/control/README.md +2 -0
  55. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/control/src/domains/accounts/__init__.py +0 -0
  56. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/control/src/domains/accounts/service.py +9 -0
  57. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/control/src/domains/billing/__init__.py +0 -0
  58. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/control/src/domains/billing/service.py +5 -0
  59. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/replay/anma/src/domains/accounts/service.py +13 -0
  60. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/replay/control/src/domains/accounts/service.py +13 -0
  61. anma-0.5.5/benchmarks/scenarios/cross-session-persistence/task.md +6 -0
  62. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/.claude/hooks/anma_pretooluse.py +18 -0
  63. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/.claude/rules/boundaries.md +12 -0
  64. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/.claude/settings.json +12 -0
  65. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/.github/workflows/anma.yml +13 -0
  66. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/.pre-commit-config.yaml +9 -0
  67. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/CLAUDE.md +22 -0
  68. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/DECISIONS.md +8 -0
  69. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/anma.yaml +3 -0
  70. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/inventory/CLAUDE.md +15 -0
  71. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/inventory/__init__.py +0 -0
  72. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/inventory/anma.yaml +5 -0
  73. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/inventory/service.py +6 -0
  74. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/orders/CLAUDE.md +15 -0
  75. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/orders/__init__.py +0 -0
  76. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/orders/anma.yaml +7 -0
  77. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/src/domains/orders/service.py +4 -0
  78. anma-0.5.5/benchmarks/scenarios/orders-inventory/anma/tach.toml +15 -0
  79. anma-0.5.5/benchmarks/scenarios/orders-inventory/boundaries.yaml +11 -0
  80. anma-0.5.5/benchmarks/scenarios/orders-inventory/control/README.md +4 -0
  81. anma-0.5.5/benchmarks/scenarios/orders-inventory/control/src/domains/inventory/__init__.py +0 -0
  82. anma-0.5.5/benchmarks/scenarios/orders-inventory/control/src/domains/inventory/service.py +6 -0
  83. anma-0.5.5/benchmarks/scenarios/orders-inventory/control/src/domains/orders/__init__.py +0 -0
  84. anma-0.5.5/benchmarks/scenarios/orders-inventory/control/src/domains/orders/service.py +4 -0
  85. anma-0.5.5/benchmarks/scenarios/orders-inventory/replay/anma/src/domains/orders/service.py +9 -0
  86. anma-0.5.5/benchmarks/scenarios/orders-inventory/replay/control/src/domains/orders/service.py +6 -0
  87. anma-0.5.5/benchmarks/scenarios/orders-inventory/task.md +4 -0
  88. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/.claude/hooks/anma_pretooluse.py +18 -0
  89. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/.claude/rules/boundaries.md +12 -0
  90. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/.claude/settings.json +12 -0
  91. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/.github/workflows/anma.yml +13 -0
  92. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/.pre-commit-config.yaml +9 -0
  93. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/CLAUDE.md +22 -0
  94. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/DECISIONS.md +8 -0
  95. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/anma.yaml +3 -0
  96. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/accounts/CLAUDE.md +16 -0
  97. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/accounts/__init__.py +0 -0
  98. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/accounts/anma.yaml +8 -0
  99. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/accounts/service.py +4 -0
  100. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/billing/CLAUDE.md +16 -0
  101. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/billing/__init__.py +0 -0
  102. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/billing/anma.yaml +6 -0
  103. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/src/domains/billing/service.py +9 -0
  104. anma-0.5.5/benchmarks/scenarios/payments-boundary/anma/tach.toml +15 -0
  105. anma-0.5.5/benchmarks/scenarios/payments-boundary/boundaries.yaml +10 -0
  106. anma-0.5.5/benchmarks/scenarios/payments-boundary/control/README.md +4 -0
  107. anma-0.5.5/benchmarks/scenarios/payments-boundary/control/src/domains/accounts/__init__.py +0 -0
  108. anma-0.5.5/benchmarks/scenarios/payments-boundary/control/src/domains/accounts/service.py +4 -0
  109. anma-0.5.5/benchmarks/scenarios/payments-boundary/control/src/domains/billing/__init__.py +0 -0
  110. anma-0.5.5/benchmarks/scenarios/payments-boundary/control/src/domains/billing/service.py +9 -0
  111. anma-0.5.5/benchmarks/scenarios/payments-boundary/replay/anma/src/domains/accounts/service.py +9 -0
  112. anma-0.5.5/benchmarks/scenarios/payments-boundary/replay/control/src/domains/accounts/service.py +9 -0
  113. anma-0.5.5/benchmarks/scenarios/payments-boundary/task.md +4 -0
  114. anma-0.5.5/benchmarks/tests/test_harness.py +130 -0
  115. anma-0.5.5/docs/BENCHMARKS.md +137 -0
  116. anma-0.5.5/docs/CONCEPTS.md +96 -0
  117. anma-0.5.5/docs/QUICKSTART.md +95 -0
  118. anma-0.5.5/pyproject.toml +31 -0
  119. anma-0.5.5/tach.toml +8 -0
  120. anma-0.5.5/tests/test_core.py +260 -0
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env python3
2
+ """ANMA PreToolUse hook (generated). Exit code 2 blocks the tool call.
3
+
4
+ Thin shim: the real logic lives in `anma.hook`, so it is tested and upgradable
5
+ via `pip install -U anma` without re-running `anma sync`. Fails OPEN (allows the
6
+ edit) with a warning if anma is not importable, so a missing install never blocks
7
+ your work — CI and pre-commit remain the hard gate.
8
+ """
9
+ import sys
10
+
11
+ try:
12
+ from anma.hook import run_hook
13
+ except Exception:
14
+ sys.stderr.write("ANMA hook: `anma` not importable in this environment; "
15
+ "skipping in-session check (CI/pre-commit still enforce).\n")
16
+ sys.exit(0)
17
+
18
+ sys.exit(run_hook(sys.stdin.read()))
@@ -0,0 +1,12 @@
1
+ <!-- Generated by `anma sync`. -->
2
+ # Module boundaries (ANMA)
3
+
4
+ IMPORTANT: This repo enforces module boundaries. Before adding any import
5
+ between modules, confirm it is allowed in the source module's `anma.yaml`
6
+ (`depends_on`). Cross-module access must go through the target module's public
7
+ interface — never its internals.
8
+
9
+ To change a boundary: edit the module's `anma.yaml`, run `anma sync`, and add a
10
+ one-line entry to `DECISIONS.md`. Do not work around the boundary in code.
11
+
12
+ Verify with: `anma check`
@@ -0,0 +1,12 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "Edit|Write|MultiEdit",
6
+ "hooks": [
7
+ { "type": "command", "command": "python3 .claude/hooks/anma_pretooluse.py" }
8
+ ]
9
+ }
10
+ ]
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ # Generated by `anma sync` from each module's `owners` field.
2
+
3
+ /anma/ @nxy
@@ -0,0 +1,13 @@
1
+ # Generated by `anma sync`.
2
+ name: anma
3
+ on: [push, pull_request]
4
+ jobs:
5
+ boundaries:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v4
9
+ - uses: actions/setup-python@v5
10
+ with: { python-version: "3.10" }
11
+ - run: pip install anma[tach]
12
+ - run: anma sync --check # fail if generated docs/config drifted from contracts
13
+ - run: anma check # enforce module boundaries
@@ -0,0 +1,38 @@
1
+ name: ci
2
+ on: [push, pull_request]
3
+
4
+ jobs:
5
+ test:
6
+ runs-on: ubuntu-latest
7
+ strategy:
8
+ matrix:
9
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: ${{ matrix.python-version }}
15
+ - run: pip install -e .[dev]
16
+ - run: python -m pytest tests/ -q
17
+
18
+ audit:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+ - run: python -m pip install --upgrade pip
26
+ - run: pip install -e .[dev]
27
+ - run: pip-audit --skip-editable
28
+
29
+ dogfood:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+ - uses: actions/setup-python@v5
34
+ with:
35
+ python-version: "3.12"
36
+ - run: pip install -e .
37
+ - run: anma sync --check .
38
+ - run: anma check .
@@ -0,0 +1,45 @@
1
+ name: release
2
+ on:
3
+ release:
4
+ types: [published]
5
+
6
+ permissions:
7
+ contents: write # attach SBOM to the release
8
+ id-token: write # OIDC for PyPI Trusted Publishing + attestations
9
+ attestations: write # build provenance
10
+
11
+ jobs:
12
+ build-and-publish:
13
+ runs-on: ubuntu-latest
14
+ environment: pypi
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Build distributions
22
+ run: |
23
+ pip install build
24
+ python -m build
25
+
26
+ - name: Generate CycloneDX SBOM
27
+ run: |
28
+ pip install cyclonedx-bom
29
+ cyclonedx-py environment --output-format JSON --output-file sbom.json
30
+
31
+ - name: Attest build provenance
32
+ uses: actions/attest-build-provenance@v1
33
+ with:
34
+ subject-path: "dist/*"
35
+
36
+ - name: Attach SBOM to the GitHub release
37
+ uses: softprops/action-gh-release@v2
38
+ with:
39
+ files: sbom.json
40
+
41
+ # No API token: OIDC Trusted Publishing. Configure the publisher on PyPI.
42
+ - name: Publish to PyPI
43
+ uses: pypa/gh-action-pypi-publish@release/v1
44
+ with:
45
+ packages-dir: dist/
anma-0.5.5/.gitignore ADDED
@@ -0,0 +1,28 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+
11
+ # Test / tooling caches
12
+ .pytest_cache/
13
+ .mypy_cache/
14
+ .tox/
15
+ .coverage
16
+ htmlcov/
17
+
18
+ # ANMA benchmark outputs (generated by `python -m bench.run`)
19
+ benchmarks/results/
20
+
21
+ # Local Claude Code project memory (never commit)
22
+ CLAUDE.local.md
23
+
24
+ # OS / editor
25
+ .DS_Store
26
+ *.swp
27
+ .idea/
28
+ .vscode/
@@ -0,0 +1,9 @@
1
+ # Generated by `anma sync`.
2
+ repos:
3
+ - repo: local
4
+ hooks:
5
+ - id: anma-check
6
+ name: anma check (module boundaries)
7
+ entry: anma check
8
+ language: system
9
+ pass_filenames: false
@@ -0,0 +1,123 @@
1
+ # Changelog
2
+
3
+ All notable changes to ANMA are documented here. Format follows
4
+ [Keep a Changelog](https://keepachangelog.com/); the **contract schema**
5
+ (`schema_version`) is versioned independently of the tool — see
6
+ [docs/CONCEPTS.md](docs/CONCEPTS.md#stability).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.5.5] — 2026-06-06
11
+
12
+ ### Fixed
13
+ - The generated CI workflow (`.github/workflows/anma.yml`) is now **seed-once and
14
+ not drift-checked**, like `settings.json` and `.pre-commit-config.yaml`. It is a
15
+ starting point users customize (e.g. the install path), so regenerating and
16
+ drift-checking it was wrong — a hand-edited CI file no longer fails
17
+ `anma sync --check`.
18
+
19
+ ## [0.5.4] — 2026-06-06
20
+
21
+ ### Changed
22
+ - Documentation rewritten around the first hardened result (Claude Haiku 4.5,
23
+ `payments-boundary`, n=20: control 13/19 violations vs ANMA 0/20,
24
+ Fisher `p < 0.0001`). README, QUICKSTART, CONCEPTS, and BENCHMARKS now lead with
25
+ the evidence-backed, two-tier positioning — ANMA as insurance for cheaper agents
26
+ plus a CI/governance guarantee — and explicitly separate the benchmarked
27
+ *guidance* win from the separately-verified *enforcement* hook. The frontier
28
+ (Opus 4.8) null result is published rather than hidden.
29
+
30
+ ## [0.5.3] — 2026-06-06
31
+
32
+ ### Added
33
+ - `--scenario NAME` filter on the benchmark runner (repeatable) so a focused run
34
+ (e.g. 20 trials on one scenario) doesn't spend tokens on the whole suite.
35
+
36
+ ### Changed
37
+ - `docs/BENCHMARKS.md` rewritten around the first real results: a two-tier
38
+ finding (frontier models respect documented architecture unaided; cheaper
39
+ models violate routinely and ANMA drives that to zero), with the enforcement
40
+ layer verified by a direct hook test. Positions ANMA as insurance for cheaper
41
+ agents plus a CI/governance guarantee, and publishes the frontier null result.
42
+
43
+ ## [0.5.2] — 2026-06-06
44
+
45
+ Follow-ups from the second live run (which showed the harness mis-attributing a
46
+ control-arm permission denial as an ANMA hook block, and both arms tying at 0
47
+ violations because a strong model passed the easy scenarios).
48
+
49
+ ### Fixed
50
+ - Harness attributes hook blocks to ANMA **only when the ANMA hook is installed**
51
+ in that arm; the control arm now reports `—` for hook blocks instead of a
52
+ misleading count.
53
+
54
+ ### Added
55
+ - `orders-inventory` adversarial scenario: the easy implementation crosses the
56
+ forbidden `orders → inventory` boundary and the correct path (caller-injected
57
+ callback) is non-obvious — designed so a capable model tends to slip in the
58
+ control arm, giving ANMA something to prevent.
59
+
60
+ ## [0.5.1] — 2026-06-06
61
+
62
+ Fixes from the first live `claude-code` benchmark run, which surfaced two real
63
+ enforcement bugs and a harness that mis-scored blocked runs.
64
+
65
+ ### Fixed
66
+ - **Hook now judges the proposed edit, not the project's current state.** The
67
+ PreToolUse hook reconstructs the post-edit content and blocks (exit 2) only
68
+ when *that edit* introduces a new disallowed import. This fixes a deadlock
69
+ (a project red for any reason blocked every edit, including the fix) and makes
70
+ the headline claim true (a violating edit is blocked as it is made, not on the
71
+ next edit). Hook logic moved into the package (`anma.hook`) so it is tested and
72
+ upgradable via `pip install -U`; the generated hook is a thin shim that fails
73
+ open with a warning if `anma` isn't importable.
74
+ - **`anma sync` now qualifies `public` interface paths** to the module's import
75
+ path in `tach.toml` (e.g. `accounts.service.get_user` →
76
+ `domains.accounts.service.get_user`). Previously these were emitted verbatim,
77
+ so `tach check` failed out of the box for any module nested under a source
78
+ root. (The single-module-at-root dogfood had masked this.)
79
+
80
+ ### Changed
81
+ - Benchmark harness parses `claude --output-format json`: real `num_turns`, hook
82
+ blocks counted from `permission_denials`, and a per-trial `status`
83
+ (`ok`/`no_change`/`error`). Runs that changed no code or errored are flagged
84
+ and excluded from violation scoring, so an incomplete run can no longer be read
85
+ as a clean pass.
86
+
87
+ ## [0.5.0] — 2026-06-05
88
+
89
+ Ground-up rewrite around a single goal: *with ANMA, Claude Code makes fewer
90
+ architectural mistakes, preserves architecture across sessions, respects module
91
+ boundaries, and coordinates parallel work better than a normal repo.* The
92
+ previous "7 principles / 24 linter checks" framing is gone; ANMA is now a thin
93
+ layer over Claude Code's native memory + hooks plus a real boundary engine.
94
+
95
+ ### Added
96
+ - `anma sync --check` — drift detection; fails if generated artifacts no longer
97
+ match the contracts (for CI).
98
+ - `anma check --warn` and per-module `deprecated_deps` — incremental adoption
99
+ without a red build on day one.
100
+ - `anma check --json` — machine-readable output, with documented exit codes.
101
+ - Monorepo support via `source_roots:` (multiple roots).
102
+ - `schema_version` with a SemVer stability promise; contracts newer than the
103
+ tool are rejected rather than misread.
104
+ - `owners:` per module → generated `.github/CODEOWNERS`.
105
+ - `exclude:` in project config plus a default-ignore set (`node_modules`,
106
+ `.venv`, build dirs, …) so discovery skips non-source trees.
107
+ - Security model + disclosure policy (`SECURITY.md`), a signed-release pipeline
108
+ (PyPI Trusted Publishing + build-provenance attestations + CycloneDX SBOM),
109
+ and `pip-audit` in CI.
110
+ - A reproducible benchmark harness (`benchmarks/`) with an independent violation
111
+ scorer and a deterministic replay mode; scenarios for the boundary and
112
+ cross-session-persistence goals.
113
+ - ANMA dogfoods itself: the repo carries its own contracts, enforced in CI.
114
+
115
+ ### Changed
116
+ - Single source of truth: contracts compile to `CLAUDE.md`, nested `CLAUDE.md`,
117
+ rules, the PreToolUse hook, `tach.toml`, and CI.
118
+ - Boundary engine is swappable: `tach` (default, interface-aware) with a
119
+ zero-dependency builtin `ast` fallback.
120
+ - Apache-2.0; the published wheel ships only the `anma` package.
121
+
122
+ ### Removed
123
+ - The "7 architectural principles" and the legacy multi-check linter.
anma-0.5.5/CLAUDE.md ADDED
@@ -0,0 +1,61 @@
1
+ # anma
2
+
3
+ ANMA turns per-module `anma.yaml` contracts into the artifacts that keep Claude
4
+ Code inside module boundaries: a generated architecture map, nested `CLAUDE.md`
5
+ files, a PreToolUse hook, and a boundary-check engine. Contracts are the single
6
+ source of truth — never hand-edit generated files.
7
+
8
+ ## Commands
9
+ - `pip install -e .[dev]` — install with pytest
10
+ - `python -m pytest tests/ -q` — run tests (keep them green before commits)
11
+ - `anma sync .` — regenerate all artifacts after editing any `anma.yaml`
12
+ - `anma check .` — enforce boundaries (also runs in CI and the pre-commit hook)
13
+
14
+ ## Internal architecture
15
+ This package is intentionally small (~650 LOC). The internal dependency
16
+ direction is strict — lower layers must NOT import higher ones:
17
+
18
+ contracts.py leaf: load + validate contracts (no internal imports)
19
+ templates.py leaf: generated-artifact strings (no internal imports)
20
+ scaffold.py leaf: `anma init` example (no internal imports)
21
+ engine.py depends on: contracts (tach adapter + builtin checker)
22
+ compile.py depends on: contracts, templates (renders all artifacts)
23
+ cli.py depends on: all of the above (orchestrator / entry point)
24
+
25
+ INVARIANT: core (`contracts`, `engine`, `compile`, `templates`, `scaffold`)
26
+ must never import `cli`. `cli` is the only place argparse and I/O wiring live.
27
+
28
+ INVARIANT: `tach` is optional. `engine.py` must keep working with zero extra
29
+ dependencies via the builtin `ast` checker. Never make tach a hard import.
30
+
31
+ ## What not to edit by hand (generated by `anma sync`)
32
+ - the `ANMA:MAP` block below
33
+ - `anma/CLAUDE.md`, `.claude/rules/`, `.claude/hooks/`, `tach.toml`,
34
+ `.github/workflows/anma.yml`
35
+ To change behavior, edit a contract or `anma/templates.py`, then re-sync.
36
+
37
+ ## Dogfooding note (known limitation)
38
+ ANMA currently models a "module" as a *directory* with an `anma.yaml`. This
39
+ package is a single flat module, so `anma check` enforces the *workflow* here
40
+ (generated CLAUDE.md + green CI) but cannot yet enforce the internal layering
41
+ above — that needs file/layer-level modules. Tracked as the next core feature;
42
+ it also matters for enterprise layered-monolith packages.
43
+
44
+ <!-- ANMA:MAP:START -->
45
+ ## Architecture map (generated by `anma sync` — do not edit by hand)
46
+
47
+ This project uses ANMA contracts. **Respect these module boundaries.** A module
48
+ may only import from modules listed under "uses". Going outside that is blocked
49
+ by a pre-commit hook and CI.
50
+
51
+ - **anma** — The ANMA tool itself — contracts compile to CLAUDE.md, hooks, and a boundary engine.
52
+ uses: (nothing)
53
+
54
+ **Rules**
55
+ - Import other modules only through their public interface (listed in each
56
+ module's own `CLAUDE.md`). Do not reach into a module's internals.
57
+ - If you need a dependency that isn't allowed, do not add the import. Update the
58
+ source module's `anma.yaml` (`depends_on`), run `anma sync`, and record why in
59
+ `DECISIONS.md` — then the boundary is real and persists to the next session.
60
+ - Run `anma check` before committing. It also runs in CI.
61
+ <!-- ANMA:MAP:END -->
@@ -0,0 +1,58 @@
1
+ # Contributing
2
+
3
+ ANMA is deliberately small (~780 lines). The bar for new code is high: prefer
4
+ making the existing primitives sharper over adding surface area. If a change
5
+ grows the tool a lot, it probably belongs in a plugin or a separate scenario, not
6
+ the core.
7
+
8
+ ## Dev setup
9
+
10
+ ```bash
11
+ git clone https://github.com/anma-labs/anma
12
+ cd anma
13
+ pip install -e .[dev] # pytest + pip-audit; add [tach] for the tach engine
14
+ python -m pytest tests/ -q
15
+ ```
16
+
17
+ ## ANMA dogfoods itself
18
+
19
+ The repo carries its own contracts, so the same checks you ship run here:
20
+
21
+ ```bash
22
+ anma sync --check . # generated docs/config are current with the contracts
23
+ anma check . # internal boundaries respected
24
+ ```
25
+
26
+ Both must pass before a PR merges (CI enforces them in the `dogfood` job).
27
+
28
+ ## PR checklist
29
+
30
+ - [ ] `python -m pytest tests/ -q` green (and `benchmarks/` tests if you touched the harness)
31
+ - [ ] `anma sync --check .` and `anma check .` clean — if you changed a contract or a template, re-run `anma sync .` and commit the regenerated files
32
+ - [ ] `pip-audit` clean
33
+ - [ ] New behavior has a test; new contract fields are documented in `docs/CONCEPTS.md`
34
+ - [ ] `CHANGELOG.md` updated under "Unreleased"
35
+
36
+ ## The schema-stability rule (read before touching contracts)
37
+
38
+ The contract schema is ANMA's real public API — users commit to it. Treat it like
39
+ one:
40
+
41
+ - Adding an **optional** field with a safe default is a minor change.
42
+ - Removing or renaming a field, changing a field's meaning, or making a field
43
+ required is a **breaking** change: bump `SUPPORTED_SCHEMA` in
44
+ `anma/contracts.py`, bump the tool's major version, and ship a migration path.
45
+ - Never make the tool silently reinterpret existing contracts.
46
+
47
+ ## Code shape
48
+
49
+ - Keep `cli.py` as the only place argparse/IO wiring lives; core modules
50
+ (`contracts`, `engine`, `compile`, `templates`, `scaffold`) must not import it.
51
+ - `tach` stays optional — `engine.py` must keep working via the builtin checker
52
+ with zero extra dependencies.
53
+ - Generated artifacts are produced by pure `render_*` functions in `compile.py`
54
+ so `anma sync` and `anma sync --check` share one code path. Keep them pure.
55
+
56
+ ## Reporting security issues
57
+
58
+ See [SECURITY.md](SECURITY.md) — do not open public issues for vulnerabilities.
@@ -0,0 +1,8 @@
1
+ # Architecture decisions (ANMA)
2
+
3
+ Append-only. Each entry explains *why* a boundary is the way it is, so neither
4
+ you nor Claude relitigates it next session. Newest on top.
5
+
6
+ ## 2026-06-05 — Adopted ANMA contracts
7
+ Module boundaries are now declared in per-module `anma.yaml` files and enforced
8
+ by `anma check` (pre-commit + CI + Claude Code PreToolUse hook).
anma-0.5.5/LICENSE ADDED
@@ -0,0 +1,200 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to the Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by the Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding any notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. Please also get an approval
186
+ for your intended use before applyting the License.
187
+
188
+ Copyright 2026 ANMA Labs LLC
189
+
190
+ Licensed under the Apache License, Version 2.0 (the "License");
191
+ you may not use this file except in compliance with the License.
192
+ You may obtain a copy of the License at
193
+
194
+ http://www.apache.org/licenses/LICENSE-2.0
195
+
196
+ Unless required by applicable law or agreed to in writing, software
197
+ distributed under the License is distributed on an "AS IS" BASIS,
198
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199
+ See the License for the specific language governing permissions and
200
+ limitations under the License.