Commit Graph
4 Commits
Author SHA1 Message Date
prosolis 556b9440b8 adventure: don't strand an order on a database blip, don't misroute a tap
Two things a code review turned up in the W9 seams.

The verdict handler answered 400 for everything ResolveAdvOrder could fail
with, not just a bad verdict. gogobee's contract says a 400 means "park this
row for a human", so a SQLite busy or a disk hiccup permanently stranded an
extract or a bout that was perfectly resolvable. Split the two apart with
ErrBadAdvVerdict: a verdict outside the terminal set is still 400, because
gogobee will never send it successfully, and a genuine storage failure is now
500 and comes back on the next poll.

The push URL builders concatenated the guid and the run id raw, while every
other builder beside them path-escapes because these values arrive over a wire.
A guid carrying a slash sent the notification tap to a different page.
2026-07-24 22:36:35 -07:00
prosolis b07abc1d13 adventure: let a player back out from the web, not only in Matrix
Three verbs to match gogobee's: call off an expedition, turn back out of
somebody else's party, send the pet sitter home. Which one this page
offers is derived here rather than pushed — leadership is already legible
in the party seats and the sitter's standing is already in the babysit
offer, so nothing new crosses the wire.

Two things running it turned up that no test would have. An applied
abandon left "Pull out of the run" sitting under a verdict saying the
expedition was over, so an applied verb now also hides the other verbs it
just made untrue. And a party member was being offered that same button
in the first place, beside the one that actually works — Pete knows from
the seat it just read that gogobee would refuse it, so it is withheld.

Also: heal the Matrix handle onto push rows stored before the column
existed, on its own endpoint rather than through the subscribe upsert,
which resets both watermarks and would have silenced the digest for
anybody who reads the site regularly. And stack the board row below sm —
four flex columns that wrapped to six lines on a phone, pre-existing.
2026-07-24 21:42:59 -07:00
prosolis 868a29e992 adventure: let a player leave town from the web, not only read about it
W5a gave the web two verbs that cost nothing. These are the three that take
arguments and spend coins: set out for a zone with a supply loadout, walk back
into the run you extracted from, hire the pet sitter for a week or a month.
Between them they cover the most common thing anybody does in the game, which
until now could only be typed into Matrix.

Arguments are the new surface, so they are the thing to be careful with. Nothing
in a request is trusted: every zone, loadout and duration is looked up in the
offer list gogobee pushed onto that owner's own private row, and the order stores
what was found there rather than what was sent. A forged zone resolves to nothing
and never becomes an order. gogobee then re-resolves all of it anyway, because an
offer is a quote and a quote is not a permission.

The money confirm is the equip panel's, lifted: cost, balance, and the balance it
leaves. When it does not cover, it says so instead of printing a negative.

Verified in a browser rather than only in tests, which is where both real defects
came from: the confirm box was appending to the whole panel and so appeared at
the bottom of the section instead of under the button that raised it, and button
prices printed as EUR45000 above a dialog reading EUR45,000.

Claude-Session: https://claude.ai/code/session_012bxpQQJDjC1mTtLN3VVtBQ
2026-07-24 19:47:26 -07:00
prosolis 6b0aae9f4a adventure: let a player act from the web, not just read about it
The equip queue proved the reverse pipe works. This gives it verbs that
play the game: pull out of a run from the adventurer page, take today's
bout from the war room.

Its own table and its own poll, not more actions on equip_orders. Every
column of that table is equip vocabulary (item, slot, tier) and these
verbs act on the character rather than on something it is carrying.

Nothing in a request names an adventurer. The session maps to one
localpart and a localpart to one adventurer, so Pete resolves the
character itself and there is no id on the wire to forge.

The panel's copy is kept honest by the verdict: an applied action hides
the offer it has just spent, a refusal puts the button back. Watching it
run is what put that there, along with the strip's layout — gogobee
answers a bout with a whole sentence of damage, which the equip strip's
two-column row squeezed into a column and wrapped the verb.

Claude-Session: https://claude.ai/code/session_012bxpQQJDjC1mTtLN3VVtBQ
2026-07-24 18:55:42 -07:00