invar-tools 1.3.3__py3-none-any.whl → 1.5.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/formatter.py +6 -1
- invar/core/models.py +13 -0
- invar/core/patterns/__init__.py +53 -0
- invar/core/patterns/detector.py +249 -0
- invar/core/patterns/p0_exhaustive.py +207 -0
- invar/core/patterns/p0_literal.py +307 -0
- invar/core/patterns/p0_newtype.py +211 -0
- invar/core/patterns/p0_nonempty.py +307 -0
- invar/core/patterns/p0_validation.py +278 -0
- invar/core/patterns/registry.py +234 -0
- invar/core/patterns/types.py +167 -0
- invar/core/trivial_detection.py +189 -0
- invar/mcp/server.py +4 -0
- invar/shell/commands/guard.py +65 -0
- invar/shell/contract_coverage.py +358 -0
- invar/shell/guard_output.py +5 -0
- invar/shell/pattern_integration.py +234 -0
- invar/shell/templates.py +2 -2
- invar/shell/testing.py +13 -2
- invar/templates/config/CLAUDE.md.jinja +1 -0
- invar/templates/skills/develop/SKILL.md.jinja +49 -0
- invar/templates/skills/review/SKILL.md.jinja +196 -31
- {invar_tools-1.3.3.dist-info → invar_tools-1.5.0.dist-info}/METADATA +24 -15
- {invar_tools-1.3.3.dist-info → invar_tools-1.5.0.dist-info}/RECORD +29 -17
- {invar_tools-1.3.3.dist-info → invar_tools-1.5.0.dist-info}/entry_points.txt +1 -0
- {invar_tools-1.3.3.dist-info → invar_tools-1.5.0.dist-info}/WHEEL +0 -0
- {invar_tools-1.3.3.dist-info → invar_tools-1.5.0.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.3.3.dist-info → invar_tools-1.5.0.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.3.3.dist-info → invar_tools-1.5.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -71,6 +71,55 @@ def calculate(x: int) -> int:
|
|
|
71
71
|
... # Implementation comes in BUILD
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
#### Function-Level Gates (DX-63)
|
|
75
|
+
|
|
76
|
+
When creating new modules, use **incremental development**:
|
|
77
|
+
|
|
78
|
+
1. Create ONE file
|
|
79
|
+
2. Write contracts for all functions (body = `...`)
|
|
80
|
+
{% if syntax == "mcp" -%}
|
|
81
|
+
3. Run `invar_guard(contracts_only=true)` to verify coverage
|
|
82
|
+
{% else -%}
|
|
83
|
+
3. Run `invar guard -c <file>` to verify coverage
|
|
84
|
+
{% endif -%}
|
|
85
|
+
4. Implement functions
|
|
86
|
+
{% if syntax == "mcp" -%}
|
|
87
|
+
5. Run `invar_guard(changed=true)`
|
|
88
|
+
{% else -%}
|
|
89
|
+
5. Run `invar guard --changed`
|
|
90
|
+
{% endif -%}
|
|
91
|
+
6. Proceed to next file
|
|
92
|
+
|
|
93
|
+
❌ Do NOT create multiple file skeletons at once
|
|
94
|
+
❌ Do NOT "structure first, fill later"
|
|
95
|
+
|
|
96
|
+
**TodoList Pattern: Interleaved SPECIFY/BUILD**
|
|
97
|
+
|
|
98
|
+
For each function:
|
|
99
|
+
```
|
|
100
|
+
□ [SPECIFY] Write contract for validate_input
|
|
101
|
+
□ [BUILD] Implement validate_input
|
|
102
|
+
□ [SPECIFY] Write contract for process_data
|
|
103
|
+
□ [BUILD] Implement process_data
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
NOT:
|
|
107
|
+
```
|
|
108
|
+
□ [SPECIFY] Write all contracts
|
|
109
|
+
□ [BUILD] Implement all functions
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Violation Self-Check** — Before writing ANY implementation code:
|
|
113
|
+
1. "Have I written the contract for THIS function?"
|
|
114
|
+
2. "Have I shown it in my response?"
|
|
115
|
+
{% if syntax == "mcp" -%}
|
|
116
|
+
3. "Have I run `invar_guard(contracts_only=true)`?"
|
|
117
|
+
{% else -%}
|
|
118
|
+
3. "Have I run `invar guard -c`?"
|
|
119
|
+
{% endif -%}
|
|
120
|
+
|
|
121
|
+
If any NO → Stop. Write contract first.
|
|
122
|
+
|
|
74
123
|
### 3. BUILD
|
|
75
124
|
|
|
76
125
|
**For complex tasks:** Enter Plan Mode first, get user approval.
|
|
@@ -1,29 +1,91 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review
|
|
3
|
-
description:
|
|
3
|
+
description: Fault-finding code review with REJECTION-FIRST mindset and AUTO-LOOP. Code is GUILTY until proven INNOCENT. Automatically cycles Reviewer→Fixer→Reviewer until quality_met or max_rounds. No human confirmation needed between roles.
|
|
4
4
|
_invar:
|
|
5
5
|
version: "{{ version }}"
|
|
6
6
|
managed: skill
|
|
7
7
|
---
|
|
8
8
|
<!--invar:skill-->
|
|
9
9
|
|
|
10
|
-
# Review Mode
|
|
10
|
+
# Review Mode (Fault-Finding with Auto-Loop)
|
|
11
11
|
|
|
12
12
|
> **Purpose:** Find problems that Guard, doctests, and property tests missed.
|
|
13
|
-
> **Mindset:**
|
|
13
|
+
> **Mindset:** REJECTION-FIRST. Code is GUILTY until proven INNOCENT.
|
|
14
|
+
> **Success Metric:** Issues FOUND, not code approved. Zero issues = you failed to look hard enough.
|
|
15
|
+
> **Workflow:** AUTOMATIC Reviewer↔Fixer loop until quality_met or max_rounds (no human confirmation).
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## Auto-Loop Configuration
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
MAX_ROUNDS = 5 # Maximum review-fix cycles
|
|
21
|
+
AUTO_TRANSITION = true # No human confirmation between roles
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Prime Directive: Reject Until Proven Correct
|
|
25
|
+
|
|
26
|
+
**You are the PROSECUTOR, not the defense attorney.**
|
|
27
|
+
|
|
28
|
+
| Trap | Reality Check |
|
|
29
|
+
|------|---------------|
|
|
30
|
+
| "Seems fine" | You failed to find the bug |
|
|
31
|
+
| "Makes sense" | You're rationalizing, not reviewing |
|
|
32
|
+
| "Edge case is unlikely" | Edge cases ARE bugs |
|
|
33
|
+
| "Comment explains it" | Comments don't fix code |
|
|
34
|
+
| "Assessed as acceptable" | "Assessed" ≠ "Fixed" |
|
|
35
|
+
|
|
36
|
+
## Role Separation (CRITICAL)
|
|
37
|
+
|
|
38
|
+
**You play TWO distinct roles that cycle AUTOMATICALLY:**
|
|
39
|
+
|
|
40
|
+
| Role | Allowed Actions | Forbidden |
|
|
41
|
+
|------|-----------------|-----------|
|
|
42
|
+
| **REVIEWER** | Find issues, judge fixes, declare quality_met | Write code, rationalize issues |
|
|
43
|
+
| **FIXER** | Implement fixes only | Declare quality_met, dismiss issues |
|
|
44
|
+
|
|
45
|
+
**Role Transition Markers (REQUIRED):**
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
49
|
+
🔍 REVIEWER [Round N] — Finding issues
|
|
50
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
51
|
+
|
|
52
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
53
|
+
🔧 FIXER [Round N] — Implementing fixes
|
|
54
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
55
|
+
|
|
56
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
57
|
+
✅ REVIEWER [Round N] — Verifying fixes
|
|
58
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Quality Gate Authority
|
|
62
|
+
|
|
63
|
+
**ONLY the Reviewer role can declare `quality_met`.**
|
|
64
|
+
|
|
65
|
+
Before declaring exit:
|
|
66
|
+
1. Re-read EVERY issue found
|
|
67
|
+
2. For each issue, verify: "Is this ACTUALLY fixed, or did I rationalize it?"
|
|
68
|
+
3. Ask: "Would I accept this excuse from someone else's code?"
|
|
69
|
+
|
|
70
|
+
**Self-Check Questions:**
|
|
71
|
+
- Did I write code AND declare quality_met? → Role confusion detected
|
|
72
|
+
- Did I say "assessed" instead of "fixed"? → Rationalization detected
|
|
73
|
+
- Did any MAJOR become a comment instead of code? → Fix failed
|
|
74
|
+
|
|
75
|
+
## Fault-Finding Persona
|
|
16
76
|
|
|
17
77
|
Assume:
|
|
18
78
|
- The code has bugs until proven otherwise
|
|
19
79
|
- The contracts may be meaningless ceremony
|
|
20
80
|
- The implementer may have rationalized poor decisions
|
|
21
81
|
- Escape hatches may be abused
|
|
82
|
+
- **Your own fixes may introduce new bugs**
|
|
22
83
|
|
|
23
84
|
You ARE here to:
|
|
24
85
|
- Find bugs, logic errors, edge cases
|
|
25
86
|
- Challenge whether contracts have semantic value
|
|
26
87
|
- Check if code matches contracts (not if code "seems right")
|
|
88
|
+
- **RE-VERIFY fixes, not trust them**
|
|
27
89
|
|
|
28
90
|
## Entry Actions
|
|
29
91
|
|
|
@@ -117,46 +179,149 @@ These are checked by Guard or linters - don't duplicate:
|
|
|
117
179
|
- Entry point thickness → Guard (entry_point_too_thick)
|
|
118
180
|
- Escape hatch count → Guard (review_suggested)
|
|
119
181
|
|
|
120
|
-
##
|
|
182
|
+
## Auto-Loop Workflow (NO HUMAN CONFIRMATION)
|
|
183
|
+
|
|
184
|
+
**The loop runs AUTOMATICALLY until exit condition is met.**
|
|
121
185
|
|
|
122
186
|
```
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
187
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
188
|
+
│ START: round = 1, issues = [] │
|
|
189
|
+
│ │
|
|
190
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
191
|
+
│ │ 🔍 REVIEWER [Round N] │ │
|
|
192
|
+
│ │ 1. Find ALL issues (don't stop at first) │ │
|
|
193
|
+
│ │ 2. Classify: CRITICAL / MAJOR / MINOR │ │
|
|
194
|
+
│ │ 3. Add to issues table │ │
|
|
195
|
+
│ │ 4. IF no CRITICAL/MAJOR → quality_met, EXIT │ │
|
|
196
|
+
│ │ 5. ELSE → AUTO-TRANSITION to FIXER │ │
|
|
197
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
198
|
+
│ ↓ (automatic) │
|
|
199
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
200
|
+
│ │ 🔧 FIXER [Round N] │ │
|
|
201
|
+
│ │ 1. Fix EACH CRITICAL/MAJOR issue with CODE │ │
|
|
202
|
+
│ │ 2. Run invar_guard() after fixes │ │
|
|
203
|
+
│ │ 3. NO declaring quality_met (forbidden) │ │
|
|
204
|
+
│ │ 4. AUTO-TRANSITION back to REVIEWER │ │
|
|
205
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
206
|
+
│ ↓ (automatic) │
|
|
207
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
208
|
+
│ │ ✅ REVIEWER [Round N] — Verification │ │
|
|
209
|
+
│ │ 1. Re-verify EACH fix: │ │
|
|
210
|
+
│ │ - Is fix CODE or just COMMENT? │ │
|
|
211
|
+
│ │ - Does fix actually address issue? │ │
|
|
212
|
+
│ │ - Did fix introduce new issues? │ │
|
|
213
|
+
│ │ 2. Update verification table │ │
|
|
214
|
+
│ │ 3. IF all CRITICAL/MAJOR fixed → quality_met, EXIT │ │
|
|
215
|
+
│ │ 4. IF round >= MAX_ROUNDS → max_rounds, EXIT │ │
|
|
216
|
+
│ │ 5. IF no progress → no_improvement, EXIT │ │
|
|
217
|
+
│ │ 6. ELSE → round++, LOOP to REVIEWER [Round N+1] │ │
|
|
218
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
219
|
+
│ │
|
|
220
|
+
│ EXIT: Generate final report │
|
|
221
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
133
222
|
```
|
|
134
223
|
|
|
224
|
+
## Loop State Tracking
|
|
225
|
+
|
|
226
|
+
**Maintain this state throughout the loop:**
|
|
227
|
+
|
|
228
|
+
```markdown
|
|
229
|
+
## Review State
|
|
230
|
+
- **Round:** N / MAX_ROUNDS
|
|
231
|
+
- **Role:** REVIEWER | FIXER
|
|
232
|
+
- **Issues Found:** [count]
|
|
233
|
+
- **Issues Fixed:** [count]
|
|
234
|
+
- **Guard Status:** PASS | FAIL
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Verification Table (Updated Each Round)
|
|
238
|
+
|
|
239
|
+
| Issue ID | Severity | Round Found | Status | Evidence |
|
|
240
|
+
|----------|----------|-------------|--------|----------|
|
|
241
|
+
| MAJOR-1 | MAJOR | 1 | ✅ Fixed (R2) | Code change at line X |
|
|
242
|
+
| MAJOR-2 | MAJOR | 1 | ❌ Unfixed | Fix attempted but failed |
|
|
243
|
+
| MAJOR-3 | MAJOR | 2 | 🔄 New | Found during re-verification |
|
|
244
|
+
| ... | ... | ... | ... | ... |
|
|
245
|
+
|
|
246
|
+
**Status Legend:**
|
|
247
|
+
- ✅ Fixed (RN) — Actually fixed with code in round N
|
|
248
|
+
- ❌ Unfixed — Fix failed or was just a comment
|
|
249
|
+
- 🔄 New — Found during re-verification (new issue)
|
|
250
|
+
- ⏭️ Backlog — MINOR, deferred to later
|
|
251
|
+
|
|
252
|
+
If ANY ❌ exists for CRITICAL/MAJOR after MAX_ROUNDS → quality_not_met
|
|
253
|
+
|
|
135
254
|
## Severity Definitions
|
|
136
255
|
|
|
137
|
-
| Level | Meaning | Examples |
|
|
138
|
-
|
|
139
|
-
| CRITICAL | Security, data loss, crash | SQL injection, unhandled null |
|
|
140
|
-
| MAJOR | Logic error, missing validation | Wrong calculation, no bounds |
|
|
141
|
-
| MINOR | Style, documentation | Naming, missing docstring |
|
|
256
|
+
| Level | Meaning | Examples | Exit Blocker? |
|
|
257
|
+
|-------|---------|----------|---------------|
|
|
258
|
+
| CRITICAL | Security, data loss, crash | SQL injection, unhandled null | **YES** |
|
|
259
|
+
| MAJOR | Logic error, missing validation | Wrong calculation, no bounds | **YES** |
|
|
260
|
+
| MINOR | Style, documentation | Naming, missing docstring | No (backlog) |
|
|
261
|
+
|
|
262
|
+
## Exit Conditions (Auto-Loop)
|
|
142
263
|
|
|
143
|
-
|
|
264
|
+
**Exit triggers (checked automatically after each REVIEWER phase):**
|
|
265
|
+
|
|
266
|
+
| Condition | Exit Reason | Result |
|
|
267
|
+
|-----------|-------------|--------|
|
|
268
|
+
| All CRITICAL/MAJOR fixed | `quality_met` | ✅ Ready for merge |
|
|
269
|
+
| Round >= MAX_ROUNDS | `max_rounds` | ⚠️ Manual review needed |
|
|
270
|
+
| No progress (same issues 2 rounds) | `no_improvement` | ❌ Architectural issue |
|
|
271
|
+
| Guard fails after fix | Continue loop | 🔄 More fixes needed |
|
|
272
|
+
|
|
273
|
+
**quality_met requires ALL of:**
|
|
274
|
+
1. Zero CRITICAL issues remaining
|
|
275
|
+
2. Zero MAJOR issues remaining (not "assessed", actually FIXED)
|
|
276
|
+
3. Verification table completed with evidence for each fix
|
|
277
|
+
4. Guard passes after all fixes
|
|
278
|
+
|
|
279
|
+
**Automatic quality_not_met:**
|
|
280
|
+
- Any MAJOR "fixed" with comment instead of code
|
|
281
|
+
- Any issue marked "assessed" or "acceptable"
|
|
282
|
+
- Fixer role declared quality_met (role violation)
|
|
283
|
+
- Infinite loop detected (no progress)
|
|
284
|
+
|
|
285
|
+
## Exit Report (Generated Automatically)
|
|
144
286
|
|
|
145
287
|
```markdown
|
|
146
|
-
|
|
288
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
289
|
+
📋 REVIEW COMPLETE
|
|
290
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
291
|
+
|
|
292
|
+
**Exit Reason:** quality_met | max_rounds | no_improvement
|
|
293
|
+
**Total Rounds:** N / MAX_ROUNDS
|
|
294
|
+
**Guard Status:** PASS | FAIL
|
|
295
|
+
|
|
296
|
+
## Verification Table
|
|
297
|
+
|
|
298
|
+
| Issue | Severity | Round | Status | Evidence |
|
|
299
|
+
|-------|----------|-------|--------|----------|
|
|
300
|
+
| MAJOR-1 | MAJOR | 1→2 | ✅ Fixed | Code at file.py:123 |
|
|
301
|
+
| ... | ... | ... | ... | ... |
|
|
302
|
+
|
|
303
|
+
## Statistics
|
|
304
|
+
|
|
305
|
+
- Issues Found: X
|
|
306
|
+
- Issues Fixed: Y
|
|
307
|
+
- Fix Rate: Y/X (Z%)
|
|
308
|
+
- New Issues from Fixes: N
|
|
309
|
+
|
|
310
|
+
## Self-Check (Reviewer Final)
|
|
147
311
|
|
|
148
|
-
|
|
149
|
-
|
|
312
|
+
- [x] All fixes are CODE, not comments
|
|
313
|
+
- [x] No "assessed as acceptable" rationalizations
|
|
314
|
+
- [x] Guard passes after all changes
|
|
315
|
+
- [x] Role separation maintained throughout
|
|
150
316
|
|
|
151
|
-
|
|
152
|
-
- [list of fixed issues]
|
|
317
|
+
## Recommendation
|
|
153
318
|
|
|
154
|
-
|
|
155
|
-
- [
|
|
319
|
+
- [x] Ready for merge (quality_met)
|
|
320
|
+
- [ ] Needs manual review (max_rounds)
|
|
321
|
+
- [ ] Architectural refactor needed (no_improvement)
|
|
156
322
|
|
|
157
|
-
**
|
|
158
|
-
- [ ]
|
|
159
|
-
- [ ] Needs more work: [issues]
|
|
323
|
+
**MINOR (Backlog):**
|
|
324
|
+
- [list deferred items]
|
|
160
325
|
```
|
|
161
326
|
<!--/invar:skill-->
|
|
162
327
|
<!--invar:extensions-->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: invar-tools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.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
|
|
@@ -61,6 +61,10 @@ agents write code that's correct by construction—not by accident.
|
|
|
61
61
|
<a href="#license"><img src="https://img.shields.io/badge/License-Apache%202.0%20%2B%20GPL--3.0-blue.svg" alt="License"></a>
|
|
62
62
|
</p>
|
|
63
63
|
|
|
64
|
+
<p align="center">
|
|
65
|
+
<a href="#why-invar"><img src="https://img.shields.io/badge/🤖_Dogfooding-Invar's_code_is_100%25_AI--generated_and_AI--verified_using_itself-8A2BE2?style=for-the-badge" alt="Dogfooding"></a>
|
|
66
|
+
</p>
|
|
67
|
+
|
|
64
68
|
### What It Looks Like
|
|
65
69
|
|
|
66
70
|
An AI agent, guided by Invar, writes code with formal contracts and built-in tests:
|
|
@@ -111,41 +115,46 @@ Guard passed.
|
|
|
111
115
|
┌───────────────────────────────────────────────────────────────────┐
|
|
112
116
|
│ Your Project │
|
|
113
117
|
│ ├── pyproject.toml │
|
|
114
|
-
│ │ └── dependencies = ["invar-runtime"] ← Ships with code
|
|
118
|
+
│ │ └── dependencies = ["invar-runtime"] ← Ships with code │
|
|
115
119
|
│ │ │
|
|
116
120
|
│ └── Development (never enters production) │
|
|
117
|
-
│ └── uvx
|
|
121
|
+
│ └── uvx invar-tools guard ← Guides agents │
|
|
118
122
|
└───────────────────────────────────────────────────────────────────┘
|
|
119
123
|
```
|
|
120
124
|
|
|
121
125
|
| Package | Purpose | Install |
|
|
122
126
|
|---------|---------|---------|
|
|
123
127
|
| **invar-runtime** | Runtime contracts. Add to your project dependencies. | `pip install invar-runtime` |
|
|
124
|
-
| **invar-tools** | Development tools. Guides agents during development. | `uvx
|
|
128
|
+
| **invar-tools** | Development tools. Guides agents during development. | `uvx invar-tools <cmd>` |
|
|
125
129
|
|
|
126
130
|
**Why uvx?** Always uses latest version, doesn't pollute project dependencies, auto-detects your project's venv.
|
|
127
131
|
|
|
128
132
|
### 🆕 New Project
|
|
129
133
|
|
|
130
134
|
```bash
|
|
131
|
-
# 1.
|
|
132
|
-
|
|
135
|
+
# 1. Enter your project directory
|
|
136
|
+
cd your-project
|
|
133
137
|
|
|
134
|
-
# 2.
|
|
138
|
+
# 2. Initialize with Claude Code (full experience)
|
|
139
|
+
uvx invar-tools init --claude
|
|
140
|
+
|
|
141
|
+
# 3. Add runtime contracts to your project
|
|
135
142
|
pip install invar-runtime
|
|
136
143
|
# Or add to pyproject.toml: dependencies = ["invar-runtime"]
|
|
137
144
|
|
|
138
|
-
#
|
|
145
|
+
# 4. Start coding with AI
|
|
139
146
|
```
|
|
140
147
|
|
|
141
148
|
### 📁 Existing Project
|
|
142
149
|
|
|
143
150
|
```bash
|
|
151
|
+
cd your-project
|
|
152
|
+
|
|
144
153
|
# Update managed files, preserve your customizations
|
|
145
|
-
uvx
|
|
154
|
+
uvx invar-tools init --claude
|
|
146
155
|
|
|
147
156
|
# Or without Claude Code integration
|
|
148
|
-
uvx
|
|
157
|
+
uvx invar-tools init
|
|
149
158
|
```
|
|
150
159
|
|
|
151
160
|
Invar's init is idempotent—safe to run multiple times. It detects existing configuration and updates only managed regions.
|
|
@@ -239,10 +248,10 @@ Guard provides fast feedback. Agent sees errors, fixes immediately:
|
|
|
239
248
|
| **Symbolic** | CrossHair | ~30s | Mathematical proof of contracts |
|
|
240
249
|
|
|
241
250
|
```
|
|
242
|
-
┌──────────┐
|
|
251
|
+
┌──────────┐ ┌───────────┐ ┌───────────┐ ┌────────────┐
|
|
243
252
|
│ ⚡ Static │ → │ 🧪 Doctest│ → │ 🎲 Property│ → │ 🔬 Symbolic│
|
|
244
|
-
│ ~0.5s │ │ ~2s
|
|
245
|
-
└──────────┘
|
|
253
|
+
│ ~0.5s │ │ ~2s │ │ ~10s │ │ ~30s │
|
|
254
|
+
└──────────┘ └───────────┘ └───────────┘ └────────────┘
|
|
246
255
|
```
|
|
247
256
|
|
|
248
257
|
```
|
|
@@ -263,8 +272,8 @@ The USBV workflow forces "specify before implement":
|
|
|
263
272
|
|
|
264
273
|
```
|
|
265
274
|
🔍 Understand → 📝 Specify → 🔨 Build → ✓ Validate
|
|
266
|
-
│ │
|
|
267
|
-
Context
|
|
275
|
+
│ │ │ │
|
|
276
|
+
Context Contracts Code Guard
|
|
268
277
|
```
|
|
269
278
|
|
|
270
279
|
Skill routing ensures agents enter through the correct workflow:
|
|
@@ -6,11 +6,11 @@ invar/core/entry_points.py,sha256=gB6h2O9gp9larxDWVA2IUclLadMF_H8eJErnscYm0GU,12
|
|
|
6
6
|
invar/core/extraction.py,sha256=mScqEMEEQdsd-Z0jx9g3scK6Z1vI9l-ESjggXPIWHZ4,6112
|
|
7
7
|
invar/core/format_specs.py,sha256=P299aRHFMXyow8STwsvaT6Bg2ALPs2wSy7SByiRZZ-A,5610
|
|
8
8
|
invar/core/format_strategies.py,sha256=LifL97JbsF8WEkVNmQpq2htyFUC3pW21myAjtRGpSxU,5774
|
|
9
|
-
invar/core/formatter.py,sha256=
|
|
9
|
+
invar/core/formatter.py,sha256=YS7Ni5duz04S1DamsaAksqTBBqXzxUTvf6O6LsxjROE,10772
|
|
10
10
|
invar/core/hypothesis_strategies.py,sha256=_MfjG7KxkmJvuPsczr_1JayR_YmiDzU2jJ8fQPoKGgs,16517
|
|
11
11
|
invar/core/inspect.py,sha256=l1knohwpLRHSNySPUjyeBHJusnU0vYiQGj4dMVgQZIo,4381
|
|
12
12
|
invar/core/lambda_helpers.py,sha256=Ap1y7N0wpgCgPHwrs2pd7zD9Qq4Ptfd2iTliprXIkME,6457
|
|
13
|
-
invar/core/models.py,sha256=
|
|
13
|
+
invar/core/models.py,sha256=5R1w15O8klEMMC0g1zgds6nGFpE6uJFSRkIbXFLNOpo,10795
|
|
14
14
|
invar/core/must_use.py,sha256=7HnnbT53lb4dOT-1mL64pz0JbQYytuw4eejNVe7iWKY,5496
|
|
15
15
|
invar/core/parser.py,sha256=ucVpGziVzUvbkXT1n_SgOrYdStDEcNBqLuRGqK3_M5g,9205
|
|
16
16
|
invar/core/postcondition_scope.py,sha256=ykjVNqZZ1zItBmI7ebgmLW5vFGE-vpaLRTvSgWaJMgM,5245
|
|
@@ -29,28 +29,40 @@ invar/core/sync_helpers.py,sha256=kd6VyFAcpKfkVcbDk3GaBi2n0EWOGICz4VmdxwbshfI,75
|
|
|
29
29
|
invar/core/tautology.py,sha256=Pmn__a0Bt55W0lAQo1G5q8Ory9KuE23dRknKw45xxbs,9221
|
|
30
30
|
invar/core/template_parser.py,sha256=vH3H8OX55scZ1hWh3xoA8oJMhgleKufCOhkTvsSuu_4,14730
|
|
31
31
|
invar/core/timeout_inference.py,sha256=BS2fJGmwOrLpYZUku4qrizgNDSIXVLFBslW-6sRAvpc,3451
|
|
32
|
+
invar/core/trivial_detection.py,sha256=KYP8jJb7QDeusAxFdX5NAML_H0NL5wLgMeBWDQmNqfU,6086
|
|
32
33
|
invar/core/utils.py,sha256=4ani-6XcWF__sD0c_tKcCA2FunaF2pYIfvR5BACWkDg,14168
|
|
33
34
|
invar/core/verification_routing.py,sha256=_jXi1txFCcUdnB3-Yavtuyk8N-XhEO_Vu_051Vuz27Y,5020
|
|
35
|
+
invar/core/patterns/__init__.py,sha256=79a3ucN0BI54RnIOe49lngKASpADygs1hll9ROCrP6s,1429
|
|
36
|
+
invar/core/patterns/detector.py,sha256=lZ2HPtDJDiGps8Y3e7jds3naZa1oGqDDscHRSX5Vv0s,8297
|
|
37
|
+
invar/core/patterns/p0_exhaustive.py,sha256=yK51l4VkriOUA6i6ujeNY3SDlogArVSW2SqtnAaMl0Y,6905
|
|
38
|
+
invar/core/patterns/p0_literal.py,sha256=eazGzNvTpDSeuZJZg9H4_1vukXREKO9GgzCQUSqAKVc,10705
|
|
39
|
+
invar/core/patterns/p0_newtype.py,sha256=T9T6vxgtRXrt2Ym_KNWuHeLNOUKFoMfqu7oE1IUAhCo,7562
|
|
40
|
+
invar/core/patterns/p0_nonempty.py,sha256=H5SXU0XNaW4H_gTw0NFN4cXckbPyTqAUl1KgGvVX9uM,10681
|
|
41
|
+
invar/core/patterns/p0_validation.py,sha256=AuPI7j2MRqBulXPCnAGVbPO2p1DVPjrM1avrIrgyCwQ,9563
|
|
42
|
+
invar/core/patterns/registry.py,sha256=XuwRBPnV5-5uMFsn66pjZV-qDkIVZezt3YH540Gi8Qs,7422
|
|
43
|
+
invar/core/patterns/types.py,sha256=d5wqYJUVF3PHYL5lv6DZnB3PWcZ_MWn7q3-PxrToAEc,5385
|
|
34
44
|
invar/mcp/__init__.py,sha256=n3S7QwMjSMqOMT8cI2jf9E0yZPjKmBOJyIYhq4WZ8TQ,226
|
|
35
45
|
invar/mcp/__main__.py,sha256=ZcIT2U6xUyGOWucl4jq422BDE3lRLjqyxb9pFylRBdk,219
|
|
36
|
-
invar/mcp/server.py,sha256=
|
|
46
|
+
invar/mcp/server.py,sha256=ay-w2YfSa1kTmBFx3x3jEgmNRC3NFEW0EYuZRt7M39w,12244
|
|
37
47
|
invar/shell/__init__.py,sha256=FFw1mNbh_97PeKPcHIqQpQ7mw-JoIvyLM1yOdxLw5uk,204
|
|
38
48
|
invar/shell/claude_hooks.py,sha256=kxkdF2gwTWcGpglccDi6-8IN1zRwelDG6Lg1VPYQgyA,12912
|
|
39
49
|
invar/shell/config.py,sha256=cixlq47h8HYa9Ku-JOo66KCUyrf59R0NX_Yb7A1fAv4,16134
|
|
50
|
+
invar/shell/contract_coverage.py,sha256=2RiXC9RBV__cKLHu0KKOWRxEgYVQNNAPAdwBjYenNHQ,11780
|
|
40
51
|
invar/shell/coverage.py,sha256=m01o898IFIdBztEBQLwwL1Vt5PWrpUntO4lv4nWEkls,11344
|
|
41
52
|
invar/shell/fs.py,sha256=wVD7DPWsCIJXuTyY_pi-5_LS82mXRdn_grJCOLn9zpU,3699
|
|
42
53
|
invar/shell/git.py,sha256=s6RQxEDQuLrmK3mru88EoYP8__4hiFW8AozlcxmY47E,2784
|
|
43
54
|
invar/shell/guard_helpers.py,sha256=QeYgbW0lgUa9Z_RCjAMG7UJdiMzz5cW48Lb2u-qgQi8,15114
|
|
44
|
-
invar/shell/guard_output.py,sha256=
|
|
55
|
+
invar/shell/guard_output.py,sha256=WrbIjy9wZ3TVAP79PMYTPwthT-_9DwmnfS3lpfeaq2M,12101
|
|
45
56
|
invar/shell/mcp_config.py,sha256=-hC7Y5BGuVs285b6gBARk7ZyzVxHwPgXSyt_GoN0jfs,4580
|
|
46
57
|
invar/shell/mutation.py,sha256=Lfyk2b8j8-hxAq-iwAgQeOhr7Ci6c5tRF1TXe3CxQCs,8914
|
|
58
|
+
invar/shell/pattern_integration.py,sha256=pRcjfq3NvMW_tvQCnaXZnD1k5AVEWK8CYOE2jN6VTro,7842
|
|
47
59
|
invar/shell/property_tests.py,sha256=N9JreyH5PqR89oF5yLcX7ZAV-Koyg5BKo-J05-GUPsA,9109
|
|
48
60
|
invar/shell/subprocess_env.py,sha256=9oXl3eMEbzLsFEgMHqobEw6oW_wV0qMEP7pklwm58Pw,11453
|
|
49
61
|
invar/shell/template_engine.py,sha256=IzOiGsKVFo0lDUdtg27wMzIJJKToclv151RDZuDnHHo,11027
|
|
50
|
-
invar/shell/templates.py,sha256=
|
|
51
|
-
invar/shell/testing.py,sha256=
|
|
62
|
+
invar/shell/templates.py,sha256=l2En95E8jRVlojdQIqdZgRLVB43f_b1d_AJapKkozwA,15908
|
|
63
|
+
invar/shell/testing.py,sha256=rTNBH0Okh2qtG9ohSXOz487baQ2gXrWT3s_WECW3HJs,11143
|
|
52
64
|
invar/shell/commands/__init__.py,sha256=MEkKwVyjI9DmkvBpJcuumXo2Pg_FFkfEr-Rr3nrAt7A,284
|
|
53
|
-
invar/shell/commands/guard.py,sha256=
|
|
65
|
+
invar/shell/commands/guard.py,sha256=eKDfOcksRM4Zg0eybi5u93cXJ42OBR3ts0um5tCB5lA,20590
|
|
54
66
|
invar/shell/commands/hooks.py,sha256=W-SOnT4VQyUvXwipozkJwgEYfiOJGz7wksrbcdWegUg,2356
|
|
55
67
|
invar/shell/commands/init.py,sha256=UzHLfAP9ddIY32HrLd32nUveFcHnB0HlbMcIgtfob9Y,18297
|
|
56
68
|
invar/shell/commands/merge.py,sha256=nuvKo8m32-OL-SCQlS4SLKmOZxQ3qj-1nGCx1Pgzifw,8183
|
|
@@ -75,7 +87,7 @@ invar/templates/pre-commit-config.yaml.template,sha256=2qWY3E8iDUqi85jE_X7y0atE8
|
|
|
75
87
|
invar/templates/proposal.md.template,sha256=UP7SpQ7gk8jVlHGLQCSQ5c-kCj1DBQEz8M-vEStK77I,1573
|
|
76
88
|
invar/templates/commands/audit.md,sha256=eXBySlQrVyk054vYQWAZYzj-HgT2QXhpzziw6GlIeGM,4112
|
|
77
89
|
invar/templates/commands/guard.md,sha256=PyeAKfrmlXsgbrTDypQqXmTDKK1JHKhHEQrHqftA7X0,1177
|
|
78
|
-
invar/templates/config/CLAUDE.md.jinja,sha256=
|
|
90
|
+
invar/templates/config/CLAUDE.md.jinja,sha256=788jlWOcSOS7xOEpTFr9H7OKYvEMmyJnDQ-oE4AG8r0,6855
|
|
79
91
|
invar/templates/config/context.md.jinja,sha256=eyjNwvtSyDCImOw6up4eqfE_ylYWv2HCHMQ1M1qJtGQ,2563
|
|
80
92
|
invar/templates/config/pre-commit.yaml.jinja,sha256=Qflmii8hngHciSgfa8mIlg3-E3D4b0xflm0-Q-cWcCc,1752
|
|
81
93
|
invar/templates/examples/README.md,sha256=xMcJZ1KEcfLJi5Ope_4FIbqDWKK3mRleAgllvgeNT6I,572
|
|
@@ -89,14 +101,14 @@ invar/templates/hooks/Stop.sh.jinja,sha256=3S6lLeAGIu5aPQVRz4jjFS9AfjCD9DdS_jagm
|
|
|
89
101
|
invar/templates/hooks/UserPromptSubmit.sh.jinja,sha256=eAQqQ-XdOCyhLpF5_1r1z7C-Ej9GQ5Isqbu_2LAtsno,2302
|
|
90
102
|
invar/templates/hooks/__init__.py,sha256=RnnMoQA-8eqbr8Y_1Vu9B8h5vAz4C-vmo8wgdcGYrz0,43
|
|
91
103
|
invar/templates/protocol/INVAR.md,sha256=Yjwvs0PK9sDUtNExXtS2g7nRV2LcUV22Xa0fY_K-_-0,9940
|
|
92
|
-
invar/templates/skills/develop/SKILL.md.jinja,sha256=
|
|
104
|
+
invar/templates/skills/develop/SKILL.md.jinja,sha256=09zKj8eTDi47boDzooEE5cBwnV3TiXy8k7Zfs9enrx4,10482
|
|
93
105
|
invar/templates/skills/investigate/SKILL.md.jinja,sha256=bOLdLMH5WUVBYOo4NpsfyvI6xx7I1lCNr_X-8bMe_kg,2744
|
|
94
106
|
invar/templates/skills/propose/SKILL.md.jinja,sha256=_iDLYN6-cfzA8n0_8sv-Dnpm1xq9IIpcDyM10mU2WUA,2420
|
|
95
|
-
invar/templates/skills/review/SKILL.md.jinja,sha256=
|
|
96
|
-
invar_tools-1.
|
|
97
|
-
invar_tools-1.
|
|
98
|
-
invar_tools-1.
|
|
99
|
-
invar_tools-1.
|
|
100
|
-
invar_tools-1.
|
|
101
|
-
invar_tools-1.
|
|
102
|
-
invar_tools-1.
|
|
107
|
+
invar/templates/skills/review/SKILL.md.jinja,sha256=e7HULz1jjLOlk2LYejQMk2F-cu7dDIwvh6lWNjx3j-Q,14123
|
|
108
|
+
invar_tools-1.5.0.dist-info/METADATA,sha256=0hzwMUBWAjfGOQc9SbF-9YxZwoaNf4R6TLUbjlIU7po,16964
|
|
109
|
+
invar_tools-1.5.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
110
|
+
invar_tools-1.5.0.dist-info/entry_points.txt,sha256=RwH_EhqgtFPsnO6RcrwrAb70Zyfb8Mh6uUtztWnUxGk,102
|
|
111
|
+
invar_tools-1.5.0.dist-info/licenses/LICENSE,sha256=qeFksp4H4kfTgQxPCIu3OdagXyiZcgBlVfsQ6M5oFyk,10767
|
|
112
|
+
invar_tools-1.5.0.dist-info/licenses/LICENSE-GPL,sha256=IvZfC6ZbP7CLjytoHVzvpDZpD-Z3R_qa1GdMdWlWQ6Q,35157
|
|
113
|
+
invar_tools-1.5.0.dist-info/licenses/NOTICE,sha256=joEyMyFhFY8Vd8tTJ-a3SirI0m2Sd0WjzqYt3sdcglc,2561
|
|
114
|
+
invar_tools-1.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|