invar-tools 1.5.0__tar.gz → 1.7.0__tar.gz

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 (285) hide show
  1. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/skills/develop/SKILL.md +2 -1
  2. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/context.md +17 -4
  3. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/examples/workflow.md +99 -0
  4. {invar_tools-1.5.0 → invar_tools-1.7.0}/CLAUDE.md +49 -28
  5. {invar_tools-1.5.0 → invar_tools-1.7.0}/INVAR.md +1 -0
  6. {invar_tools-1.5.0 → invar_tools-1.7.0}/PKG-INFO +1 -1
  7. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-62-proactive-reference-reading.md +1 -1
  8. invar_tools-1.7.0/docs/proposals/DX-64-version-display-unification.md +104 -0
  9. invar_tools-1.7.0/docs/proposals/DX-65-single-file-guard.md +157 -0
  10. invar_tools-1.7.0/docs/proposals/DX-66-escape-hatch-visibility.md +154 -0
  11. invar_tools-1.7.0/docs/proposals/DX-67-explicit-skill-invocation.md +208 -0
  12. invar_tools-1.7.0/docs/proposals/DX-68-agent-behavior-optimization.md +299 -0
  13. invar_tools-1.7.0/docs/proposals/DX-69-project-uninstall.md +181 -0
  14. invar_tools-1.7.0/docs/proposals/LX-02-agent-portability-analysis.md +579 -0
  15. invar_tools-1.7.0/docs/proposals/LX-04-pi-agent-support.md +373 -0
  16. {invar_tools-1.5.0/docs/proposals → invar_tools-1.7.0/docs/proposals/completed}/DX-63-contracts-first-enforcement.md +2 -1
  17. invar_tools-1.7.0/docs/proposals/completed/LX-03-multi-agent-support.md +60 -0
  18. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/index.md +154 -22
  19. invar_tools-1.7.0/docs/reference/agent-information-hierarchy.md +268 -0
  20. invar_tools-1.7.0/docs/testing/v1.5.0-stress-test.md +255 -0
  21. invar_tools-1.7.0/docs/testing/v1.5.0-test-report.md +172 -0
  22. invar_tools-1.7.0/docs/testing/v1.5.0-workflow-compliance.md +167 -0
  23. {invar_tools-1.5.0 → invar_tools-1.7.0}/pyproject.toml +1 -1
  24. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/__init__.py +7 -1
  25. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/entry_points.py +12 -10
  26. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/formatter.py +15 -0
  27. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/models.py +85 -0
  28. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/guard.py +38 -9
  29. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/init.py +8 -79
  30. invar_tools-1.7.0/src/invar/shell/commands/uninstall.py +341 -0
  31. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/config.py +46 -0
  32. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/guard_output.py +10 -0
  33. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/templates.py +1 -70
  34. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/CLAUDE.md.template +18 -10
  35. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/commands/audit.md +6 -0
  36. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/commands/guard.md +6 -0
  37. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/config/CLAUDE.md.jinja +51 -30
  38. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/config/context.md.jinja +14 -0
  39. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/pre-commit-config.yaml.template +2 -0
  40. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/protocol/INVAR.md +1 -0
  41. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/skills/develop/SKILL.md.jinja +2 -1
  42. invar_tools-1.5.0/.serena/cache/python/document_symbols.pkl +0 -0
  43. invar_tools-1.5.0/.serena/cache/python/raw_document_symbols.pkl +0 -0
  44. invar_tools-1.5.0/docs/proposals/LX-02-agent-portability-analysis.md +0 -445
  45. invar_tools-1.5.0/docs/proposals/LX-03-multi-agent-support.md +0 -422
  46. invar_tools-1.5.0/src/invar/templates/aider.conf.yml.template +0 -31
  47. invar_tools-1.5.0/src/invar/templates/cursorrules.template +0 -40
  48. {invar_tools-1.5.0 → invar_tools-1.7.0}/.aider.conf.yml +0 -0
  49. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/commands/audit.md +0 -0
  50. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/commands/guard.md +0 -0
  51. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/PostToolUse.sh +0 -0
  52. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/PreToolUse.sh +0 -0
  53. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/Stop.sh +0 -0
  54. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/UserPromptSubmit.sh +0 -0
  55. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/invar.PostToolUse.sh +0 -0
  56. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/invar.PreToolUse.sh +0 -0
  57. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/invar.Stop.sh +0 -0
  58. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/hooks/invar.UserPromptSubmit.sh +0 -0
  59. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/skills/investigate/SKILL.md +0 -0
  60. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/skills/propose/SKILL.md +0 -0
  61. {invar_tools-1.5.0 → invar_tools-1.7.0}/.claude/skills/review/SKILL.md +0 -0
  62. {invar_tools-1.5.0 → invar_tools-1.7.0}/.cursorrules +0 -0
  63. {invar_tools-1.5.0 → invar_tools-1.7.0}/.github/workflows/ci.yml +0 -0
  64. {invar_tools-1.5.0 → invar_tools-1.7.0}/.github/workflows/publish.yml +0 -0
  65. {invar_tools-1.5.0 → invar_tools-1.7.0}/.gitignore +0 -0
  66. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/archive/sessions-2025-12.md +0 -0
  67. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/examples/README.md +0 -0
  68. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/examples/conftest.py +0 -0
  69. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/examples/contracts.py +0 -0
  70. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/examples/core_shell.py +0 -0
  71. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/examples/functional.py +0 -0
  72. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/mcp-setup.md +0 -0
  73. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/project-additions.md +0 -0
  74. {invar_tools-1.5.0 → invar_tools-1.7.0}/.invar/proposals/TEMPLATE.md +0 -0
  75. {invar_tools-1.5.0 → invar_tools-1.7.0}/.mcp.json +0 -0
  76. {invar_tools-1.5.0 → invar_tools-1.7.0}/.pre-commit-config.yaml +0 -0
  77. {invar_tools-1.5.0 → invar_tools-1.7.0}/.serena/.gitignore +0 -0
  78. {invar_tools-1.5.0 → invar_tools-1.7.0}/.serena/project.yml +0 -0
  79. {invar_tools-1.5.0 → invar_tools-1.7.0}/LICENSE +0 -0
  80. {invar_tools-1.5.0 → invar_tools-1.7.0}/LICENSE-GPL +0 -0
  81. {invar_tools-1.5.0 → invar_tools-1.7.0}/NOTICE +0 -0
  82. {invar_tools-1.5.0 → invar_tools-1.7.0}/README.md +0 -0
  83. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/.nojekyll +0 -0
  84. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/agents.md +0 -0
  85. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/design.md +0 -0
  86. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/diagrams.md +0 -0
  87. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/guide.md +0 -0
  88. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/guides/aider.md +0 -0
  89. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/guides/cline.md +0 -0
  90. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/guides/continue.md +0 -0
  91. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/guides/cursor.md +0 -0
  92. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/guides/multi-agent.md +0 -0
  93. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/decisions-2024.md +0 -0
  94. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/feedback/compliance-analysis.md +0 -0
  95. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/feedback/feedback-memo.md +0 -0
  96. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/feedback/index.md +0 -0
  97. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/index.md +0 -0
  98. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/original-vision.md +0 -0
  99. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/protocol-evolution.md +0 -0
  100. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/history/research/cruxeval-quick-validation.md +0 -0
  101. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/index.html +0 -0
  102. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/logo.svg +0 -0
  103. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-23-entry-point-detection.md +0 -0
  104. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-25-functional-patterns.md +0 -0
  105. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-29-pure-content-detection.md +0 -0
  106. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-37-coverage-integration.md +0 -0
  107. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-38-contract-quality-rules.md +0 -0
  108. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-39-workflow-efficiency.md +0 -0
  109. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-40-smart-tool-redirect-hook.md +0 -0
  110. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-41-automatic-review-orchestration.md +0 -0
  111. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-42-workflow-auto-routing.md +0 -0
  112. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-43-cross-platform-distribution.md +0 -0
  113. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-46-documentation-audit.md +0 -0
  114. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-48-code-structure-reorganization.md +0 -0
  115. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-49-protocol-distribution-unification.md +0 -0
  116. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-50-workflow-enforcement.md +0 -0
  117. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-51-workflow-phase-visibility.md +0 -0
  118. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-52-venv-dependency-injection.md +0 -0
  119. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-53-review-loop-effectiveness.md +0 -0
  120. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-54-agent-native-context-management.md +0 -0
  121. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-55-claude-init-conflict-resolution.md +0 -0
  122. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-56-template-sync-unification.md +0 -0
  123. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-60-structured-rules-ssot.md +0 -0
  124. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-61-functional-pattern-guidance.md +0 -0
  125. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/DX-61-implementation-design.md +0 -0
  126. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/LX-01-multi-language-feasibility.md +0 -0
  127. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/2024-12-21-guard-enhancements.md +0 -0
  128. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/2024-12-21-language-inspired-enhancements.md +0 -0
  129. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/2024-12-21-test-first-enhancement.md +0 -0
  130. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/2025-12-21-dx-improvements.md +0 -0
  131. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/2025-12-23-dx-20-property-testing-enhancements.md +0 -0
  132. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/2025-12-23-dx-21-package-and-init.md +0 -0
  133. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/AGENT-IMPROVEMENTS.md +0 -0
  134. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-11-documentation-restructure.md +0 -0
  135. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-12-hypothesis-fallback.md +0 -0
  136. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-13-incremental-prove.md +0 -0
  137. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-14-expanded-prove-usage.md +0 -0
  138. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-16-agent-tool-enforcement.md +0 -0
  139. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-17-workflow-enforcement.md +0 -0
  140. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-22-verification-strategy.md +0 -0
  141. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-24-mechanism-documentation.md +0 -0
  142. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-26-guard-simplification.md +0 -0
  143. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-27-system-prompt-protocol.md +0 -0
  144. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-28-semantic-verification.md +0 -0
  145. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-30-visible-workflow.md +0 -0
  146. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-31-adversarial-reviewer.md +0 -0
  147. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-32-workflow-iteration.md +0 -0
  148. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-33-verification-blind-spots.md +0 -0
  149. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-34-review-cycle.md +0 -0
  150. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-35-workflow-phase-separation.md +0 -0
  151. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-36-documentation-restructuring.md +0 -0
  152. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-45-template-consistency.md +0 -0
  153. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-47-command-skill-naming.md +0 -0
  154. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-57-claude-code-hooks.md +0 -0
  155. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/proposals/completed/DX-58-document-structure-optimization.md +0 -0
  156. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/architecture/index.md +0 -0
  157. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/contracts/advanced.md +0 -0
  158. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/contracts/completeness.md +0 -0
  159. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/contracts/doctests.md +0 -0
  160. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/contracts/index.md +0 -0
  161. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/contracts/pre-post.md +0 -0
  162. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/documentation.md +0 -0
  163. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/index.md +0 -0
  164. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/proposal-workflow.md +0 -0
  165. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/rules/index.md +0 -0
  166. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/rules/severity.md +0 -0
  167. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/verification/crosshair-vs-hypothesis.md +0 -0
  168. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/verification/index.md +0 -0
  169. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/verification/smart-routing.md +0 -0
  170. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/workflow/index.md +0 -0
  171. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/workflow/session-start.md +0 -0
  172. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/reference/workflow/usbv.md +0 -0
  173. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/terminal-gif-guide.md +0 -0
  174. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/test-reports/DX-55-test-report.md +0 -0
  175. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/test-reports/DX-56-test-report.md +0 -0
  176. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/test-reports/DX-58-test-scenario.md +0 -0
  177. {invar_tools-1.5.0 → invar_tools-1.7.0}/docs/vision.md +0 -0
  178. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/LICENSE +0 -0
  179. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/README.md +0 -0
  180. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/pyproject.toml +0 -0
  181. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/src/invar_runtime/__init__.py +0 -0
  182. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/src/invar_runtime/contracts.py +0 -0
  183. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/src/invar_runtime/decorators.py +0 -0
  184. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/src/invar_runtime/invariant.py +0 -0
  185. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/src/invar_runtime/relations.py +0 -0
  186. {invar_tools-1.5.0 → invar_tools-1.7.0}/runtime/src/invar_runtime/resource.py +0 -0
  187. {invar_tools-1.5.0 → invar_tools-1.7.0}/scripts/smart-guard.sh +0 -0
  188. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/core/__init__.py +0 -0
  189. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/__init__.py +0 -0
  190. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/contracts.py +0 -0
  191. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/extraction.py +0 -0
  192. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/format_specs.py +0 -0
  193. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/format_strategies.py +0 -0
  194. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/hypothesis_strategies.py +0 -0
  195. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/inspect.py +0 -0
  196. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/lambda_helpers.py +0 -0
  197. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/must_use.py +0 -0
  198. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/parser.py +0 -0
  199. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/__init__.py +0 -0
  200. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/detector.py +0 -0
  201. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/p0_exhaustive.py +0 -0
  202. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/p0_literal.py +0 -0
  203. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/p0_newtype.py +0 -0
  204. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/p0_nonempty.py +0 -0
  205. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/p0_validation.py +0 -0
  206. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/registry.py +0 -0
  207. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/patterns/types.py +0 -0
  208. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/postcondition_scope.py +0 -0
  209. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/property_gen.py +0 -0
  210. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/purity.py +0 -0
  211. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/purity_heuristics.py +0 -0
  212. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/references.py +0 -0
  213. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/review_trigger.py +0 -0
  214. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/rule_meta.py +0 -0
  215. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/rules.py +0 -0
  216. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/shell_analysis.py +0 -0
  217. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/shell_architecture.py +0 -0
  218. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/strategies.py +0 -0
  219. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/suggestions.py +0 -0
  220. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/sync_helpers.py +0 -0
  221. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/tautology.py +0 -0
  222. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/template_parser.py +0 -0
  223. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/timeout_inference.py +0 -0
  224. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/trivial_detection.py +0 -0
  225. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/utils.py +0 -0
  226. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/core/verification_routing.py +0 -0
  227. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/mcp/__init__.py +0 -0
  228. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/mcp/__main__.py +0 -0
  229. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/mcp/server.py +0 -0
  230. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/py.typed +0 -0
  231. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/__init__.py +0 -0
  232. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/claude_hooks.py +0 -0
  233. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/__init__.py +0 -0
  234. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/hooks.py +0 -0
  235. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/merge.py +0 -0
  236. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/mutate.py +0 -0
  237. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/perception.py +0 -0
  238. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/sync_self.py +0 -0
  239. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/template_sync.py +0 -0
  240. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/test.py +0 -0
  241. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/commands/update.py +0 -0
  242. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/contract_coverage.py +0 -0
  243. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/coverage.py +0 -0
  244. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/fs.py +0 -0
  245. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/git.py +0 -0
  246. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/guard_helpers.py +0 -0
  247. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/mcp_config.py +0 -0
  248. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/mutation.py +0 -0
  249. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/pattern_integration.py +0 -0
  250. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/property_tests.py +0 -0
  251. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/prove/__init__.py +0 -0
  252. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/prove/accept.py +0 -0
  253. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/prove/cache.py +0 -0
  254. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/prove/crosshair.py +0 -0
  255. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/prove/hypothesis.py +0 -0
  256. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/subprocess_env.py +0 -0
  257. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/template_engine.py +0 -0
  258. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/shell/testing.py +0 -0
  259. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/__init__.py +0 -0
  260. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/config/pre-commit.yaml.jinja +0 -0
  261. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/context.md.template +0 -0
  262. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/examples/README.md +0 -0
  263. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/examples/conftest.py +0 -0
  264. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/examples/contracts.py +0 -0
  265. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/examples/core_shell.py +0 -0
  266. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/examples/workflow.md +0 -0
  267. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/hooks/PostToolUse.sh.jinja +0 -0
  268. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/hooks/PreToolUse.sh.jinja +0 -0
  269. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/hooks/Stop.sh.jinja +0 -0
  270. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/hooks/UserPromptSubmit.sh.jinja +0 -0
  271. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/hooks/__init__.py +0 -0
  272. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/manifest.toml +0 -0
  273. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/proposal.md.template +0 -0
  274. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/skills/investigate/SKILL.md.jinja +0 -0
  275. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/skills/propose/SKILL.md.jinja +0 -0
  276. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/invar/templates/skills/review/SKILL.md.jinja +0 -0
  277. {invar_tools-1.5.0 → invar_tools-1.7.0}/src/shell/__init__.py +0 -0
  278. {invar_tools-1.5.0 → invar_tools-1.7.0}/tests/__init__.py +0 -0
  279. {invar_tools-1.5.0 → invar_tools-1.7.0}/tests/conftest.py +0 -0
  280. {invar_tools-1.5.0 → invar_tools-1.7.0}/tests/integration/__init__.py +0 -0
  281. {invar_tools-1.5.0 → invar_tools-1.7.0}/tests/integration/test_cli_flags.py +0 -0
  282. {invar_tools-1.5.0 → invar_tools-1.7.0}/tests/integration/test_dx55_regression.py +0 -0
  283. {invar_tools-1.5.0 → invar_tools-1.7.0}/tests/integration/test_dx56_sync.py +0 -0
  284. {invar_tools-1.5.0 → invar_tools-1.7.0}/tests/test_subprocess_env.py +0 -0
  285. {invar_tools-1.5.0 → invar_tools-1.7.0}/uv.lock +0 -0
@@ -17,7 +17,8 @@ _invar:
17
17
 
18
18
  Before any workflow action:
19
19
  1. Read `.invar/context.md` (especially Key Rules section)
20
- 2. Display routing announcement
20
+ 2. **Check Task Router** — read examples before coding in `core/` or `shell/`
21
+ 3. Display routing announcement
21
22
 
22
23
  ### Routing Announcement
23
24
 
@@ -19,6 +19,18 @@
19
19
  - `invar_guard()` = static + doctests + CrossHair + Hypothesis
20
20
  - Final must show: `✓ Final: guard PASS | ...`
21
21
 
22
+ ## Task Router (DX-62)
23
+
24
+ | If you are about to... | STOP and read first |
25
+ |------------------------|---------------------|
26
+ | Write code in `core/` | `.invar/examples/contracts.py` |
27
+ | Write code in `shell/` | `.invar/examples/core_shell.py` |
28
+ | Add `@pre`/`@post` contracts | `.invar/examples/contracts.py` |
29
+ | Use functional patterns | `.invar/examples/functional.py` |
30
+ | Implement a feature | `.invar/examples/workflow.md` |
31
+
32
+ **Rule:** Match found above? Read the file BEFORE writing code.
33
+
22
34
  ## Self-Reminder
23
35
 
24
36
  <!-- DX-54: AI should re-read this file periodically -->
@@ -136,12 +148,13 @@ gh release create vX.Y.Z --title "vX.Y.Z - Title" --notes "..."
136
148
 
137
149
  | File | Owner | Edit? |
138
150
  |------|-------|-------|
139
- | INVAR.md | **Source** | Yes (this IS the source) |
140
- | CLAUDE.md | User | Yes |
151
+ | src/invar/templates/ | **SSOT** | Yes (templates are source) |
152
+ | INVAR.md | Sync | No (`invar dev sync`) |
153
+ | CLAUDE.md | Sync + User | Regions only |
141
154
  | .invar/context.md | User | Yes (this file) |
142
- | .invar/examples/ | Sync | `invar update --force` |
155
+ | .invar/examples/ | Sync | `invar dev sync` |
143
156
 
144
- **Note:** This is the Invar project. INVAR.md is the **source**, not a copy.
157
+ **Version Flow:** `templates/` Invar project (via `invar dev sync`, syntax=mcp) AND → User projects (via `invar init/update`, syntax=cli)
145
158
 
146
159
  ---
147
160
 
@@ -136,6 +136,105 @@ Code Health: 100%
136
136
  # If triggered: invoke /review sub-agent before completion
137
137
  ```
138
138
 
139
+ ## Interleaved SPECIFY/BUILD (DX-63)
140
+
141
+ For multi-function tasks, use **interleaved** pattern instead of batch creation.
142
+
143
+ ### ❌ Wrong: Batch Creation
144
+
145
+ ```
146
+ # Creates 5 files at once, then fills implementations
147
+ 1. Create file1.py, file2.py, file3.py, file4.py, file5.py (skeletons)
148
+ 2. Implement all functions
149
+ 3. Run guard → 40 missing_contract errors
150
+ 4. Retrofit contracts (descriptive, not prescriptive)
151
+ ```
152
+
153
+ ### ✅ Correct: Interleaved Pattern
154
+
155
+ ```
156
+ TodoList:
157
+ □ [SPECIFY] Write contracts for parser.py
158
+ □ [BUILD] Implement parser.py
159
+ □ [SPECIFY] Write contracts for validator.py
160
+ □ [BUILD] Implement validator.py
161
+ □ [SPECIFY] Write contracts for formatter.py
162
+ □ [BUILD] Implement formatter.py
163
+ ```
164
+
165
+ ### Function-Level Gates
166
+
167
+ For each file:
168
+
169
+ ```python
170
+ # Step 1: Create file with contracts only (body = ...)
171
+ @pre(lambda text: len(text) > 0)
172
+ @post(lambda result: all(isinstance(t, Token) for t in result))
173
+ def tokenize(text: str) -> list[Token]:
174
+ """Tokenize input text."""
175
+ ...
176
+
177
+ @pre(lambda tokens: len(tokens) > 0)
178
+ @post(lambda result: isinstance(result, AST))
179
+ def parse(tokens: list[Token]) -> AST:
180
+ """Parse tokens into AST."""
181
+ ...
182
+ ```
183
+
184
+ ```bash
185
+ # Step 2: Verify contract coverage
186
+ $ invar guard -c src/core/parser.py
187
+ Contract Coverage Check
188
+ ========================================
189
+ Files: 1 | Functions: 2
190
+
191
+ Coverage: 2/2 (100%) ✓
192
+ Trivial: 0/2 (0%) ✓
193
+
194
+ Ready for BUILD phase.
195
+ ```
196
+
197
+ ```python
198
+ # Step 3: Implement (only after coverage check passes)
199
+ @pre(lambda text: len(text) > 0)
200
+ @post(lambda result: all(isinstance(t, Token) for t in result))
201
+ def tokenize(text: str) -> list[Token]:
202
+ """
203
+ Tokenize input text.
204
+
205
+ >>> tokenize("hello world")
206
+ [Token('hello'), Token('world')]
207
+ """
208
+ return [Token(word) for word in text.split()]
209
+ ```
210
+
211
+ ```bash
212
+ # Step 4: Full verification
213
+ $ invar guard --changed
214
+ Guard passed.
215
+
216
+ # Step 5: Proceed to next file
217
+ ```
218
+
219
+ ### Violation Self-Check
220
+
221
+ Before writing ANY implementation code, ask:
222
+
223
+ 1. "Have I written the contract for THIS function?"
224
+ 2. "Have I shown it in my response?"
225
+ 3. "Have I run `invar guard -c`?"
226
+
227
+ If any NO → Stop. Write contract first.
228
+
229
+ ### Benefits
230
+
231
+ | Without DX-63 | With DX-63 |
232
+ |---------------|------------|
233
+ | 81 errors at end | 0 errors |
234
+ | 4+ guard cycles | 1 cycle |
235
+ | ~7000 tokens | ~4000 tokens |
236
+ | Descriptive contracts | Prescriptive contracts |
237
+
139
238
  ## When to Use Visible Workflow
140
239
 
141
240
  Use for:
@@ -8,33 +8,36 @@
8
8
  | **Shell** | Returns `Result[T, E]` from `returns` library |
9
9
  | **Flow** | USBV: Understand → Specify → Build → Validate |
10
10
 
11
- <!--/invar:critical--><!--invar:managed version="5.0"-->
12
- # Project Development Guide
11
+ ### Contract Rules (CRITICAL)
13
12
 
14
- > **Protocol:** Follow [INVAR.md](./INVAR.md) — includes Check-In, USBV workflow, and Task Completion requirements.
13
+ ```python
14
+ # ❌ WRONG: Lambda must include ALL parameters
15
+ @pre(lambda x: x >= 0)
16
+ def calc(x: int, y: int = 0): ...
15
17
 
16
- ## Check-In (DX-54)
18
+ # CORRECT: Include defaults too
19
+ @pre(lambda x, y=0: x >= 0)
20
+ def calc(x: int, y: int = 0): ...
17
21
 
18
- Your first message MUST display:
22
+ # WRONG: @post cannot access parameters
23
+ @post(lambda result: result > x) # 'x' not available!
19
24
 
20
- ```
21
- Check-In: [project] | [branch] | [clean/dirty]
25
+ # ✅ CORRECT: @post only sees 'result'
26
+ @post(lambda result: result >= 0)
22
27
  ```
23
28
 
24
- Actions:
25
- 1. Read `.invar/context.md` (Key Rules + Current State + Lessons Learned)
26
- 2. Show one-line status
29
+ <!--/invar:critical--><!--invar:managed version="5.0"-->
30
+ # Project Development Guide
27
31
 
28
- Example:
29
- ```
30
- ✓ Check-In: MyProject | main | clean
31
- ```
32
+ > **Protocol:** Follow [INVAR.md](./INVAR.md) — includes Check-In, USBV workflow, and Task Completion requirements.
32
33
 
33
- **Do NOT execute guard or map at Check-In.**
34
- Guard is for VALIDATE phase and Final only.
34
+ ## Check-In
35
35
 
36
- This is your sign-in. The user sees it immediately.
37
- No visible check-in = Session not started.
36
+ > See [INVAR.md#check-in](./INVAR.md#check-in-required) for full protocol.
37
+
38
+ **Your first message MUST display:** `✓ Check-In: [project] | [branch] | [clean/dirty]`
39
+
40
+ **Actions:** Read `.invar/context.md`, then show status. Do NOT run guard at Check-In.
38
41
 
39
42
  ---
40
43
 
@@ -70,6 +73,14 @@ src/{project}/
70
73
  | Core | `@pre`/`@post` + doctests, pure (no I/O) |
71
74
  | Shell | Returns `Result[T, E]` from `returns` library |
72
75
 
76
+ ### Core vs Shell (Edge Cases)
77
+
78
+ - File/network/env vars → **Shell**
79
+ - `datetime.now()`, `random` → **Inject param** OR Shell
80
+ - Pure logic → **Core**
81
+
82
+ > Full decision tree: [INVAR.md#core-shell](./INVAR.md#decision-tree-core-vs-shell)
83
+
73
84
  ## Documentation Structure
74
85
 
75
86
  | File | Owner | Edit? | Purpose |
@@ -80,6 +91,8 @@ src/{project}/
80
91
  | .invar/project-additions.md | User | Yes | Project rules → injected into CLAUDE.md |
81
92
  | .invar/examples/ | Invar | No | **Must read:** Core/Shell patterns, workflow |
82
93
 
94
+ > **Before writing code:** Check Task Router in `.invar/context.md`
95
+
83
96
  ## Visible Workflow (DX-30)
84
97
 
85
98
  For complex tasks (3+ functions), show 3 checkpoints in TodoList:
@@ -150,18 +163,26 @@ Guard triggers `review_suggested` for: security-sensitive files, escape hatches
150
163
 
151
164
  ## Workflow Routing (MANDATORY)
152
165
 
153
- When user message contains these triggers, you MUST invoke the corresponding skill:
166
+ When user message contains these triggers, you MUST use the **Skill tool** to invoke the skill:
167
+
168
+ | Trigger Words | Skill Tool Call | Notes |
169
+ |---------------|-----------------|-------|
170
+ | "review", "review and fix" | `Skill(skill="review")` | Adversarial review with fix loop |
171
+ | "implement", "add", "fix", "update" | `Skill(skill="develop")` | Unless in review context |
172
+ | "why", "explain", "investigate" | `Skill(skill="investigate")` | Research mode, no code changes |
173
+ | "compare", "should we", "design" | `Skill(skill="propose")` | Decision facilitation |
174
+
175
+ **⚠️ CRITICAL: You must call the Skill tool, not just follow the workflow mentally.**
154
176
 
155
- | Trigger Words | Skill | Notes |
156
- |---------------|-------|-------|
157
- | "review", "review and fix" | `/review` | Adversarial review with fix loop |
158
- | "implement", "add", "fix", "update" | `/develop` | Unless in review context |
159
- | "why", "explain", "investigate" | `/investigate` | Research mode, no code changes |
160
- | "compare", "should we", "design" | `/propose` | Decision facilitation |
177
+ The Skill tool reads `.claude/skills/<skill>/SKILL.md` which contains:
178
+ - Detailed phase instructions (USBV breakdown)
179
+ - Error handling rules
180
+ - Timeout policies
181
+ - Incremental development patterns (DX-63)
161
182
 
162
183
  **Violation check (before writing ANY code):**
163
- - "Am I in a workflow?"
164
- - "Did I invoke the correct skill?"
184
+ - "Did I call `Skill(skill="...")`?"
185
+ - "Am I following the SKILL.md instructions?"
165
186
 
166
187
  ---
167
188
 
@@ -241,7 +262,7 @@ pip install -e runtime/ # Runtime in dev mode
241
262
  <!-- ========================================================================
242
263
  USER REGION - EDITABLE
243
264
  Add your team conventions and project-specific rules below.
244
- This section is preserved across invar update and sync-self.
265
+ This section is preserved across `invar update` and `invar dev sync`.
245
266
  ======================================================================== -->
246
267
  <!--/invar:user-->
247
268
 
@@ -267,6 +267,7 @@ invar guard # Full: static + doctests + CrossHair + Hypothesis
267
267
  invar guard --static # Static only (quick debug, ~0.5s)
268
268
  invar guard --changed # Modified files only
269
269
  invar guard --coverage # Collect branch coverage
270
+ invar guard -c # Contract coverage only (DX-63)
270
271
  invar sig <file> # Show contracts + signatures
271
272
  invar map --top 10 # Most-referenced symbols
272
273
  invar rules # List all rules with detection/hints (JSON)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: invar-tools
3
- Version: 1.5.0
3
+ Version: 1.7.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
@@ -252,7 +252,7 @@ class PatternSuggestion:
252
252
 
253
253
  ### Phase 1: Context.md Task Router (Low Risk)
254
254
  - Add Task Router section to context.md template
255
- - Update existing projects via `invar sync-self`
255
+ - Update existing projects via `invar dev sync`
256
256
  - No behavior change required, just improved guidance
257
257
 
258
258
  ### Phase 2: Pre-Flight Confirmation (Medium Risk)
@@ -0,0 +1,104 @@
1
+ # DX-64: 版本显示统一
2
+
3
+ ## 问题描述
4
+
5
+ `invar version` 命令显示 `1.0.0`,但实际 PyPI 包版本是 `1.5.0`。
6
+
7
+ ### 当前行为
8
+
9
+ ```bash
10
+ $ invar version
11
+ invar 1.0.0
12
+
13
+ $ pip show invar-tools | grep Version
14
+ Version: 1.5.0
15
+ ```
16
+
17
+ ### 问题影响
18
+
19
+ 1. **用户困惑** - 不清楚实际安装的版本
20
+ 2. **故障排除困难** - 报告问题时版本信息不准确
21
+ 3. **升级验证困难** - 无法确认升级是否成功
22
+
23
+ ## 提案方案
24
+
25
+ ### 方案 A: 显示包版本 (推荐)
26
+
27
+ 从 `importlib.metadata` 获取实际包版本:
28
+
29
+ ```python
30
+ import importlib.metadata
31
+
32
+ @app.command()
33
+ def version() -> None:
34
+ """Show Invar version."""
35
+ pkg_version = importlib.metadata.version("invar-tools")
36
+ console.print(f"invar-tools {pkg_version}")
37
+ ```
38
+
39
+ **输出:**
40
+ ```
41
+ invar-tools 1.5.0
42
+ ```
43
+
44
+ ### 方案 B: 同时显示包版本和协议版本
45
+
46
+ ```python
47
+ @app.command()
48
+ def version() -> None:
49
+ """Show Invar version."""
50
+ pkg_version = importlib.metadata.version("invar-tools")
51
+ protocol_version = "5.0" # 从 INVAR.md 或配置读取
52
+ console.print(f"invar-tools {pkg_version}")
53
+ console.print(f"protocol {protocol_version}")
54
+ ```
55
+
56
+ **输出:**
57
+ ```
58
+ invar-tools 1.5.0
59
+ protocol 5.0
60
+ ```
61
+
62
+ ### 方案 C: 详细版本信息
63
+
64
+ ```python
65
+ @app.command()
66
+ def version(verbose: bool = False) -> None:
67
+ """Show Invar version."""
68
+ pkg_version = importlib.metadata.version("invar-tools")
69
+
70
+ if verbose:
71
+ console.print(f"invar-tools: {pkg_version}")
72
+ console.print(f"protocol: 5.0")
73
+ console.print(f"python: {sys.version.split()[0]}")
74
+ console.print(f"platform: {sys.platform}")
75
+ else:
76
+ console.print(f"invar-tools {pkg_version}")
77
+ ```
78
+
79
+ ## 实现计划
80
+
81
+ 1. 修改 `src/invar/shell/commands/guard.py` 中的 `version` 命令
82
+ 2. 使用 `importlib.metadata.version()` 获取包版本
83
+ 3. 可选: 添加 `--verbose` 标志显示详细信息
84
+
85
+ ## 影响评估
86
+
87
+ | 维度 | 影响 |
88
+ |------|------|
89
+ | 复杂度 | 低 |
90
+ | 风险 | 低 |
91
+ | 向后兼容 | 是 (输出格式变化) |
92
+ | 测试 | 需更新版本测试 |
93
+
94
+ ## 决策
95
+
96
+ **推荐方案 A** - 简单直接,解决核心问题。
97
+
98
+ ---
99
+
100
+ *提案状态: ✅ 已完成*
101
+ *创建日期: 2025-12-29*
102
+ *完成日期: 2025-12-29*
103
+ *来源: v1.5.0 测试报告 V150-01*
104
+ *实现: commit c1a446e*
@@ -0,0 +1,157 @@
1
+ # DX-65: Guard 单文件支持
2
+
3
+ ## 问题描述
4
+
5
+ `invar guard` 命令只接受目录路径,不支持单文件验证。
6
+
7
+ ### 当前行为
8
+
9
+ ```bash
10
+ $ invar guard src/core/calculator.py
11
+ Error: Invalid value for '[PATH]': Directory 'src/core/calculator.py' is a file.
12
+ ```
13
+
14
+ ### 用户场景
15
+
16
+ 1. **快速验证单个文件** - 修改一个文件后想快速检查
17
+ 2. **精确定位问题** - 已知问题在某文件,只想检查该文件
18
+ 3. **CI/CD 优化** - 只验证 PR 中变更的文件
19
+
20
+ ## 提案方案
21
+
22
+ ### 方案 A: 自动检测路径类型 (推荐)
23
+
24
+ ```python
25
+ @app.command()
26
+ def guard(
27
+ path: Path = typer.Argument(
28
+ Path("."),
29
+ help="Project root directory or single file",
30
+ exists=True,
31
+ ),
32
+ ...
33
+ ) -> None:
34
+ if path.is_file():
35
+ # 单文件模式
36
+ files_to_check = [path]
37
+ else:
38
+ # 目录模式
39
+ files_to_check = find_python_files(path)
40
+ ```
41
+
42
+ **用法:**
43
+ ```bash
44
+ invar guard src/core/calculator.py # 单文件
45
+ invar guard src/core/ # 目录
46
+ invar guard # 项目根目录
47
+ ```
48
+
49
+ ### 方案 B: 显式标志
50
+
51
+ ```python
52
+ @app.command()
53
+ def guard(
54
+ path: Path = ...,
55
+ file: bool = typer.Option(False, "--file", "-f", help="Treat path as file"),
56
+ ...
57
+ ) -> None:
58
+ if file:
59
+ files_to_check = [path]
60
+ else:
61
+ files_to_check = find_python_files(path)
62
+ ```
63
+
64
+ **用法:**
65
+ ```bash
66
+ invar guard -f src/core/calculator.py
67
+ invar guard --file src/core/calculator.py
68
+ ```
69
+
70
+ ### 方案 C: 多路径支持
71
+
72
+ ```python
73
+ @app.command()
74
+ def guard(
75
+ paths: list[Path] = typer.Argument(
76
+ [Path(".")],
77
+ help="Files or directories to check",
78
+ ),
79
+ ...
80
+ ) -> None:
81
+ files_to_check = []
82
+ for path in paths:
83
+ if path.is_file():
84
+ files_to_check.append(path)
85
+ else:
86
+ files_to_check.extend(find_python_files(path))
87
+ ```
88
+
89
+ **用法:**
90
+ ```bash
91
+ invar guard src/core/calculator.py src/core/validator.py
92
+ invar guard src/core/*.py # Shell 展开
93
+ ```
94
+
95
+ ## 实现细节
96
+
97
+ ### 配置加载
98
+
99
+ 单文件模式仍需加载项目配置:
100
+
101
+ ```python
102
+ def guard_single_file(file_path: Path) -> Result[GuardReport, str]:
103
+ # 向上查找 pyproject.toml 或 invar.toml
104
+ project_root = find_project_root(file_path)
105
+ config = load_config(project_root)
106
+
107
+ # 确定文件分类 (Core/Shell)
108
+ classification = classify_file(file_path, config)
109
+
110
+ # 运行相应规则
111
+ return run_rules(file_path, classification, config)
112
+ ```
113
+
114
+ ### 输出格式
115
+
116
+ 单文件模式可简化输出:
117
+
118
+ ```json
119
+ {
120
+ "status": "passed",
121
+ "file": "src/core/calculator.py",
122
+ "classification": "core",
123
+ "errors": 0,
124
+ "warnings": 1,
125
+ "fixes": [...]
126
+ }
127
+ ```
128
+
129
+ ## 与现有功能的交互
130
+
131
+ | 功能 | 单文件支持 | 说明 |
132
+ |------|------------|------|
133
+ | `--changed` | 兼容 | 如果文件未变更,跳过 |
134
+ | `-c` (contracts-only) | 兼容 | 只检查该文件合约 |
135
+ | `--coverage` | 需调整 | 覆盖率只针对单文件 |
136
+ | `--strict` | 兼容 | 应用于单文件 |
137
+
138
+ ## 影响评估
139
+
140
+ | 维度 | 影响 |
141
+ |------|------|
142
+ | 复杂度 | 中 |
143
+ | 风险 | 低 |
144
+ | 向后兼容 | 是 |
145
+ | 测试 | 需新增单文件测试 |
146
+
147
+ ## 决策
148
+
149
+ **推荐方案 A** - 自动检测最符合用户直觉。
150
+
151
+ ---
152
+
153
+ *提案状态: ✅ 已完成*
154
+ *创建日期: 2025-12-29*
155
+ *完成日期: 2025-12-29*
156
+ *来源: v1.5.0 测试报告 V150-02*
157
+ *实现: commit 6eeaf9e*