invar-tools 1.7.1__py3-none-any.whl → 1.10.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. invar/__init__.py +8 -0
  2. invar/core/language.py +88 -0
  3. invar/core/models.py +106 -0
  4. invar/core/patterns/detector.py +6 -1
  5. invar/core/patterns/p0_exhaustive.py +15 -3
  6. invar/core/patterns/p0_literal.py +15 -3
  7. invar/core/patterns/p0_newtype.py +15 -3
  8. invar/core/patterns/p0_nonempty.py +15 -3
  9. invar/core/patterns/p0_validation.py +15 -3
  10. invar/core/patterns/registry.py +5 -1
  11. invar/core/patterns/types.py +5 -1
  12. invar/core/property_gen.py +4 -0
  13. invar/core/rules.py +84 -18
  14. invar/core/sync_helpers.py +27 -1
  15. invar/core/template_helpers.py +32 -0
  16. invar/core/ts_parsers.py +286 -0
  17. invar/core/ts_sig_parser.py +307 -0
  18. invar/node_tools/MANIFEST +7 -0
  19. invar/node_tools/__init__.py +51 -0
  20. invar/node_tools/fc-runner/cli.js +77 -0
  21. invar/node_tools/quick-check/cli.js +28 -0
  22. invar/node_tools/ts-analyzer/cli.js +480 -0
  23. invar/shell/claude_hooks.py +35 -12
  24. invar/shell/commands/guard.py +36 -1
  25. invar/shell/commands/init.py +133 -7
  26. invar/shell/commands/perception.py +157 -33
  27. invar/shell/commands/skill.py +187 -0
  28. invar/shell/commands/template_sync.py +65 -13
  29. invar/shell/commands/uninstall.py +77 -12
  30. invar/shell/commands/update.py +6 -14
  31. invar/shell/contract_coverage.py +1 -0
  32. invar/shell/fs.py +66 -13
  33. invar/shell/pi_hooks.py +213 -0
  34. invar/shell/prove/guard_ts.py +899 -0
  35. invar/shell/skill_manager.py +353 -0
  36. invar/shell/template_engine.py +28 -4
  37. invar/shell/templates.py +4 -4
  38. invar/templates/claude-md/python/critical-rules.md +33 -0
  39. invar/templates/claude-md/python/quick-reference.md +24 -0
  40. invar/templates/claude-md/typescript/critical-rules.md +40 -0
  41. invar/templates/claude-md/typescript/quick-reference.md +24 -0
  42. invar/templates/claude-md/universal/check-in.md +25 -0
  43. invar/templates/claude-md/universal/skills.md +73 -0
  44. invar/templates/claude-md/universal/workflow.md +55 -0
  45. invar/templates/commands/{audit.md → audit.md.jinja} +18 -1
  46. invar/templates/config/AGENT.md.jinja +256 -0
  47. invar/templates/config/CLAUDE.md.jinja +16 -209
  48. invar/templates/config/context.md.jinja +19 -0
  49. invar/templates/examples/{README.md → python/README.md} +2 -0
  50. invar/templates/examples/{conftest.py → python/conftest.py} +1 -1
  51. invar/templates/examples/{contracts.py → python/contracts.py} +81 -4
  52. invar/templates/examples/python/core_shell.py +227 -0
  53. invar/templates/examples/python/functional.py +613 -0
  54. invar/templates/examples/typescript/README.md +31 -0
  55. invar/templates/examples/typescript/contracts.ts +163 -0
  56. invar/templates/examples/typescript/core_shell.ts +374 -0
  57. invar/templates/examples/typescript/functional.ts +601 -0
  58. invar/templates/examples/typescript/workflow.md +95 -0
  59. invar/templates/hooks/PostToolUse.sh.jinja +10 -1
  60. invar/templates/hooks/PreToolUse.sh.jinja +38 -0
  61. invar/templates/hooks/Stop.sh.jinja +1 -1
  62. invar/templates/hooks/UserPromptSubmit.sh.jinja +7 -0
  63. invar/templates/hooks/pi/invar.ts.jinja +82 -0
  64. invar/templates/manifest.toml +8 -6
  65. invar/templates/onboard/assessment.md.jinja +214 -0
  66. invar/templates/onboard/patterns/python.md +347 -0
  67. invar/templates/onboard/patterns/typescript.md +452 -0
  68. invar/templates/onboard/roadmap.md.jinja +168 -0
  69. invar/templates/protocol/INVAR.md.jinja +51 -0
  70. invar/templates/protocol/python/architecture-examples.md +41 -0
  71. invar/templates/protocol/python/contracts-syntax.md +56 -0
  72. invar/templates/protocol/python/markers.md +44 -0
  73. invar/templates/protocol/python/tools.md +24 -0
  74. invar/templates/protocol/python/troubleshooting.md +38 -0
  75. invar/templates/protocol/typescript/architecture-examples.md +52 -0
  76. invar/templates/protocol/typescript/contracts-syntax.md +73 -0
  77. invar/templates/protocol/typescript/markers.md +48 -0
  78. invar/templates/protocol/typescript/tools.md +65 -0
  79. invar/templates/protocol/typescript/troubleshooting.md +104 -0
  80. invar/templates/protocol/universal/architecture.md +36 -0
  81. invar/templates/protocol/universal/completion.md +14 -0
  82. invar/templates/protocol/universal/contracts-concept.md +37 -0
  83. invar/templates/protocol/universal/header.md +17 -0
  84. invar/templates/protocol/universal/session.md +17 -0
  85. invar/templates/protocol/universal/six-laws.md +10 -0
  86. invar/templates/protocol/universal/usbv.md +14 -0
  87. invar/templates/protocol/universal/visible-workflow.md +25 -0
  88. invar/templates/skills/develop/SKILL.md.jinja +98 -3
  89. invar/templates/skills/extensions/_registry.yaml +93 -0
  90. invar/templates/skills/extensions/acceptance/SKILL.md +383 -0
  91. invar/templates/skills/extensions/invar-onboard/SKILL.md +448 -0
  92. invar/templates/skills/extensions/invar-onboard/patterns/python.md +347 -0
  93. invar/templates/skills/extensions/invar-onboard/patterns/typescript.md +452 -0
  94. invar/templates/skills/extensions/invar-onboard/templates/assessment.md.jinja +214 -0
  95. invar/templates/skills/extensions/invar-onboard/templates/roadmap.md.jinja +168 -0
  96. invar/templates/skills/extensions/security/SKILL.md +382 -0
  97. invar/templates/skills/extensions/security/patterns/_common.yaml +126 -0
  98. invar/templates/skills/extensions/security/patterns/python.yaml +155 -0
  99. invar/templates/skills/extensions/security/patterns/typescript.yaml +194 -0
  100. invar/templates/skills/investigate/SKILL.md.jinja +15 -0
  101. invar/templates/skills/propose/SKILL.md.jinja +33 -0
  102. invar/templates/skills/review/SKILL.md.jinja +346 -71
  103. {invar_tools-1.7.1.dist-info → invar_tools-1.10.0.dist-info}/METADATA +326 -19
  104. invar_tools-1.10.0.dist-info/RECORD +173 -0
  105. invar/templates/examples/core_shell.py +0 -127
  106. invar/templates/protocol/INVAR.md +0 -310
  107. invar_tools-1.7.1.dist-info/RECORD +0 -112
  108. /invar/templates/examples/{workflow.md → python/workflow.md} +0 -0
  109. {invar_tools-1.7.1.dist-info → invar_tools-1.10.0.dist-info}/WHEEL +0 -0
  110. {invar_tools-1.7.1.dist-info → invar_tools-1.10.0.dist-info}/entry_points.txt +0 -0
  111. {invar_tools-1.7.1.dist-info → invar_tools-1.10.0.dist-info}/licenses/LICENSE +0 -0
  112. {invar_tools-1.7.1.dist-info → invar_tools-1.10.0.dist-info}/licenses/LICENSE-GPL +0 -0
  113. {invar_tools-1.7.1.dist-info → invar_tools-1.10.0.dist-info}/licenses/NOTICE +0 -0
@@ -0,0 +1,155 @@
1
+ # Python Security Patterns
2
+ # Extends _common.yaml with Python-specific patterns
3
+
4
+ version: "1.0"
5
+ extends: _common
6
+
7
+ patterns:
8
+ # A03: Injection
9
+ sql_injection_fstring:
10
+ category: A03
11
+ severity: Critical
12
+ description: "SQL injection via f-string formatting"
13
+ regex:
14
+ - "f\"[^\"]*SELECT[^\"]*\\{[^}]+\\}\""
15
+ - "f'[^']*SELECT[^']*\\{[^}]+\\}'"
16
+ - "f\"[^\"]*INSERT[^\"]*\\{[^}]+\\}\""
17
+ - "f\"[^\"]*UPDATE[^\"]*\\{[^}]+\\}\""
18
+ - "f\"[^\"]*DELETE[^\"]*\\{[^}]+\\}\""
19
+ false_positive_hints:
20
+ - "Check if query uses ORM with proper parameterization"
21
+ - "Verify if variable is validated/sanitized before use"
22
+
23
+ sql_injection_format:
24
+ category: A03
25
+ severity: Critical
26
+ description: "SQL injection via .format() or % formatting"
27
+ regex:
28
+ - "\\.format\\([^)]*\\)[^\"]*SELECT"
29
+ - "SELECT[^\"]*\\.format\\("
30
+ - "%s[^\"]*SELECT|SELECT[^\"]*%s"
31
+ - "\"%.*SELECT.*%.*\"\\s*%"
32
+ false_positive_hints:
33
+ - "Check if parameterized queries are used"
34
+
35
+ command_injection:
36
+ category: A03
37
+ severity: Critical
38
+ description: "Command injection via shell execution"
39
+ regex:
40
+ - "os\\.system\\s*\\("
41
+ - "os\\.popen\\s*\\("
42
+ - "subprocess\\.call\\s*\\([^)]*shell\\s*=\\s*True"
43
+ - "subprocess\\.run\\s*\\([^)]*shell\\s*=\\s*True"
44
+ - "subprocess\\.Popen\\s*\\([^)]*shell\\s*=\\s*True"
45
+ false_positive_hints:
46
+ - "Check if command includes user input"
47
+ - "Prefer subprocess with list arguments (shell=False)"
48
+
49
+ code_execution:
50
+ category: A03
51
+ severity: Critical
52
+ description: "Dynamic code execution"
53
+ regex:
54
+ - "\\beval\\s*\\("
55
+ - "\\bexec\\s*\\("
56
+ - "compile\\s*\\([^)]+,[^)]+,[\"']exec[\"']\\)"
57
+ false_positive_hints:
58
+ - "Check if input is from trusted source"
59
+ - "Consider safer alternatives (ast.literal_eval)"
60
+
61
+ template_injection:
62
+ category: A03
63
+ severity: High
64
+ description: "Server-side template injection"
65
+ regex:
66
+ - "render_template_string\\s*\\("
67
+ - "Template\\s*\\(\\s*\\w+\\s*\\)"
68
+ - "Environment\\s*\\([^)]*\\)\\.from_string"
69
+ false_positive_hints:
70
+ - "Check if template content is user-controlled"
71
+
72
+ # A08: Data Integrity Failures
73
+ unsafe_pickle:
74
+ category: A08
75
+ severity: High
76
+ description: "Unsafe deserialization with pickle"
77
+ regex:
78
+ - "pickle\\.loads?\\s*\\("
79
+ - "cPickle\\.loads?\\s*\\("
80
+ - "_pickle\\.loads?\\s*\\("
81
+ false_positive_hints:
82
+ - "Check if data source is trusted"
83
+ - "Consider using JSON or other safe formats"
84
+
85
+ unsafe_yaml:
86
+ category: A08
87
+ severity: High
88
+ description: "Unsafe YAML loading"
89
+ regex:
90
+ - "yaml\\.load\\s*\\([^)]*\\)"
91
+ - "yaml\\.unsafe_load\\s*\\("
92
+ exclude_if_contains:
93
+ - "Loader=yaml.SafeLoader"
94
+ - "Loader=SafeLoader"
95
+ false_positive_hints:
96
+ - "Use yaml.safe_load() instead"
97
+
98
+ # A01: Broken Access Control
99
+ missing_auth_decorator:
100
+ category: A01
101
+ severity: Medium
102
+ description: "Route potentially missing authentication"
103
+ regex:
104
+ - "@app\\.route\\s*\\([^)]*\\)\\s*\\ndef\\s+\\w+\\s*\\([^)]*\\)\\s*:"
105
+ - "@router\\.(get|post|put|delete)\\s*\\([^)]*\\)\\s*\\n(?!.*@.*auth)"
106
+ false_positive_hints:
107
+ - "Check if route should be public"
108
+ - "Verify auth is handled in middleware"
109
+
110
+ # A02: Cryptographic Failures (Python-specific)
111
+ weak_password_hash:
112
+ category: A02
113
+ severity: High
114
+ description: "Weak password hashing"
115
+ regex:
116
+ - "hashlib\\.md5\\s*\\("
117
+ - "hashlib\\.sha1\\s*\\("
118
+ - "crypt\\.crypt\\s*\\("
119
+ false_positive_hints:
120
+ - "Use bcrypt, argon2, or scrypt for passwords"
121
+ - "MD5/SHA1 ok for non-password checksums"
122
+
123
+ # A05: Security Misconfiguration
124
+ flask_debug:
125
+ category: A05
126
+ severity: High
127
+ description: "Flask debug mode enabled"
128
+ regex:
129
+ - "app\\.run\\s*\\([^)]*debug\\s*=\\s*True"
130
+ - "FLASK_DEBUG\\s*=\\s*1"
131
+ - "FLASK_ENV\\s*=\\s*[\"']development[\"']"
132
+ false_positive_hints:
133
+ - "Ensure this is not production configuration"
134
+
135
+ django_debug:
136
+ category: A05
137
+ severity: High
138
+ description: "Django debug mode enabled"
139
+ regex:
140
+ - "DEBUG\\s*=\\s*True"
141
+ file_pattern: "settings*.py"
142
+ false_positive_hints:
143
+ - "Check if this is production settings file"
144
+
145
+ # A07: Authentication Failures
146
+ weak_jwt:
147
+ category: A07
148
+ severity: High
149
+ description: "Weak JWT configuration"
150
+ regex:
151
+ - "algorithm\\s*=\\s*[\"']none[\"']"
152
+ - "algorithms\\s*=\\s*\\[[\"']none[\"']\\]"
153
+ - "verify\\s*=\\s*False"
154
+ false_positive_hints:
155
+ - "JWT should use HS256 or RS256 minimum"
@@ -0,0 +1,194 @@
1
+ # TypeScript/JavaScript Security Patterns
2
+ # Extends _common.yaml with TS/JS-specific patterns
3
+
4
+ version: "1.0"
5
+ extends: _common
6
+
7
+ patterns:
8
+ # A03: Injection
9
+ xss_innerhtml:
10
+ category: A03
11
+ severity: High
12
+ description: "Cross-site scripting via innerHTML"
13
+ regex:
14
+ - "\\.innerHTML\\s*="
15
+ - "\\.outerHTML\\s*="
16
+ - "document\\.write\\s*\\("
17
+ - "document\\.writeln\\s*\\("
18
+ false_positive_hints:
19
+ - "Check if content is from user input"
20
+ - "Use textContent or DOMPurify for sanitization"
21
+
22
+ xss_react:
23
+ category: A03
24
+ severity: High
25
+ description: "React XSS via dangerouslySetInnerHTML"
26
+ regex:
27
+ - "dangerouslySetInnerHTML"
28
+ false_positive_hints:
29
+ - "Ensure content is sanitized with DOMPurify"
30
+ - "Verify source of HTML content"
31
+
32
+ xss_vue:
33
+ category: A03
34
+ severity: High
35
+ description: "Vue XSS via v-html directive"
36
+ regex:
37
+ - "v-html\\s*="
38
+ false_positive_hints:
39
+ - "Sanitize content before using v-html"
40
+
41
+ xss_angular:
42
+ category: A03
43
+ severity: High
44
+ description: "Angular XSS via innerHTML binding"
45
+ regex:
46
+ - "\\[innerHTML\\]\\s*="
47
+ - "bypassSecurityTrustHtml"
48
+ false_positive_hints:
49
+ - "bypassSecurityTrust* should only be used with trusted content"
50
+
51
+ code_execution:
52
+ category: A03
53
+ severity: Critical
54
+ description: "Dynamic code execution"
55
+ regex:
56
+ - "\\beval\\s*\\("
57
+ - "new\\s+Function\\s*\\("
58
+ - "setTimeout\\s*\\(\\s*[\"'][^\"']*[\"']"
59
+ - "setInterval\\s*\\(\\s*[\"'][^\"']*[\"']"
60
+ false_positive_hints:
61
+ - "Avoid eval with user input"
62
+ - "Use JSON.parse for data parsing"
63
+
64
+ prototype_pollution:
65
+ category: A03
66
+ severity: High
67
+ description: "Prototype pollution vulnerability"
68
+ regex:
69
+ - "__proto__"
70
+ - "constructor\\s*\\[\\s*[\"']prototype[\"']\\s*\\]"
71
+ - "Object\\.assign\\s*\\(\\s*\\{\\s*\\}\\s*,"
72
+ false_positive_hints:
73
+ - "Check if object keys come from user input"
74
+ - "Use Object.create(null) for dictionaries"
75
+
76
+ sql_injection:
77
+ category: A03
78
+ severity: Critical
79
+ description: "SQL injection via string concatenation"
80
+ regex:
81
+ - "`[^`]*SELECT[^`]*\\$\\{[^}]+\\}`"
82
+ - "\"[^\"]*SELECT[^\"]*\"\\s*\\+"
83
+ - "'[^']*SELECT[^']*'\\s*\\+"
84
+ false_positive_hints:
85
+ - "Use parameterized queries or ORM"
86
+
87
+ nosql_injection:
88
+ category: A03
89
+ severity: High
90
+ description: "NoSQL injection (MongoDB)"
91
+ regex:
92
+ - "\\$where\\s*:"
93
+ - "\\$regex\\s*:\\s*\\w+"
94
+ - "find\\s*\\(\\s*\\{[^}]*\\$"
95
+ false_positive_hints:
96
+ - "Validate and sanitize query parameters"
97
+
98
+ command_injection:
99
+ category: A03
100
+ severity: Critical
101
+ description: "Command injection via child_process"
102
+ regex:
103
+ - "child_process\\.exec\\s*\\("
104
+ - "child_process\\.execSync\\s*\\("
105
+ - "exec\\s*\\(\\s*`"
106
+ - "execSync\\s*\\(\\s*`"
107
+ false_positive_hints:
108
+ - "Use execFile with array arguments instead"
109
+ - "Validate/sanitize command input"
110
+
111
+ # A01: Broken Access Control
112
+ cors_wildcard:
113
+ category: A01
114
+ severity: Medium
115
+ description: "CORS allows all origins"
116
+ regex:
117
+ - "Access-Control-Allow-Origin[\"']?\\s*:\\s*[\"']?\\*"
118
+ - "origin\\s*:\\s*[\"']?\\*"
119
+ - "cors\\s*\\(\\s*\\)"
120
+ false_positive_hints:
121
+ - "Specify allowed origins explicitly"
122
+ - "cors() without options allows all origins"
123
+
124
+ # A02: Cryptographic Failures (JS-specific)
125
+ weak_crypto:
126
+ category: A02
127
+ severity: Medium
128
+ description: "Weak cryptographic algorithm"
129
+ regex:
130
+ - "createHash\\s*\\([\"']md5[\"']\\)"
131
+ - "createHash\\s*\\([\"']sha1[\"']\\)"
132
+ - "createCipher\\s*\\([\"']des"
133
+ false_positive_hints:
134
+ - "Use SHA-256 or stronger for security"
135
+
136
+ jwt_none_algorithm:
137
+ category: A02
138
+ severity: Critical
139
+ description: "JWT with 'none' algorithm"
140
+ regex:
141
+ - "algorithm[\"']?\\s*:\\s*[\"']none[\"']"
142
+ - "algorithms\\s*:\\s*\\[[\"']none[\"']\\]"
143
+ false_positive_hints:
144
+ - "Never allow 'none' algorithm in production"
145
+
146
+ # A05: Security Misconfiguration
147
+ express_trust_proxy:
148
+ category: A05
149
+ severity: Low
150
+ description: "Express trust proxy configuration"
151
+ regex:
152
+ - "trust\\s+proxy[\"']?\\s*,\\s*true"
153
+ false_positive_hints:
154
+ - "Only enable if behind a trusted reverse proxy"
155
+
156
+ helmet_disabled:
157
+ category: A05
158
+ severity: Medium
159
+ description: "Security headers potentially disabled"
160
+ regex:
161
+ - "helmet\\s*\\(\\s*\\{\\s*[^}]*:\\s*false"
162
+ false_positive_hints:
163
+ - "Avoid disabling security headers"
164
+
165
+ # A08: Data Integrity Failures
166
+ unsafe_json_parse:
167
+ category: A08
168
+ severity: Low
169
+ description: "JSON.parse without error handling"
170
+ regex:
171
+ - "JSON\\.parse\\s*\\([^)]+\\)(?!\\s*\\.catch|\\s*\\)\\s*\\.catch)"
172
+ false_positive_hints:
173
+ - "Wrap in try-catch for untrusted input"
174
+
175
+ # A07: Authentication Failures
176
+ hardcoded_jwt_secret:
177
+ category: A07
178
+ severity: Critical
179
+ description: "Hardcoded JWT secret"
180
+ regex:
181
+ - "jwt\\.sign\\s*\\([^,]+,\\s*[\"'][^\"']+[\"']"
182
+ - "secret\\s*:\\s*[\"'][^\"']{8,}[\"']"
183
+ false_positive_hints:
184
+ - "Use environment variables for secrets"
185
+
186
+ session_insecure:
187
+ category: A07
188
+ severity: Medium
189
+ description: "Insecure session configuration"
190
+ regex:
191
+ - "secure\\s*:\\s*false"
192
+ - "httpOnly\\s*:\\s*false"
193
+ false_positive_hints:
194
+ - "Set secure: true and httpOnly: true in production"
@@ -11,6 +11,21 @@ _invar:
11
11
 
12
12
  > **Purpose:** Understand before acting. Gather information, analyze code, report findings.
13
13
 
14
+ ## Scope Boundaries
15
+
16
+ **This skill IS for:**
17
+ - Understanding vague or unclear tasks
18
+ - Analyzing existing code and architecture
19
+ - Researching before implementation
20
+ - Answering "why", "what", "how does" questions
21
+
22
+ **This skill is NOT for:**
23
+ - Writing or modifying code → switch to `/develop`
24
+ - Making design decisions → switch to `/propose`
25
+ - Reviewing code quality → switch to `/review`
26
+
27
+ **Drift detection:** If you find yourself wanting to edit files → STOP, exit to `/develop`.
28
+
14
29
  ## Constraints
15
30
 
16
31
  **FORBIDDEN in this phase:**
@@ -10,6 +10,39 @@ _invar:
10
10
  # Proposal Mode
11
11
 
12
12
  > **Purpose:** Facilitate human decision-making with clear options and trade-offs.
13
+ > **Mindset:** OPTIONS, not decisions — human chooses.
14
+
15
+ ## Scope Boundaries
16
+
17
+ **This skill IS for:**
18
+ - Presenting design choices with trade-offs
19
+ - Facilitating architectural decisions
20
+ - Comparing approaches (A vs B)
21
+ - Creating formal proposals for complex decisions
22
+
23
+ **This skill is NOT for:**
24
+ - Implementing the chosen option → switch to `/develop`
25
+ - Researching to understand the problem → switch to `/investigate`
26
+ - Reviewing existing code → switch to `/review`
27
+
28
+ **Drift detection:** If you find yourself writing implementation code → STOP, wait for user choice, then exit to `/develop`.
29
+
30
+ ## Constraints
31
+
32
+ **FORBIDDEN in this phase:**
33
+ - Writing implementation code (beyond examples)
34
+ - Making decisions for the user
35
+ - Creating files other than proposals
36
+ - Committing changes
37
+
38
+ **ALLOWED:**
39
+ - Read, Glob, Grep (research for options)
40
+ {% if syntax == "mcp" -%}
41
+ - invar_sig, invar_map (understand current state)
42
+ {% else -%}
43
+ - invar sig, invar map (understand current state)
44
+ {% endif -%}
45
+ - Creating proposal documents in `docs/proposals/`
13
46
 
14
47
  ## Entry Actions
15
48