117 lines
5.7 KiB
Markdown
117 lines
5.7 KiB
Markdown
# 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.
|