invar-tools 1.3.1__py3-none-any.whl → 1.3.2__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/shell/templates.py +2 -2
- invar_tools-1.3.2.dist-info/METADATA +505 -0
- {invar_tools-1.3.1.dist-info → invar_tools-1.3.2.dist-info}/RECORD +8 -8
- invar_tools-1.3.1.dist-info/METADATA +0 -377
- {invar_tools-1.3.1.dist-info → invar_tools-1.3.2.dist-info}/WHEEL +0 -0
- {invar_tools-1.3.1.dist-info → invar_tools-1.3.2.dist-info}/entry_points.txt +0 -0
- {invar_tools-1.3.1.dist-info → invar_tools-1.3.2.dist-info}/licenses/LICENSE +0 -0
- {invar_tools-1.3.1.dist-info → invar_tools-1.3.2.dist-info}/licenses/LICENSE-GPL +0 -0
- {invar_tools-1.3.1.dist-info → invar_tools-1.3.2.dist-info}/licenses/NOTICE +0 -0
invar/shell/templates.py
CHANGED
|
@@ -434,7 +434,7 @@ Find your Python path: `python -c "import sys; print(sys.executable)"`
|
|
|
434
434
|
|
|
435
435
|
```bash
|
|
436
436
|
# Recommended: use uvx (no installation needed)
|
|
437
|
-
uvx invar-tools guard
|
|
437
|
+
uvx --from invar-tools invar guard
|
|
438
438
|
|
|
439
439
|
# Or install globally
|
|
440
440
|
pip install invar-tools
|
|
@@ -449,7 +449,7 @@ Run the MCP server directly:
|
|
|
449
449
|
|
|
450
450
|
```bash
|
|
451
451
|
# Using uvx
|
|
452
|
-
uvx invar-tools mcp
|
|
452
|
+
uvx --from invar-tools invar mcp
|
|
453
453
|
|
|
454
454
|
# Or if installed
|
|
455
455
|
invar mcp
|
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: invar-tools
|
|
3
|
+
Version: 1.3.2
|
|
4
|
+
Summary: AI-native software engineering tools with design-by-contract verification
|
|
5
|
+
Project-URL: Homepage, https://github.com/tefx/invar
|
|
6
|
+
Project-URL: Documentation, https://github.com/tefx/invar#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/tefx/invar
|
|
8
|
+
Project-URL: Issues, https://github.com/tefx/invar/issues
|
|
9
|
+
Author: Invar Team
|
|
10
|
+
License-Expression: GPL-3.0-or-later
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
License-File: LICENSE-GPL
|
|
13
|
+
License-File: NOTICE
|
|
14
|
+
Keywords: ai,code-quality,contracts,design-by-contract,static-analysis
|
|
15
|
+
Classifier: Development Status :: 3 - Alpha
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: crosshair-tool>=0.0.60
|
|
25
|
+
Requires-Dist: hypothesis>=6.0
|
|
26
|
+
Requires-Dist: invar-runtime>=1.0
|
|
27
|
+
Requires-Dist: jinja2>=3.0
|
|
28
|
+
Requires-Dist: mcp>=1.0
|
|
29
|
+
Requires-Dist: pre-commit>=3.0
|
|
30
|
+
Requires-Dist: pydantic>=2.0
|
|
31
|
+
Requires-Dist: returns>=0.20
|
|
32
|
+
Requires-Dist: rich>=13.0
|
|
33
|
+
Requires-Dist: typer>=0.9
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: coverage[toml]>=7.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: ruff>=0.1; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
<p align="center">
|
|
43
|
+
<img src="docs/logo.svg" alt="Invar Logo" width="128" height="128">
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
<h1 align="center">Invar</h1>
|
|
47
|
+
|
|
48
|
+
<p align="center">
|
|
49
|
+
<strong>From AI-generated to AI-engineered code.</strong>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
Invar brings decades of software engineering best practices to AI-assisted development.<br>
|
|
54
|
+
Through automated verification, structured workflows, and proven design patterns,<br>
|
|
55
|
+
agents write code that's correct by construction—not by accident.
|
|
56
|
+
</p>
|
|
57
|
+
|
|
58
|
+
<p align="center">
|
|
59
|
+
<a href="https://badge.fury.io/py/invar-tools"><img src="https://badge.fury.io/py/invar-tools.svg" alt="PyPI version"></a>
|
|
60
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11+-blue.svg" alt="Python 3.11+"></a>
|
|
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
|
+
</p>
|
|
63
|
+
|
|
64
|
+
### What It Looks Like
|
|
65
|
+
|
|
66
|
+
An AI agent, guided by Invar, writes code with formal contracts and built-in tests:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from invar_runtime import pre, post
|
|
70
|
+
|
|
71
|
+
@pre(lambda items: len(items) > 0)
|
|
72
|
+
@post(lambda result: result >= 0)
|
|
73
|
+
def average(items: list[float]) -> float:
|
|
74
|
+
"""
|
|
75
|
+
Calculate the average of a non-empty list.
|
|
76
|
+
|
|
77
|
+
>>> average([1.0, 2.0, 3.0])
|
|
78
|
+
2.0
|
|
79
|
+
>>> average([10.0])
|
|
80
|
+
10.0
|
|
81
|
+
"""
|
|
82
|
+
return sum(items) / len(items)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Invar's Guard automatically verifies the code—the agent sees results and fixes issues without human intervention:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
$ invar guard
|
|
89
|
+
Invar Guard Report
|
|
90
|
+
========================================
|
|
91
|
+
No violations found.
|
|
92
|
+
----------------------------------------
|
|
93
|
+
Files checked: 1 | Errors: 0 | Warnings: 0
|
|
94
|
+
Contract coverage: 100% (1/1 functions)
|
|
95
|
+
|
|
96
|
+
Code Health: 100% ████████████████████ (Excellent)
|
|
97
|
+
✓ Doctests passed
|
|
98
|
+
✓ CrossHair: no counterexamples found
|
|
99
|
+
✓ Hypothesis: property tests passed
|
|
100
|
+
----------------------------------------
|
|
101
|
+
Guard passed.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🚀 Quick Start
|
|
107
|
+
|
|
108
|
+
### 📦 Two Packages, Different Purposes
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
┌───────────────────────────────────────────────────────────────────┐
|
|
112
|
+
│ Your Project │
|
|
113
|
+
│ ├── pyproject.toml │
|
|
114
|
+
│ │ └── dependencies = ["invar-runtime"] ← Ships with code │
|
|
115
|
+
│ │ │
|
|
116
|
+
│ └── Development (never enters production) │
|
|
117
|
+
│ └── uvx --from invar-tools invar guard ← Guides agents │
|
|
118
|
+
└───────────────────────────────────────────────────────────────────┘
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
| Package | Purpose | Install |
|
|
122
|
+
|---------|---------|---------|
|
|
123
|
+
| **invar-runtime** | Runtime contracts. Add to your project dependencies. | `pip install invar-runtime` |
|
|
124
|
+
| **invar-tools** | Development tools. Guides agents during development. | `uvx --from invar-tools invar <cmd>` |
|
|
125
|
+
|
|
126
|
+
**Why uvx?** Always uses latest version, doesn't pollute project dependencies, auto-detects your project's venv.
|
|
127
|
+
|
|
128
|
+
### 🆕 New Project
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# 1. Initialize with Claude Code (full experience)
|
|
132
|
+
uvx --from invar-tools invar init --claude
|
|
133
|
+
|
|
134
|
+
# 2. Add runtime contracts to your project
|
|
135
|
+
pip install invar-runtime
|
|
136
|
+
# Or add to pyproject.toml: dependencies = ["invar-runtime"]
|
|
137
|
+
|
|
138
|
+
# 3. Start coding with AI
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 📁 Existing Project
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Update managed files, preserve your customizations
|
|
145
|
+
uvx --from invar-tools invar init --claude
|
|
146
|
+
|
|
147
|
+
# Or without Claude Code integration
|
|
148
|
+
uvx --from invar-tools invar init
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Invar's init is idempotent—safe to run multiple times. It detects existing configuration and updates only managed regions.
|
|
152
|
+
|
|
153
|
+
### 💬 Example Interaction
|
|
154
|
+
|
|
155
|
+
**You say:**
|
|
156
|
+
> "Add a function that calculates compound interest with validation"
|
|
157
|
+
|
|
158
|
+
**Agent responds (automatically guided by Invar):**
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
✓ Check-In: my-project | main | clean
|
|
162
|
+
|
|
163
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
164
|
+
📍 /develop → SPECIFY (2/4)
|
|
165
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
166
|
+
|
|
167
|
+
First, I'll define the contract:
|
|
168
|
+
|
|
169
|
+
@pre(lambda principal, rate, years: principal > 0 and rate >= 0 and years > 0)
|
|
170
|
+
@post(lambda result: result >= principal)
|
|
171
|
+
def compound_interest(principal: float, rate: float, years: int) -> float:
|
|
172
|
+
...
|
|
173
|
+
|
|
174
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
175
|
+
📍 /develop → VALIDATE (4/4)
|
|
176
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
177
|
+
|
|
178
|
+
$ invar guard --changed
|
|
179
|
+
WARN: missing doctest example (compound_interest)
|
|
180
|
+
|
|
181
|
+
[Agent adds doctest, re-runs guard]
|
|
182
|
+
|
|
183
|
+
$ invar guard --changed
|
|
184
|
+
Guard passed. (1 file, 0 errors)
|
|
185
|
+
|
|
186
|
+
✓ Final: guard PASS | 0 errors, 0 warnings
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Key insight:** The agent verifies and fixes automatically. You review the result, not the process.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Why Invar?
|
|
194
|
+
|
|
195
|
+
### ⚠️ The Problem: Unconstrained AI = Unpredictable Quality
|
|
196
|
+
|
|
197
|
+
Without guardrails, AI-generated code has systematic risks:
|
|
198
|
+
- **No specification** → Agent guesses intent, misses edge cases
|
|
199
|
+
- **No feedback loop** → Errors accumulate undetected
|
|
200
|
+
- **No workflow** → Jumps to implementation, skips validation
|
|
201
|
+
- **No separation** → I/O mixed with logic, code becomes untestable
|
|
202
|
+
|
|
203
|
+
Invar addresses each from the ground up.
|
|
204
|
+
|
|
205
|
+
### ✅ Solution 1: Contracts as Specification
|
|
206
|
+
|
|
207
|
+
Contracts (`@pre`/`@post`) turn vague intent into verifiable specifications:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
# Without contracts: "calculate average" is ambiguous
|
|
211
|
+
def average(items):
|
|
212
|
+
return sum(items) / len(items) # What if empty? What's the return type?
|
|
213
|
+
|
|
214
|
+
# With contracts: specification is explicit and verifiable
|
|
215
|
+
@pre(lambda items: len(items) > 0) # Precondition: non-empty input
|
|
216
|
+
@post(lambda result: result >= 0) # Postcondition: non-negative output
|
|
217
|
+
def average(items: list[float]) -> float:
|
|
218
|
+
"""
|
|
219
|
+
>>> average([1.0, 2.0, 3.0])
|
|
220
|
+
2.0
|
|
221
|
+
"""
|
|
222
|
+
return sum(items) / len(items)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Benefits:**
|
|
226
|
+
- Agent knows exactly what to implement
|
|
227
|
+
- Edge cases are explicit in the contract
|
|
228
|
+
- Verification is automatic, not manual review
|
|
229
|
+
|
|
230
|
+
### ✅ Solution 2: Multi-Layer Verification
|
|
231
|
+
|
|
232
|
+
Guard provides fast feedback. Agent sees errors, fixes immediately:
|
|
233
|
+
|
|
234
|
+
| Layer | Tool | Speed | What It Catches |
|
|
235
|
+
|-------|------|-------|-----------------|
|
|
236
|
+
| **Static** | Guard rules | ~0.5s | Architecture violations, missing contracts |
|
|
237
|
+
| **Doctest** | pytest | ~2s | Example correctness |
|
|
238
|
+
| **Property** | Hypothesis | ~10s | Edge cases via random inputs |
|
|
239
|
+
| **Symbolic** | CrossHair | ~30s | Mathematical proof of contracts |
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
243
|
+
│ ⚡ Static │ → │ 🧪 Doctest│ → │ 🎲 Property│ → │ 🔬 Symbolic│
|
|
244
|
+
│ ~0.5s │ │ ~2s │ │ ~10s │ │ ~30s │
|
|
245
|
+
└──────────┘ └──────────┘ └──────────┘ └──────────┘
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
Agent writes code
|
|
250
|
+
↓
|
|
251
|
+
invar guard ←──────┐
|
|
252
|
+
↓ │
|
|
253
|
+
Error found? │
|
|
254
|
+
↓ Yes │
|
|
255
|
+
Agent fixes ────────┘
|
|
256
|
+
↓ No
|
|
257
|
+
Done ✓
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### ✅ Solution 3: Workflow Discipline
|
|
261
|
+
|
|
262
|
+
The USBV workflow forces "specify before implement":
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
🔍 Understand → 📝 Specify → 🔨 Build → ✓ Validate
|
|
266
|
+
│ │ │ │
|
|
267
|
+
Context Contracts Code Guard
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Skill routing ensures agents enter through the correct workflow:
|
|
271
|
+
|
|
272
|
+
| User Intent | Skill Invoked | Behavior |
|
|
273
|
+
|-------------|---------------|----------|
|
|
274
|
+
| "why does X fail?" | `/investigate` | Research only, no code changes |
|
|
275
|
+
| "should we use A or B?" | `/propose` | Present options with trade-offs |
|
|
276
|
+
| "add feature X" | `/develop` | Full USBV workflow |
|
|
277
|
+
| (after develop) | `/review` | Adversarial review with fix loop |
|
|
278
|
+
|
|
279
|
+
### ✅ Solution 4: Architecture Constraints
|
|
280
|
+
|
|
281
|
+
| Pattern | Enforcement | Benefit |
|
|
282
|
+
|---------|-------------|---------|
|
|
283
|
+
| **Core/Shell** | Guard blocks I/O imports in Core | 100% testable business logic |
|
|
284
|
+
| **Result[T, E]** | Guard warns if Shell returns bare values | Explicit error handling |
|
|
285
|
+
|
|
286
|
+
### 🔮 Future: Quality Guidance (DX-61)
|
|
287
|
+
|
|
288
|
+
Beyond "correct or not"—Invar will suggest improvements:
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
SUGGEST: 3 string parameters in 'find_symbol'
|
|
292
|
+
→ Consider NewType for semantic clarity
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
From gatekeeper to mentor.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## 🏗️ Core Concepts
|
|
300
|
+
|
|
301
|
+
### Core/Shell Architecture
|
|
302
|
+
|
|
303
|
+
Separate pure logic from I/O for maximum testability:
|
|
304
|
+
|
|
305
|
+
| Zone | Location | Requirements |
|
|
306
|
+
|------|----------|--------------|
|
|
307
|
+
| **Core** | `**/core/**` | `@pre`/`@post` contracts, doctests, no I/O imports |
|
|
308
|
+
| **Shell** | `**/shell/**` | `Result[T, E]` return types |
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
┌─────────────────────────────────────────────┐
|
|
312
|
+
│ 🐚 Shell (I/O Layer) │
|
|
313
|
+
│ load_config, save_result, fetch_data │
|
|
314
|
+
└──────────────────┬──────────────────────────┘
|
|
315
|
+
│
|
|
316
|
+
▼
|
|
317
|
+
┌─────────────────────────────────────────────┐
|
|
318
|
+
│ 💎 Core (Pure Logic) │
|
|
319
|
+
│ parse_config, validate, calculate │
|
|
320
|
+
└──────────────────┬──────────────────────────┘
|
|
321
|
+
│
|
|
322
|
+
▼ Result[T, E]
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
# Core: Pure, testable, provable
|
|
327
|
+
def parse_config(content: str) -> Config:
|
|
328
|
+
return Config.parse(content)
|
|
329
|
+
|
|
330
|
+
# Shell: Handles I/O, returns Result
|
|
331
|
+
def load_config(path: Path) -> Result[Config, str]:
|
|
332
|
+
try:
|
|
333
|
+
return Success(parse_config(path.read_text()))
|
|
334
|
+
except FileNotFoundError:
|
|
335
|
+
return Failure(f"Not found: {path}")
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Session Protocol
|
|
339
|
+
|
|
340
|
+
Clear boundaries for every AI session:
|
|
341
|
+
|
|
342
|
+
| Phase | Format | Purpose |
|
|
343
|
+
|-------|--------|---------|
|
|
344
|
+
| **Start** | `✓ Check-In: project \| branch \| status` | Context visibility |
|
|
345
|
+
| **End** | `✓ Final: guard PASS \| 0 errors` | Verification proof |
|
|
346
|
+
|
|
347
|
+
### Intellectual Heritage
|
|
348
|
+
|
|
349
|
+
**Foundational Theory:**
|
|
350
|
+
Design-by-Contract (Meyer, 1986) ·
|
|
351
|
+
Functional Core/Imperative Shell (Bernhardt) ·
|
|
352
|
+
Property-Based Testing (QuickCheck, 2000) ·
|
|
353
|
+
Symbolic Execution (King, 1976)
|
|
354
|
+
|
|
355
|
+
**Inspired By:**
|
|
356
|
+
Eiffel · Dafny · Idris · Haskell
|
|
357
|
+
|
|
358
|
+
**AI Programming Research:**
|
|
359
|
+
AlphaCodium · Parsel · Reflexion · Clover
|
|
360
|
+
|
|
361
|
+
**Dependencies:**
|
|
362
|
+
[deal](https://github.com/life4/deal) ·
|
|
363
|
+
[returns](https://github.com/dry-python/returns) ·
|
|
364
|
+
[CrossHair](https://github.com/pschanely/CrossHair) ·
|
|
365
|
+
[Hypothesis](https://hypothesis.readthedocs.io/)
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 🖥️ Platform Experience
|
|
370
|
+
|
|
371
|
+
| Feature | Claude Code | Other Editors |
|
|
372
|
+
|---------|-------------|---------------|
|
|
373
|
+
| CLI verification (`invar guard`) | ✅ | ✅ |
|
|
374
|
+
| Protocol document (INVAR.md) | ✅ | ✅ |
|
|
375
|
+
| MCP tool integration | ✅ Auto-configured | Manual setup possible |
|
|
376
|
+
| Workflow skills | ✅ Auto-configured | Include in system prompt |
|
|
377
|
+
| Pre-commit hooks | ✅ | ✅ |
|
|
378
|
+
| Sub-agent review | ✅ | — |
|
|
379
|
+
|
|
380
|
+
**Claude Code** provides the full experience—MCP tools, skill routing, and hooks are auto-configured by `invar init --claude`.
|
|
381
|
+
|
|
382
|
+
**Other editors** can achieve similar results by:
|
|
383
|
+
1. Adding INVAR.md content to system prompts
|
|
384
|
+
2. Manually configuring MCP servers (if supported)
|
|
385
|
+
3. Using CLI commands for verification
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 📂 What Gets Installed
|
|
390
|
+
|
|
391
|
+
`invar init --claude` creates:
|
|
392
|
+
|
|
393
|
+
| File/Directory | Purpose | Editable? |
|
|
394
|
+
|----------------|---------|-----------|
|
|
395
|
+
| `INVAR.md` | Protocol for AI agents | No (managed) |
|
|
396
|
+
| `CLAUDE.md` | Project configuration | Yes |
|
|
397
|
+
| `.claude/skills/` | Workflow skills | Yes |
|
|
398
|
+
| `.claude/hooks/` | Tool call interception | Yes |
|
|
399
|
+
| `.invar/examples/` | Reference patterns | No (managed) |
|
|
400
|
+
| `.invar/context.md` | Project state, lessons | Yes |
|
|
401
|
+
| `pyproject.toml` | `[tool.invar]` section | Yes |
|
|
402
|
+
|
|
403
|
+
**Recommended structure:**
|
|
404
|
+
|
|
405
|
+
```
|
|
406
|
+
src/{project}/
|
|
407
|
+
├── core/ # Pure logic (@pre/@post, doctests, no I/O)
|
|
408
|
+
└── shell/ # I/O operations (Result[T, E] returns)
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## ⚙️ Configuration
|
|
414
|
+
|
|
415
|
+
```toml
|
|
416
|
+
# pyproject.toml
|
|
417
|
+
|
|
418
|
+
[tool.invar.guard]
|
|
419
|
+
# Option 1: Explicit paths
|
|
420
|
+
core_paths = ["src/myapp/core"]
|
|
421
|
+
shell_paths = ["src/myapp/shell"]
|
|
422
|
+
|
|
423
|
+
# Option 2: Pattern matching (for existing projects)
|
|
424
|
+
core_patterns = ["**/domain/**", "**/models/**"]
|
|
425
|
+
shell_patterns = ["**/api/**", "**/cli/**"]
|
|
426
|
+
|
|
427
|
+
# Option 3: Auto-detection (when no paths/patterns specified)
|
|
428
|
+
# - Default paths: src/core, core, src/shell, shell
|
|
429
|
+
# - Content analysis: @pre/@post → Core, Result → Shell
|
|
430
|
+
|
|
431
|
+
# Size limits
|
|
432
|
+
max_file_lines = 500
|
|
433
|
+
max_function_lines = 50
|
|
434
|
+
|
|
435
|
+
# Requirements
|
|
436
|
+
require_contracts = true
|
|
437
|
+
require_doctests = true
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### 🚪 Escape Hatches
|
|
441
|
+
|
|
442
|
+
For code that intentionally breaks rules:
|
|
443
|
+
|
|
444
|
+
```toml
|
|
445
|
+
# Exclude entire directories
|
|
446
|
+
[[tool.invar.guard.rule_exclusions]]
|
|
447
|
+
pattern = "**/generated/**"
|
|
448
|
+
rules = ["*"]
|
|
449
|
+
|
|
450
|
+
# Exclude specific rules for specific files
|
|
451
|
+
[[tool.invar.guard.rule_exclusions]]
|
|
452
|
+
pattern = "**/legacy_api.py"
|
|
453
|
+
rules = ["missing_contract", "shell_result"]
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## 🔧 Tool Reference
|
|
459
|
+
|
|
460
|
+
### CLI Commands
|
|
461
|
+
|
|
462
|
+
| Command | Purpose |
|
|
463
|
+
|---------|---------|
|
|
464
|
+
| `invar guard` | Full verification (static + doctest + property + symbolic) |
|
|
465
|
+
| `invar guard --changed` | Only git-modified files |
|
|
466
|
+
| `invar guard --static` | Static analysis only (~0.5s) |
|
|
467
|
+
| `invar init` | Initialize or update project |
|
|
468
|
+
| `invar sig <file>` | Show signatures and contracts |
|
|
469
|
+
| `invar map` | Symbol map with reference counts |
|
|
470
|
+
| `invar rules` | List all rules |
|
|
471
|
+
| `invar test` | Property-based tests (Hypothesis) |
|
|
472
|
+
| `invar verify` | Symbolic verification (CrossHair) |
|
|
473
|
+
| `invar hooks` | Manage Claude Code hooks |
|
|
474
|
+
|
|
475
|
+
### MCP Tools
|
|
476
|
+
|
|
477
|
+
| Tool | Purpose |
|
|
478
|
+
|------|---------|
|
|
479
|
+
| `invar_guard` | Smart multi-layer verification |
|
|
480
|
+
| `invar_sig` | Extract signatures and contracts |
|
|
481
|
+
| `invar_map` | Symbol map with reference counts |
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## 📚 Learn More
|
|
486
|
+
|
|
487
|
+
**Created by `invar init`:**
|
|
488
|
+
- `INVAR.md` — Protocol v5.0
|
|
489
|
+
- `.invar/examples/` — Reference patterns
|
|
490
|
+
|
|
491
|
+
**Documentation:**
|
|
492
|
+
- [Vision & Philosophy](./docs/vision.md)
|
|
493
|
+
- [Technical Design](./docs/design.md)
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 📄 License
|
|
498
|
+
|
|
499
|
+
| Component | License | Notes |
|
|
500
|
+
|-----------|---------|-------|
|
|
501
|
+
| **invar-runtime** | [Apache-2.0](LICENSE) | Use freely in any project |
|
|
502
|
+
| **invar-tools** | [GPL-3.0](LICENSE-GPL) | Improvements must be shared |
|
|
503
|
+
| **Documentation** | [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/) | Share with attribution |
|
|
504
|
+
|
|
505
|
+
See [NOTICE](NOTICE) for third-party licenses.
|
|
@@ -47,7 +47,7 @@ invar/shell/mutation.py,sha256=Lfyk2b8j8-hxAq-iwAgQeOhr7Ci6c5tRF1TXe3CxQCs,8914
|
|
|
47
47
|
invar/shell/property_tests.py,sha256=N9JreyH5PqR89oF5yLcX7ZAV-Koyg5BKo-J05-GUPsA,9109
|
|
48
48
|
invar/shell/subprocess_env.py,sha256=9oXl3eMEbzLsFEgMHqobEw6oW_wV0qMEP7pklwm58Pw,11453
|
|
49
49
|
invar/shell/template_engine.py,sha256=IzOiGsKVFo0lDUdtg27wMzIJJKToclv151RDZuDnHHo,11027
|
|
50
|
-
invar/shell/templates.py,sha256=
|
|
50
|
+
invar/shell/templates.py,sha256=FGrHtVCUNF6K6KHrJquI9vyET0zyDkVy5ND1mAeY6NE,15934
|
|
51
51
|
invar/shell/testing.py,sha256=PTrrCB0nIARuDQa_XREoRzbnqjXxju1l9Eb83pivH6c,10634
|
|
52
52
|
invar/shell/commands/__init__.py,sha256=MEkKwVyjI9DmkvBpJcuumXo2Pg_FFkfEr-Rr3nrAt7A,284
|
|
53
53
|
invar/shell/commands/guard.py,sha256=aYqOhxclt_oF93TcSGN1zaB4RUsSQjMUYxfBw2QmqoM,18038
|
|
@@ -93,10 +93,10 @@ invar/templates/skills/develop/SKILL.md.jinja,sha256=AYlvhOnHW-EbuLnt8KwVweoKuV1
|
|
|
93
93
|
invar/templates/skills/investigate/SKILL.md.jinja,sha256=bOLdLMH5WUVBYOo4NpsfyvI6xx7I1lCNr_X-8bMe_kg,2744
|
|
94
94
|
invar/templates/skills/propose/SKILL.md.jinja,sha256=_iDLYN6-cfzA8n0_8sv-Dnpm1xq9IIpcDyM10mU2WUA,2420
|
|
95
95
|
invar/templates/skills/review/SKILL.md.jinja,sha256=UDzhdjjzXKeR4olM6S2xHkw_Z-uznaBb9467O2_EOhY,5367
|
|
96
|
-
invar_tools-1.3.
|
|
97
|
-
invar_tools-1.3.
|
|
98
|
-
invar_tools-1.3.
|
|
99
|
-
invar_tools-1.3.
|
|
100
|
-
invar_tools-1.3.
|
|
101
|
-
invar_tools-1.3.
|
|
102
|
-
invar_tools-1.3.
|
|
96
|
+
invar_tools-1.3.2.dist-info/METADATA,sha256=mF3BbovusFAmksInxjWG_s257mh0LkUGcGKxBbtY9KA,16695
|
|
97
|
+
invar_tools-1.3.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
98
|
+
invar_tools-1.3.2.dist-info/entry_points.txt,sha256=xjkp8_Kipb6KJR6VNfkAEqiOpvrwUnwUG53cegBA6pQ,57
|
|
99
|
+
invar_tools-1.3.2.dist-info/licenses/LICENSE,sha256=qeFksp4H4kfTgQxPCIu3OdagXyiZcgBlVfsQ6M5oFyk,10767
|
|
100
|
+
invar_tools-1.3.2.dist-info/licenses/LICENSE-GPL,sha256=IvZfC6ZbP7CLjytoHVzvpDZpD-Z3R_qa1GdMdWlWQ6Q,35157
|
|
101
|
+
invar_tools-1.3.2.dist-info/licenses/NOTICE,sha256=joEyMyFhFY8Vd8tTJ-a3SirI0m2Sd0WjzqYt3sdcglc,2561
|
|
102
|
+
invar_tools-1.3.2.dist-info/RECORD,,
|
|
@@ -1,377 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: invar-tools
|
|
3
|
-
Version: 1.3.1
|
|
4
|
-
Summary: AI-native software engineering tools with design-by-contract verification
|
|
5
|
-
Project-URL: Homepage, https://github.com/tefx/invar
|
|
6
|
-
Project-URL: Documentation, https://github.com/tefx/invar#readme
|
|
7
|
-
Project-URL: Repository, https://github.com/tefx/invar
|
|
8
|
-
Project-URL: Issues, https://github.com/tefx/invar/issues
|
|
9
|
-
Author: Invar Team
|
|
10
|
-
License-Expression: GPL-3.0-or-later
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
License-File: LICENSE-GPL
|
|
13
|
-
License-File: NOTICE
|
|
14
|
-
Keywords: ai,code-quality,contracts,design-by-contract,static-analysis
|
|
15
|
-
Classifier: Development Status :: 3 - Alpha
|
|
16
|
-
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
18
|
-
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
|
-
Classifier: Typing :: Typed
|
|
23
|
-
Requires-Python: >=3.11
|
|
24
|
-
Requires-Dist: crosshair-tool>=0.0.60
|
|
25
|
-
Requires-Dist: hypothesis>=6.0
|
|
26
|
-
Requires-Dist: invar-runtime>=1.0
|
|
27
|
-
Requires-Dist: jinja2>=3.0
|
|
28
|
-
Requires-Dist: mcp>=1.0
|
|
29
|
-
Requires-Dist: pre-commit>=3.0
|
|
30
|
-
Requires-Dist: pydantic>=2.0
|
|
31
|
-
Requires-Dist: returns>=0.20
|
|
32
|
-
Requires-Dist: rich>=13.0
|
|
33
|
-
Requires-Dist: typer>=0.9
|
|
34
|
-
Provides-Extra: dev
|
|
35
|
-
Requires-Dist: coverage[toml]>=7.0; extra == 'dev'
|
|
36
|
-
Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
37
|
-
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
38
|
-
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
39
|
-
Requires-Dist: ruff>=0.1; extra == 'dev'
|
|
40
|
-
Description-Content-Type: text/markdown
|
|
41
|
-
|
|
42
|
-
# Invar
|
|
43
|
-
|
|
44
|
-
[](https://badge.fury.io/py/invar-tools)
|
|
45
|
-
[](https://www.python.org/downloads/)
|
|
46
|
-
[](#license)
|
|
47
|
-
|
|
48
|
-
> **Don't hope AI code is correct. Know it.**
|
|
49
|
-
|
|
50
|
-
Invar is a verification framework for AI-assisted development. It provides contracts, verification, and a structured workflow methodology.
|
|
51
|
-
|
|
52
|
-
```python
|
|
53
|
-
from invar_runtime import pre, post
|
|
54
|
-
|
|
55
|
-
@pre(lambda items: len(items) > 0)
|
|
56
|
-
@post(lambda result: result >= 0)
|
|
57
|
-
def average(items: list[float]) -> float:
|
|
58
|
-
"""
|
|
59
|
-
>>> average([1, 2, 3])
|
|
60
|
-
2.0
|
|
61
|
-
"""
|
|
62
|
-
return sum(items) / len(items)
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## Experience Tiers
|
|
68
|
-
|
|
69
|
-
| Platform | Experience | Features |
|
|
70
|
-
|----------|------------|----------|
|
|
71
|
-
| **Claude Code** | Full | USBV workflow + skill automation + MCP integration |
|
|
72
|
-
| **Cursor/Windsurf** | Basic | INVAR.md protocol + CLI verification |
|
|
73
|
-
| **Other editors** | Minimal | CLI verification tools only |
|
|
74
|
-
|
|
75
|
-
**Why tiers?** The skill system (`/develop`, `/review`, etc.) requires Claude Code's sub-agent capabilities. Other editors receive the protocol document and CLI tools.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## Installation
|
|
80
|
-
|
|
81
|
-
### Two Packages, Different Purposes
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
85
|
-
│ Your Project │
|
|
86
|
-
│ ├── src/ │
|
|
87
|
-
│ │ └── from invar_runtime import pre, post ← Runtime │
|
|
88
|
-
│ │ │
|
|
89
|
-
│ └── Development (not shipped with your code) │
|
|
90
|
-
│ └── uvx invar-tools guard ← Tools │
|
|
91
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
| Package | Install | Purpose |
|
|
95
|
-
|---------|---------|---------|
|
|
96
|
-
| **invar-tools** | `uvx invar-tools <cmd>` | Development: verification, init, MCP server |
|
|
97
|
-
| **invar-runtime** | `pip install invar-runtime` | Production: add to your project's dependencies |
|
|
98
|
-
|
|
99
|
-
### Quick Install
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
# Development tools (recommended: use without installing)
|
|
103
|
-
uvx invar-tools guard
|
|
104
|
-
uvx invar-tools init --claude
|
|
105
|
-
|
|
106
|
-
# Runtime contracts (add to your project)
|
|
107
|
-
pip install invar-runtime
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Why uvx is recommended:**
|
|
111
|
-
- Always uses latest version
|
|
112
|
-
- Doesn't pollute project dependencies
|
|
113
|
-
- Automatically accesses your project's venv dependencies (numpy, pandas, etc.)
|
|
114
|
-
- If your project has `invar-tools` installed, uvx will detect and use it
|
|
115
|
-
|
|
116
|
-
**When to use pip install instead:**
|
|
117
|
-
- CI/CD environments where uvx isn't available
|
|
118
|
-
- Projects with C extensions AND Python version mismatch between uvx and project
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Quick Start
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
# 1. Initialize your project
|
|
126
|
-
cd your-project
|
|
127
|
-
uvx invar-tools init --claude # Full experience (Claude Code)
|
|
128
|
-
uvx invar-tools init # Basic experience (other editors)
|
|
129
|
-
|
|
130
|
-
# 2. Write code with AI (AI follows INVAR.md protocol)
|
|
131
|
-
|
|
132
|
-
# 3. Verify code quality
|
|
133
|
-
uvx invar-tools guard # Runs static analysis + doctests + property tests
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## The USBV Workflow
|
|
139
|
-
|
|
140
|
-
AI agents follow a four-phase development cycle:
|
|
141
|
-
|
|
142
|
-
```
|
|
143
|
-
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
|
|
144
|
-
│ Understand│ → │ Specify │ → │ Build │ → │ Validate │
|
|
145
|
-
│ │ │ │ │ │ │ │
|
|
146
|
-
│ Intent │ │ @pre/@post│ │ Implement │ │ invar │
|
|
147
|
-
│ Inspect │ │ Doctests │ │ leaves │ │ guard │
|
|
148
|
-
│ Constraints │ Design │ │ first │ │ │
|
|
149
|
-
└───────────┘ └───────────┘ └───────────┘ └───────────┘
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
**Key insight:** Specify contracts BEFORE implementation. The contract becomes the specification.
|
|
153
|
-
|
|
154
|
-
See [INVAR.md](./INVAR.md) for complete protocol.
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## Session Protocol
|
|
159
|
-
|
|
160
|
-
Every AI session follows this format:
|
|
161
|
-
|
|
162
|
-
**First message (Check-In):**
|
|
163
|
-
```
|
|
164
|
-
✓ Check-In: [project] | [branch] | [clean/dirty]
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**Last message (Final):**
|
|
168
|
-
```
|
|
169
|
-
✓ Final: guard PASS | 0 errors, 2 warnings
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Check-In shows project context. Guard verification runs during VALIDATE phase and Final, not at Check-In.
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Core/Shell Architecture
|
|
177
|
-
|
|
178
|
-
Invar enforces separation between pure logic and I/O:
|
|
179
|
-
|
|
180
|
-
| Zone | Requirements | Forbidden |
|
|
181
|
-
|------|--------------|-----------|
|
|
182
|
-
| **Core** (`**/core/**`) | `@pre`/`@post` contracts, doctests | I/O imports (os, pathlib, requests...) |
|
|
183
|
-
| **Shell** (`**/shell/**`) | `Result[T, E]` returns | - |
|
|
184
|
-
|
|
185
|
-
```python
|
|
186
|
-
# Core: Pure logic, receives data
|
|
187
|
-
def parse_config(content: str) -> Config:
|
|
188
|
-
return Config.parse(content)
|
|
189
|
-
|
|
190
|
-
# Shell: Handles I/O, returns Result
|
|
191
|
-
def load_config(path: Path) -> Result[Config, str]:
|
|
192
|
-
content = path.read_text()
|
|
193
|
-
return Success(parse_config(content))
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## Commands
|
|
199
|
-
|
|
200
|
-
### Guard (Primary)
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
invar guard # Full verification (static + doctests + property tests)
|
|
204
|
-
invar guard --changed # Only git-modified files
|
|
205
|
-
invar guard --static # Static analysis only (~0.5s)
|
|
206
|
-
invar guard --coverage # Collect branch coverage (doctest + hypothesis)
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
**Flags:**
|
|
210
|
-
|
|
211
|
-
| Flag | Purpose |
|
|
212
|
-
|------|---------|
|
|
213
|
-
| `--strict` | Treat warnings as errors |
|
|
214
|
-
| `--explain` | Show rule explanations |
|
|
215
|
-
| `--agent` | JSON output for AI tools |
|
|
216
|
-
| `--coverage` | Branch coverage from doctest + hypothesis phases |
|
|
217
|
-
|
|
218
|
-
### Other Commands
|
|
219
|
-
|
|
220
|
-
```bash
|
|
221
|
-
invar sig <file> # Show signatures + contracts
|
|
222
|
-
invar map --top 10 # Most-referenced symbols
|
|
223
|
-
invar rules # List all rules
|
|
224
|
-
invar update # Update managed files
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## Workflow Skills (Claude Code)
|
|
230
|
-
|
|
231
|
-
`invar init --claude` creates workflow skills in `.claude/skills/`:
|
|
232
|
-
|
|
233
|
-
| Skill | Trigger | Purpose |
|
|
234
|
-
|-------|---------|---------|
|
|
235
|
-
| `/investigate` | "why", "explain", vague tasks | Exploration, no code changes |
|
|
236
|
-
| `/propose` | "should we", "compare" | Decision facilitation with options |
|
|
237
|
-
| `/develop` | "add", "fix", "implement" | USBV implementation workflow |
|
|
238
|
-
| `/review` | After develop, `review_suggested` | Adversarial review with fix loop |
|
|
239
|
-
|
|
240
|
-
**Note:** Skills are Claude Code exclusive. Other editors use INVAR.md protocol directly.
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
## Configuration
|
|
245
|
-
|
|
246
|
-
### pyproject.toml
|
|
247
|
-
|
|
248
|
-
```toml
|
|
249
|
-
[tool.invar.guard]
|
|
250
|
-
# Directory classification
|
|
251
|
-
core_paths = ["src/myapp/core"]
|
|
252
|
-
shell_paths = ["src/myapp/shell"]
|
|
253
|
-
|
|
254
|
-
# Or use patterns for existing projects
|
|
255
|
-
core_patterns = ["**/domain/**", "**/models/**"]
|
|
256
|
-
shell_patterns = ["**/api/**", "**/cli/**"]
|
|
257
|
-
|
|
258
|
-
# Size limits
|
|
259
|
-
max_file_lines = 500
|
|
260
|
-
max_function_lines = 50
|
|
261
|
-
|
|
262
|
-
# Contract requirements
|
|
263
|
-
require_contracts = true
|
|
264
|
-
require_doctests = true
|
|
265
|
-
|
|
266
|
-
# Doctest-heavy code
|
|
267
|
-
exclude_doctest_lines = true
|
|
268
|
-
|
|
269
|
-
# Rule exclusions
|
|
270
|
-
[[tool.invar.guard.rule_exclusions]]
|
|
271
|
-
pattern = "**/generated/**"
|
|
272
|
-
rules = ["*"]
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
---
|
|
276
|
-
|
|
277
|
-
## Rules Reference
|
|
278
|
-
|
|
279
|
-
| Rule | Severity | What It Checks |
|
|
280
|
-
|------|----------|----------------|
|
|
281
|
-
| `file_size` | ERROR | File > max lines |
|
|
282
|
-
| `function_size` | WARN | Function > max lines |
|
|
283
|
-
| `missing_contract` | ERROR | Core function lacks @pre/@post |
|
|
284
|
-
| `missing_doctest` | WARN | Contracted function lacks doctest |
|
|
285
|
-
| `forbidden_import` | ERROR | I/O import in Core |
|
|
286
|
-
| `shell_result` | WARN | Shell function not returning Result |
|
|
287
|
-
| `empty_contract` | ERROR | Contract is `lambda: True` |
|
|
288
|
-
|
|
289
|
-
Full list: `invar rules --explain`
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## MCP Integration (Claude Code)
|
|
294
|
-
|
|
295
|
-
`invar init --claude` automatically configures MCP:
|
|
296
|
-
|
|
297
|
-
```json
|
|
298
|
-
{
|
|
299
|
-
"mcpServers": {
|
|
300
|
-
"invar": {
|
|
301
|
-
"command": "uvx",
|
|
302
|
-
"args": ["invar-tools", "mcp"]
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**MCP Tools:**
|
|
309
|
-
|
|
310
|
-
| Tool | Replaces | Purpose |
|
|
311
|
-
|------|----------|---------|
|
|
312
|
-
| `invar_guard` | `pytest`, `crosshair` | Smart verification |
|
|
313
|
-
| `invar_sig` | Reading entire files | Show contracts and signatures |
|
|
314
|
-
| `invar_map` | `grep` for functions | Symbol map with reference counts |
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Platform Support
|
|
319
|
-
|
|
320
|
-
| Feature | Claude Code | Cursor/Windsurf | Others |
|
|
321
|
-
|---------|-------------|-----------------|--------|
|
|
322
|
-
| Smart Guard CLI | ✅ | ✅ | ✅ |
|
|
323
|
-
| INVAR.md protocol | ✅ | ✅ | ✅ |
|
|
324
|
-
| MCP integration | ✅ | ❌ | ❌ |
|
|
325
|
-
| Workflow skills | ✅ | ❌ | ❌ |
|
|
326
|
-
| Sub-agent review | ✅ | ❌ | ❌ |
|
|
327
|
-
|
|
328
|
-
**Claude Code** provides the full experience with automated workflow and independent review.
|
|
329
|
-
|
|
330
|
-
**Other editors** receive the protocol and CLI tools. Workflow adherence is manual.
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## File Ownership
|
|
335
|
-
|
|
336
|
-
| File | Owner | Edit? |
|
|
337
|
-
|------|-------|-------|
|
|
338
|
-
| `INVAR.md` | Invar | No (`invar update` manages) |
|
|
339
|
-
| `CLAUDE.md` | You | Yes (project config) |
|
|
340
|
-
| `.claude/skills/` | You | Yes (customize workflows) |
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
## Runtime Behavior
|
|
345
|
-
|
|
346
|
-
Contracts are checked at runtime via [deal](https://github.com/life4/deal).
|
|
347
|
-
|
|
348
|
-
```bash
|
|
349
|
-
# Disable in production for performance
|
|
350
|
-
DEAL_DISABLE=1 python app.py
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
---
|
|
354
|
-
|
|
355
|
-
## Learn More
|
|
356
|
-
|
|
357
|
-
**In your project** (created by `invar init`):
|
|
358
|
-
- `INVAR.md` — Protocol v5.0 for AI agents
|
|
359
|
-
- `CLAUDE.md` — Project configuration
|
|
360
|
-
- `.invar/examples/` — Reference patterns
|
|
361
|
-
|
|
362
|
-
**Documentation:**
|
|
363
|
-
- [docs/vision.md](./docs/vision.md) — Design philosophy
|
|
364
|
-
- [docs/design.md](./docs/design.md) — Technical architecture
|
|
365
|
-
- [GitHub Pages](https://tefx.github.io/Invar/) — Visual overview
|
|
366
|
-
|
|
367
|
-
---
|
|
368
|
-
|
|
369
|
-
## License
|
|
370
|
-
|
|
371
|
-
| Component | License | Purpose |
|
|
372
|
-
|-----------|---------|---------|
|
|
373
|
-
| **invar-runtime** | [Apache-2.0](LICENSE) | Runtime contracts - use freely |
|
|
374
|
-
| **invar-tools** | [GPL-3.0](LICENSE-GPL) | CLI tools - improvements shared |
|
|
375
|
-
| **Documentation** | [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/) | Share with attribution |
|
|
376
|
-
|
|
377
|
-
See [NOTICE](NOTICE) for third-party licenses.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|