Skip to content

prototype(hawkins): fix JATOS bootstrap races against jatos.js init - #25

Closed
htsukamoto5 wants to merge 7 commits into
mainfrom
prototype/hawkins-smoke
Closed

htsukamoto5 wants to merge 7 commits into
mainfrom
prototype/hawkins-smoke

Conversation

@htsukamoto5

Copy link
Copy Markdown
Member

@this branch fixes two JATOS bootstrap failures found during live verification on cortex.jatos.org, plus packaging for that testing. Reviewable packet only — not yet authorized to merge.

What changed

  • bootstrap/jatos.js awaits jatos.onLoad() before constructing the JATOS adapter. The adapter snapshots participantId in its constructor and joinGroup reads the run IDs at call time, both with no wait or retry, while jatos.js resolves them asynchronously. Two live failure modes, same root cause:
    1. Connecting early built an unjoinable ...undefinedpublix/undefined/group/join URL (instant bootstrap_error no-match screen).
    2. Constructing early baked in a literal "undefined" participant id for every member, so both lobby pushes overwrote each other under one session key and the lobby stayed solo forever (confirmed via groupSession.getAll() showing an "undefined" key).
  • reference-game-hawkins.html: the local adapter is constructed inside connectLocalDeployment(), so its ?mp_session= minting no longer trips the session-agreement check on the JATOS path.
  • Regression tests for deployment picking and adapter-construction ordering; all suites pass (bootstrap 27/27, pipeline 39/39, exits 31/31, dropout 18/18).
  • scripts/make-jzip.mjs: study packager used for the live JATOS builds (fresh UUIDs per run, so re-imports create new studies).

Verified live

  • Both runx frames open group channels, land in one group, leave the lobby, and proceed to pairing.

Still open (do not merge before these)

  • Two-separate-workers General Multiple test (ecological validity; runx reuses one worker).
  • Batch-cap behavior: whether pre-match timeouts consume maxTotalWorkers slots.
  • JATOS-NEXT-STEPS.md (full verification log) is intentionally uncommitted and not part of this packet.

Mandyx22 and others added 7 commits July 31, 2026 14:52
Audited reference-game-hawkins.html against the experiment code and manuscript
behind the paper: OSF osf.io/vzvmf -> github component = hawkrobe/tangrams. The
paper's two variants are "free-matching" (the Clark & Wilkes-Gibbs style board
replication, experiments/tangrams_unconstrained) and "cued" -- "a more
straightforwardly sequential cued variant ... where directors were privately cued
to refer to targets one-by-one and feedback was given on each trial"
(experiments/tangrams_sequential). This file is the cued one.

Changed to match:

- Stimulus geometry. game.core.js lays out SQUARE 300x300px cells and
  stimuli/objectSet.js draws every tangram at exactly 0.7x its natural PNG size,
  so the shapes are NOT normalised -- one uniform scale preserves their relative
  sizes. Cells are square and each image gets width = originalDrawWidth/300 as a
  percent of the cell content box, exact at any cell_size.

- scramble_mode: "disjoint" (new plugin option). The original re-rolls both
  layouts until no tangram shares a cell between players; plain "independent" left
  ~1/e of them coinciding, so positional reference sometimes worked by luck.

- Role-keyed feedback_content (new plugin option): the director sees only the
  object the matcher clicked, the matcher only the true target, per the paper --
  "the director saw which tangram their partner clicked, and the matcher saw the
  intended tangram". CSS repaints the plugin's red "wrong" highlight green, since
  the original highlights green either way and carries the outcome only through
  the score counter.

- Persistent round counter and running score above the board, matching the
  original's #roundnumber/#score, with show_running_score off.

- Instruction wording from client_onjoingame. Only edit: the original tells both
  roles they may "talk to the director", a copy-paste slip, so each role now names
  the other.

- Typing indicator, built on the multiplayer API rather than forking the plugin.
  The original has one ("Participants saw a binary indicator that their partner
  was currently typing"; sharedUtils/clientBase.js playerTyping).

Already correct and left alone: 2 players, fixed roles, 6x2 grid, 72 trials as 6
shuffled blocks of 12, per-trial re-scrambling, cued target, unrestricted two-way
chat, per-round chat log, the messageSent click gate, the 3000ms feedback window,
and unnumbered cells (the paper removed the numbers for the cued version; the
plugin only draws slot badges when there is more than one target).

Two documented differences remain, in the file header: gate semantics (the
original's gate opens on any message, including the matcher's own) and the absence
of the original's pre-game comprehension quiz.

Requires the plugin's reference-game-cued-fidelity branch for the two new options.
Adds reference-game-hawkins-local.html, the vendored offline twin, since the CDN
build cannot run until the plugin publishes to npm; vendor/ is gitignored.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Record exact roster validation before role assignment and remove the stale overflow route now that the role gate requires exactly two participants. Add structural coverage for the deployment bootstrap, explicit partner binding, centralized timeout, and timeline ordering.
Let deployments finalize an allocated dyad before the portable timeline validates its roster. Local runs retain a no-op implementation, while backend-specific code can supply a sealed roster without extending plugin contracts.
Await jatos.onLoad() before constructing the JATOS adapter. The adapter
snapshots participantId in its constructor and joinGroup reads the run IDs
at call time, both with no wait or retry, while jatos.js resolves them
asynchronously. Connecting early produced an unjoinable
"...undefinedpublix/undefined/group/join" URL, and constructing early baked
in a literal "undefined" participant id shared by every member, so both
lobby pushes overwrote each other under one session key and the lobby
stayed solo forever. Both failure modes seen live on cortex.jatos.org.

Also construct the local adapter inside connectLocalDeployment() so its
?mp_session= minting no longer trips the session-agreement check on the
JATOS path.

Adds regression tests for deployment picking and adapter-construction
ordering, plus the scripts/make-jzip.mjs study packager used for live
JATOS verification.@
@jodeleeuw

Copy link
Copy Markdown
Member

Superseded by #26, which rebuilds the Hawkins pilot on the session-based jspsych-multiplayer API (session IDs, shared randomness, group formation, rejoin detection) and carries over the parts of this PR that still apply.

@jodeleeuw jodeleeuw closed this Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants