analint 0.0.1__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 (130) hide show
  1. analint-0.0.1/.gitignore +14 -0
  2. analint-0.0.1/CHANGELOG.md +45 -0
  3. analint-0.0.1/CONTRIBUTING.md +83 -0
  4. analint-0.0.1/LICENSE +21 -0
  5. analint-0.0.1/PKG-INFO +752 -0
  6. analint-0.0.1/README.md +723 -0
  7. analint-0.0.1/examples/branch_protection/README.md +40 -0
  8. analint-0.0.1/examples/branch_protection/spec.py +454 -0
  9. analint-0.0.1/examples/cloak/README.md +33 -0
  10. analint-0.0.1/examples/cloak/spec.py +264 -0
  11. analint-0.0.1/examples/coin/README.md +33 -0
  12. analint-0.0.1/examples/coin/spec.py +199 -0
  13. analint-0.0.1/examples/ecommerce/README.md +28 -0
  14. analint-0.0.1/examples/ecommerce/spec.py +164 -0
  15. analint-0.0.1/examples/expectations.toml +156 -0
  16. analint-0.0.1/examples/fulfillment/README.md +33 -0
  17. analint-0.0.1/examples/fulfillment/__init__.py +0 -0
  18. analint-0.0.1/examples/fulfillment/actions.py +171 -0
  19. analint-0.0.1/examples/fulfillment/entities.py +90 -0
  20. analint-0.0.1/examples/fulfillment/events.py +23 -0
  21. analint-0.0.1/examples/fulfillment/invariants.py +34 -0
  22. analint-0.0.1/examples/fulfillment/queries.py +76 -0
  23. analint-0.0.1/examples/fulfillment/scenarios.py +224 -0
  24. analint-0.0.1/examples/fulfillment/spec.py +13 -0
  25. analint-0.0.1/examples/k8s_replicaset/README.md +58 -0
  26. analint-0.0.1/examples/k8s_replicaset/spec.py +342 -0
  27. analint-0.0.1/examples/mafia/README.md +31 -0
  28. analint-0.0.1/examples/mafia/spec.py +441 -0
  29. analint-0.0.1/examples/oauth/README.md +46 -0
  30. analint-0.0.1/examples/oauth/__init__.py +1 -0
  31. analint-0.0.1/examples/oauth/assurance.py +378 -0
  32. analint-0.0.1/examples/oauth/oauth.qnt +293 -0
  33. analint-0.0.1/examples/oauth/protocol.py +172 -0
  34. analint-0.0.1/examples/oauth/spec.py +25 -0
  35. analint-0.0.1/examples/play.py +134 -0
  36. analint-0.0.1/examples/sunless_crypt/README.md +34 -0
  37. analint-0.0.1/examples/sunless_crypt/spec.py +324 -0
  38. analint-0.0.1/examples/taskboard/README.md +31 -0
  39. analint-0.0.1/examples/taskboard/__init__.py +0 -0
  40. analint-0.0.1/examples/taskboard/actions.py +140 -0
  41. analint-0.0.1/examples/taskboard/entities.py +95 -0
  42. analint-0.0.1/examples/taskboard/events.py +36 -0
  43. analint-0.0.1/examples/taskboard/flows.py +39 -0
  44. analint-0.0.1/examples/taskboard/invariants.py +30 -0
  45. analint-0.0.1/examples/taskboard/scenarios.py +289 -0
  46. analint-0.0.1/examples/taskboard/spec.py +12 -0
  47. analint-0.0.1/examples/trollbridge/README.md +33 -0
  48. analint-0.0.1/examples/trollbridge/spec.py +165 -0
  49. analint-0.0.1/pyproject.toml +128 -0
  50. analint-0.0.1/src/analint/__init__.py +94 -0
  51. analint-0.0.1/src/analint/cli.py +273 -0
  52. analint-0.0.1/src/analint/loader/__init__.py +15 -0
  53. analint-0.0.1/src/analint/loader/discovery.py +17 -0
  54. analint-0.0.1/src/analint/loader/python_loader.py +242 -0
  55. analint-0.0.1/src/analint/mcp_server.py +171 -0
  56. analint-0.0.1/src/analint/models/__init__.py +72 -0
  57. analint-0.0.1/src/analint/models/action.py +89 -0
  58. analint-0.0.1/src/analint/models/contract.py +61 -0
  59. analint-0.0.1/src/analint/models/effect.py +75 -0
  60. analint-0.0.1/src/analint/models/entity.py +282 -0
  61. analint-0.0.1/src/analint/models/event.py +35 -0
  62. analint-0.0.1/src/analint/models/expr.py +108 -0
  63. analint-0.0.1/src/analint/models/flow.py +59 -0
  64. analint-0.0.1/src/analint/models/initial.py +30 -0
  65. analint-0.0.1/src/analint/models/invariant.py +26 -0
  66. analint-0.0.1/src/analint/models/lifecycle.py +85 -0
  67. analint-0.0.1/src/analint/models/param.py +402 -0
  68. analint-0.0.1/src/analint/models/predicate.py +152 -0
  69. analint-0.0.1/src/analint/models/quantifier.py +280 -0
  70. analint-0.0.1/src/analint/models/query.py +104 -0
  71. analint-0.0.1/src/analint/models/root.py +104 -0
  72. analint-0.0.1/src/analint/models/scenario.py +40 -0
  73. analint-0.0.1/src/analint/models/scope.py +254 -0
  74. analint-0.0.1/src/analint/py.typed +0 -0
  75. analint-0.0.1/src/analint/query.py +438 -0
  76. analint-0.0.1/src/analint/reporter/__init__.py +12 -0
  77. analint-0.0.1/src/analint/reporter/base.py +192 -0
  78. analint-0.0.1/src/analint/reporter/exploration_artifact.py +122 -0
  79. analint-0.0.1/src/analint/reporter/json_reporter.py +101 -0
  80. analint-0.0.1/src/analint/reporter/terminal.py +178 -0
  81. analint-0.0.1/src/analint/validator/__init__.py +3 -0
  82. analint-0.0.1/src/analint/validator/artifact_builder.py +207 -0
  83. analint-0.0.1/src/analint/validator/engine.py +333 -0
  84. analint-0.0.1/src/analint/validator/exploration_service.py +193 -0
  85. analint-0.0.1/src/analint/validator/explorer.py +1048 -0
  86. analint-0.0.1/src/analint/validator/flow_runner.py +99 -0
  87. analint-0.0.1/src/analint/validator/kernel.py +441 -0
  88. analint-0.0.1/src/analint/validator/rule_checker.py +157 -0
  89. analint-0.0.1/src/analint/validator/scenario_runner.py +133 -0
  90. analint-0.0.1/src/analint/validator/state_checks.py +78 -0
  91. analint-0.0.1/src/analint/validator/structural.py +1057 -0
  92. analint-0.0.1/tests/__init__.py +0 -0
  93. analint-0.0.1/tests/fixtures/__init__.py +0 -0
  94. analint-0.0.1/tests/fixtures/broken_spec.py +45 -0
  95. analint-0.0.1/tests/fixtures/composed/__init__.py +1 -0
  96. analint-0.0.1/tests/fixtures/composed/component.py +28 -0
  97. analint-0.0.1/tests/fixtures/composed/spec.py +16 -0
  98. analint-0.0.1/tests/fixtures/inconclusive/spec.py +16 -0
  99. analint-0.0.1/tests/fixtures/multiple_specs.py +4 -0
  100. analint-0.0.1/tests/fixtures/simple_spec.py +47 -0
  101. analint-0.0.1/tests/fixtures/warns/spec.py +14 -0
  102. analint-0.0.1/tests/snapshots/README.md +60 -0
  103. analint-0.0.1/tests/snapshots/examples.json +1617 -0
  104. analint-0.0.1/tests/test_characterization.py +156 -0
  105. analint-0.0.1/tests/test_composition.py +104 -0
  106. analint-0.0.1/tests/test_create_delete.py +236 -0
  107. analint-0.0.1/tests/test_example_expectations.py +89 -0
  108. analint-0.0.1/tests/test_exploration_artifact.py +213 -0
  109. analint-0.0.1/tests/test_exploration_service.py +156 -0
  110. analint-0.0.1/tests/test_explorer.py +809 -0
  111. analint-0.0.1/tests/test_expressions.py +127 -0
  112. analint-0.0.1/tests/test_flow.py +214 -0
  113. analint-0.0.1/tests/test_kernel.py +182 -0
  114. analint-0.0.1/tests/test_loader.py +29 -0
  115. analint-0.0.1/tests/test_models.py +916 -0
  116. analint-0.0.1/tests/test_multiplicity.py +268 -0
  117. analint-0.0.1/tests/test_params.py +167 -0
  118. analint-0.0.1/tests/test_play_runner.py +70 -0
  119. analint-0.0.1/tests/test_presence.py +235 -0
  120. analint-0.0.1/tests/test_quantifiers.py +356 -0
  121. analint-0.0.1/tests/test_query.py +278 -0
  122. analint-0.0.1/tests/test_scaling_models.py +41 -0
  123. analint-0.0.1/tests/test_soundness.py +198 -0
  124. analint-0.0.1/tests/test_trace.py +139 -0
  125. analint-0.0.1/tests/test_transition_conformance.py +433 -0
  126. analint-0.0.1/tests/test_typecheck_probes.py +67 -0
  127. analint-0.0.1/tests/test_validator.py +86 -0
  128. analint-0.0.1/tests/test_verdict.py +110 -0
  129. analint-0.0.1/tests/typecheck_probes/authoring_forms.py +53 -0
  130. analint-0.0.1/tests/typecheck_probes/negative_forms.py +24 -0
@@ -0,0 +1,14 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ .pytest_cache/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ dist/
9
+ *.egg-info/
10
+ .coverage
11
+ coverage.xml
12
+ htmlcov/
13
+ reviews/
14
+ _apalache-out/
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project follows
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html). While the version is
6
+ `0.x` the public API may change between minor releases.
7
+
8
+ ## [0.0.1] — 2026-06-21
9
+
10
+ First public release. The engine and CLI are mature and covered by an extensive
11
+ test suite; this release makes them installable and documents their scope.
12
+
13
+ ### Added
14
+
15
+ - **DSL** for declaring system behaviour in Python: `Entity` with field
16
+ constraints, `Invariant`, `Action` (`pre` / `effect` / `post` / `emits`),
17
+ `Event`, `Lifecycle`, `Scenario`, `Flow`, parameterized actions
18
+ (`Param`), finite quantifiers/aggregates, `Scope` multiplicity, and `Spec` as
19
+ the top-level aggregate.
20
+ - **Validator** with a single transition kernel shared by scenarios, flows, and
21
+ the explorer; structural validation; scenario execution; executable multi-step
22
+ flows.
23
+ - **Bounded reachability engine**: BFS over a finite state graph with reachability
24
+ queries (`Reachable`, `Unreachable`, `AlwaysHolds`, `NoDeadEnd`, `DeadActions`),
25
+ state-diff witness/counterexample traces, and a deterministic
26
+ `analint.exploration/v1` artifact.
27
+ - **CLI** `analint`: `check`, `show`, `affects`, `explore`, `trace`, with
28
+ `--what-if` hypothesis testing, terminal and JSON output, and meaningful exit
29
+ codes.
30
+ - **MCP server** (`analint-mcp`, optional `mcp` extra) exposing the same surface
31
+ to AI agents.
32
+ - **Examples** spanning business analytics, game/narrative rules, and two external
33
+ evidence models (GitHub branch protection, OAuth 2.0 auth-code + PKCE), plus a
34
+ project-sized Kubernetes ReplicaSet dogfood.
35
+
36
+ ### Scope and honesty
37
+
38
+ - Verification is **bounded reachability** over a finite state space: it checks
39
+ safety and reachability and reports a three-valued verdict
40
+ (`PASS` / `FAIL` / `INCONCLUSIVE`), preferring `INCONCLUSIVE` / `NOT_CHECKED`
41
+ over a silent pass.
42
+ - It deliberately does **not** model liveness or temporal "eventually"
43
+ properties. This is a scope boundary, not a defect.
44
+
45
+ [0.0.1]: https://github.com/angru/analint/releases/tag/v0.0.1
@@ -0,0 +1,83 @@
1
+ # Contributing to analint
2
+
3
+ Thanks for your interest in analint. This is an early public release (`0.0.1`):
4
+ issues, reproductions, and example specs are especially welcome.
5
+
6
+ All new repository content — code, comments, docs, commit messages — is written in
7
+ **English**. (Some historical research notes are in Russian; leave them as-is.)
8
+
9
+ ## Development setup
10
+
11
+ analint uses [uv](https://docs.astral.sh/uv/) and targets **Python 3.12+**.
12
+
13
+ ```bash
14
+ git clone https://github.com/angru/analint
15
+ cd analint
16
+ uv sync # create the env and install dev dependencies
17
+ uv run analint examples/ecommerce/ # smoke test
18
+ ```
19
+
20
+ ## Running the checks
21
+
22
+ ```bash
23
+ uv run pytest # full test suite
24
+ uv run ruff check . # lint
25
+ uv run ruff format --check . # formatting
26
+ uv run ty check # type check (src/)
27
+ ```
28
+
29
+ A few specific things to know about the test suite:
30
+
31
+ - `tests/test_characterization.py` is the behavioural regression oracle: a
32
+ committed golden snapshot (`tests/snapshots/examples.json`) of every example's
33
+ verdict, per-scenario results, and per-query graph hashes/traces. If you
34
+ **intentionally** change behaviour, regenerate it — never mechanically, always
35
+ after confirming the new snapshot is correct:
36
+
37
+ ```bash
38
+ UPDATE_SNAPSHOT=1 uv run pytest tests/test_characterization.py
39
+ ```
40
+
41
+ See `tests/snapshots/README.md` for the regen rule and expected deltas.
42
+ - `tests/test_transition_conformance.py` is the fine-grained kernel gate. Agreed
43
+ semantics stay green; known target changes are `xfail(strict=True)`, so fixing
44
+ one produces an XPASS until its marker is deliberately removed.
45
+
46
+ ## Trying the CLI
47
+
48
+ ```bash
49
+ uv run analint check . # validate the spec in the cwd
50
+ uv run analint show action <id> -p <spec> # inspect one action
51
+ uv run analint affects <Entity.field> -p <spec> # blast radius of a field
52
+ uv run analint explore -p <spec> # bounded reachability exploration
53
+ uv run analint check . --what-if file.py # test a hypothesis without editing files
54
+ ```
55
+
56
+ Exit codes: `0` ok · `1` findings · `2` usage · `3` spec failed to load · `4`
57
+ inconclusive (a query exhausted its exploration budget — it proved nothing). JSON
58
+ output carries a three-valued `verdict` (`PASS`/`FAIL`/`INCONCLUSIVE`).
59
+
60
+ ## How the project works
61
+
62
+ - **`ROADMAP.md` is the single source of truth** for status and priorities.
63
+ `research/` holds dated design rationale that the roadmap links to;
64
+ `AGENTS.md` is a detailed map of the codebase.
65
+ - The project is **review-gated and fail-closed by design**: a verification
66
+ feature that hides a defect is the worst possible outcome here. Prefer
67
+ `INCONCLUSIVE` / `NOT_CHECKED` over a silent pass. When you add or change a
68
+ verification path, adversarially self-probe it — plant a defect the new path
69
+ should catch and confirm the overall verdict actually goes `FAIL`.
70
+ - Keep changes semantically focused: one behavioural change per commit, with the
71
+ characterization snapshot updated deliberately in the same commit.
72
+
73
+ ## Pull requests
74
+
75
+ 1. Branch from `main`.
76
+ 2. Make the change; add or update tests and (if behaviour changed) the snapshot.
77
+ 3. Ensure `pytest`, `ruff`, and `ty` are green.
78
+ 4. Open a PR describing **what guarantee changed**, not just the diff.
79
+
80
+ ## License
81
+
82
+ By contributing, you agree that your contributions are licensed under the
83
+ project's [MIT License](LICENSE).
analint-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 angru
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.