Skip to content

Commit 025f82c

Browse files
vosesoftclaude
andcommitted
project-level CLAUDE.md with working preferences
Captures the operating procedures and gotchas that have accumulated across the development of v0.3: - Git push policy: Claude does pushes itself; don't bounce to user. - Release pipeline behaviour and what to watch. - Quality gate that must run before every commit. - Where to bump versions (5 places must match for registry verifier to accept). - Microsoft Store Python + Claude Desktop file-virtualisation gotcha (use `py` or full path, never bare `python`). - Stale-bug-report pattern: training-data references to old tools deleted in v0.3.0-alpha.1. - Architectural anchors: XLL simulation kickoff, MRService.dll bundled activation, Excel interactive-launch requirement, and the tuple-vs-list pitfall in `_as_2d` that fix landed in alpha.11. Lives at repo root so any future Claude session opened against this repo picks it up automatically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a33b7bc commit 025f82c

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Working preferences for Claude on this repo
2+
3+
Read this before doing work on `modelrisk-mcp`.
4+
5+
## Git push policy
6+
7+
**Always do `git push` yourself.** Don't ask the user to switch to PowerShell and run it. The credential dialog works reliably from the bash/PowerShell shell Claude uses, provided the repo-local credential helper is set to `manager`:
8+
9+
```bash
10+
git config --local credential.https://github.com.helper "manager"
11+
```
12+
13+
That's already configured for `modelrisk-mcp` and shouldn't need to be re-set. If a push hangs, it's almost always Git Credential Manager waiting on the OS chooser — wait it out or check the user's screen for the dialog. **Don't fall back to telling the user to push manually.**
14+
15+
The standard sequence after a tagged commit:
16+
17+
```
18+
git push origin main
19+
git push origin <new-tag>
20+
gh run watch <run-id> --repo vosesoftware/modelrisk-mcp --exit-status
21+
```
22+
23+
## Release pipeline (automated)
24+
25+
Pushing a tag `v*.*.*` or `v*.*.*-*` triggers `.github/workflows/release.yml`. Five jobs run, all green-or-fail:
26+
27+
1. `build-wheel` — wheel + sdist via `uv build`
28+
2. `build-windows-exe` — PyInstaller exe + obfuscation scan (release-blocker)
29+
3. `publish-pypi` — wheel + sdist via OIDC trusted publishing
30+
4. `publish-mcp-registry``mcp-publisher` via GitHub OIDC against `registry.modelcontextprotocol.io`
31+
5. `github-release` — assets attached to a GitHub Release page
32+
33+
After a tag pushes, watch the run with `gh run watch <id> --exit-status` and confirm all five jobs green. Then confirm the version appears on PyPI (`curl pypi.org/pypi/modelrisk-mcp/json | jq .info.version`) and on the MCP Registry.
34+
35+
## Quality gate before every commit
36+
37+
Always run all three before committing. No exceptions:
38+
39+
```
40+
.venv/Scripts/python.exe -m pytest tests/unit -q
41+
.venv/Scripts/python.exe -m ruff check src tests scripts
42+
.venv/Scripts/python.exe -m mypy src
43+
```
44+
45+
`mypy` runs on `src` only — running it on `tests/` surfaces a lot of test-time-only `type: ignore` lint noise that's not actionable.
46+
47+
## Version bumping
48+
49+
Bump in five places per release. They must all match or the registry verifier rejects:
50+
51+
- `src/modelrisk_mcp/__init__.py::__version__`
52+
- `pyproject.toml::version`
53+
- `server.json::version` AND `packages[0].version`
54+
- `tests/unit/test_server_boot.py::test_version_is_set` assertion
55+
- `uv.lock` (regenerates automatically on `uv sync --extra dev`)
56+
57+
The CHANGELOG entry under the new version header gets the user-facing summary.
58+
59+
## File-virtualisation gotcha (Microsoft Store Python + Claude Desktop)
60+
61+
The user has Microsoft Store Python at `C:\Users\timou\AppData\Local\Python\pythoncore-3.14-64\python.exe`. The `python` command alias is intercepted by Windows App Execution Aliases and goes to the Store stub instead of the real install. **Always use `py -m modelrisk_mcp ...` or the full path, never bare `python -m ...`.**
62+
63+
The user also has two Claude Desktop installs (regular + MS Store packaged). Both share `%APPDATA%\Claude\` via Windows file virtualisation, so a single config write reaches both.
64+
65+
## Stale-bug-report pattern
66+
67+
When the user (or Claude in a fresh session) reports a bug that references tools we deleted (`use_vba_helper_for_simulation`, `ensure_modelrisk_active` and the bitness-mismatch hypothesis), that's training-data drift — those tools were removed in v0.3.0-alpha.1 when we pivoted from ATL COM dispatch to the MRService.dll + XLL command surface. The MCP server's actual `tools/list` returns the current 38 tools; nothing named that way is registered.
68+
69+
## Architectural anchors
70+
71+
- Simulation kickoff: `Application.Run("VoseStartSimulCustom12", options_array)` then `Application.Run("VoseGetDataSZ12", session_name, save_path)`. The session-name format is `h<hwndExcel>_SaveResultsToFile_<book_name>`.
72+
- Results read: ctypes against `MRService.dll`. Bundled activation key in `bridge/_keymat.py`; rotation script in `scripts/encode_activation_key.py`.
73+
- Excel must be launched **interactively** (Start menu / taskbar) before the MCP server tries `run_simulation` — when launched programmatically, the XLL skips `xlAutoOpen` and the simulation commands aren't in Excel's `Application.Run` table.
74+
- Real Excel returns `Range.formula` as **tuples**, not lists. `_as_2d` must accept both at every nesting level — a regression here silently collapses list-scans into single records (the alpha.11 fix). Don't regress this.

0 commit comments

Comments
 (0)