tasca 0.1.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 (181) hide show
  1. tasca-0.1.0/.agents/commands/audit.md +146 -0
  2. tasca-0.1.0/.agents/commands/guard.md +83 -0
  3. tasca-0.1.0/.agents/instructions.md +370 -0
  4. tasca-0.1.0/.agents/mcp.json +9 -0
  5. tasca-0.1.0/.agents/skills/develop/SKILL.md +435 -0
  6. tasca-0.1.0/.agents/skills/invar-reflect/CONFIG.md +480 -0
  7. tasca-0.1.0/.agents/skills/invar-reflect/SKILL.md +466 -0
  8. tasca-0.1.0/.agents/skills/invar-reflect/template.md +343 -0
  9. tasca-0.1.0/.agents/skills/investigate/SKILL.md +105 -0
  10. tasca-0.1.0/.agents/skills/propose/SKILL.md +130 -0
  11. tasca-0.1.0/.agents/skills/review/SKILL.md +325 -0
  12. tasca-0.1.0/.env.example +95 -0
  13. tasca-0.1.0/.github/workflows/publish.yml +19 -0
  14. tasca-0.1.0/.gitignore +84 -0
  15. tasca-0.1.0/.pre-commit-config.yaml +47 -0
  16. tasca-0.1.0/INVAR.md +434 -0
  17. tasca-0.1.0/LICENSE +661 -0
  18. tasca-0.1.0/PKG-INFO +175 -0
  19. tasca-0.1.0/README.md +138 -0
  20. tasca-0.1.0/docs/adr-001-mermaid-rendering.md +75 -0
  21. tasca-0.1.0/docs/adr-002-mermaid-svg-sanitization.md +122 -0
  22. tasca-0.1.0/docs/deployment-ops-v0.1.md +66 -0
  23. tasca-0.1.0/docs/e2e-testing.md +158 -0
  24. tasca-0.1.0/docs/frontend-stack-and-integration-v0.1.md +81 -0
  25. tasca-0.1.0/docs/implementation-readiness-checklist.md +100 -0
  26. tasca-0.1.0/docs/repo-structure-v0.1.md +201 -0
  27. tasca-0.1.0/docs/spec-conformance-note-v0.1.md +75 -0
  28. tasca-0.1.0/docs/tasca-data-schema-v0.1.md +105 -0
  29. tasca-0.1.0/docs/tasca-design-notes.md +234 -0
  30. tasca-0.1.0/docs/tasca-http-api-v0.1.md +111 -0
  31. tasca-0.1.0/docs/tasca-interaction-design-v0.2.md +337 -0
  32. tasca-0.1.0/docs/tasca-mcp-interface-v0.1.md +543 -0
  33. tasca-0.1.0/docs/tasca-search-export-v0.1.md +85 -0
  34. tasca-0.1.0/docs/tasca-technical-design-v0.1.md +367 -0
  35. tasca-0.1.0/docs/tasca-web-uiux-v0.1.md +314 -0
  36. tasca-0.1.0/docs/terminology-mapping-v0.1.md +107 -0
  37. tasca-0.1.0/plan.yaml +14864 -0
  38. tasca-0.1.0/pyproject.toml +108 -0
  39. tasca-0.1.0/scripts/run-e2e-external-server.sh +232 -0
  40. tasca-0.1.0/src/tasca/__init__.py +8 -0
  41. tasca-0.1.0/src/tasca/cli.py +635 -0
  42. tasca-0.1.0/src/tasca/config.py +110 -0
  43. tasca-0.1.0/src/tasca/core/__init__.py +11 -0
  44. tasca-0.1.0/src/tasca/core/_word_lists.py +132 -0
  45. tasca-0.1.0/src/tasca/core/contracts.py +35 -0
  46. tasca-0.1.0/src/tasca/core/domain/__init__.py +7 -0
  47. tasca-0.1.0/src/tasca/core/domain/patron.py +33 -0
  48. tasca-0.1.0/src/tasca/core/domain/saying.py +174 -0
  49. tasca-0.1.0/src/tasca/core/domain/seat.py +46 -0
  50. tasca-0.1.0/src/tasca/core/domain/table.py +81 -0
  51. tasca-0.1.0/src/tasca/core/human_readable_ids.py +352 -0
  52. tasca-0.1.0/src/tasca/core/schema.py +393 -0
  53. tasca-0.1.0/src/tasca/core/services/__init__.py +8 -0
  54. tasca-0.1.0/src/tasca/core/services/dedup_cleanup_service.py +202 -0
  55. tasca-0.1.0/src/tasca/core/services/dedup_service.py +110 -0
  56. tasca-0.1.0/src/tasca/core/services/limits_service.py +479 -0
  57. tasca-0.1.0/src/tasca/core/services/mention_service.py +448 -0
  58. tasca-0.1.0/src/tasca/core/services/saying_service.py +169 -0
  59. tasca-0.1.0/src/tasca/core/services/seat_service.py +332 -0
  60. tasca-0.1.0/src/tasca/core/services/table_service.py +261 -0
  61. tasca-0.1.0/src/tasca/core/svg_sanitizer.py +312 -0
  62. tasca-0.1.0/src/tasca/core/svg_sanitizer_internal.py +241 -0
  63. tasca-0.1.0/src/tasca/core/table_state_machine.py +305 -0
  64. tasca-0.1.0/src/tasca/main.py +84 -0
  65. tasca-0.1.0/src/tasca/shell/__init__.py +8 -0
  66. tasca-0.1.0/src/tasca/shell/api/__init__.py +7 -0
  67. tasca-0.1.0/src/tasca/shell/api/app.py +233 -0
  68. tasca-0.1.0/src/tasca/shell/api/auth.py +93 -0
  69. tasca-0.1.0/src/tasca/shell/api/deps.py +65 -0
  70. tasca-0.1.0/src/tasca/shell/api/routes/__init__.py +7 -0
  71. tasca-0.1.0/src/tasca/shell/api/routes/export.py +326 -0
  72. tasca-0.1.0/src/tasca/shell/api/routes/health.py +36 -0
  73. tasca-0.1.0/src/tasca/shell/api/routes/patrons.py +159 -0
  74. tasca-0.1.0/src/tasca/shell/api/routes/sayings.py +513 -0
  75. tasca-0.1.0/src/tasca/shell/api/routes/search.py +154 -0
  76. tasca-0.1.0/src/tasca/shell/api/routes/seats.py +161 -0
  77. tasca-0.1.0/src/tasca/shell/api/routes/tables.py +305 -0
  78. tasca-0.1.0/src/tasca/shell/logging.py +229 -0
  79. tasca-0.1.0/src/tasca/shell/mcp/__init__.py +9 -0
  80. tasca-0.1.0/src/tasca/shell/mcp/database.py +104 -0
  81. tasca-0.1.0/src/tasca/shell/mcp/proxy.py +642 -0
  82. tasca-0.1.0/src/tasca/shell/mcp/responses.py +55 -0
  83. tasca-0.1.0/src/tasca/shell/mcp/server.py +2302 -0
  84. tasca-0.1.0/src/tasca/shell/services/limited_saying_service.py +123 -0
  85. tasca-0.1.0/src/tasca/shell/services/table_id_generator.py +105 -0
  86. tasca-0.1.0/src/tasca/shell/storage/__init__.py +8 -0
  87. tasca-0.1.0/src/tasca/shell/storage/database.py +302 -0
  88. tasca-0.1.0/src/tasca/shell/storage/dedup_repo.py +551 -0
  89. tasca-0.1.0/src/tasca/shell/storage/idempotency_repo.py +237 -0
  90. tasca-0.1.0/src/tasca/shell/storage/patron_repo.py +251 -0
  91. tasca-0.1.0/src/tasca/shell/storage/saying_repo.py +465 -0
  92. tasca-0.1.0/src/tasca/shell/storage/search_repo.py +576 -0
  93. tasca-0.1.0/src/tasca/shell/storage/seat_repo.py +445 -0
  94. tasca-0.1.0/src/tasca/shell/storage/table_repo.py +441 -0
  95. tasca-0.1.0/tests/__init__.py +3 -0
  96. tasca-0.1.0/tests/conftest.py +11 -0
  97. tasca-0.1.0/tests/integration/__init__.py +5 -0
  98. tasca-0.1.0/tests/integration/conftest.py +473 -0
  99. tasca-0.1.0/tests/integration/harness.py +1054 -0
  100. tasca-0.1.0/tests/integration/test_api.py +371 -0
  101. tasca-0.1.0/tests/integration/test_cli.py +442 -0
  102. tasca-0.1.0/tests/integration/test_mcp.py +1204 -0
  103. tasca-0.1.0/tests/integration/test_mcp_proxy.py +239 -0
  104. tasca-0.1.0/tests/repro/conftest.py +11 -0
  105. tasca-0.1.0/tests/repro/issue_l3_error_paths.py +953 -0
  106. tasca-0.1.0/tests/repro/issue_l3_mcp_smoke.py +713 -0
  107. tasca-0.1.0/tests/unit/__init__.py +5 -0
  108. tasca-0.1.0/tests/unit/api/__init__.py +0 -0
  109. tasca-0.1.0/tests/unit/api/test_csp_middleware.py +246 -0
  110. tasca-0.1.0/tests/unit/api/test_export_routes.py +402 -0
  111. tasca-0.1.0/tests/unit/api/test_patrons_routes.py +241 -0
  112. tasca-0.1.0/tests/unit/api/test_sayings_routes.py +637 -0
  113. tasca-0.1.0/tests/unit/api/test_search_routes.py +302 -0
  114. tasca-0.1.0/tests/unit/api/test_seats_routes.py +425 -0
  115. tasca-0.1.0/tests/unit/api/test_tables_routes.py +504 -0
  116. tasca-0.1.0/tests/unit/mcp/test_mcp_server.py +2108 -0
  117. tasca-0.1.0/tests/unit/mcp/test_proxy.py +832 -0
  118. tasca-0.1.0/tests/unit/mcp/test_proxy_middleware.py +495 -0
  119. tasca-0.1.0/tests/unit/services/__init__.py +1 -0
  120. tasca-0.1.0/tests/unit/services/test_table_id_generator.py +210 -0
  121. tasca-0.1.0/tests/unit/storage/__init__.py +0 -0
  122. tasca-0.1.0/tests/unit/storage/test_search_repo.py +699 -0
  123. tasca-0.1.0/tests/unit/storage/test_table_repo.py +334 -0
  124. tasca-0.1.0/tests/unit/test_cli.py +665 -0
  125. tasca-0.1.0/tests/unit/test_dedup.py +474 -0
  126. tasca-0.1.0/tests/unit/test_dedup_cleanup.py +524 -0
  127. tasca-0.1.0/tests/unit/test_human_readable_ids.py +930 -0
  128. tasca-0.1.0/tests/unit/test_limits_service.py +565 -0
  129. tasca-0.1.0/tests/unit/test_logging_observability.py +291 -0
  130. tasca-0.1.0/tests/unit/test_mention.py +488 -0
  131. tasca-0.1.0/tests/unit/test_saying.py +873 -0
  132. tasca-0.1.0/tests/unit/test_seat_ttl.py +721 -0
  133. tasca-0.1.0/tests/unit/test_svg_sanitizer.py +898 -0
  134. tasca-0.1.0/tests/unit/test_table.py +224 -0
  135. tasca-0.1.0/tests/unit/test_table_version.py +588 -0
  136. tasca-0.1.0/uv.lock +2015 -0
  137. tasca-0.1.0/web/index.html +13 -0
  138. tasca-0.1.0/web/package-lock.json +7816 -0
  139. tasca-0.1.0/web/package.json +41 -0
  140. tasca-0.1.0/web/public/vite.svg +1 -0
  141. tasca-0.1.0/web/src/App.tsx +21 -0
  142. tasca-0.1.0/web/src/api/AuthConnector.tsx +22 -0
  143. tasca-0.1.0/web/src/api/client.ts +104 -0
  144. tasca-0.1.0/web/src/api/patrons.ts +64 -0
  145. tasca-0.1.0/web/src/api/sayings.ts +202 -0
  146. tasca-0.1.0/web/src/api/tables.ts +183 -0
  147. tasca-0.1.0/web/src/auth/AuthContext.tsx +183 -0
  148. tasca-0.1.0/web/src/components/Board.tsx +92 -0
  149. tasca-0.1.0/web/src/components/CommandConsole.test.tsx +357 -0
  150. tasca-0.1.0/web/src/components/CommandConsole.tsx +182 -0
  151. tasca-0.1.0/web/src/components/ConfirmDialog.tsx +159 -0
  152. tasca-0.1.0/web/src/components/MentionInput.tsx +421 -0
  153. tasca-0.1.0/web/src/components/ModeIndicator.css +200 -0
  154. tasca-0.1.0/web/src/components/ModeIndicator.tsx +178 -0
  155. tasca-0.1.0/web/src/components/RequestSummaryButton.tsx +185 -0
  156. tasca-0.1.0/web/src/components/SeatDeck.tsx +453 -0
  157. tasca-0.1.0/web/src/components/Stream.tsx +337 -0
  158. tasca-0.1.0/web/src/components/TableControls.tsx +188 -0
  159. tasca-0.1.0/web/src/components/index.ts +19 -0
  160. tasca-0.1.0/web/src/constants/presence.ts +9 -0
  161. tasca-0.1.0/web/src/hooks/useLongPoll.ts +276 -0
  162. tasca-0.1.0/web/src/main.tsx +10 -0
  163. tasca-0.1.0/web/src/rendering/markdown.security.test.tsx +229 -0
  164. tasca-0.1.0/web/src/rendering/markdown.tsx +82 -0
  165. tasca-0.1.0/web/src/rendering/math.security.test.tsx +500 -0
  166. tasca-0.1.0/web/src/rendering/math.tsx +327 -0
  167. tasca-0.1.0/web/src/rendering/mermaid.security.test.ts +365 -0
  168. tasca-0.1.0/web/src/rendering/mermaid.tsx +300 -0
  169. tasca-0.1.0/web/src/rendering/svg-sanitizer.security.test.ts +324 -0
  170. tasca-0.1.0/web/src/rendering/svg-sanitizer.ts +402 -0
  171. tasca-0.1.0/web/src/routes/Table.tsx +349 -0
  172. tasca-0.1.0/web/src/routes/Watchtower.tsx +495 -0
  173. tasca-0.1.0/web/src/styles/dialog.css +122 -0
  174. tasca-0.1.0/web/src/styles/index.css +31 -0
  175. tasca-0.1.0/web/src/styles/table.css +1805 -0
  176. tasca-0.1.0/web/src/styles/watchtower.css +659 -0
  177. tasca-0.1.0/web/src/test/setup.ts +5 -0
  178. tasca-0.1.0/web/tsconfig.json +25 -0
  179. tasca-0.1.0/web/tsconfig.node.json +11 -0
  180. tasca-0.1.0/web/tsconfig.tsbuildinfo +1 -0
  181. tasca-0.1.0/web/vite.config.ts +21 -0
@@ -0,0 +1,146 @@
1
+ ---
2
+ _invar:
3
+ version: "5.0"
4
+ type: command
5
+ ---
6
+
7
+ # Audit
8
+
9
+ Read-only code review. Reports issues without fixing them.
10
+
11
+ ---
12
+
13
+ ## Behavior
14
+
15
+ 1. Analyze code for issues (style, bugs, security, architecture)
16
+ 2. Report findings with file:line references
17
+ 3. **Do NOT make any changes** - report only
18
+
19
+ ---
20
+
21
+ ## Adversarial Reviewer Persona
22
+
23
+ You are an **adversarial code reviewer**. Your job is to FIND PROBLEMS.
24
+
25
+ ### Your Mindset
26
+
27
+ Assume:
28
+ - The code has bugs until proven otherwise
29
+ - The contracts may be meaningless ceremony
30
+ - The implementer may have rationalized poor decisions
31
+ - Escape hatches may be abused
32
+
33
+ You are NOT here to:
34
+ - Validate that code works
35
+ - Confirm the implementer did a good job
36
+ - Be nice or diplomatic
37
+
38
+ You ARE here to:
39
+ - Find bugs, logic errors, edge cases
40
+ - Challenge whether contracts have semantic value
41
+ - Identify code smells and duplication
42
+ - Question every escape hatch
43
+ - Check if code matches contracts (not if code "seems right")
44
+
45
+ **Your success is measured by problems found, not code approved.**
46
+
47
+ ---
48
+
49
+ ## Review Checklist
50
+
51
+ > **Principle:** Only items requiring semantic judgment. Mechanical checks are excluded (see bottom).
52
+
53
+ ### A. Contract Semantic Value
54
+
55
+ - [ ] Does @pre constrain inputs beyond type checking?
56
+ - Bad: `@pre(lambda x: isinstance(x, int))`
57
+ - Good: `@pre(lambda x: x > 0 and x < MAX_VALUE)`
58
+ - [ ] Does @post verify meaningful output properties?
59
+ - Bad: `@post(lambda result: result is not None)`
60
+ - Good: `@post(lambda result: len(result) == len(input))`
61
+
62
+ - [ ] Could someone implement correctly from contracts alone?
63
+ - [ ] Are boundary conditions explicit in contracts?
64
+
65
+ ### B. Doctest Coverage
66
+ - [ ] Do doctests cover normal cases?
67
+ - [ ] Do doctests cover boundary cases?
68
+ - [ ] Do doctests cover error cases?
69
+ - [ ] Are doctests testing behavior, not just syntax?
70
+
71
+ ### C. Code Quality
72
+ - [ ] Is duplicated code worth extracting?
73
+ - [ ] Is naming consistent and clear?
74
+ - [ ] Is complexity justified?
75
+
76
+ ### D. Escape Hatch Audit
77
+ - [ ] Is each @invar:allow justification valid?
78
+ - [ ] Could refactoring eliminate the need?
79
+ - [ ] Is there a pattern suggesting systematic issues?
80
+
81
+ ### E. Logic Verification
82
+ - [ ] Do contracts correctly capture intended behavior?
83
+ - [ ] Are there paths that bypass contract checks?
84
+ - [ ] Are there implicit assumptions not in contracts?
85
+ - [ ] What happens with unexpected inputs?
86
+
87
+ ### F. Security
88
+ - [ ] Are inputs validated against security threats (injection, XSS)?
89
+ - [ ] No hardcoded secrets (API keys, passwords, tokens)?
90
+ - [ ] Are authentication/authorization checks correct?
91
+ - [ ] Is sensitive data properly protected?
92
+
93
+ ### G. Error Handling & Observability
94
+ - [ ] Are exceptions caught at appropriate level?
95
+ - [ ] Are error messages clear without leaking sensitive info?
96
+ - [ ] Are critical operations logged for debugging?
97
+ - [ ] Is there graceful degradation on failure?
98
+
99
+ ---
100
+
101
+ ## Excluded (Covered by Guard)
102
+
103
+ These are checked by Guard or linters - don't duplicate:
104
+ - Core/Shell separation → Guard (forbidden_import, impure_call)
105
+ - Shell returns Result[T,E] → Guard (shell_result)
106
+ - Missing contracts → Guard (missing_contract)
107
+ - File/function size limits → Guard (file_size, function_size)
108
+ - Entry point thickness → Guard (entry_point_too_thick)
109
+ - Escape hatch count → Guard (review_suggested)
110
+
111
+ ---
112
+
113
+ ## Report Format
114
+
115
+ For each issue found, use severity levels:
116
+
117
+ | Severity | Meaning |
118
+ |----------|---------|
119
+ | **CRITICAL** | Must fix before completion |
120
+ | **MAJOR** | Fix or provide written justification |
121
+ | **MINOR** | Optional, can defer |
122
+
123
+ ```markdown
124
+ ### [CRITICAL/MAJOR/MINOR] Issue Title
125
+
126
+ **Location:** file.py:line_number
127
+ **Category:** contract_quality | logic_error | security | escape_hatch | code_smell
128
+ **Problem:** What's wrong
129
+ **Suggestion:** How to fix (but don't implement)
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Instructions
135
+
136
+ 1. Run `invar guard --changed` to see current state
137
+ 2. Go through each checklist category
138
+ 3. For each issue, determine severity (CRITICAL/MAJOR/MINOR)
139
+ 4. Report with structured format above
140
+ 5. Be thorough and adversarial
141
+
142
+ **Remember:** You are READ-ONLY. Report issues, don't fix them.
143
+
144
+ ---
145
+
146
+ Now review the recent changes or the files specified by the user.
@@ -0,0 +1,83 @@
1
+ ---
2
+ _invar:
3
+ version: "5.0"
4
+ type: command
5
+ ---
6
+
7
+ # Guard
8
+
9
+ Run Invar verification on the project and report results.
10
+
11
+ ---
12
+
13
+ ## Behavior
14
+
15
+ Execute `invar_guard()` and report:
16
+ - Pass/fail status
17
+ - Error count with details
18
+ - Warning count with details
19
+
20
+ **Do NOT fix issues** - just report verification results.
21
+
22
+ ---
23
+
24
+ ## When to Use
25
+
26
+ - Quick verification check
27
+ - Before committing changes
28
+ - After pulling changes
29
+ - To see current project health
30
+
31
+ ---
32
+
33
+ ## Execution
34
+
35
+ Run verification:
36
+
37
+ ```
38
+ invar_guard(changed=true)
39
+ ```
40
+
41
+ Or for full project verification:
42
+
43
+ ```
44
+ invar_guard()
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Report Format
50
+
51
+ ```
52
+ ## Guard Results
53
+
54
+ **Status:** PASS / FAIL
55
+ **Errors:** N
56
+ **Warnings:** N
57
+
58
+ ### Errors (if any)
59
+
60
+ | Rule | File | Line | Message |
61
+ |------|------|------|---------|
62
+ | missing_contract | src/foo.py | 42 | Function 'bar' has no @pre/@post |
63
+
64
+ ### Warnings (if any)
65
+
66
+ | Rule | File | Line | Message |
67
+ |------|------|------|---------|
68
+ | function_size | src/baz.py | 15 | Function exceeds 50 lines |
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Next Steps
74
+
75
+ After reporting results:
76
+ - If PASS: No action needed
77
+ - If FAIL: User decides whether to fix issues
78
+
79
+ **Remember:** You are READ-ONLY. Report results, don't fix them.
80
+
81
+ ---
82
+
83
+ Now run verification on the current project.
@@ -0,0 +1,370 @@
1
+
2
+
3
+ <!--invar:critical-->
4
+ ## ⚡ Critical Rules
5
+
6
+ | Always | Remember |
7
+ |--------|----------|
8
+ | **Verify** | `invar guard` — NOT pytest, NOT crosshair |
9
+ | **Core** | `@pre/@post` + doctests, NO I/O imports |
10
+ | **Shell** | Returns `Result[T, E]` from `returns` library |
11
+ | **Flow** | USBV: Understand → Specify → Build → Validate |
12
+
13
+ ### Contract Rules (CRITICAL)
14
+
15
+ ```python
16
+ # ❌ WRONG: Lambda must include ALL parameters
17
+ @pre(lambda x: x >= 0)
18
+ def calc(x: int, y: int = 0): ...
19
+
20
+ # ✅ CORRECT: Include defaults too
21
+ @pre(lambda x, y=0: x >= 0)
22
+ def calc(x: int, y: int = 0): ...
23
+
24
+ # ❌ WRONG: @post cannot access parameters
25
+ @post(lambda result: result > x) # 'x' not available!
26
+
27
+ # ✅ CORRECT: @post only sees 'result'
28
+ @post(lambda result: result >= 0)
29
+ ```
30
+
31
+ <!--/invar:critical-->
32
+
33
+
34
+
35
+ <!--invar:managed version="5.0"-->
36
+ # Project Development Guide
37
+
38
+ > **Protocol:** Follow [INVAR.md](./INVAR.md) — includes Check-In, USBV workflow, and Task Completion requirements.
39
+
40
+ ## Check-In
41
+
42
+ > See [INVAR.md#check-in](./INVAR.md#check-in-required) for full protocol.
43
+
44
+ **Your first message MUST display:** `✓ Check-In: [project] | [branch] | [clean/dirty]`
45
+
46
+ **Actions:** Read `.invar/context.md`, then show status. Do NOT run guard at Check-In.
47
+
48
+ ---
49
+
50
+ ## Final
51
+
52
+ Your last message for an implementation task MUST display:
53
+
54
+ ```
55
+ ✓ Final: guard PASS | 0 errors, 2 warnings
56
+ ```
57
+
58
+ Execute `invar guard` and show this one-line summary.
59
+
60
+
61
+ This is your sign-out. Completes the Check-In/Final pair.
62
+
63
+
64
+ ---
65
+
66
+
67
+ ## Project Structure
68
+
69
+ ```
70
+ src/{project}/
71
+ ├── core/ # Pure logic (@pre/@post, doctests, no I/O)
72
+ └── shell/ # I/O operations (Result[T, E] return type)
73
+ ```
74
+
75
+ **Key insight:** Core receives data (strings), Shell handles I/O (paths, files).
76
+
77
+ ## Quick Reference
78
+
79
+ | Zone | Requirements |
80
+ |------|-------------|
81
+ | Core | `@pre`/`@post` + doctests, pure (no I/O) |
82
+ | Shell | Returns `Result[T, E]` from `returns` library |
83
+
84
+ ### Core vs Shell (Edge Cases)
85
+
86
+ - File/network/env vars → **Shell**
87
+ - `datetime.now()`, `random` → **Inject param** OR Shell
88
+ - Pure logic → **Core**
89
+
90
+ > Full decision tree: [INVAR.md#core-shell](./INVAR.md#decision-tree-core-vs-shell)
91
+
92
+
93
+
94
+ ### Document Tools (DX-76)
95
+
96
+ | I want to... | Use |
97
+ |--------------|-----|
98
+ | View document structure | `invar doc toc <file> [--format text]` |
99
+ | Read specific section | `invar doc read <file> <section>` |
100
+ | Search sections by title | `invar doc find <pattern> <files...>` |
101
+ | Replace section content | `invar doc replace <file> <section>` |
102
+ | Insert new section | `invar doc insert <file> <anchor>` |
103
+ | Delete section | `invar doc delete <file> <section>` |
104
+
105
+ **Section addressing:** slug path (`requirements/auth`), fuzzy (`auth`), index (`#0/#1`), line (`@48`)
106
+
107
+ ## Tool Selection
108
+
109
+ ### Calling Methods (Priority Order)
110
+
111
+ Invar tools can be called in 3 ways. **Try in order:**
112
+
113
+ 1. **MCP tools** (Claude Code with MCP enabled)
114
+ - Direct function calls: `invar_guard()`, `invar_sig()`, etc.
115
+ - No Bash wrapper needed
116
+
117
+ 2. **CLI command** (if `invar` installed in PATH)
118
+ - Via Bash: `invar guard`, `invar sig`, etc.
119
+ - Install: `pip install invar-tools`
120
+
121
+ 3. **uvx fallback** (always available, no install needed)
122
+ - Via Bash: `uvx invar-tools guard`, `uvx invar-tools sig`, etc.
123
+
124
+ ---
125
+
126
+ ### Parameter Reference
127
+
128
+ **guard** - Verify code quality
129
+ ```bash
130
+ # CLI
131
+ invar guard # Check changed files (default)
132
+ invar guard --all # Check all files
133
+ ```
134
+
135
+ **sig** - Show function signatures and contracts
136
+ ```bash
137
+ # CLI
138
+ invar sig src/foo.py
139
+ invar sig src/foo.py::function_name
140
+ ```
141
+
142
+ **map** - Find entry points
143
+ ```bash
144
+ # CLI
145
+ invar map [path] --top 10
146
+ ```
147
+
148
+ **refs** - Find all references to a symbol
149
+ ```bash
150
+ # CLI
151
+ invar refs src/foo.py::MyClass
152
+ ```
153
+
154
+ **doc*** - Document tools
155
+ ```bash
156
+ # CLI
157
+ invar doc toc docs/spec.md
158
+ invar doc read docs/spec.md intro
159
+ ```
160
+
161
+ ---
162
+
163
+ ### Quick Examples
164
+
165
+ ```bash
166
+ # Verify after changes (all three methods identical)
167
+ invar guard # CLI
168
+ uvx invar-tools guard # uvx
169
+
170
+ # Full project check
171
+ invar guard --all # CLI
172
+ uvx invar-tools guard --all # uvx
173
+
174
+ # See function contracts
175
+ invar sig src/core/parser.py
176
+ uvx invar-tools sig src/core/parser.py
177
+ ```
178
+
179
+ **Note**: All three methods now have identical default behavior.
180
+
181
+
182
+ ## Documentation Structure
183
+
184
+ | File | Owner | Edit? | Purpose |
185
+ |------|-------|-------|---------|
186
+ | INVAR.md | Invar | No | Protocol (`invar update` to sync) |
187
+ | CLAUDE.md | User | Yes | Project customization (this file) |
188
+ | .invar/context.md | User | Yes | Project state, lessons learned |
189
+ | .invar/project-additions.md | User | Yes | Project rules → injected into CLAUDE.md |
190
+ | .invar/examples/ | Invar | No | **Must read:** Core/Shell patterns, workflow |
191
+
192
+ > **Before writing code:** Check Task Router in `.invar/context.md`
193
+
194
+ ## Visible Workflow (DX-30)
195
+
196
+ For complex tasks (3+ functions), show 3 checkpoints in TodoList:
197
+
198
+ ```
199
+ □ [UNDERSTAND] Task description, codebase context, constraints
200
+ □ [SPECIFY] Contracts and design decomposition
201
+ □ [VALIDATE] Guard results, Review Gate status, integration status
202
+ ```
203
+
204
+ **BUILD is internal work** — not shown in TodoList.
205
+
206
+ **Show contracts before code.** See `.invar/examples/workflow.md` for full example.
207
+
208
+ ## Phase Visibility (DX-51)
209
+
210
+ Each USBV phase transition requires a visible header:
211
+
212
+ ```
213
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
214
+ 📍 /develop → SPECIFY (2/4)
215
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
216
+ ```
217
+
218
+ **Three-layer visibility:**
219
+ - **Skill** (`/develop`) — Routing announcement
220
+ - **Phase** (`SPECIFY 2/4`) — Phase header (this section)
221
+ - **Tasks** — TodoWrite items
222
+
223
+ Phase headers are SEPARATE from TodoWrite. Phase = where you are; TodoWrite = what to do.
224
+
225
+ ---
226
+
227
+ ## Context Management (DX-54)
228
+
229
+ Re-read `.invar/context.md` when:
230
+ 1. Entering any workflow (/develop, /review, etc.)
231
+ 2. Completing a TodoWrite task (before moving to next)
232
+ 3. Conversation exceeds ~15-20 exchanges
233
+ 4. Unsure about project rules or patterns
234
+
235
+ **Refresh is transparent** — do not announce "I'm refreshing context."
236
+ Only show routing announcements when entering workflows.
237
+
238
+
239
+ ---
240
+
241
+ ## Commands (User-Invokable)
242
+
243
+ | Command | Purpose |
244
+ |---------|---------|
245
+ | `/audit` | Read-only code review (reports issues, no fixes) |
246
+ | `/guard` | Run Invar verification (reports results) |
247
+
248
+ ## Skills (Agent-Invoked)
249
+
250
+ | Skill | Triggers | Purpose |
251
+ |-------|----------|---------|
252
+ | `/investigate` | "why", "explain", vague tasks | Research mode, no code changes |
253
+ | `/propose` | "should we", "compare" | Decision facilitation |
254
+ | `/develop` | "add", "fix", "implement" | USBV implementation workflow |
255
+ | `/review` | After /develop, `review_suggested` | Adversarial review with fix loop |
256
+
257
+ **Note:** Skills are invoked by agent based on context. Use `/audit` for user-initiated review.
258
+
259
+ Guard triggers `review_suggested` for: security-sensitive files, escape hatches >= 3, contract coverage < 50%.
260
+
261
+ ---
262
+
263
+ ## Workflow Routing (MANDATORY)
264
+
265
+ When user message contains these triggers, you MUST use the **Skill tool** to invoke the skill:
266
+
267
+ | Trigger Words | Skill Tool Call | Notes |
268
+ |---------------|-----------------|-------|
269
+ | "review", "review and fix" | `Skill(skill="review")` | Adversarial review with fix loop |
270
+ | "implement", "add", "fix", "update" | `Skill(skill="develop")` | Unless in review context |
271
+ | "why", "explain", "investigate" | `Skill(skill="investigate")` | Research mode, no code changes |
272
+ | "compare", "should we", "design" | `Skill(skill="propose")` | Decision facilitation |
273
+
274
+ **CRITICAL: You must call the Skill tool, not just follow the workflow mentally.**
275
+
276
+ The Skill tool reads `.claude/skills/<skill>/SKILL.md` which contains:
277
+ - Detailed phase instructions (USBV breakdown)
278
+ - Error handling rules
279
+ - Timeout policies
280
+ - Incremental development patterns (DX-63)
281
+
282
+ **Violation check (before writing ANY code):**
283
+ - "Did I call `Skill(skill="...")`?"
284
+ - "Am I following the SKILL.md instructions?"
285
+
286
+ ---
287
+
288
+ ## Routing Control (DX-42)
289
+
290
+ Agent announces routing decision before entering any workflow:
291
+
292
+ ```
293
+ 📍 Routing: /[skill] — [trigger or reason]
294
+ Task: [summary]
295
+ ```
296
+
297
+ **User can redirect with natural language:**
298
+ - "wait" / "stop" — pause and ask for direction
299
+ - "just do it" — proceed with /develop
300
+ - "let's discuss" — switch to /propose
301
+ - "explain first" — switch to /investigate
302
+
303
+ **Simple task optimization:** For simple tasks (single file, clear target, <50 lines), agent may offer:
304
+
305
+ ```
306
+ 📊 Simple task. Auto-orchestrate? [Y/N]
307
+ ```
308
+
309
+ - Y → Full cycle without intermediate confirmations
310
+ - N → Normal step-by-step workflow
311
+
312
+ **Auto-review (DX-41):** When Guard outputs `review_suggested`, agent automatically
313
+ enters /review. Say "skip" to bypass.
314
+
315
+ <!--/invar:managed-->
316
+
317
+ <!--invar:project-->
318
+ <!-- ========================================================================
319
+ PROJECT REGION - INVAR PROJECT ONLY
320
+ This section is populated by .invar/project-additions.md via `invar dev sync`.
321
+ For other projects, this region remains empty.
322
+ ======================================================================== -->
323
+ <!--/invar:project-->
324
+
325
+ <!--invar:user-->
326
+ <!-- ========================================================================
327
+ USER REGION - EDITABLE
328
+ Add your team conventions and project-specific rules below.
329
+ This section is preserved across `invar update` and `invar dev sync`.
330
+ ======================================================================== -->
331
+ <!--/invar:user-->
332
+
333
+ ---
334
+
335
+ *Generated by `invar init` v5.0. Customize the user section freely.*
336
+
337
+
338
+ <!-- VECTL:AGENTS:BEGIN -->
339
+ ## Plan Tracking (vectl)
340
+
341
+ vectl tracks this repo's implementation plan as a structured `plan.yaml`:
342
+ what to do next, who claimed it, and what counts as done (with verification evidence).
343
+
344
+ Full guide: `uvx vectl guide`
345
+ Quick view: `uvx vectl status`
346
+
347
+ ### Claim-time Guidance
348
+ - `uvx vectl claim` may emit a bounded Guidance block delimited by:
349
+ - `--- VECTL:GUIDANCE:BEGIN ---`
350
+ - `--- VECTL:GUIDANCE:END ---`
351
+ - For automation/CI: use `uvx vectl claim --no-guidance` to keep stdout clean.
352
+
353
+ ### CLI vs MCP
354
+ - Source of truth: `plan.yaml` (channel-agnostic).
355
+ - If MCP is available (IDE / Claude host), prefer MCP tools for plan operations.
356
+ - Otherwise use CLI (`uvx vectl ...`).
357
+ - Evidence requirements are identical across CLI and MCP.
358
+
359
+ ### Rules
360
+ - One claimed step at a time.
361
+ - Evidence is mandatory when completing (commands run + outputs + gaps).
362
+ - Spec uncertainty: leave `# SPEC QUESTION: ...` in code, do not guess.
363
+
364
+ ### For Architects / Planners
365
+ - **Design Mode**: Run `uvx vectl guide --on planning` to learn the Architect Protocol.
366
+ - **Ambiguity = Failure**: Workers will hallucinate if steps are vague.
367
+ - **Constraint Tools**:
368
+ - `--evidence-template`: Force workers to provide specific proof (e.g., "Paste logs here").
369
+ - `--refs`: Pin specific files (e.g., "src/auth.py") to the worker's context.
370
+ <!-- VECTL:AGENTS:END -->
@@ -0,0 +1,9 @@
1
+ {
2
+ "mcpServers": {
3
+ "invar": {
4
+ "type": "stdio",
5
+ "command": "uv",
6
+ "args": ["run", "invar", "mcp"]
7
+ }
8
+ }
9
+ }