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.
- invar/core/contracts.py +75 -5
- invar/core/entry_points.py +294 -0
- invar/core/format_specs.py +196 -0
- invar/core/format_strategies.py +197 -0
- invar/core/formatter.py +27 -4
- invar/core/hypothesis_strategies.py +47 -5
- invar/core/lambda_helpers.py +1 -0
- invar/core/models.py +23 -17
- invar/core/parser.py +6 -2
- invar/core/property_gen.py +81 -40
- invar/core/purity.py +10 -4
- invar/core/review_trigger.py +298 -0
- invar/core/rule_meta.py +61 -2
- invar/core/rules.py +83 -19
- invar/core/shell_analysis.py +252 -0
- invar/core/shell_architecture.py +171 -0
- invar/core/suggestions.py +6 -0
- invar/core/tautology.py +1 -0
- invar/core/utils.py +51 -4
- invar/core/verification_routing.py +158 -0
- invar/invariant.py +1 -0
- invar/mcp/server.py +20 -3
- invar/shell/cli.py +59 -31
- invar/shell/config.py +259 -10
- invar/shell/fs.py +5 -2
- invar/shell/git.py +2 -0
- invar/shell/guard_helpers.py +78 -3
- invar/shell/guard_output.py +100 -24
- invar/shell/init_cmd.py +27 -7
- invar/shell/mcp_config.py +3 -0
- invar/shell/mutate_cmd.py +184 -0
- invar/shell/mutation.py +314 -0
- invar/shell/perception.py +2 -0
- invar/shell/property_tests.py +17 -2
- invar/shell/prove.py +35 -3
- invar/shell/prove_accept.py +113 -0
- invar/shell/prove_fallback.py +148 -46
- invar/shell/templates.py +34 -0
- invar/shell/test_cmd.py +3 -1
- invar/shell/testing.py +6 -17
- invar/shell/update_cmd.py +2 -0
- invar/templates/CLAUDE.md.template +65 -9
- invar/templates/INVAR.md +96 -23
- invar/templates/aider.conf.yml.template +16 -14
- invar/templates/commands/review.md +200 -0
- invar/templates/cursorrules.template +22 -13
- invar/templates/examples/contracts.py +3 -1
- invar/templates/examples/core_shell.py +3 -1
- {invar_tools-1.0.0.dist-info → invar_tools-1.2.0.dist-info}/METADATA +81 -15
- invar_tools-1.2.0.dist-info/RECORD +77 -0
- invar_tools-1.2.0.dist-info/licenses/LICENSE +190 -0
- invar_tools-1.2.0.dist-info/licenses/LICENSE-GPL +674 -0
- invar_tools-1.2.0.dist-info/licenses/NOTICE +63 -0
- invar_tools-1.0.0.dist-info/RECORD +0 -64
- invar_tools-1.0.0.dist-info/licenses/LICENSE +0 -21
- {invar_tools-1.0.0.dist-info → invar_tools-1.2.0.dist-info}/WHEEL +0 -0
- {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
|
|
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
|
-
##
|
|
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
|
-
|
|
94
|
+
## USBV Workflow (DX-32)
|
|
76
95
|
|
|
77
|
-
|
|
78
|
-
2. **invar_map** (top=10) — Understand code structure
|
|
96
|
+
**U**nderstand → **S**pecify → **B**uild → **V**alidate
|
|
79
97
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
**
|
|
105
|
+
**Key:** Inspect before Contract. Depth varies naturally. Iterate when needed.
|
|
85
106
|
|
|
86
|
-
|
|
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
|
-
##
|
|
109
|
+
## Visible Workflow (DX-30)
|
|
110
|
+
|
|
111
|
+
For complex tasks (3+ functions), show 3 checkpoints in TodoList:
|
|
90
112
|
|
|
91
113
|
```
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
**
|
|
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
|
-
-
|
|
138
|
+
- Check-In displayed: `✓ Check-In: guard PASS | top: <entry1>, <entry2>`
|
|
106
139
|
- Intent explicitly stated
|
|
107
140
|
- Contract written before implementation
|
|
108
|
-
- Final
|
|
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
|
-
|
|
202
|
+
# DX-22: Doctest lines are always excluded from size calculations by default
|
|
130
203
|
```
|
|
131
204
|
|
|
132
205
|
---
|
|
133
206
|
|
|
134
|
-
*Protocol
|
|
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/
|
|
8
|
-
- .invar/examples/
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
## Check-In
|
|
16
|
+
Your first message MUST display:
|
|
17
|
+
✓ Check-In: guard PASS | top: <entry1>, <entry2>
|
|
18
18
|
|
|
19
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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
|
|
3
|
+
Follow the Invar Protocol in INVAR.md — includes Check-In, USBV workflow, and Task Completion requirements.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Check-In
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Your first message MUST display:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
|
|
11
|
-
invar_map (top=10) # Understand code structure
|
|
10
|
+
✓ Check-In: guard PASS | top: <entry1>, <entry2>
|
|
12
11
|
```
|
|
13
12
|
|
|
14
|
-
|
|
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
|
-
|
|
15
|
+
This is your sign-in. The user sees it immediately.
|
|
16
|
+
No visible check-in = Session not started.
|
|
19
17
|
|
|
20
|
-
|
|
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:
|
|
27
|
-
-
|
|
28
|
-
- Task complete only when final invar_guard passes.
|
|
36
|
+
- Workflow: Understand → Specify → Build → Validate (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
|
-
|
|
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
|
-
|
|
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.
|
|
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:
|
|
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 ::
|
|
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
|
[](https://badge.fury.io/py/invar-tools)
|
|
41
43
|
[](https://www.python.org/downloads/)
|
|
42
|
-
[](#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
|
-
###
|
|
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 (
|
|
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
|
-
|
|
106
|
+
```python
|
|
107
|
+
# In your code
|
|
108
|
+
from invar_runtime import pre, post
|
|
82
109
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|
95
|
-
|
|
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
|
-
|
|
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.
|