docs: add briefing for the Caspian-side agent implementing Tasks 2-4/6

This commit is contained in:
pyr0ball 2026-07-04 06:01:55 -07:00
parent a06b3a28df
commit 37571e8b8a

View file

@ -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.