5.3 KiB
Briefing for the Claude Code instance running on Caspian
You're picking up Tasks 2, 3, 4, and 6 of the implementation plan at
docs/superpowers/plans/2026-07-03-runtime-observation-mcp-plan.md in this same repo (you
have it via the SMB share). Read that whole plan file first -- this briefing only covers
things it doesn't, mostly because your Claude Code config on this machine is separate from
the one on the Linux box that wrote it, so nothing here can be assumed to already be in
place. Tasks 1 and 5 are being done on the Linux side in parallel; don't duplicate them.
Hard constraints (from this repo's docs/HANDOFF.md -- these are non-negotiable)
- Never commit original game data or binaries.
*.EXE *.DLL *.FF *.DAT *.MAP *.INI *.cue *.bin,BIGFILE.DAT,WORLDS/,tmp_cd/,archive/, anything undertools/ghidra_*are all gitignored already -- don't fight the.gitignore, and ifgit addpicks up something that looks like game data, stop and check before committing. - No em dashes in any output (commit messages, docs, code comments) -- use plain hyphens. This has been a consistent style through the whole project; keep it consistent here.
- Commit style: conventional prefixes (
feat:,docs:,fix:,chore:), solo-repo history onmain. Look atgit log --oneline -10for the actual tone/format before writing your first commit message. - Follow the plan's checkbox steps in order and don't skip the "run test / confirm it fails" steps -- they're there on purpose, not filler.
Coding style for this Python work
No enforced linter/formatter is configured in this repo yet, so match what's already in
tools/dbg_path.py and the code already written in the plan (Task 1's
havoc_debug_protocol.py, Task 2-4's havoc_debug_agent.py) rather than importing a
different personal style:
- Type hints on function signatures where they're not fighting
ctypes(thectypes.Structuresubclasses themselves don't need them; plain functions and methods should have them). - Plain
raise OSError(...)/raise ValueError(...)with a message including the failing value (e.g.f"ReadProcessMemory failed at 0x{addr:X}: {k.GetLastError()}") -- always include enough context in the message to debug from the error alone, don't just re-raise bare. - No docstrings on obvious one-liners; a short one-line docstring on anything non-obvious
(matches this session's style in the rest of the repo's
docs/*.mdandtools/*.py). - Don't add error handling for cases that can't happen (e.g. don't defensively check
self._process_info is not Nonein every method iflaunch()is a documented precondition) -- match the plan's existing code, which doesn't do this.
Lessons learned this session -- please don't repeat these
- A binary patch was shipped and crashed the game because only 2 of a shared global's
203 read-sites were checked for safety before patching. It was reverted and documented as
a mistake (see
docs/PATCHES.md"FPS-coupling" section for the full story). The equivalent risk here: audit every consumer of shared state before assuming a change is safe, don't stop at the first plausible-looking call site. This mostly applies to theDebugAgent's internal state (_breakpoints,_watchpoints,_threads) more than to the game binary itself, but the discipline is the same. - A "fix" was declared confirmed based on one successful test case, then contradicted by the very next test (the alt-tab-while-paused fix looked complete until the user tested alt-tab-while-not-paused and it wasn't). Don't over-claim "confirmed working" in commit messages or docs until you've actually run the specific scenario, not just an adjacent one.
- Two prior Ghidra-side patches were verified by re-importing the patched artifact into a
completely fresh, independent analysis rather than trusting the same context that wrote
it. The equivalent here: after building the debug agent, the smoke tests in Tasks 2/3
(Step 7 / Step 3) are not optional or skippable even though they're manual rather than
pytest-- they're the actual verification, since none of this can be meaningfully unit tested without the real Win32 APIs and the real game process. - When something doesn't work as expected, say so plainly and figure out why rather than
quietly declaring victory -- this project's whole documentation style (see
docs/METHODOLOGY.md,docs/PATCHES.md) is built around recording dead ends honestly, not just successes. Keep that up in whatever you write.
Where to look for context
docs/HANDOFF.md-- full project bootstrap, environment, constraintsdocs/FUNCTIONS.md-- function-by-function RE progress, including the alt-tab bug this whole MCP exists to help solvedocs/PATCHES.md-- binary patch history, including the reverted one (lesson #1 above)docs/superpowers/specs/2026-07-03-runtime-observation-mcp-design.md-- the approved design spec this plan implementstools/dbg_path.py-- the proven starting point for the Win32 debug loop
When you're done with Tasks 2/3/4
Task 6 (end-to-end integration) needs Task 5's MCP server, which is being built on the Linux
side. Check git log for a commit like "feat: wire MCP tool definitions and bearer-token
auth into server" before starting Task 6 -- if it's not there yet, finish and commit Tasks
2-4 and wait rather than blocking on it.