{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"7360793e-5c39-4c8f-8242-bba9598b7a53","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"6b52ece7f6ab26a0fce36552825edd760abe00f4f578f51d2b6e65908a0361f7","dependsOn":[],"execution":{"mustProduce":["dist/index.html"],"network":true,"profile":"none","requires":["network"],"skillHash":"b166f8ae3180dd8550019d4ca11bb9ac637e46ce9c93c32a5d519709af082637","skillId":"import-site","tools":[]},"key":"import_site","kind":"code","role":"implement","skillHash":"b166f8ae3180dd8550019d4ca11bb9ac637e46ce9c93c32a5d519709af082637","skillId":"import-site","state":"accepted"},{"acceptedSubmissionHash":"2399e4d64d6a3a27ec9e7c5aeb38db11c77b12fbfe0e88e5aaa094d864620d0c","dependsOn":["import_site"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"8189a3059fc9bb774ad7dcee66b87f32e25d781025f0e9f82a4c75182fe0ef19","skillId":"site-content-check","tools":[]},"key":"site_content_check","kind":"code","role":"review","skillHash":"8189a3059fc9bb774ad7dcee66b87f32e25d781025f0e9f82a4c75182fe0ef19","skillId":"site-content-check","state":"accepted"}],"objective":"Every 10 minutes Squeekchain certifies how much work the wheel did. Players bet testnet ETH on whether the next round lands over or under a line, then anyone can press Settle and the contract reads SqueekCore directly and pays winners pro rata. There is no admin, no fee and no oracle, and every stake is refunded if nobody backed the winner or SqueekCore never certifies the round.\n\nAI on the wheel: each upcoming round gets an AI line from a decay-weighted model of recent rounds. Players bet that the hamster beats the AI or that the AI holds, and a DeepSeek analyst explains the line in plain words. An Ask AI chat answers questions about the site in English or Vietnamese.\n\nAlso built in: lines taken from the wheel's recent quartiles, a leaderboard of top earners and AI slayers rebuilt from onchain events, invite links that open a specific round and bet, claim history with transaction links, and the full contract source inside the app.\n\nIt reads the live SqueekCore reported by the Squeekchain API, because the core in the published deployment record has stopped receiving settlements. The app warns if the API ever switches to another core.\n\nThe code repository is https://github.com/ekervo/wheel-odds and the executable is https://wheel-odds.vercel.app.","parentJobId":null,"planHash":"59d0a782512a4a31bf1e7aebf88f6cbc797fcb9991cd08fcd1f04881f099e832","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"7360793e-5c39-4c8f-8242-bba9598b7a53","publication":{"commit":null,"deliveredAt":null,"repoUrl":null},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51486","feedbackHash":"03d2b9b639cbcc787a7b150aa38b3a2df5de5448f74a9b50e0097e95251bb268","nodeKey":"import_site","submissionHash":"6b52ece7f6ab26a0fce36552825edd760abe00f4f578f51d2b6e65908a0361f7","tag1":"verification:structural","tag2":"acceptance-v2","value":1},{"agentId":"52276","feedbackHash":"a67e09142b120035414b000a20311f9791fd9bf5f991309bdc111c41a7541ca8","nodeKey":"site_content_check","submissionHash":"2399e4d64d6a3a27ec9e7c5aeb38db11c77b12fbfe0e88e5aaa094d864620d0c","tag1":"review:submission","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"9d416dad4877965b8bf129c30cba1e6cd3b89d570e84e2ad16ff5cc0ffd891c2","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"41822d343cdb63ba","findings":[{"citation":"resolved","description":"The hosted main bundle (dist/assets/index-sNWbgWDr.js) includes this share-base calculation. With the production BASE_URL './', ownBase resolves against location.origin + '/' instead of the current document directory. On a path-based IPFS gateway, ShareButton therefore copies a link to the gateway root and omits /ipfs/<CID>/. Friends cannot open the app or the selected bet from that link. This is a functional hosting advisory, not a hosting blocker.","line":5,"path":"src/lib/share.ts","reproduction":"Serve dist at https://gateway.example/ipfs/bafyExample/ and open it directly (window.self === window.top). Press 'Invite friends to round 783', or select line 250 / Over and press 'Share this bet'. getShareBase() returns https://gateway.example, so the copied bet link is https://gateway.example/?r=783&l=250&s=over. Expected: https://gateway.example/ipfs/bafyExample/?r=783&l=250&s=over. Reproduced by executing the unchanged src/lib/share.ts with production BASE_URL './' and window.location set to that gateway URL.","severity":"medium","snippet":"const ownBase = () => trimSlash(new URL(import.meta.env?.BASE_URL ?? '/', `${window.location.origin}/`).href)","title":"Invite links lose the IPFS gateway path"},{"citation":"resolved","description":"The hosted main bundle (dist/assets/index-sNWbgWDr.js) scans all market events but caps the ledger history used to recognize AI lines at the latest 400 rounds. Once an old settled round's forecast inputs fall outside that window, forecast() returns null, so buildLeaderboard() reclassifies its AI bets and wins as ordinary bets. The 'AI slayers' scores shrink or disappear solely because time passed, despite the UI describing a leaderboard across all settled markets. Fetch each settled target's required history, or retain its verified AI line, instead of limiting lifetime scoring to the most recent window. This is advisory, not a hosting blocker.","line":54,"path":"src/hooks/useLeaderboard.ts","reproduction":"Run useLeaderboard(10000)'s queryFn with a client returning two BetPlaced events for round 100, line 100: Alice stakes 0.001 ETH Over and Bob stakes 0.001 ETH Under; return Settled(100,100,200,true,false). Have roundPage return work=100 for every other certified round and work=200 for round 100. At state.settledThroughRound=200, the unchanged hook fetches enough history and returns Alice aiBets=1, aiBeats=1. Change only state.settledThroughRound to 1000 and supply the same historical work and events. The 400-round cap now fetches only rounds 601-1000, forecast(100) returns null, and the hook returns Alice aiBets=0, aiBeats=0. Expected her historical score to remain 1/1. Reproduced by executing the actual hook, fetchRecentRounds, forecast and buildLeaderboard with mocked chain reads.","severity":"medium","snippet":"        const count = want > 400n ? 400n : want > 0n ? want : 60n","title":"AI slayer rankings discard older wins as the wheel advances"},{"citation":"resolved","description":"In the hosted main bundle (dist/assets/index-sNWbgWDr.js), the selected market is stored as an offset from clock.current, while pickState and the BetPanel's amount persist. Every round boundary increments the selected market even if the player has already selected a specific round and entered a stake. The next click sends ETH to that new round without a new selection; this also happens when the originally chosen round is still open. Store the selected absolute round or close/reset the pending bet when its target changes. This is an advisory transaction-intent defect, not evidence of a wallet drainer or a hosting blocker.","line":29,"path":"src/components/MarketBoard.tsx","reproduction":"Using the production app with an injected mock wallet (record eth_sendTransaction without broadcasting), set the browser clock to 2026-11-01T00:09:00Z; with the configured genesis 1793022600 and duration 600 this is current round 782. Select tab #784, select Over on Runs at all, and enter 0.01 ETH. Advance the browser clock by 61 seconds without selecting another round. The selected tab changes to #785 and the open panel retains 0.01. Press 'Bet over 0': decoding the recorded transaction yields bet(785,0,true) with value 0.01 ETH. Expected the prepared bet to remain bet(784,0,true), or to be explicitly reset; round 784 is still open until 00:20Z. Reproduced in Chromium against the unchanged production bundle.","severity":"medium","snippet":"  const round = clock ? clock.current + BigInt(offset) : undefined","title":"An open bet panel silently changes its target round"}],"hash":"2399e4d64d6a3a27ec9e7c5aeb38db11c77b12fbfe0e88e5aaa094d864620d0c","nodeId":"ea58ecdc-169e-43fe-99d8-24cc65e8fd18","outcome":"completed","summary":"Saved three medium advisories to [.imd-findings.json](/home/imd4/.identitymd/work/7360793e-5c39-4c8f-8242-bba9598b7a53/ea58ecdc-169e-43fe-99d8-24cc65e8fd18/.imd-findings.json):\n\n- Prepared bets change rounds at rollover.\n- IPFS invite links lose the gateway path.\n- AI slayer rankings discard older wins.\n\nNo critical/high hosting blockers found. Reviewed all 85 export files and application sources. Six isolated Foundry checks passed. Application files unchanged.","treeHash":null,"usage":{"cachedInputTokens":6504744,"inputTokens":263059,"model":"gpt-6.1-sol","outputTokens":20200,"runtime":"codex","turns":7,"wallClockMs":303356}},{"artifacts":[],"attempt":1,"bundleHash":"25990702badd291ea56b5aaa8c495cc9d85d33dada12c480b37df6daea8934a6","device":"0e78515c4d95885a","findings":[],"hash":"6b52ece7f6ab26a0fce36552825edd760abe00f4f578f51d2b6e65908a0361f7","nodeId":"e1a2bf7a-b1f0-4e57-8299-5653f172f0f2","outcome":"completed","summary":"The site builds unchanged, and the output is in `dist/` with `dist/index.html`. I didn't run it in a browser or open the built page, so I only checked the build output.\n\n- **Package manager:** Bun 1.3.14, the version pinned in `.bun-version`. I installed it from npm into `/tmp` because it wasn't on the machine. Dependencies came from `bun install --frozen-lockfile`, which installed 833 packages from `bun.lock`.\n- **Build command:** `bun run build`, which runs `vite build`.\n- **Where it wrote:** `dist/` at the repository root, 2.9 MB, well under the 8 MiB limit.\n- **Asset paths:** they are relative. `vite.config.ts` already sets `base: './'`, so `index.html` loads `./assets/index-sNWbgWDr.js` and `./assets/index-DA2g4RVm.css`.\n- **Fonts:** `index.html` also links Google Fonts. That link is in the repository's own `index.html`, so I left it as it is.\n- **`.gitignore`:** I removed only the `dist/` line so the export can be committed. `git status` shows that edit and the new `dist/`, and nothing else changed.\n- **Extra file:** `dist/HamsterRoundMarket.sol` came from the repository's `public/` folder and is the contract source shown inside the app.\n- **`.well-known`:** I didn't create one, since the site doesn't serve anything from there.\n\nI haven't committed anything.","treeHash":"623be2fc7608682301a5f1a8ee2546a7ecef1a8c","usage":{"cachedInputTokens":73985,"inputTokens":12,"model":"claude-sonnet-5-5","outputTokens":1270,"runtime":"claude","turns":6,"wallClockMs":46531}}],"verification":[{"checks":[],"detail":"paths and tree verified; no suite was run for this kind of work","evaluation":"structural","profile":"none","status":"accepted","submissionHash":"6b52ece7f6ab26a0fce36552825edd760abe00f4f578f51d2b6e65908a0361f7","verifiedTreeHash":"623be2fc7608682301a5f1a8ee2546a7ecef1a8c","verifierVersion":"0.1.0+a6eb4461"}]}