Fix batch 8a-fix3: Dungeon play loop (PA.f98-PA.f109, PA.f111)
- PA.f98 (high): dispatch takes each subject by its full id, exactly as
table_view prints it in brackets, never the short <handle>__ actor-tool
prefix. parse_dispatch now matches on a new full_id_text (mirrors the
library's own id_text, undocumented-but-identical, without handle_for's
8-hex truncation) and returns unmatched ids separately; the dispatch call
site folds them into the result as a named refusal ("`<text>` names no
dispatchable subject") instead of dropping them. Actor tool descriptions
now carry their own subject's label and full id (round_tools annotates the
library's own actor_tools output in place, so table.rs stays untouched).
dispatch's own tool description and PLAY_INSTRUCTIONS restated to match.
- PA.f104 (medium): dispatched is no longer snapshotted once before a
round's own calls execute; an actor call now derives it fresh from the
turn's own record at the point of resolution, so a same-round
[dispatch(Mara), <mara>__speak, end_turn] resolves speak identically on a
first pass and on resume.
- PA.f99 (medium, test gap): added a before-submit test hook
(#[cfg(test)] only) fired right before each of the three submit doors
(commit_authoring_run, execute_advance_time, execute_actor_call). It hands
the hook a fresh PlayTurnStore::pull_current_from_disk_for_test() read —
a fresh `pull_all` against the store's own already-owned redb Database,
never the cached self.state and never a second store (CultCache's
single-owner lock refuses a second OwnedRedbMessagePackBackingStore::new
on the same path outright; discovered building this seam). Three new
tests observe the durable body at the moment of submission.
- PA.f100 (medium, test gap): the same request key, reused only after
eviction from the KeyLedger window, must mint two distinct fresh turn_ids.
- PA.f101 (medium, test gap): answers: None while a question is open is
refused (StaleAnswer) and records nothing.
- PA.f102 (medium, test gap): split the old "exhausted beyond retries" test,
which actually only ever drove RecoveryRequired, into an honestly-named
RecoveryRequired test (asserts exactly one call) plus a new Retryable
budget-exhaustion test (asserts exactly ROUND_BUDGET + 1 calls, pinned to
a literal, not to the ROUND_RETRY_BUDGET symbol, so a budget mutation
can't drag the expectation along with it). retry_delay's zero-under-test
behavior is now its own small #[cfg(test)] bool (skip_retry_delay_in_test)
rather than a #[cfg(test)] swap over the whole formula; the formula itself
(backoff_delay) is a free function, always compiled, with its own unit
test.
- PA.f103 (medium, test gap): added tests for a narrate failure right after
end_turn and at the round budget, both closing with the fault recorded.
The snapshot-failure site in execute_round is reported, not covered: no
deterministic way to fail WorldMailbox::snapshot exists in this crate's
test harness without tearing down the mailbox's own background actor
independently of the fixture; documented in place.
- PA.f105 (low-medium): the resume path through execute_round now runs the
same handle-collision check round_tools runs (it never did). Added a real
test forcing a genuine collision between two real SubjectIds (spliced via
serde_json, since SubjectId is #[serde(transparent)]) and calling
round_tools directly — this was wrongly reported infeasible in the prior
pass. The resume-path (execute_round) wiring itself has no live-collision
test: forcing one needs the kernel's own snapshot to already carry one,
and the kernel mints every SubjectId internally; documented alongside the
precedent this codebase already uses for the same shape of gap
(a_refused_player_act_sets_the_refusal_line).
- PA.f108 (low): empty or whitespace-only text with no turn open to
continue (none at all, or Closed) is refused (PlayError::EmptyOpening)
before a fresh turn opens, making zero inference calls.
- PA.f109 (low): run's outcome is now RunOutcome::Ran or
Replayed { turn_id }; a replay reads ClosedTurnKeys::turn_id for the
first time anywhere in production (via a new turn_id_for_key on the
store and turn_id_for on the ledger).
- PA.f111: PLAY_INSTRUCTIONS' own doc comment rewritten off the "fresh
table_view per round" framing into the recorded-opening rule (S6).
Every mutation named in the task spec (delete/move each of the three
PA.f99 persists, turn_id=hash(key), delete the round_tools collision call,
accept a None answer, accept an empty opening, make RecoveryRequired retry,
raise the retry budget, remove the backoff cap, turn each of the two
testable close-with-fault sites back into a bare `?`) was applied, run
against its matching test, confirmed to fail, and reverted.
Test counts: Dungeon bin 98 -> 113, lib 622 -> 622 (one test renamed and
reshaped, no net add), persona-projection 30 -> 32.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
d28912cf64
commit
754c7fe288
1 changed files with 1320 additions and 70 deletions
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue