Build a single-page prediction game called "Squeek Streak" for the Squeekchain hamster economy.

Core loop: players predict the NEXT 10-minute round's total wheel work in 4 bands — SLEEP (0), STROLL (1–99), RUN (100–499), SPRINT (500+) — finer-grained than existing prediction games. Settle each prediction against the real settled round work, read live from the official Squeekchain API: https://api.squeekchain.com/v1/status (coreStatus, rpmMilli, speedMmPerSecond, cumulativeWorkUnits) and round history from /v1/settlements?range=24h. Auto-refund when round data is missing.

What makes it different: (1) a streak multiplier — consecutive correct predictions pay escalating rewards; (2) a 1v1 duel mode — two players stake SP on the same round, winner takes the pot; (3) a weekly net-profit leaderboard and per-player prediction history; (4) 300 SP daily relief when the balance runs low so players never get stuck.

Rules: play with SP points (start 1,000 SP — not real tokens). Wallet connect via injected provider with message-signature login (no gas, no transactions).

UI: clean, playful hamster-themed design, full English, mobile responsive. Live panel shows current wheel state (running/sleeping, RPM, speed, current round work, rounds settled, 10-minute countdown)

Published · Site

site
squeek-streak-little-wheel-big-p.identitymd.eth · an earlier version, since replaced
ipfs
bafybeib37zdssmhpquhivqdk2dweslr4se4ueqh4nfqjkkpeyg6pbrieti · 863 KB
source
identity-md-launches/launch-2871-build-single-page-prediction-game · pull request

Work

  1. Posted1 h 11 minto the first attempt
  2. Build websiteAgent #4552 files changedsent back

    Implemented Squeek Streak with the static export in dist/, source, lockfile, and documentation. Delivery size: 1.59 MiB.

    Build and typecheck passed, alongside 23 unit tests, 10 browser scenarios, and 16 design checks.

    Duels and leaderboards are browser-local. Setup and limitations are documented in README.md and validation.

    ran oncodex · gpt-6.1-sol · 12 turns · 1h 10m · 144.2K in · 128.5K out · 10.7M cached
    submissiona2e29777373fc55e233d2c6900f7a4e46dfa3a897e8713300dd8d0a5079a8b5d
    devicee9bb398fec9e3e04ea53c86435faac5769186a43cd1fde455755c1fd3d13111f
    started from0243d7da4a4337ae8b16bcdf15bb4ead736fd68f
    bundle072d02d5303988d652f861a2b65ef11604774b24d7a2fc42c9bf7f8b7b9f37e9 · 783 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    changed · 52 files
    DESIGN.mdREADME.mddist/assets/ccip-yY84DLA7.jsdist/assets/dist-BFFSo6mz.jsdist/assets/index-B60QhPD9.jsdist/assets/index-DEzPNR3Q.cssdist/favicon.svgdist/fonts/OFL.txtdist/fonts/nunito-sans-latin.woff2dist/index.htmldist/share.pngdist/wallets/LICENSE.txtdist/wallets/coinbase.svgdist/wallets/metamask.svgdist/wallets/phantom.svgdist/wallets/rabby.svgdocs/THIRD_PARTY_NOTICES.mddocs/images/desktop-live.pngdocs/images/keyboard-focus.pngdocs/images/mobile-first-screen.pngdocs/images/mobile-wallet-sheet.pngdocs/licenses/design-guidance-LICENSE.txtdocs/unit-tests.txtdocs/validation-results.jsondocs/validation.mdindex.htmlpackage-lock.jsonpackage.jsonpublic/favicon.svgpublic/fonts/OFL.txtpublic/fonts/nunito-sans-latin.woff2public/share.pngpublic/wallets/LICENSE.txtpublic/wallets/coinbase.svgpublic/wallets/metamask.svgpublic/wallets/phantom.svgpublic/wallets/rabby.svgsrc/App.tsxsrc/components/Art.tsxsrc/components/Modal.tsxsrc/components/Wallet.tsxsrc/lib/api.tssrc/lib/game.tssrc/lib/hooks.tssrc/lib/wallet.tssrc/main.tsxsrc/style.csstests/browser.mjstests/game.test.tstests/harness.mjstsconfig.jsonvite.config.ts
  3. Design criticAgent #1119found 2 high, 1 medium
    AreaResult
    Requirements24 met, 2 missing, 0 faked
    Broken game/layout features2
    First screen at 390pxProduct and action visible
    taste@116/16 passed
    Copy findings0
    Share cardPresent; 1 defect

    Saved three substantiated findings in .imd-findings.json:

    • High — bug: Reopening after the grace period refunds confirmed wins and losses.
    • High — bug: A valid 24-character name makes history filters overflow at 320px.
    • Medium — bug: The share-card PNG contains a broken logo placeholder.

    Each includes exact source citations, a concrete fix, and measured reproduction evidence.

    Brief requirementStatus and evidence
    “Single-page…Squeek Streak”Met — page structure and header
    “NEXT 10-minute round’s total wheel work”Met — round form and roundAt
    “SLEEP (0), STROLL (1–99), RUN (100–499), SPRINT (500+)”Met — BANDS and four radio choices
    “Settle each prediction against…real settled round work”Missing on return visits — finding 1
    Official status API and its four named fieldsMet — src/lib/api.ts
    History from /v1/settlements?range=24hMet — feed requests
    “Auto-refund when round data is missing”Met — missing-data refund reproduced
    Escalating streak multiplierMet — settlement ledger and reward display
    Two-player duel; equal stakes; winner takes potMet locally — duel implementation and disclosed browser boundary
    Weekly net-profit leaderboardMet locally — weeklyProfit and leaderboard
    Per-player prediction historyMet — player filter and history rows
    “300 SP daily relief” when lowMet — claim and repeat-claim restriction checked
    “SP points…not real tokens”Met — rules and page disclosure
    “Start 1,000 SP”Met — player initialization
    Injected-provider wallet connectionMet — connector implementation and wallet sheet
    Message-signature loginMet in source — signing and verification
    “No gas, no transactions”Met in source — message-only authentication
    Clean, playful hamster designMet — illustrations and consistent visual system
    “Full English”Met — interface copy
    “Mobile responsive”Missing for maximum names at 320px — finding 2
    Running/sleeping wheel stateMet — state badge
    RPMMet — live metric
    SpeedMet — live metric
    Current round workMet — live metric
    Rounds settledMet — live-panel footer
    Ten-minute countdownMet — round timer

    The visual idea is a free wheel-work prediction game carried by simple hamster illustrations and warm, quiet panels.

    Chromium interactions were verified. WebKit interaction and real-wallet signing remain unverified. Website files were unchanged.

    ran oncodex · gpt-6.1-sol · 7 turns · 8m 5s · 114.4K in · 17.2K out · 1.7M cached
    submissione7e423f18f4e8808738794a6009d592bcec64ece8f52a23580801d31889d92ef
    device9ef5559b56f3a7a2ec8a9896819d9168ac4eee992eae221a5be37d5ff536c38f
    started fromddb67ab78ab638dcadb46eef253387a3c05db5bd
    bundlenone
    applied one2cd4987db41a77b8b3c7306a26893d67c3077a514ead45a3ffaca4d570a8b27
    • highbug: reopening after the grace period refunds confirmed winning and losing roundssrc/lib/game.ts:307

      Now: a pending solo pick can use a confirmed result only before the local 20-minute deadline; later visits refund it even when the API proves the round settled on time. The initial App settlement effect also runs before history loads, making that refund irreversible. Matched duels have the same deadline-first behavior.

      Change to: wait for the initial history check before making a missing-data refund, and settle pending picks from an exact result confirmed within the grace period before considering a refund. Apply the same rule to solo and matched duels, while preserving refunds already legitimately completed.

      Why: the brief requires settling each prediction against real settled round work and refunding when round data is missing. Closing the page must not turn confirmed wins or losses into risk-free refunds.

      390x844, production dist in Chromium; use tests/harness.mjs fixtures(now) and mockFeed with now=2026-11-02T12:03:00Z.

      Select Run and stake 100 SP for round 102 (12:10–12:20 UTC); click Lock prediction and verify balance 900 SP.

      Navigate to about:blank to stop the app.

      Add a safe history settlement with previousSettledThroughRound="101", settledThroughRound="102", workAdded="280", blockTimestamp="2026-11-02T12:20:01.000Z"; set status/history timestamps and the browser clock to 12:40:00.001Z, then reopen the page with the same localStorage.

      Expected: Won, payout 200 SP, balance 1100 SP, streak 1 because exact round data was confirmed one second after round end.

      Actual after the live feed has loaded: Refunded, payout 100 SP, balance 1000 SP, streak 0, reason "Round data unavailable within 20 minutes".

      The source guard rejects the timely result based on observation time rather than confirmation time; the first effect can refund before the fetch returns.

      Repeat with Sleep selected against the same 280-work result: expected Lost and 900 SP, actual Refunded and 1000 SP.

      Both variants were reproduced in the production export.

    • highbug: long player names push the history filters outside a 320px viewportsrc/style.css:1931

      Now: the mobile history filter row retains its intrinsic minimum width. A valid 24-character player name makes the filters 298px wide inside a 264px content area, leaving the Result selector outside the viewport.

      Change to: within the existing mobile media query, give .history-filters flex: 1 1 100% and min-width: 0, and give .select-label:first-child min-width: 0; retain both selectors and the CSV button below them. This keeps the row at the available width without hiding overflow.

      Why: the brief requires a mobile-responsive game; the review requires no horizontal scroll at 320px, including the longest values the interface permits.

      320x844, Chromium, production dist, a fresh guest league.

      Click the Seedling profile, enter exactly WWWWWWWWWWWWWWWWWWWWWWWW (24 W characters), and click Save player name.

      Scroll to Prediction history with its default Player and Result filters.

      Expected: both selectors remain inside the 320px viewport and the page scrollWidth is 320.

      Actual: document.documentElement.scrollWidth is 326; .history-toolbar spans x=28..292 (264px), but .history-filters spans x=28..326 (298px), with the Result select at x=211..326.

      The screenshot visibly cuts the right edge of that control.

      Applying the specified CSS in the browser makes the filter row 264px and scrollWidth 320.

      At 390px the same input has no horizontal overflow.

    • mediumbug: the social share image permanently embeds a broken logo placeholderindex.html:21

      Now: the Open Graph image exists, so the metadata probe passes, but public/share.png itself contains a broken-image icon inside an empty logo square beside the Squeek Streak wordmark. The identical faulty PNG is shipped in dist/share.png.

      Change to: regenerate the existing share.png with the local hamster mark embedded before capture, or delete the failed image box and move the wordmark left into its space. Copy the corrected asset into the static export.

      Why: link previews use the flattened PNG; hosting cannot repair an image-loading failure already baked into its pixels.

      At any page width, read the og:image value in index.html and open public/share.png or dist/share.png at its native 1200x630 size.

      Expected: a rendered hamster logo beside the wordmark, or a wordmark with no empty logo box.

      Actual: a 48x48 empty outlined image rectangle at approximately x=70,y=60 contains the browser broken-image glyph in its upper-left corner.

      This is visible when viewing the PNG directly, with no page or network loading involved; public/share.png and dist/share.png are byte-identical.

  4. Build websiteAgent #1522 files changed

    All three findings reproduced and fixed: settlement after reopening, mobile filter overflow, and the share-card logo. Rebuilt dist/.

    Build, typecheck, 28 unit tests, 13 browser scenarios, and 16 design checks passed.

    Responses and validation limitations are recorded in .imd-responses.json and docs/validation.md.

    ran oncodex · gpt-6.1-sol · 7 turns · 12m 3s · 114.9K in · 26.5K out · 2.7M cached
    submission1d1b2e8495a0ae5c4ed9153d3ceb805dcb54f26a2e913026556bf58efab0f0f4
    device3a271480f26269e36f6994c9ba67a8ad19fcf40f7b5edfad684b8422691362fe
    started fromddb67ab78ab638dcadb46eef253387a3c05db5bd
    bundlee2cd4987db41a77b8b3c7306a26893d67c3077a514ead45a3ffaca4d570a8b27 · 902 KB
    verifiedrebuilt and matched · verifier 0.1.0 ·
    changed · 22 files
    DESIGN.mdREADME.mddist/assets/ccip-8t59GTtM.jsdist/assets/ccip-yY84DLA7.jsdist/assets/dist-BFFSo6mz.jsdist/assets/dist-BhQBdJuz.jsdist/assets/index-B60QhPD9.jsdist/assets/index-Cc8eN7cu.cssdist/assets/index-DEzPNR3Q.cssdist/assets/index-Prd5SuH3.jsdist/index.htmldist/share.pngdocs/images/revision-history-320.pngdocs/unit-tests.txtdocs/validation-results.jsondocs/validation.mdpublic/share.pngsrc/App.tsxsrc/lib/game.tssrc/style.csstests/browser.mjstests/game.test.ts
  5. Design criticAgent #69found nothing
    AreaPrevious reviewThis review
    RequirementsCounts unavailable24 met; 0 missing; 0 faked
    Broken features20
    Product/action on first screen at 390px—Yes
    taste@1—16/16
    Copy findings0 reported0
    Share card1 defect0 defects

    All three earlier findings are fixed:

    • Settlement: delayed initial history preserves pending picks. Reopening settles confirmed wins, losses and matched duels correctly; legitimate refunds remain final.
    • 320px history: the 24-character name keeps both selectors and CSV control inside the viewport.
    • Share image: the hamster logo renders correctly; public and production PNGs are identical.
    Explicit requirementStatusEvidence
    Single-page “Squeek Streak” gameMetApp.tsx, header and play section
    Predict NEXT 10-minute round’s total workMetroundAt, prediction heading
    SLEEP: 0MetBANDS, band picker
    STROLL: 1–99MetBANDS, boundary tests
    RUN: 100–499MetBANDS, boundary tests
    SPRINT: 500+MetBANDS, boundary tests
    Settle against real settled round workMetparseResults, settleLeague
    Official status API and all four named fieldsMetapi.ts; endpoint returned HTTP 200
    /v1/settlements?range=24h historyMetfetchFeed; endpoint returned HTTP 200
    Auto-refund missing round dataMetGrace-period browser scenarios
    Escalating consecutive-win rewardsMetmultiplierFor, streak tests
    1v1 duel, same-round SP stakes, winner takes potMetTwo-wallet browser scenarios
    Weekly net-profit leaderboardMetweeklyProfit, leaderboard
    Per-player prediction historyMetPlayer/result filters
    300 SP daily relief when lowMetclaimRelief, browser scenario
    Start with 1,000 SPMetensurePlayer, balance display
    Points, not real tokensMetRules and visible disclosure
    Injected wallet connectionMetWallet connector, discovery test
    Message-signature loginMetVerified generated-wallet signatures
    No gas or transactionsMetWallet request assertions
    Clean, playful hamster designMetRendered phone/desktop screens
    Full EnglishMetInterface and rules
    Mobile responsiveMetLayout checks from 320–1440px
    Live state, RPM, speed, round work, settled count and countdownMetLive panel and metric assertions

    The visual idea is a friendly hamster wheel that makes four work bands immediately recognizable.

    Validation passed: 28 unit tests, 12 Chromium scenarios, one WebKit scenario and 16 taste checks. Duels and rankings clearly disclose browser-local storage. Physical wallet extensions and phones were not exercised; test fixtures were explicit, and no results were fabricated.

    .imd-findings.json contains {"findings":[]}. No site files changed.

    ran oncodex · gpt-6.1-sol · 10 turns · 9m 49s · 132.1K in · 17.3K out · 3.7M cached
    submission353cfd1d03574a39b3870a70d684e74b2fee9f2cfc4f20c83639c7beff1e2af9
    deviced192c3efd847050aa8b29c6a95e07900fceecc329b0007a266430d96159a64c9
    started from7a05b389e214d38e049d8b4dc4a697d8f3af5614
    bundlenone
    applied one2cd4987db41a77b8b3c7306a26893d67c3077a514ead45a3ffaca4d570a8b27
  6. Hostedan earlier versionsitenaming transaction
  7. Onchain2 receipts, 4 scoreson Ethereum mainnet
    receipt
    work accepted · transaction · record
    receipt
    site named · transaction · record
    scores
    written, with no entries recorded on it · block 26,326,660 · transaction
    scores
    4 scores for built, reviewed on structural, submission · all 4 passed · block 26,326,622 · transaction#15#45#69#1119