Commit Graph
100 Commits
Author SHA1 Message Date
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
Quintine 3bebc68cd5 Compose the Sneak Attack arrival with the Bene Gesserit reactions
A positive Moritani Sneak Attack now resolves its committed Terror entry first —
placing the reserve forces and accruing the Heighliners token — and then offers
the Bene Gesserit reactions under the same adopted shipment classification used
for ordinary off-planet arrivals: an eligible Advanced Intrusion choice when
Bene Gesserit fighters stand in the destination, carrying the free
spiritual-advisor follow-up, and the advisor shipment itself when the intrusion
is declined, with its existing territory, storm and occupancy validation. A
zero-force resolution still opens none of them, and the last "Sneak Attack
combined with Bene Gesserit arrival reactions" guard is removed rather than left
as a duplicate check.

This selected order is an implementation interpretation, not a located ruling;
the source note, the pending-interpretation registry, the component inventory,
the player reference and the status log record it. Evidence:
tests/moritani-force-leader.test.ts asserts the post-entry Intrusion offer and
the full decline -> advisor decision -> placement chain with nothing left
pending; the former gated-interaction pin was replaced by the composed
behaviour. Offline suite 7,798/7,798 with typecheck and lint clean, plus the
reference guide tests 10/10. No game, seat, saved state or deployment changes.
2026-10-07 18:53:19 +11:00
Quintine 972b781d0a Adopt the Sneak Attack shipment classification for Heighliners
A positive Moritani Sneak Attack in Shipment and Movement now accrues the
Heighliners token once for its owner through the same techIncome helper as an
ordinary off-planet arrival. The token still enforces its working phase, its
printed Guild exception and one accrual per turn, and a zero-force resolution
accrues nothing; the previous phase-5 guard is removed rather than duplicated.

This is an explicitly adopted implementation interpretation, not a retrieved
publisher ruling: the printed verb is "Send", and classifying the expressly
off-planet reserve transfer as a shipment is the supported reading already
recorded in the source note. Bene Gesserit spiritual-advisor accompaniment and
Intrusion stay gated because their ordering inherits the unresolved
arrival-timing boundary; a Spice Blow worm-ride Sneak Attack stays outside the
token's working phase.

Evidence: tests/moritani-force-leader.test.ts asserts the accrual, the
once-per-turn guard, the unchanged zero-force resolution and the altered-sector
rejection; the former unsupported-classification pin was replaced by the
adopted behaviour rather than re-pinned. The component inventory, the source
note, the pending-interpretation registry, the player reference and the status
log record the reduced boundary. Offline suite 7,797/7,797 with typecheck and
lint clean. No game, seat, saved state or deployment changes.
2026-10-07 18:40:19 +11:00
Quintine 0e1a442dca Wire the Tleilaxu Ambassador force return
The last unimplemented Ambassador effect is now reachable. A placed Tleilaxu
token gives its beneficiary — the Ecaz owner or its ally — a private
ecazAmbassador decision at the new revival stage: one to four physical counters
return from the Tanks to reserves at zero cost, quoted by the existing
game/tleilaxu-ambassador-forces.ts, which also enforces the shared
Fedaykin/Sardaukar one-per-turn counter and keeps Ixian cyborgs uncapped.

The player view projects the maximum, Tanks and elite inventory and current
elite usage to the beneficiary only; the entry control offers a per-count
button and an explicit "Return no forces" decline; all four AI profiles choose
a legal return from the decision owner's own view or decline when the Tanks are
empty. Player-facing coverage text now lists Tleilaxu.

Kept gated exactly as recorded: the printed leader alternative, ordinary
force/free/leader allowance accounting around this independent grant,
dead-twice eligibility, and Tleilaxu free-income repeat scope. No ordinary
revival allowance, price, phase or income path changes.

Evidence: tests/tleilaxu-ambassador-engine.test.ts drives a genuine arrival into
a placed token and asserts the beneficiary-only projection, the typed return
with unchanged spice, the shared elite limit, malformed/over-maximum rejection
with immutability, the ordinary-only return, the decline path and the rendered
control. The four-profile ecaz-entry-bots loop now covers tleilaxu, and the
former unsupported-effect and copy-list pins were updated to the supported
behaviour rather than re-pinned. Offline suite 7,797/7,797 with typecheck and
lint clean. No game, seat, saved state or deployment changes.
2026-10-07 18:28:57 +11:00
Quintine 07c20ae806 Diagnose stalled administrator decisions from the operations page
Add an owner-only, read-only sample of at most ten live rooms whose public
pending interaction — decision, response, Truthtrance or phase opening — has
been idle longest, with the room code, idle duration, interaction kind, turn
and phase. GET /api/admin/operations?stalled=1 repeats live owner authority,
answers no-store, rejects any other query combination and repairs nothing;
paused, closed, removed and archived rooms are excluded and no private game
content is selected. The aggregate sample adds stalledRooms and
oldestStalledChange for the same predicate.

Owner-only unit coverage asserts the counters, the oldest stalled write, the
bounded oldest-first order, every exclusion boundary, idle arithmetic, the
absence of private content and the owner recheck after demotion. The anonymous
HTTP boundary denies the new read, and the full HTTP integration suite passes
55/55 against a local build of this revision. The panel was verified in the
real browser against six hours of genuine idle rooms, which caught and fixed a
missing threshold field in the response.

No game, seat, saved state, deployment, public start or played-save conversion
changes.
2026-10-07 17:51:08 +11:00
Quintine e05a205a47 Compose the deferred Terror arrival and green the mixed E3 programmes
Queue a committed Terror entry whose arrival also opened its own
interaction — Guild income, a Bene Gesserit fighter Intrusion or advisor
choice, or Fremen storm protection — in the additive
Game.pendingArrivalReaction list, and open the oldest queued entry from
settleAutomaticContinuations once nothing is pending. Payment, force
transfer and the original movement never replay; a Terror entry already in
flight and every Ambassador combination still reject.

Both withdrawn mixed E3 programme pairs are green: Moritani 9/9 and Ecaz
14/14, stable across 20 consecutive full-file runs. Their recorded resume
constraints became real fixture repairs, and the two restored consumer
omissions were corrected against the engine rather than re-pinned.

Repair pre-existing failures inherited at 45e6084 against current engine
behavior: stale Discovery and module gates in the native skills, Ix and
expansion-faction prototypes, the advanced Moritani skill boundary, the
Richese Nexus betrayal sale-credit expectation, one incidental gate
message and one flaky Collection-readiness assertion that reproduced at
HEAD.

Offline suite 7,793/7,793 with typecheck and lint clean. No game, seat,
saved-state, deployment, public-start or played-save conversion changes.
2026-10-07 17:24:23 +11:00
Quintine 45e6084424 Record mixed E3 Nexus composition scope and receipts 2026-10-07 15:17:01 +11:00
Quintine 48b2755088 Compose original mixed E3 and three-family Nexus 2026-10-07 15:16:37 +11:00
Quintine 6935b8650d Record exact mixed Nexus container verification receipt 2026-10-07 14:20:50 +11:00
Quintine 05ab2c92b0 Compose original mixed and paired Nexus optional modules 2026-10-07 14:12:47 +11:00
Quintine 0e1797d4e0 Record exact single-native Nexus publication receipt 2026-10-07 11:57:26 +11:00
Quintine 30a0bdbbb6 Compose original single-native E1 E2 Nexus modules and skills 2026-10-07 11:50:25 +11:00
Quintine 204d91902d Record exact standalone Nexus verification receipt 2026-10-07 10:24:12 +11:00
Quintine 185f3b37be Compose standalone E3 Nexus without Leader Skills 2026-10-07 10:18:19 +11:00
Quintine ec3d26f663 Record exact native Homeworld Nexus verification receipt 2026-10-07 09:00:55 +11:00
Quintine 2efa10a9d6 Compose native Homeworld Nexus optional modules 2026-10-07 08:54:53 +11:00
Quintine 71bc325289 Record exact classic Homeworld Nexus verification 2026-10-07 07:24:21 +11:00
Quintine c7073dc6b6 Compose classic Homeworld Nexus optional modules 2026-10-07 07:14:52 +11:00
Quintine b5f5de5c83 Record exact native Homeworld verification and publication 2026-10-07 05:32:50 +11:00
Quintine 3fb047c93d Compose native Homeworld skill and Discovery modules 2026-10-07 05:16:26 +11:00
Quintine a8758bc6b5 Record exact optional-module checkpoint and native work boundary 2026-10-06 19:59:04 +11:00
Quintine fa025220f8 Compose classic Homeworld optional modules through original rules 2026-10-06 18:56:55 +11:00
Quintine 3dd36bd9ff Record exact Homeworld checkpoint surface and container proof 2026-10-06 18:22:17 +11:00
Quintine e2dcebca35 Compose classic Homeworld Skills and Discovery with physical custody 2026-10-06 18:07:41 +11:00
Quintine 4a3bd8fe90 Correct native Nexus Discovery evidence and live scope guidance 2026-10-06 12:03:13 +11:00
Quintine b5b3a949d3 Record native trained Nexus Discovery publication proof 2026-10-06 10:44:46 +11:00
Quintine 2270c07f97 Compose native trained Skills Nexus Discovery modules 2026-10-06 10:13:07 +11:00
Quintine 958d7b3436 Record combined Nexus Discovery publication proof 2026-10-06 04:16:27 +11:00
Quintine c8a6d0bb3c Compose original classic and paired Nexus Discovery modules 2026-10-06 04:06:16 +11:00
Quintine 9e8c718739 Record native Discovery skills publication proof 2026-10-06 01:05:11 +11:00
Quintine 555afe4070 Compose native Discovery skills and repair hidden trainer participation 2026-10-06 00:51:21 +11:00
Quintine d51142bf9a Record original Discovery Stronghold publication proof 2026-10-05 22:25:43 +11:00
Quintine b0267827b5 Compose Discovery Strongholds and repair mandatory Ecaz battles 2026-10-05 22:13:53 +11:00
Quintine e798914aab Record classic Nexus Discovery publication proof 2026-10-05 21:29:34 +11:00
Quintine a2a92bb408 Compose classic Nexus with original Discovery modules 2026-10-05 21:23:02 +11:00
Quintine 4672b97417 Record combined Discovery checkpoint publication proof 2026-10-05 17:46:34 +11:00
Quintine c12b463439 Compose classic Discovery skills and Advanced Orgiz collection 2026-10-05 17:35:51 +11:00
Quintine 1947e354ce Record native Discovery checkpoint publication proof 2026-10-05 15:40:56 +11:00
Quintine 67ce690064 Connect native Discovery setup and nested force paths 2026-10-05 15:28:50 +11:00
Quintine 8d17fab3de Record high Ecaz Homeworld victory publication proof 2026-10-05 14:46:53 +11:00
Quintine 17bc4537c3 Connect printed high Ecaz Homeworld alliance victory 2026-10-05 14:41:11 +11:00
Quintine cfa0fe3952 Record occupied Tupile checkpoint publication proof 2026-10-05 14:10:30 +11:00
Quintine 3e79021a6e Connect occupied Tupile capacity and original cleanup 2026-10-05 14:03:25 +11:00
Quintine d637dbaf63 Record occupied Homeworld checkpoint publication proof 2026-10-05 13:02:47 +11:00
Quintine 0774ae6f83 Connect occupied Homeworld economics and Bidding 2026-10-05 12:48:08 +11:00
Quintine a6e80c7e23 Record exact occupied Homeworld checkpoint verification and image receipts 2026-10-05 09:25:20 +11:00
Quintine 5e902e384d Connect stable occupied Homeworld income sharing and native protections 2026-10-05 09:12:41 +11:00
Quintine 84d2ba1d3d Record verified standalone E3 checkpoint and publication receipts 2026-10-05 06:29:35 +11:00
Quintine 83f825513a Compose standalone E3 Nexus Skills and original module mechanics 2026-10-05 06:19:40 +11:00
Quintine a8c02b4a85 Record verified paired module publication and runtime evidence 2026-10-05 02:29:33 +11:00
Quintine 8b6bf38560 Make native fixtures deterministic and expose verifier failures safely 2026-10-05 02:07:51 +11:00
Quintine 2d24f43721 Compose paired Nexus Skills with original Tech and Strongholds 2026-10-05 01:08:58 +11:00
Quintine 449e27b415 Compose classic Nexus Skills with original Tech and Strongholds 2026-10-04 23:59:58 +11:00
Quintine 03aedc14d7 Record paired native skill checkpoint verification 2026-10-04 22:46:16 +11:00
Quintine fba673d215 Compose paired Nexus and native skills with signed marker shipments 2026-10-04 22:30:26 +11:00
Quintine 54ce1de1df Record classic Nexus skill checkpoint verification 2026-10-04 20:55:07 +11:00
Quintine 3ae5e1f994 Compose classic Nexus and Leader Skills with physical Suk rescue 2026-10-04 20:41:39 +11:00
Quintine c8482a2d96 Record paired Nexus module checkpoint verification 2026-10-04 19:36:10 +11:00
Quintine 9f254a6912 Compose paired Nexus with original Tech and Stronghold modules 2026-10-04 19:26:51 +11:00
Quintine 8f2dd3b1a4 Record classic Nexus checkpoint CI and exact revision proof 2026-10-04 17:20:00 +11:00
Quintine 8ceee7afd0 Compose classic Nexus with Tech and Advanced Stronghold Cards 2026-10-04 17:01:00 +11:00
Quintine b8585cdd92 Record native Tech checkpoint publication and exact runtime proof 2026-10-04 15:09:18 +11:00
Quintine 2da3c9273b Compose native faction Tech and Advanced Strongholds without Skills 2026-10-04 14:59:12 +11:00
Quintine 7cdb9b5a62 Record standalone E3 skill module container verification 2026-10-04 11:53:18 +11:00
Quintine 2b72021611 Compose standalone E3 Leader Skills with Tech and Strongholds 2026-10-04 11:41:13 +11:00
Quintine a8f5a3c953 Record combined Skills Stronghold container verification 2026-10-04 10:04:12 +11:00
Quintine f259488a9a Compose Advanced Leader Skills and Strongholds with optional Tech 2026-10-04 09:50:55 +11:00
Quintine 3c7725c3a5 Record native Skills Tech checkpoint container verification 2026-10-04 08:57:32 +11:00
Quintine 219489ae04 Compose native E1/E2 Leader Skills with original Tech Tokens 2026-10-04 08:48:47 +11:00
Quintine 7a6972cd1b Record classic Skills Tech verified publication 2026-10-04 06:17:39 +11:00
Quintine b71f953635 Compose classic Leader Skills with original Tech Tokens 2026-10-04 06:01:53 +11:00
Quintine 21d71e8282 Record verified E3 Stronghold checkpoint publication 2026-10-04 01:55:46 +10:00
Quintine 39e2954ab4 Compose native Ecaz and Moritani Stronghold rule paths 2026-10-04 01:31:22 +10:00
Quintine 50808aed5e Record verified Basic Occupy container publication 2026-10-03 21:05:38 +10:00
Quintine 5f082696a6 Compose source-clear Basic even-force Ecaz Occupy 2026-10-03 20:34:22 +10:00
Quintine 63e57bd894 Record verified native Ecaz container publication 2026-10-03 18:48:42 +10:00
Quintine f17f4e703e Compose native Ecaz skills with original Ambassador and Duke paths 2026-10-03 18:34:40 +10:00
Quintine df8f335b98 Record verified native Richese container publication 2026-10-03 17:58:44 +10:00
Quintine 032b41aa87 Compose native Richese skills and Advanced contribution receipts 2026-10-03 17:46:10 +10:00
Quintine 10d74f8db8 Record verified skill-first Moritani container publication 2026-10-03 15:50:47 +10:00
Quintine d41a7e03a9 Compose native Advanced Moritani skills with skill-first assassination 2026-10-03 15:34:12 +10:00
Quintine cb1f81977e Record verified Tleilaxu skill container publication 2026-10-03 14:21:48 +10:00
Quintine d86d2088e6 Compose Advanced Tleilaxu skills and original foreign ghola lifecycle 2026-10-03 14:06:49 +10:00
Quintine d327d1943b Record verified Advanced native skill publication 2026-10-03 13:20:08 +10:00
Quintine 7ee064df14 Compose Advanced native Ixian and CHOAM Leader Skills 2026-10-03 13:06:44 +10:00
Quintine 64c8dfc770 Record verified Richese Occupy checkpoint publication 2026-10-03 09:05:55 +10:00
Quintine 113667da55 Compose native Richese No-Field and Stone with Advanced Occupy 2026-10-03 08:48:26 +10:00
Quintine 03c77604de Record exact mixed Truthtrance publication evidence 2026-10-03 07:16:17 +10:00
Quintine cd985c7c34 Support mixed current-fact and shipment Truthtrance questions 2026-10-03 07:11:28 +10:00
Quintine 0ceb28bd31 Record exact native payment wave publication evidence 2026-10-02 21:22:36 +10:00
Quintine b83d75d9d3 Integrate native Banker payments and Tleilaxu Ixian Nexus replacement 2026-10-02 21:12:52 +10:00
Quintine d72f3a2172 Record exact native Mentat publication evidence 2026-10-02 19:43:40 +10:00
Quintine 589e1b9df2 Integrate private Mentat questions with native Basic skill profiles 2026-10-02 19:36:07 +10:00
Quintine 3fc070fcfa Record exact Moritani clarification publication evidence 2026-10-02 19:01:33 +10:00
Quintine 934b2ee4d7 Adopt authorized Advanced Moritani normal-reveal forfeiture 2026-10-02 18:55:40 +10:00
Quintine b89e93a67f Record exact combined-card Occupy publication evidence 2026-10-02 18:14:45 +10:00
Quintine cd532222a5 Integrate sourced Treachery cards with Advanced Occupy 2026-10-02 17:53:24 +10:00
Quintine 85caee6c83 Record exact native Occupy publication evidence 2026-10-02 15:05:30 +10:00
Quintine 1057eb2719 Integrate native Ixian CHOAM and Tleilaxu Occupy aftermath 2026-10-02 14:47:54 +10:00
Quintine 3333432be8 Record exact Advanced Occupy publication evidence 2026-10-02 13:22:47 +10:00