invar-tools 1.0.0__py3-none-any.whl → 1.2.0__py3-none-any.whl

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 (57) hide show
  1. invar/core/contracts.py +75 -5
  2. invar/core/entry_points.py +294 -0
  3. invar/core/format_specs.py +196 -0
  4. invar/core/format_strategies.py +197 -0
  5. invar/core/formatter.py +27 -4
  6. invar/core/hypothesis_strategies.py +47 -5
  7. invar/core/lambda_helpers.py +1 -0
  8. invar/core/models.py +23 -17
  9. invar/core/parser.py +6 -2
  10. invar/core/property_gen.py +81 -40
  11. invar/core/purity.py +10 -4
  12. invar/core/review_trigger.py +298 -0
  13. invar/core/rule_meta.py +61 -2
  14. invar/core/rules.py +83 -19
  15. invar/core/shell_analysis.py +252 -0
  16. invar/core/shell_architecture.py +171 -0
  17. invar/core/suggestions.py +6 -0
  18. invar/core/tautology.py +1 -0
  19. invar/core/utils.py +51 -4
  20. invar/core/verification_routing.py +158 -0
  21. invar/invariant.py +1 -0
  22. invar/mcp/server.py +20 -3
  23. invar/shell/cli.py +59 -31
  24. invar/shell/config.py +259 -10
  25. invar/shell/fs.py +5 -2
  26. invar/shell/git.py +2 -0
  27. invar/shell/guard_helpers.py +78 -3
  28. invar/shell/guard_output.py +100 -24
  29. invar/shell/init_cmd.py +27 -7
  30. invar/shell/mcp_config.py +3 -0
  31. invar/shell/mutate_cmd.py +184 -0
  32. invar/shell/mutation.py +314 -0
  33. invar/shell/perception.py +2 -0
  34. invar/shell/property_tests.py +17 -2
  35. invar/shell/prove.py +35 -3
  36. invar/shell/prove_accept.py +113 -0
  37. invar/shell/prove_fallback.py +148 -46
  38. invar/shell/templates.py +34 -0
  39. invar/shell/test_cmd.py +3 -1
  40. invar/shell/testing.py +6 -17
  41. invar/shell/update_cmd.py +2 -0
  42. invar/templates/CLAUDE.md.template +65 -9
  43. invar/templates/INVAR.md +96 -23
  44. invar/templates/aider.conf.yml.template +16 -14
  45. invar/templates/commands/review.md +200 -0
  46. invar/templates/cursorrules.template +22 -13
  47. invar/templates/examples/contracts.py +3 -1
  48. invar/templates/examples/core_shell.py +3 -1
  49. {invar_tools-1.0.0.dist-info → invar_tools-1.2.0.dist-info}/METADATA +81 -15
  50. invar_tools-1.2.0.dist-info/RECORD +77 -0
  51. invar_tools-1.2.0.dist-info/licenses/LICENSE +190 -0
  52. invar_tools-1.2.0.dist-info/licenses/LICENSE-GPL +674 -0
  53. invar_tools-1.2.0.dist-info/licenses/NOTICE +63 -0
  54. invar_tools-1.0.0.dist-info/RECORD +0 -64
  55. invar_tools-1.0.0.dist-info/licenses/LICENSE +0 -21
  56. {invar_tools-1.0.0.dist-info → invar_tools-1.2.0.dist-info}/WHEEL +0 -0
  57. {invar_tools-1.0.0.dist-info → invar_tools-1.2.0.dist-info}/entry_points.txt +0 -0
invar/templates/INVAR.md CHANGED
@@ -5,8 +5,14 @@
5
5
  │ This file is managed by Invar. Changes may be lost on │
6
6
  │ `invar update`. Add project content to CLAUDE.md instead. │
7
7
  └─────────────────────────────────────────────────────────────┘
8
+
9
+ License: CC-BY-4.0 (Creative Commons Attribution 4.0 International)
10
+ https://creativecommons.org/licenses/by/4.0/
11
+
12
+ You are free to share and adapt this document, provided you give
13
+ appropriate credit to the Invar project.
8
14
  -->
9
- # The Invar Protocol v3.26
15
+ # The Invar Protocol v4.0
10
16
 
11
17
  > **"Trade structure for safety."**
12
18
 
@@ -70,46 +76,113 @@ def read_config(path: Path) -> Result[dict, str]:
70
76
 
71
77
  More examples: `.invar/examples/`
72
78
 
73
- ## Session Start (Required)
79
+ ## Check-In (Required)
80
+
81
+ Your first message MUST display:
82
+
83
+ ```
84
+ ✓ Check-In: guard PASS | top: <entry1>, <entry2>
85
+ ```
86
+
87
+ Execute `invar_guard(changed=true)` and `invar_map(top=10)`, then show this one-line summary.
88
+
89
+ This is your sign-in. The user sees it immediately.
90
+ No visible check-in = Session not started.
91
+
92
+ Then read `.invar/context.md` for project state and lessons learned.
74
93
 
75
- Before writing any code, execute:
94
+ ## USBV Workflow (DX-32)
76
95
 
77
- 1. **invar_guard** (changed=true) Check existing violations
78
- 2. **invar_map** (top=10) — Understand code structure
96
+ **U**nderstand **S**pecify **B**uild **V**alidate
79
97
 
80
- Then read:
81
- - `.invar/examples/` — Core/Shell patterns
82
- - `.invar/context.md` Project state, lessons learned
98
+ | Phase | Purpose | Activities |
99
+ |-------|---------|------------|
100
+ | UNDERSTAND | Know what and why | Intent, Inspect (invar sig/map), Constraints |
101
+ | SPECIFY | Define boundaries | @pre/@post, Design decomposition, Doctests |
102
+ | BUILD | Write code | Implement leaves, Compose |
103
+ | VALIDATE | Confirm correctness | invar guard, Review Gate, Reflect |
83
104
 
84
- **Skipping these steps Non-compliant code Rework required.**
105
+ **Key:** Inspect before Contract. Depth varies naturally. Iterate when needed.
85
106
 
86
- Use MCP tools if available (`invar_guard`, `invar_map`), otherwise use CLI commands.
87
- For agent-specific entry format, see your configuration file (CLAUDE.md, .cursorrules, etc).
107
+ **Review Gate:** When Guard triggers `review_suggested` (escape hatches ≥3, security paths, low coverage), invoke `/review` before completion.
88
108
 
89
- ## ICIDIV Workflow (Required Order)
109
+ ## Visible Workflow (DX-30)
110
+
111
+ For complex tasks (3+ functions), show 3 checkpoints in TodoList:
90
112
 
91
113
  ```
92
- 1. Intent — What? Core or Shell? Edge cases?
93
- 2. Contract — @pre/@post + doctests BEFORE code
94
- 3. Inspect — invar sig <file>, invar map --top 10
95
- 4. Design — Decompose: leaves first, then compose
96
- 5. Implement — Write code to pass your doctests
97
- 6. Verify — invar guard. If fail: reflect → fix → verify
114
+ [UNDERSTAND] Task description, codebase context, constraints
115
+ [SPECIFY] Contracts (@pre/@post) and design decomposition
116
+ [VALIDATE] Guard results, Review Gate if triggered, integration status
98
117
  ```
99
118
 
100
- **Contract before Implement. Verify after every change. No exceptions.**
119
+ **BUILD is internal work** not shown in TodoList.
120
+
121
+ **Show contracts before code.** Example:
122
+
123
+ ```python
124
+ [SPECIFY] calculate_discount:
125
+ @pre(lambda price, rate: price > 0 and 0 <= rate <= 1)
126
+ @post(lambda result: result >= 0)
127
+ def calculate_discount(price: float, rate: float) -> float: ...
128
+
129
+ [BUILD] Now coding...
130
+ ```
131
+
132
+ **When to use:** New features (3+ functions), architectural changes, Core modifications.
133
+ **Skip for:** Single-line fixes, documentation, trivial refactoring.
101
134
 
102
135
  ## Task Completion
103
136
 
104
137
  A task is complete only when ALL conditions are met:
105
- - Session Start executed (invar_guard + invar_map, context read)
138
+ - Check-In displayed: `✓ Check-In: guard PASS | top: <entry1>, <entry2>`
106
139
  - Intent explicitly stated
107
140
  - Contract written before implementation
108
- - Final **invar_guard** passed
141
+ - Final displayed: `✓ Final: guard PASS | <errors>, <warnings>`
109
142
  - User requirement satisfied
110
143
 
111
144
  **Missing any = Task incomplete.**
112
145
 
146
+ ## Markers
147
+
148
+ ### Entry Points
149
+
150
+ Entry points are framework callbacks (`@app.route`, `@app.command`) at Shell boundary.
151
+ - **Exempt** from `Result[T, E]` — must match framework signature
152
+ - **Keep thin** (max 15 lines) — delegate to Shell functions that return Result
153
+
154
+ Auto-detected by decorators. For custom callbacks:
155
+
156
+ ```python
157
+ # @shell:entry
158
+ def on_custom_event(data: dict) -> dict:
159
+ result = handle_event(data)
160
+ return result.unwrap_or({"error": "failed"})
161
+ ```
162
+
163
+ ### Shell Complexity
164
+
165
+ When shell function complexity is justified:
166
+
167
+ ```python
168
+ # @shell_complexity: Subprocess with error classification
169
+ def run_external_tool(...): ...
170
+
171
+ # @shell_orchestration: Multi-step pipeline coordination
172
+ def process_batch(...): ...
173
+ ```
174
+
175
+ ### Architecture Escape Hatch
176
+
177
+ When rule violation has valid architectural justification:
178
+
179
+ ```python
180
+ # @invar:allow shell_result: Framework callback signature fixed
181
+ def flask_handler(): ...
182
+ ```
183
+
184
+ See `invar rules` for all rule names.
185
+
113
186
  ## Commands
114
187
 
115
188
  ```bash
@@ -126,9 +199,9 @@ invar map --top 10 # Most-referenced symbols
126
199
  [tool.invar.guard]
127
200
  core_paths = ["src/myapp/core"]
128
201
  shell_paths = ["src/myapp/shell"]
129
- exclude_doctest_lines = true # Don't count doctests in function size
202
+ # DX-22: Doctest lines are always excluded from size calculations by default
130
203
  ```
131
204
 
132
205
  ---
133
206
 
134
- *Protocol v3.26 | [Guide](docs/INVAR-GUIDE.md) | [Examples](.invar/examples/)*
207
+ *Protocol v4.0 — USBV workflow (DX-32) | [Guide](docs/INVAR-GUIDE.md) | [Examples](.invar/examples/)*
@@ -4,26 +4,28 @@
4
4
  # Auto-read protocol files at session start
5
5
  read:
6
6
  - INVAR.md
7
- - .invar/examples/core_example.py
8
- - .invar/examples/shell_example.py
7
+ - .invar/examples/contracts.py
8
+ - .invar/examples/core_shell.py
9
9
  - .invar/context.md
10
10
 
11
11
  # System prompt addition
12
12
  system-prompt: |
13
13
  Follow the Invar Protocol in INVAR.md.
14
14
 
15
- Before writing code, execute:
16
- 1. invar_guard (changed=true) - or: invar guard --changed
17
- 2. invar_map (top=10) - or: invar map --top 10
15
+ ## Check-In
16
+ Your first message MUST display:
17
+ Check-In: guard PASS | top: <entry1>, <entry2>
18
18
 
19
- Use MCP tools if available, otherwise use CLI commands.
19
+ Execute: invar guard --changed && invar map --top 10
20
+ This is your sign-in. No visible check-in = Session not started.
20
21
 
21
- Workflow (ICIDIV):
22
- - Intent: What? Core or Shell?
23
- - Contract: @pre/@post + doctests BEFORE code
24
- - Inspect: invar_sig (or: invar sig <file>)
25
- - Design: Decompose first
26
- - Implement: Pass your doctests
27
- - Verify: invar_guard (or: invar guard)
22
+ ## Final
23
+ Your last message MUST display:
24
+ Final: guard PASS | 0 errors, 2 warnings
28
25
 
29
- Task complete only when final invar_guard passes.
26
+ Execute: invar guard
27
+ This is your sign-out. Completes the Check-In/Final pair.
28
+
29
+ ## Workflow (USBV)
30
+ Understand → Specify → Build → Validate
31
+ Inspect before Contract. Depth varies naturally.
@@ -0,0 +1,200 @@
1
+ # Code Review (Reviewer Role)
2
+
3
+ ## Mode Detection (Required First Step)
4
+
5
+ Before reviewing, determine the appropriate mode:
6
+
7
+ ### Check for `review_suggested`
8
+
9
+ Look at your conversation history for recent `invar guard` output, or run:
10
+ ```bash
11
+ invar guard --changed
12
+ ```
13
+
14
+ Check if `review_suggested` warning is present:
15
+ ```
16
+ WARNING: review_suggested - High escape hatch count: N @invar:allow markers
17
+ WARNING: review_suggested - Security-sensitive path detected
18
+ WARNING: review_suggested - Low contract coverage
19
+ ```
20
+
21
+ ### Select Mode
22
+
23
+ | Condition | Mode | Why |
24
+ |-----------|------|-----|
25
+ | `review_suggested` present | **Isolated** | Eliminates confirmation bias |
26
+ | No trigger | **Quick** | Faster, context preserved |
27
+ | User requests `--isolated` | **Isolated** | Explicit override |
28
+ | User requests `--quick` | **Quick** | Explicit override |
29
+
30
+ ---
31
+
32
+ ## Isolated Mode
33
+
34
+ **Use when:** `review_suggested` triggered, or user explicitly requests isolation.
35
+
36
+ Spawn an independent reviewer with fresh context using Task tool:
37
+
38
+ ```
39
+ I'll spawn an independent reviewer to eliminate confirmation bias...
40
+
41
+ [Task tool call]
42
+ prompt: |
43
+ You are an adversarial code reviewer. Your job is to FIND PROBLEMS.
44
+
45
+ Review these files: {files_to_review}
46
+
47
+ Read .claude/commands/review.md for the full checklist, then:
48
+ 1. Check contract semantic value (not just syntax)
49
+ 2. Audit all escape hatches (@invar:allow)
50
+ 3. Look for logic errors and edge cases
51
+ 4. Check security if applicable
52
+
53
+ Report issues as CRITICAL/MAJOR/MINOR with file:line locations.
54
+
55
+ Your success is measured by problems found, not code approved.
56
+
57
+ subagent_type: "general-purpose"
58
+ ```
59
+
60
+ After receiving the sub-agent's report, summarize findings for the user.
61
+
62
+ **Key:** The sub-agent has NO conversation history. It only sees the code.
63
+
64
+ ---
65
+
66
+ ## Quick Mode
67
+
68
+ **Use when:** No `review_suggested` trigger, routine review needed.
69
+
70
+ Proceed with same-context review below.
71
+
72
+ ---
73
+
74
+ ## Adversarial Reviewer Persona
75
+
76
+ You are an **adversarial code reviewer**. Your job is to FIND PROBLEMS.
77
+
78
+ ### Your Mindset
79
+
80
+ Assume:
81
+ - The code has bugs until proven otherwise
82
+ - The contracts may be meaningless ceremony
83
+ - The implementer may have rationalized poor decisions
84
+ - Escape hatches may be abused
85
+
86
+ You are NOT here to:
87
+ - Validate that code works
88
+ - Confirm the implementer did a good job
89
+ - Be nice or diplomatic
90
+
91
+ You ARE here to:
92
+ - Find bugs, logic errors, edge cases
93
+ - Challenge whether contracts have semantic value
94
+ - Identify code smells and duplication
95
+ - Question every escape hatch
96
+ - Check if code matches contracts (not if code "seems right")
97
+
98
+ **Your success is measured by problems found, not code approved.**
99
+
100
+ ---
101
+
102
+ ## Review Checklist
103
+
104
+ > **Principle:** Only items requiring semantic judgment. Mechanical checks are excluded (see bottom).
105
+
106
+ ### A. Contract Semantic Value
107
+ - [ ] Does @pre constrain inputs beyond type checking?
108
+ - Bad: `@pre(lambda x: isinstance(x, int))`
109
+ - Good: `@pre(lambda x: x > 0 and x < MAX_VALUE)`
110
+ - [ ] Does @post verify meaningful output properties?
111
+ - Bad: `@post(lambda result: result is not None)`
112
+ - Good: `@post(lambda result: len(result) == len(input))`
113
+ - [ ] Could someone implement correctly from contracts alone?
114
+ - [ ] Are boundary conditions explicit in contracts?
115
+
116
+ ### B. Doctest Coverage
117
+ - [ ] Do doctests cover normal cases?
118
+ - [ ] Do doctests cover boundary cases?
119
+ - [ ] Do doctests cover error cases?
120
+ - [ ] Are doctests testing behavior, not just syntax?
121
+
122
+ ### C. Code Quality
123
+ - [ ] Is duplicated code worth extracting?
124
+ - [ ] Is naming consistent and clear?
125
+ - [ ] Is complexity justified?
126
+
127
+ ### D. Escape Hatch Audit
128
+ - [ ] Is each @invar:allow justification valid?
129
+ - [ ] Could refactoring eliminate the need?
130
+ - [ ] Is there a pattern suggesting systematic issues?
131
+
132
+ ### E. Logic Verification
133
+ - [ ] Do contracts correctly capture intended behavior?
134
+ - [ ] Are there paths that bypass contract checks?
135
+ - [ ] Are there implicit assumptions not in contracts?
136
+ - [ ] What happens with unexpected inputs?
137
+
138
+ ### F. Security
139
+ - [ ] Are inputs validated against security threats (injection, XSS)?
140
+ - [ ] No hardcoded secrets (API keys, passwords, tokens)?
141
+ - [ ] Are authentication/authorization checks correct?
142
+ - [ ] Is sensitive data properly protected?
143
+
144
+ ### G. Error Handling & Observability
145
+ - [ ] Are exceptions caught at appropriate level?
146
+ - [ ] Are error messages clear without leaking sensitive info?
147
+ - [ ] Are critical operations logged for debugging?
148
+ - [ ] Is there graceful degradation on failure?
149
+
150
+ ---
151
+
152
+ ## Excluded (Covered by Tools)
153
+
154
+ These are checked by Guard or linters - don't duplicate:
155
+ - Core/Shell separation → Guard (forbidden_import, impure_call)
156
+ - Shell returns Result[T,E] → Guard (shell_result)
157
+ - Missing contracts → Guard (missing_contract)
158
+ - File/function size limits → Guard (file_size, function_size)
159
+ - Entry point thickness → Guard (entry_point_too_thick)
160
+ - Magic numbers → Linters (ruff)
161
+ - Escape hatch count → Guard (review_suggested)
162
+
163
+ ---
164
+
165
+ ## Report Format
166
+
167
+ For each issue found, use severity levels:
168
+
169
+ | Severity | Meaning | Enforcement |
170
+ |----------|---------|-------------|
171
+ | **CRITICAL** | Must fix before completion | Blocking |
172
+ | **MAJOR** | Fix or provide written justification | Strong |
173
+ | **MINOR** | Optional, can defer | Advisory |
174
+
175
+ ```markdown
176
+ ### [CRITICAL/MAJOR/MINOR] Issue Title
177
+
178
+ **Location:** file.py:line_number
179
+ **Category:** contract_quality | logic_error | security | escape_hatch | code_smell
180
+ **Problem:** What's wrong
181
+ **Suggestion:** How to fix (if applicable)
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Instructions Summary
187
+
188
+ 1. **Mode Detection:** Check for `review_suggested` in guard output
189
+ 2. **If Isolated Mode:** Spawn Task sub-agent (fresh context)
190
+ 3. **If Quick Mode:** Proceed with same-context adversarial review
191
+ 4. Go through each checklist category
192
+ 5. For each issue, determine severity (CRITICAL/MAJOR/MINOR)
193
+ 6. Report with structured format above
194
+ 7. Be thorough and adversarial
195
+
196
+ **Remember:** You are READ-ONLY. Report issues, don't fix them directly.
197
+
198
+ ---
199
+
200
+ Now review the recent changes or the files specified by the user.
@@ -1,28 +1,37 @@
1
1
  # Invar Protocol
2
2
 
3
- Follow the Invar Protocol in INVAR.md — includes Session Start, ICIDIV workflow, and Task Completion requirements.
3
+ Follow the Invar Protocol in INVAR.md — includes Check-In, USBV workflow, and Task Completion requirements.
4
4
 
5
- ## Cursor-Specific: Entry Verification
5
+ ## Check-In
6
6
 
7
- Before writing any code, execute and show output from:
7
+ Your first message MUST display:
8
8
 
9
9
  ```
10
- invar_guard (changed=true) # Check existing violations
11
- invar_map (top=10) # Understand code structure
10
+ Check-In: guard PASS | top: <entry1>, <entry2>
12
11
  ```
13
12
 
14
- Use MCP tools if available, otherwise use CLI commands:
15
- - `invar guard --changed`
16
- - `invar map --top 10`
13
+ Execute `invar guard --changed` and `invar map --top 10`, then show this one-line summary.
17
14
 
18
- Then read .invar/examples/ and .invar/context.md.
15
+ This is your sign-in. The user sees it immediately.
16
+ No visible check-in = Session not started.
19
17
 
20
- Skipping these steps leads to non-compliant code.
18
+ Then read `.invar/context.md` for project state and lessons learned.
19
+
20
+ ## Final
21
+
22
+ Your last message for an implementation task MUST display:
23
+
24
+ ```
25
+ ✓ Final: guard PASS | 0 errors, 2 warnings
26
+ ```
27
+
28
+ Execute `invar guard` and show this one-line summary.
29
+
30
+ This is your sign-out. Completes the Check-In/Final pair.
21
31
 
22
32
  ## Quick Reference
23
33
 
24
34
  - Core (`**/core/**`): @pre/@post contracts, doctests, pure (no I/O)
25
35
  - Shell (`**/shell/**`): Result[T, E] return type
26
- - Workflow: IntentContractInspectDesign → Implement → Verify
27
- - Contract before Implement. No exceptions.
28
- - Task complete only when final invar_guard passes.
36
+ - Workflow: UnderstandSpecifyBuildValidate (USBV)
37
+ - Inspect before Contract. Depth varies naturally.
@@ -5,7 +5,9 @@ Reference patterns for @pre/@post contracts and doctests.
5
5
  Managed by Invar - do not edit directly.
6
6
  """
7
7
 
8
- from deal import post, pre
8
+ # Use invar_runtime for lightweight runtime contracts
9
+ # (or 'from deal import pre, post' works too - deal is the underlying library)
10
+ from invar_runtime import post, pre
9
11
 
10
12
  # =============================================================================
11
13
  # GOOD: Complete Contract
@@ -7,7 +7,9 @@ Managed by Invar - do not edit directly.
7
7
 
8
8
  from pathlib import Path
9
9
 
10
- from deal import post, pre
10
+ # Use invar_runtime for lightweight runtime contracts
11
+ # (or 'from deal import pre, post' works too - deal is the underlying library)
12
+ from invar_runtime import post, pre
11
13
  from returns.result import Failure, Result, Success
12
14
 
13
15
  # =============================================================================
@@ -1,18 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: invar-tools
3
- Version: 1.0.0
3
+ Version: 1.2.0
4
4
  Summary: AI-native software engineering tools with design-by-contract verification
5
5
  Project-URL: Homepage, https://github.com/tefx/invar
6
6
  Project-URL: Documentation, https://github.com/tefx/invar#readme
7
7
  Project-URL: Repository, https://github.com/tefx/invar
8
8
  Project-URL: Issues, https://github.com/tefx/invar/issues
9
9
  Author: Invar Team
10
- License-Expression: MIT
10
+ License-Expression: GPL-3.0-or-later
11
11
  License-File: LICENSE
12
+ License-File: LICENSE-GPL
13
+ License-File: NOTICE
12
14
  Keywords: ai,code-quality,contracts,design-by-contract,static-analysis
13
15
  Classifier: Development Status :: 3 - Alpha
14
16
  Classifier: Intended Audience :: Developers
15
- Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
16
18
  Classifier: Programming Language :: Python :: 3
17
19
  Classifier: Programming Language :: Python :: 3.11
18
20
  Classifier: Programming Language :: Python :: 3.12
@@ -39,7 +41,7 @@ Description-Content-Type: text/markdown
39
41
 
40
42
  [![PyPI version](https://badge.fury.io/py/invar-tools.svg)](https://badge.fury.io/py/invar-tools)
41
43
  [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
42
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44
+ [![License](https://img.shields.io/badge/License-Apache%202.0%20%2B%20GPL--3.0-blue.svg)](#license)
43
45
 
44
46
  **Don't hope AI code is correct. Know it.**
45
47
 
@@ -62,39 +64,74 @@ def average(items: list[float]) -> float:
62
64
 
63
65
  ## Installation
64
66
 
65
- ### Development Tools
67
+ ### Two Packages, Different Purposes
68
+
69
+ ```
70
+ ┌─────────────────────────────────────────────────────────────────┐
71
+ │ Your Project │
72
+ │ ├── src/ │
73
+ │ │ └── from invar_runtime import pre, post ← Runtime │
74
+ │ │ │
75
+ │ └── Development (not shipped with your code) │
76
+ │ └── uvx invar-tools guard ← Tools │
77
+ └─────────────────────────────────────────────────────────────────┘
78
+ ```
79
+
80
+ | Package | Install | When to Use |
81
+ |---------|---------|-------------|
82
+ | **invar-tools** | `uvx invar-tools <cmd>` | Development: verification, init, MCP server |
83
+ | **invar-runtime** | `pip install invar-runtime` | Production: add to your project's dependencies |
84
+
85
+ ### Development Tools (invar-tools)
66
86
 
67
87
  ```bash
68
- # Recommended: use without installing
88
+ # Recommended: use without installing (always latest, isolated)
69
89
  uvx invar-tools guard
90
+ uvx invar-tools init --claude
91
+ uvx invar-tools map --top 10
70
92
 
71
93
  # Or install globally
72
94
  pip install invar-tools
95
+ invar guard
73
96
  ```
74
97
 
75
- ### Runtime Contracts (for your project)
98
+ ### Runtime Contracts (invar-runtime)
99
+
100
+ Add to your project's `requirements.txt` or `pyproject.toml`:
76
101
 
77
102
  ```bash
78
103
  pip install invar-runtime
79
104
  ```
80
105
 
81
- **Packages:**
106
+ ```python
107
+ # In your code
108
+ from invar_runtime import pre, post
82
109
 
83
- | Package | Size | Purpose |
84
- |---------|------|---------|
85
- | `invar-runtime` | ~3MB | Runtime contracts (`@pre`, `@post`, etc.) |
86
- | `invar-tools` | ~100MB | Development tools (`guard`, `map`, `sig`, MCP) |
110
+ @pre(lambda x: x > 0)
111
+ @post(lambda result: result >= 0)
112
+ def calculate(x: float) -> float:
113
+ ...
114
+ ```
87
115
 
88
116
  ---
89
117
 
90
118
  ## Quick Start
91
119
 
92
120
  ```bash
121
+ # 1. Initialize your project (no install required!)
93
122
  cd your-project
94
- invar init # Creates INVAR.md, CLAUDE.md, .invar/
95
- invar guard # Verify code quality
123
+ uvx invar-tools init --claude # Creates INVAR.md, CLAUDE.md, configures MCP
124
+
125
+ # 2. Write code with AI (AI follows INVAR.md protocol)
126
+
127
+ # 3. Verify code quality
128
+ uvx invar-tools guard # Runs static analysis + doctests
96
129
  ```
97
130
 
131
+ > **Why uvx?** No global install needed. Always uses latest version. Isolated environment.
132
+ >
133
+ > Alternative: `pip install invar-tools` then use `invar` instead of `uvx invar-tools`
134
+
98
135
  **Multi-Agent Support:** `invar init` auto-detects and configures:
99
136
 
100
137
  | AI Tool | Configuration |
@@ -266,6 +303,25 @@ Manual setup: See `.invar/mcp-setup.md` after running `invar init`.
266
303
 
267
304
  ---
268
305
 
306
+ ## Platform Support (DX-31)
307
+
308
+ The Independent Adversarial Reviewer (DX-31) has different capabilities depending on your AI coding assistant:
309
+
310
+ | Feature | Claude Code | Other Agents |
311
+ |---------|-------------|--------------|
312
+ | Guard `review_suggested` | ✅ | ✅ |
313
+ | Automatic sub-agent review | ✅ Task tool | ❌ Manual action |
314
+ | Context isolation | ✅ Fresh context | N/A |
315
+ | Adversarial mindset | ✅ Prompt-based | User responsibility |
316
+
317
+ **Claude Code:** Full independent review with context isolation. When Guard outputs `review_suggested`, the agent automatically spawns a sub-agent reviewer that sees only the code (not the implementation history).
318
+
319
+ **Cursor, Windsurf, Copilot, etc.:** Guard outputs `review_suggested` as a warning. Users must manually invoke review or use external code review tools.
320
+
321
+ **Why context isolation matters:** The same agent that wrote code has "author blindness" — it remembers its rationale and unconsciously validates its own decisions. An isolated reviewer sees only the code.
322
+
323
+ ---
324
+
269
325
  ## File Ownership
270
326
 
271
327
  | File | Owner | Edit? |
@@ -318,4 +374,14 @@ DEAL_DISABLE=1 python app.py
318
374
 
319
375
  ## License
320
376
 
321
- MIT
377
+ This project uses a dual-license structure:
378
+
379
+ | Component | License | Purpose |
380
+ |-----------|---------|---------|
381
+ | **invar-runtime** | [Apache-2.0](LICENSE) | Runtime contracts - use freely in your projects |
382
+ | **invar-tools** | [GPL-3.0](LICENSE-GPL) | CLI tools - ensures improvements are shared |
383
+ | **Documentation** | [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/) | Protocol docs - share with attribution |
384
+
385
+ **For users:** You can use `invar-runtime` in any project (including proprietary). The `invar-tools` CLI is for development only and doesn't affect your project's license.
386
+
387
+ See [NOTICE](NOTICE) for third-party licenses.