Lane 11 PR 17: the J7 journey and demo seed wave B (#737) #989

Merged
claude-bot merged 8 commits from build/lane11-17-j7 into main 2026-10-01 16:36:15 +00:00
Collaborator

Part of #737. The last build PR of lane 11 (contract §4, PR 17). No migration; the bot API is untouched.

J7, a character made, shown and levelled

webapp/frontend/e2e/j7-a-character.spec.js, on desktop, phone and keyboard, with axe on every page and dialog reached. It runs in a campaign of its own, The Blackfen Warrant, so it does not disturb what J0–J6 count in Amberwake. The e2e seed imports the PF2e mini pack through the GM's own import and makes Odile Marsh's page and block.

  1. Priya starts a Pathfinder character. Eight steps; Next says why it waits. Ancestry, background and class from the loaded content. She leaves mid-way, Members shows "Carry on with …", and it reopens with her choice kept. Nine boosts, no dice anywhere. Finish makes the page; Max HP 20.
  2. Dana shows Odile's block by field at the table: three groups ticked, "GM notes" never offered. The bot receives one reveal carrying the shown lines and none of the kept ones.
  3. Priya is handed what was shown and nothing else: checked on the table card, on Odile's page, and in the raw API answers.
  4. Dana awards 1,000 XP; the sheet shows a level waiting.
  5. Priya levels up: "Level 2 brings 12 Hit Points. Max HP 20 → 32", a feat she can't take shown disabled with why, What changes, Reach level 2, one milestone on the evening, and a version kept from before.
  6. Dana takes it back; Priya's answer holds no line of the block.

Bugs J7 and the seed found, fixed here

  • A sheet could say "Someone else changed this sheet" about your own save. Leaving a sheet while its autosave was on its way left the draft on the device at the old version; on return it was sent again and refused. This affected every sheet, not only a character being started. A restored draft now drops whatever the server already holds, and a leave-save that lands clears the device copy. A draft that still differs keeps its old base, so a real change elsewhere still raises the conflict.
  • A retired character kept collecting the party's XP (Aldous read 2,730 with "Level 5 is waiting"). A character who was in a party and has left gets no party awards; one who was never in any party still does. This is question L18.
  • Three buttons shared one name on the Ancestry step. Each "Choose from the loaded content" now says what it chooses.

Demo seed, wave B

Every sheet goes through the service its route calls.

  • Ossian Vale stands at exactly 1,000 XP, through the ledger (D204), so his header says "Level 7 is waiting". The other Pathfinder sheets carry what their levels spent and are not waiting. This also settles wave A's "PF2e XP reads 0" caveat.
  • Tam Ridley's level 3 is made by Level up itself: the d10 is rolled and kept, the version before it is kept, and the campaign has "Tam Ridley reached level 3" (D210).
  • Two characters begun and left: Perrin Loake in Amberwake ("Carry on with Perrin Loake"), and Corwin Hale in Hollow & Ash with six kept 4d6 rolls, a die dropped in each.
  • Ids stay stable across --reset.

Left as it is, and why

  • Converted public stat blocks stay readable by the whole table, not only the party. PR 7 built it that way deliberately, the migration is merged, and party would take a block away from a member with no active character at upgrade. The contract's row is noted as differing. This is question L17.
  • A class feat step still offers other classes' feats. Question L19; a follow-up.

Checked

  • Journeys: the whole suite on the merged tree, 151 passed, 11 skipped (the designed ones), none failed. J7 is 6/6 on each project.
  • Backend: full suite, 6563 passed, 14 skipped.
  • Frontend: vitest 3570 passed, 1 skipped; eslint 0 errors.
  • ruff 0.4.4 format --check and check; changelog, version sync and every coverage/lane*.py.

Follow-ups

  • #988: reading a sheet may rewrite its updated_at (seen in the seed's tests, not yet reproduced).
  • The two seeded half-made characters clear after 30 days, as the product does (D249); --reset puts them back.

🤖 Generated with Claude Code

Part of #737. The last build PR of lane 11 (contract §4, PR 17). No migration; the bot API is untouched. ## J7, a character made, shown and levelled `webapp/frontend/e2e/j7-a-character.spec.js`, on desktop, phone and keyboard, with axe on every page and dialog reached. It runs in a campaign of its own, **The Blackfen Warrant**, so it does not disturb what J0–J6 count in Amberwake. The e2e seed imports the PF2e mini pack through the GM's own import and makes Odile Marsh's page and block. 1. **Priya starts a Pathfinder character.** Eight steps; Next says why it waits. Ancestry, background and class from the loaded content. She leaves mid-way, Members shows "Carry on with …", and it reopens with her choice kept. Nine boosts, no dice anywhere. Finish makes the page; Max HP 20. 2. **Dana shows Odile's block by field** at the table: three groups ticked, "GM notes" never offered. The bot receives one reveal carrying the shown lines and none of the kept ones. 3. **Priya is handed what was shown and nothing else**: checked on the table card, on Odile's page, and in the raw API answers. 4. **Dana awards 1,000 XP**; the sheet shows a level waiting. 5. **Priya levels up**: "Level 2 brings 12 Hit Points. Max HP 20 → 32", a feat she can't take shown disabled with why, What changes, Reach level 2, one milestone on the evening, and a version kept from before. 6. **Dana takes it back**; Priya's answer holds no line of the block. ## Bugs J7 and the seed found, fixed here - **A sheet could say "Someone else changed this sheet" about your own save.** Leaving a sheet while its autosave was on its way left the draft on the device at the old version; on return it was sent again and refused. This affected every sheet, not only a character being started. A restored draft now drops whatever the server already holds, and a leave-save that lands clears the device copy. A draft that still differs keeps its old base, so a real change elsewhere still raises the conflict. - **A retired character kept collecting the party's XP** (Aldous read 2,730 with "Level 5 is waiting"). A character who was in a party and has left gets no party awards; one who was never in any party still does. This is question L18. - **Three buttons shared one name** on the Ancestry step. Each "Choose from the loaded content" now says what it chooses. ## Demo seed, wave B Every sheet goes through the service its route calls. - **Ossian Vale stands at exactly 1,000 XP**, through the ledger (D204), so his header says "Level 7 is waiting". The other Pathfinder sheets carry what their levels spent and are not waiting. This also settles wave A's "PF2e XP reads 0" caveat. - **Tam Ridley's level 3** is made by Level up itself: the d10 is rolled and kept, the version before it is kept, and the campaign has "Tam Ridley reached level 3" (D210). - **Two characters begun and left**: Perrin Loake in Amberwake ("Carry on with Perrin Loake"), and Corwin Hale in Hollow & Ash with six kept 4d6 rolls, a die dropped in each. - Ids stay stable across `--reset`. ## Left as it is, and why - **Converted public stat blocks stay readable by the whole table**, not only the party. PR 7 built it that way deliberately, the migration is merged, and `party` would take a block away from a member with no active character at upgrade. The contract's row is noted as differing. This is question L17. - **A class feat step still offers other classes' feats.** Question L19; a follow-up. ## Checked - Journeys: the whole suite on the merged tree, 151 passed, 11 skipped (the designed ones), none failed. J7 is 6/6 on each project. - Backend: full suite, 6563 passed, 14 skipped. - Frontend: vitest 3570 passed, 1 skipped; eslint 0 errors. - ruff 0.4.4 `format --check` and `check`; changelog, version sync and every `coverage/lane*.py`. ## Follow-ups - #988: reading a sheet may rewrite its `updated_at` (seen in the seed's tests, not yet reproduced). - The two seeded half-made characters clear after 30 days, as the product does (D249); `--reset` puts them back. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
WIP.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
WIP.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Found by J7. Leaving a sheet while its save was on the way left the draft on
the device on the old version; put back, it was sent again and refused as
'someone else changed this sheet' by the person's own save.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
WIP.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Also: a character who has left every party gets no more party awards (found
by the seed: a retired character's sheet said a level was waiting).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merge remote-tracking branch 'origin/main' into build/lane11-17-j7
All checks were successful
CI / Backend lint (ruff) (pull_request) Successful in 30s
CI / Does this change touch the recording path? (pull_request) Successful in 37s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Feedback site tests (pull_request) Successful in 43s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 51s
CI / Bot/backend version sync (pull_request) Successful in 50s
CI / Docker image build (pull_request) Successful in 55s
CI / Bot tests and audit (pull_request) Successful in 1m49s
CI / Frontend (shard 2/2) (pull_request) Successful in 6m1s
CI / Frontend (shard 1/2) (pull_request) Successful in 7m22s
CI / Backend migration, tests, and audit (pull_request) Successful in 18m7s
CI / End-to-end journeys (phone) (pull_request) Successful in 20m21s
CI / End-to-end journeys (desktop) (pull_request) Successful in 21m17s
CI / End-to-end journeys (keyboard) (pull_request) Successful in 21m18s
dc59a5b55f
Sign in to join this conversation.
No description provided.