diff --git a/docs/superpowers/plans/2026-07-03-caspian-agent-briefing.md b/docs/superpowers/plans/2026-07-03-caspian-agent-briefing.md new file mode 100644 index 0000000..8540f70 --- /dev/null +++ b/docs/superpowers/plans/2026-07-03-caspian-agent-briefing.md @@ -0,0 +1,81 @@ +# 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 under `tools/ghidra_*` are + all gitignored already -- don't fight the `.gitignore`, and if `git add` picks 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 + on `main`. Look at `git log --oneline -10` for 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` (the `ctypes.Structure` + subclasses 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/*.md` and `tools/*.py`). +- Don't add error handling for cases that can't happen (e.g. don't defensively check + `self._process_info is not None` in every method if `launch()` is a documented + precondition) -- match the plan's existing code, which doesn't do this. + +## Lessons learned this session -- please don't repeat these + +1. **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 the + `DebugAgent`'s internal state (`_breakpoints`, `_watchpoints`, `_threads`) more than to the + game binary itself, but the discipline is the same. +2. **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. +3. 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. +4. 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, constraints +- `docs/FUNCTIONS.md` -- function-by-function RE progress, including the alt-tab bug this + whole MCP exists to help solve +- `docs/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 implements +- `tools/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.