feat(state): scope card evidence and policy memory by reported run identity
This commit is contained in:
parent
484551047c
commit
ba519a850e
9 changed files with 343 additions and 82 deletions
117
docs/RUN_STATE.md
Normal file
117
docs/RUN_STATE.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# Run identity and card-evidence provenance
|
||||
|
||||
## What is available
|
||||
|
||||
The vendored mod exposes `current_run.run_id` through `GET /api/v1/compendium`.
|
||||
Its format includes save scope, profile, and start time. The seed describes
|
||||
content; it is not the identity of an attempt.
|
||||
|
||||
The live player serializer exposes hand, draw, discard, and exhaust piles during
|
||||
combat. It does not expose the persistent run deck. The compendium exposes a
|
||||
save path, but the runner does not follow that path or read the save file.
|
||||
|
||||
Sources checked:
|
||||
|
||||
- `vendor/STS2MCP/McpMod.Compendium.cs`: `BuildCurrentRunContext`.
|
||||
- `vendor/STS2MCP/McpMod.StateBuilder.cs`: `BuildPlayerState`.
|
||||
|
||||
## Ownership and identity
|
||||
|
||||
`run.py` owns one `run_state.RunContext` per invocation. The context owns the
|
||||
current `PolicyContext` and optional combat-pile evidence. The context performs
|
||||
no network or file operations.
|
||||
|
||||
The runner requests identity after each stable in-run observation, before
|
||||
proposing an action. Menu, game-over, unknown, and overlay observations do not
|
||||
trigger this request. Dry-run still performs identity reads.
|
||||
|
||||
This deliberately uses the existing full compendium endpoint. It adds one local
|
||||
HTTP read per stable in-run step. A smaller identity endpoint would reduce cost,
|
||||
but this pass does not modify the mod or add a polling cache with stale identities.
|
||||
Live latency has not been measured.
|
||||
|
||||
A usable identity requires `is_in_progress: true` and a nonempty string `run_id`.
|
||||
Missing or malformed identity remains unknown. The runner never substitutes a
|
||||
seed, character name, or floor number as an identity.
|
||||
|
||||
- A different reported run ID resets policy memory, duplicate-action guards,
|
||||
rejection counts, and card evidence.
|
||||
- `--stop-on-run-end` stops before acting in the replacement run, with reason
|
||||
`run_changed`. This reports a run boundary, not victory or defeat.
|
||||
- Observed menu/game-over transitions clear run evidence and active-run policy memory.
|
||||
- Unknown states and overlays preserve pending-action guards.
|
||||
- Missing identity or a transport error discards card evidence but retains action
|
||||
guards. Erasing accepted toggles during a metadata outage could toggle them again.
|
||||
- The last known ID is retained privately across a metadata outage, so recovery
|
||||
with a different ID can still reset state. Decision rows use null during the outage.
|
||||
|
||||
### Identity is reported, not atomic
|
||||
|
||||
The mod derives identity from save metadata. The observation and compendium are
|
||||
separate requests. They are not an atomic snapshot, and save metadata can lag.
|
||||
The runner cannot prove that both responses describe exactly the same instant.
|
||||
A live observation-level run ID would provide a stronger association.
|
||||
|
||||
Do not infer exact attribution or game-action completion from this identity alone.
|
||||
Externally switching runs while the bot acts remains a coordination risk.
|
||||
|
||||
## Card evidence
|
||||
|
||||
The runner no longer reads or writes `deck.json`. Existing files remain untouched.
|
||||
No card evidence survives a runner restart. Unscoped legacy input to
|
||||
`facts.deck_context` becomes `unknown`.
|
||||
|
||||
A combat-pile snapshot is retained only when a reported run ID is available.
|
||||
Its provenance includes:
|
||||
|
||||
- `source: combat_piles`;
|
||||
- reported `run_id`;
|
||||
- `observed_step` within the current session;
|
||||
- observed act and floor;
|
||||
- `persistent_deck: false`;
|
||||
- which pile lists were present;
|
||||
- freshness: `observed_combat_piles` or `historical_combat_piles`.
|
||||
|
||||
The counts retain visible temporary cards, including Status cards. Filtering out
|
||||
Status cards would not reconstruct the persistent deck: generated Attack cards,
|
||||
temporary upgrades, and unavailable card data would still remain problems.
|
||||
Pile-list presence does not establish complete coverage.
|
||||
|
||||
Evidence can carry into immediate reward decisions in the same reported room.
|
||||
Opening a card reward or skipping it preserves that limited evidence. Other
|
||||
accepted non-combat actions discard it because they can change cards or leave the
|
||||
room. Rejected requests do not establish such a change.
|
||||
|
||||
A room change, missing room coordinates, identity failure, new reported run ID,
|
||||
or observed run exit discards evidence. The policy receives `unknown` when no
|
||||
scoped evidence remains. This reduces available synergy context intentionally;
|
||||
it is safer than presenting stale combat piles as the current persistent deck.
|
||||
|
||||
An exact persistent-deck source is still unavailable. This pass labels that
|
||||
limitation; it does not implement a complete deck tracker or a save-file parser.
|
||||
|
||||
## Minimal trace additions
|
||||
|
||||
Decision rows now include reported `run_id`, `run_seed`, and available
|
||||
`deck_provenance`. The provenance describes available macro-policy evidence;
|
||||
it does not mean every handler used it. Combat policy uses the combat observation directly.
|
||||
|
||||
Identity changes and identity transport failures have separate trace events.
|
||||
Full observation/action linkage, unique capture names, session identity, and
|
||||
session finalization remain recording work.
|
||||
|
||||
## Validation
|
||||
|
||||
- 279 existing-script assertions passed: 68 facts, 110 policy, and 101 runner.
|
||||
This includes two upgrade-selection assertions added concurrently.
|
||||
- Runner integration flows cover same-seed run replacement, single-run stopping,
|
||||
metadata outages, temporary cards, provenance, mutation invalidation, room
|
||||
boundaries, unknown rooms, and restart/cache isolation.
|
||||
- Eighteen temporary whole-process scenarios passed with real HTTP clients and
|
||||
loopback fixtures. Five exercise the new identity/provenance behavior.
|
||||
- The offline audit replayed 346 stored observations without policy exceptions.
|
||||
- Dataset integrity passed for 37 runs, 1,052 decisions, and 346 observations.
|
||||
- Python compilation and shell syntax checks passed.
|
||||
|
||||
No live game actions, paid model calls, dependencies, vendor edits, or dataset
|
||||
rewrites were required. Temporary probes were not added to the repository.
|
||||
Loading…
Add table
Add a link
Reference in a new issue