Commit Graph
289 Commits
Author SHA1 Message Date
Quintine 03e3d9bdbf Retain original Advanced Strongholds in fresh Semuta games 2026-10-12 07:24:52 +11:00
Quintine bab8f3403d Offer Semuta on printed native battle cancellation costs 2026-10-12 06:57:15 +11:00
Quintine 74768647f4 Preserve native Ixian casualties and Moritani retention across Semuta 2026-10-12 06:13:47 +11:00
Quintine a6869b0166 Connect Semuta reactions before original native Tech award 2026-10-12 05:44:56 +11:00
Quintine a1d620d7b0 feat: preserve native live-hand audits through Semuta discards 2026-10-12 05:09:54 +11:00
Quintine f09ddf1b18 feat: preserve quoted CHOAM income through Semuta battle discards 2026-10-12 04:40:04 +11:00
Quintine 0d545deb63 feat: preserve native Face Dance through Semuta battle discards 2026-10-12 04:16:12 +11:00
Quintine 12e4bcbf45 feat: restore final CHOAM Mentat after Semuta Gamont reactions 2026-10-12 03:37:23 +11:00
Quintine c468dc9e44 feat: preserve elite and No-Field Gamont selections through Semuta 2026-10-12 03:21:29 +11:00
Quintine 3171afc522 feat: connect Semuta to reactive CHOAM denial discards 2026-10-12 02:43:16 +11:00
Quintine d319faa80c feat: offer Semuta after clean battle Distrans transfers 2026-10-12 02:08:24 +11:00
Quintine 235f763625 feat: connect Basic native Semuta Terror discard reactions 2026-10-12 02:00:22 +11:00
Quintine 6709522890 feat: offer Semuta after paid battle Box searches 2026-10-12 01:44:21 +11:00
Quintine 066a097618 feat: offer Semuta after ordinary battle Ghola revival 2026-10-12 01:40:24 +11:00
Quintine da61249592 feat: resume Semuta battle discards before Harkonnen capture 2026-10-12 01:35:00 +11:00
Quintine d4a9835807 Offer Semuta on a battle-plan Truthtrance promise 2026-10-12 00:29:18 +11:00
Quintine 871e932319 Offer Semuta on a Truthtrance shipment promise 2026-10-12 00:22:28 +11:00
Quintine a487f3e1b3 Correct stale Richese runtime and Semuta guidance 2026-10-11 21:33:14 +11:00
Quintine b19e6dc940 Offer Semuta on a queued Truthtrance answer 2026-10-11 21:19:42 +11:00
Quintine bcabaaf596 Enable native Fremen Cunning with original Nexus components 2026-10-11 18:56:20 +11:00
Quintine 18693b3207 Resume native Intrusion after final-flight Semuta response 2026-10-11 17:25:26 +11:00
Quintine 9efa17b2b7 Offer Semuta before native Black Market replacement draws 2026-10-11 17:03:04 +11:00
Quintine d1ba8e0c7e Activate approved normal Mentat and document Emperor gift ruling 2026-10-11 16:46:17 +11:00
Quintine eb63967b5c Connect owned Sandmaster stronghold pile allocation 2026-10-09 05:24:33 +11:00
Quintine 0040ed1921 Connect owned Sandmaster destination pile choices 2026-10-09 04:51:12 +11:00
Quintine 24863480cb Connect owned Sandmaster ground pile selection 2026-10-09 03:54:00 +11:00
Quintine a1517ec949 Connect owned multi-pile battle skill choices 2026-10-09 03:14:14 +11:00
Quintine f2fd274502 Repair deterministic Occupy test transitions and card staging 2026-10-09 02:53:09 +11:00
Quintine 38b1ba3419 Allow provisional Kulon and Ornithopter coexistence 2026-10-09 02:46:41 +11:00
Quintine 048c8e60ff Resolve the high-threshold revival deployment question provisionally 2026-10-09 02:12:58 +11:00
Quintine 5e2a320512 Repair inherited stale rule guards and two minimal-legal bot gaps 2026-10-09 01:49:39 +11:00
Quintine b892967eb3 Connect provisional Basic current-sole Homeworld benefits and repair stale rule guards 2026-10-09 01:26:20 +11:00
Quintine 66e061ccca Connect Richese final-cache and provisional full-hand acquisition 2026-10-08 20:29:45 +11:00
Quintine 451ecc950c Connect provisional late-paid Recruits accounting 2026-10-08 19:31:42 +11:00
Quintine be8703dc51 Connect printed Diplomat defenses and Ecaz Tanked Duke Cunning 2026-10-08 19:05:08 +11:00
Quintine 039fe4e87f Connect Sandmaster collection to physical Ambassador relocation 2026-10-08 17:23:43 +11:00
Quintine 7cef1a3412 Connect Advanced allied reserve transit and legal departure 2026-10-08 16:58:21 +11:00
Quintine 869412bebd Connect Advanced Auditor repeated revival and provisional native cycles 2026-10-08 16:51:05 +11:00
Quintine 85729f9819 Connect provisional Advanced Richese mixed battles and exchanges 2026-10-08 16:46:48 +11:00
Quintine 4ed6beb33a Apply supplied Advanced Ixian Technology Richese-lot exclusion 2026-10-08 16:35:13 +11:00
Quintine 0315917987 Connect supplied Advanced Fremen Ecaz two-sietch victory allowance 2026-10-08 16:26:49 +11:00
Quintine 59a406830c Connect source-ordered Advanced Ecaz new-ally Duke grant 2026-10-08 10:14:08 +11:00
Quintine f29f14128f Connect provisional Basic full-hand Nullentropy Box exchange 2026-10-08 09:30:34 +11:00
Quintine 8d55b8f3f7 Connect provisional Basic Guild and Karama allied No-Field prices 2026-10-08 09:15:48 +11:00
Quintine 2ede6b55ea Connect provisional Basic mixed Richese No-Field battles 2026-10-08 09:02:10 +11:00
Quintine 2d0f20b69c Connect the Basic Ecaz new-ally Duke loan 2026-10-08 08:30:38 +11:00
Quintine c28e24b5fa Prioritize Basic faction prototypes and connect three missing rule paths 2026-10-08 08:23:20 +11:00
Quintine 7e3bec2721 Implement the five 7 October pending rule rulings
The user answered five recorded questions; each ruling is indexed in
RULE_DECISIONS.md and implemented with a focused regression.

- CHOAM opening income counts as a qualifying collection, so low-population
  Tupile adds its bank increment under the Inflation multiplier. The engine
  guard is removed and the projection/notice expose the added bonus.
- An exhausted Richese cache is legal and restores one ordinary lot; the
  canceled/prevented compulsory cache auction branch restores the reduction
  before the ordinary pool runs and the cache offer is skipped when no cache
  lot can run. The pure continuation quote mirrors the count.
- Suk-rescued casualties count toward Advanced Atreides' seven Kwisatz
  Haderach losses: the battle-loss counter gains the full dialed allocation in
  both rescue paths, and the earlier Suk availability restriction is removed.
- The Guild Nexus Secret Ally reserve return overrides the Arrakis-to-native-
  Homeworld restriction for the holder's own reserves and deposits through the
  shared native-reserve pipeline (generalized from the revival deposit).
- Interior passengers count as entering the territories a relocated Ixian HMS
  points into, so Sandmaster collects there before the native collection.

Full offline suite 7804/7804, types and lint pass. Historical evidence and
superseded test expectations are updated to the ruled behaviour; preserved
combined Homeworld/Nexus, occupation and Richese captures are unblocked but
not re-run here. No existing game, seat or saved state was changed.
2026-10-07 21:56:17 +11:00
Quintine e493bcf58e Report database size and make four genuine suites reproducible
Operations now report the SQLite database size and page count, read through
PRAGMA page_count/page_size in the same authority-checked batch as the
lifecycle counters with non-numeric values clamped to zero; the page renders
both and states that free disk space is still unknown.

replaceMoritaniAssassinationTraitors draws the first distinct physical Traitor
Card from the reserve instead of the reserve's first entry, because the face-up
set-aside card can still sit in that list: re-drawing it produced a receipt
whose replacement equalled the revealed card, which the assassination integrity
check rejects mid-Mentat. With no distinct card left the step is blocked with an
explicit reason instead of committing an invalid receipt.

Four tests were made reproducible after measuring their real failure rates,
because a suite that fails for random reasons cannot act as a checkpoint gate:
the Discovery typed Spice Blow test now removes other cards for the same
territory so one blow deposits the printed amount (0/20 after, ~20% before); the
Discovery E2 skills deal is pinned with the new shared
tests/deterministic-random.ts helper so a Lasgun-shield explosion cannot
pre-empt its skill consumer (0/12 after, ~20% before); the Ecaz Occupy Ix/CHOAM
policy check accepts any legal continuation and still asserts the phase it
reaches (0/30 after, ~10% before); and the mixed-E3 Moritani Cunning test keeps
the random storm off red_chasm's single sector (0/25 after, ~20% before).

Offline suite 7,801/7,801 with typecheck and lint clean. No game, seat, saved
state or deployment changes.
2026-10-07 19:55:43 +11:00
Quintine 8bea4c1a0c Record administrator failed attempts without storing credentials
Rejected administrator authentication and authorization attempts are now
recorded durably in a new additive admin_attempts table with a fixed reason
(invalid_key_format, unknown_or_disabled_key, missing_session,
unknown_or_expired_session, role_denied), the attempt kind, the attempted role
and an already-known account id. No key, key hash, session token, session hash,
request body, origin, address or user agent is stored, and the
unknown/disabled distinction is deliberately collapsed so the lookup cannot
become an account-enumeration oracle.

GET /api/admin/operations?attempts=1 returns seven-day per-reason counters plus
the twenty most recent attempts, newest first, to a live owner only, with
no-store and the same query guard as the other reads. The operations page adds
"List failed attempts" with the counters and the bounded sample, truncating each
account id to eight characters. Recording is best-effort inside the rejection
path, so a rejected request keeps its own answer even when the table is
unavailable, and the history never locks out, disables or revokes anything by
itself.

Evidence: tests/admin-attempts.test.ts asserts every recorded reason, the
kind/role/account fields, that successful sign-ins and privileged reads record
nothing, that no credential text appears anywhere in the page, the reporting
window, the twenty-row bound and the owner-only recheck after demotion, and that
a dropped attempts table leaves the original rejection answer unchanged. The
anonymous HTTP boundary denies ?attempts=1, and the panel was verified in the
real browser against a genuine recorded rejection. The shared AdminError moved
to db/admin-error.ts so the recorder and the access module no longer form a
value-import cycle. Offline suite 7,801/7,801 with typecheck and lint clean. No
game, seat, saved state or deployment changes.
2026-10-07 19:11:45 +11:00