{"workflow":{"id":"404e09fa-cadc-4f0a-9de1-3103786f62b1","objective":"Release Noughts (ERC-20 symbol NGHT) on Sepolia as an evm_project: the fixed-supply launch token plus one application contract. Token: Noughts (NGHT), total supply 1,000,000,000 NGHT with 18 decimals, minted once to the deployer. Application contract: TicTacToeWager. Currency: NGHT is the app's working currency. TicTacToeWager takes the NGHT address as its only constructor argument (constructorArgs [\"$token\"]), stores it immutable, exposes it as token(), and holds no NGHT at deploy; players get NGHT by swapping Sepolia ETH in the launch pool the factory seeds. Every payment in is approve + SafeERC20.safeTransferFrom (permit not required). TicTacToeWager has no payable function and no receive/fallback, so it never holds ETH. Payouts are pull-based (the recipient calls to collect; nothing is pushed to third parties), follow checks-effects-interactions and are nonReentrant. No owner, admin, pause or upgrade path. Two-player tic-tac-toe with equal NGHT stakes, many games by id. open(stake): stake >= 1 NGHT is pulled; the creator plays X. join(id): a different address pays the same stake and plays O; X moves first. cancel(id): creator only, before anyone joins; refunds the stake. move(id, cell): cell 0..8, only the player to move, only an empty cell, only while the game is active; the board is packed in one storage word. After each move the contract checks the 8 lines: a win credits the winner 2 x stake; a full board with no win is a draw and credits each player their stake. claimTimeout(id): if the player to move has not moved within 1 hour of the last move (or of join, for X's first move), the other player may claim 2 x stake. A finished game accepts no more moves or claims. withdraw() pays credited NGHT. Views: game(id), gameCount(), board(id), turn(id), moveDeadline(id), withdrawable(address), token(). Events: Opened, Joined, Moved(id, player, cell), Won, Drawn, TimedOut, Cancelled, Withdrawn. The site calls it a Sepolia test game with no real value. Tests (Foundry) must cover: every win line for both players, a draw, moving out of turn, an occupied or out-of-range cell, self-join, cancel after join refused, timeout at exactly 1 hour, moves after the end, and the invariant that NGHT held equals stakes of active or open games + withdrawable balances. The independent adversarial review must attack: win detection on packed bits, timeout claims by the wrong player or at the boundary, paying a game twice (win then timeout), and reentrancy on withdraw. Deploy through the project factory, then publish a one-page website to open or join a game, play on a 3x3 board, show whose turn it is and the move timer, and claim timeouts. The page reads the NGHT address from TicTacToeWager.token(), shows the connected wallet's NGHT balance, allowance and withdrawable balance, has an Approve step before every paying action and a Withdraw button, and says that NGHT comes from swapping Sepolia ETH in the launch pool (no in-page swap). Lists come from contract views and events only (no backend, no indexer). Keep it to one small page; the static export has index.html in dist/.","status":"completed","brief":"# Approved workflow\n\nRelease Noughts (ERC-20 symbol NGHT) on Sepolia as an evm_project: the fixed-supply launch token plus one application contract. Token: Noughts (NGHT), total supply 1,000,000,000 NGHT with 18 decimals, minted once to the deployer. Application contract: TicTacToeWager. Currency: NGHT is the app's working currency. TicTacToeWager takes the NGHT address as its only constructor argument (constructorArgs [\"$token\"]), stores it immutable, exposes it as token(), and holds no NGHT at deploy; players get NGHT by swapping Sepolia ETH in the launch pool the factory seeds. Every payment in is approve + SafeERC20.safeTransferFrom (permit not required). TicTacToeWager has no payable function and no receive/fallback, so it never holds ETH. Payouts are pull-based (the recipient calls to collect; nothing is pushed to third parties), follow checks-effects-interactions and are nonReentrant. No owner, admin, pause or upgrade path. Two-player tic-tac-toe with equal NGHT stakes, many games by id. open(stake): stake >= 1 NGHT is pulled; the creator plays X. join(id): a different address pays the same stake and plays O; X moves first. cancel(id): creator only, before anyone joins; refunds the stake. move(id, cell): cell 0..8, only the player to move, only an empty cell, only while the game is active; the board is packed in one storage word. After each move the contract checks the 8 lines: a win credits the winner 2 x stake; a full board with no win is a draw and credits each player their stake. claimTimeout(id): if the player to move has not moved within 1 hour of the last move (or of join, for X's first move), the other player may claim 2 x stake. A finished game accepts no more moves or claims. withdraw() pays credited NGHT. Views: game(id), gameCount(), board(id), turn(id), moveDeadline(id), withdrawable(address), token(). Events: Opened, Joined, Moved(id, player, cell), Won, Drawn, TimedOut, Cancelled, Withdrawn. The site calls it a Sepolia test game with no real value. Tests (Foundry) must cover: every win line for both players, a draw, moving out of turn, an occupied or out-of-range cell, self-join, cancel after join refused, timeout at exactly 1 hour, moves after the end, and the invariant that NGHT held equals stakes of active or open games + withdrawable balances. The independent adversarial review must attack: win detection on packed bits, timeout claims by the wrong player or at the boundary, paying a game twice (win then timeout), and reentrancy on withdraw. Deploy through the project factory, then publish a one-page website to open or join a game, play on a 3x3 board, show whose turn it is and the move timer, and claim timeouts. The page reads the NGHT address from TicTacToeWager.token(), shows the connected wallet's NGHT balance, allowance and withdrawable balance, has an Approve step before every paying action and a Withdraw button, and says that NGHT comes from swapping Sepolia ETH in the launch pool (no in-page swap). Lists come from contract views and events only (no backend, no indexer). Keep it to one small page; the static export has index.html in dist/.\n\nSepolia (11155111) only. GitHub publication and IPFS hosting are approved. Launch token: a separate fixed-supply ERC-20, 18 decimals, no constructor arguments, exactly 1,000,000,000 minted to msg.sender, no mint or admin functions. The factory sends that supply to LP and rewards, so no application contract may need a launch-token balance at deploy. Application contracts are fully configured in nonpayable constructors using only address, uint, bool or bytes32 arguments (no strings, arrays, proxies, delegatecall or selfdestruct); anything else is set at runtime. No owner unless the request names one, and then it is $owner. No external oracles, VRF or keepers: randomness is commit-reveal or a future blockhash read within 256 blocks with a refund path. foundry.toml sets bytecode_hash = \"none\". The website is a static export with index.html in dist/. Site label lab-tictactoe.\n\nBuild NGHT and TicTacToeWager (TicTacToeWager takes constructorArgs [\"$token\"]; stakes are NGHT) with Foundry tests and an independent adversarial review, deploy them through the project factory, then build the one-page website against the live deployment.\n","briefDigest":"07461500242b755372e9bcdfd95806edfc93ebfcb184b20cff829526728423e9"},"planning":null,"id":"ecdbb805-d7db-44f1-abfe-9b21ff5f2ef6","state":"completed","template":"shape:chain","objective":"WORKFLOW CONTRACT STAGE CONTEXT: the stage produces implemented and tested contracts, ABI documentation and an independently reviewed launch.json. Each assignment contributes only within its own role and write scope. Source-producing assignments own implementation, tests and ABI exports at docs/abi/<Contract>.json where their scope permits. The generated manifest assignment writes only launch.json. Review assignments inspect accepted source and manifest and return findings without editing files; they do not implement contracts or generate ABI files. Use the supplied canonical manifest guidance: policy and signed artifact linkage belong to services, while concrete source, constructor, policy or authorization conflicts remain review findings. Services publish source, attest, admit and deploy after this stage, then start the frontend. Read .imd/reads/workflow.md for the complete approved requirements and apply them to your assigned contribution; later service outcomes are not prerequisites of this assignment.","blockedReason":null,"createdAt":"2026-09-27T05:32:22.623Z","updatedAt":"2026-09-27T05:52:36.552Z","paidBy":"0x8a3b860f6dbfbbbb07f21905ed8cb0234538bdc8","via":"api.imd.fun","parentJobId":null,"project":{"id":"ecdbb805-d7db-44f1-abfe-9b21ff5f2ef6","head":"bfda8ddc-a696-4fbc-81dd-4f92e6329b4a","running":null,"versions":[{"jobId":"ecdbb805-d7db-44f1-abfe-9b21ff5f2ef6","workflowId":"404e09fa-cadc-4f0a-9de1-3103786f62b1","objective":"Release Noughts (ERC-20 symbol NGHT) on Sepolia as an evm_project: the fixed-supply launch token plus one application contract. Token: Noughts (NGHT), total supply 1,000,000,000 NGHT with 18 decimals, minted once to the deployer. Application contract: TicTacToeWager. Currency: NGHT is the app's working currency. TicTacToeWager takes the NGHT address as its only constructor argument (constructorArgs [\"$token\"]), stores it immutable, exposes it as token(), and holds no NGHT at deploy; players get NGHT by swapping Sepolia ETH in the launch pool the factory seeds. Every payment in is approve + SafeERC20.safeTransferFrom (permit not required). TicTacToeWager has no payable function and no receive/fallback, so it never holds ETH. Payouts are pull-based (the recipient calls to collect; nothing is pushed to third parties), follow checks-effects-interactions and are nonReentrant. No owner, admin, pause or upgrade path. Two-player tic-tac-toe with equal NGHT stakes, many games by id. open(stake): stake >= 1 NGHT is pulled; the creator plays X. join(id): a different address pays the same stake and plays O; X moves first. cancel(id): creator only, before anyone joins; refunds the stake. move(id, cell): cell 0..8, only the player to move, only an empty cell, only while the game is active; the board is packed in one storage word. After each move the contract checks the 8 lines: a win credits the winner 2 x stake; a full board with no win is a draw and credits each player their stake. claimTimeout(id): if the player to move has not moved within 1 hour of the last move (or of join, for X's first move), the other player may claim 2 x stake. A finished game accepts no more moves or claims. withdraw() pays credited NGHT. Views: game(id), gameCount(), board(id), turn(id), moveDeadline(id), withdrawable(address), token(). Events: Opened, Joined, Moved(id, player, cell), Won, Drawn, TimedOut, Cancelled, Withdrawn. The site calls it a Sepolia test game with no real value. Tests (Foundry) must cover: every win line for both players, a draw, moving out of turn, an occupied or out-of-range cell, self-join, cancel after join refused, timeout at exactly 1 hour, moves after the end, and the invariant that NGHT held equals stakes of active or open games + withdrawable balances. The independent adversarial review must attack: win detection on packed bits, timeout claims by the wrong player or at the boundary, paying a game twice (win then timeout), and reentrancy on withdraw. Deploy through the project factory, then publish a one-page website to open or join a game, play on a 3x3 board, show whose turn it is and the move timer, and claim timeouts. The page reads the NGHT address from TicTacToeWager.token(), shows the connected wallet's NGHT balance, allowance and withdrawable balance, has an Approve step before every paying action and a Withdraw button, and says that NGHT comes from swapping Sepolia ETH in the launch pool (no in-page swap). Lists come from contract views and events only (no backend, no indexer). Keep it to one small page; the static export has index.html in dist/.","baseCommit":"0243d7da4a4337ae8b16bcdf15bb4ead736fd68f","state":"completed","createdAt":"2026-09-27T05:32:22.623Z"}]},"deliver":true,"host":false,"site":null,"launch":{"requested":true,"kind":"evm_project","id":"14ab260c-c63f-40c2-b1c4-8dbc94c39f89","status":"live","chainId":11155111},"oracleRequestId":null,"delivery":{"repoUrl":"https://github.com/identity-md-launches/launch-282-tictactoewager","pullRequestUrl":null,"commit":"6f077123785d0ab280b4f1513807d028038c79e3","deliveredAt":"2026-09-27T05:52:51.440Z","media":null},"media":null,"nodes":[{"key":"adversarial_review","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project","manifest"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-09-27T05:52:36.552Z","verdict":null,"seat":{"tokenId":"1649","agentId":"50975"},"live":null},{"key":"build_contract_project","role":"implement","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-09-27T05:43:32.846Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ff982c0f","verifiedTreeHash":"c376b2f38d3a253fa1a0fae568f229d2aa1ffa0b","at":"2026-09-27T05:43:32.850Z","failedChecks":[]},"seat":{"tokenId":"901","agentId":"51358"},"live":null},{"key":"manifest","role":"integrate","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":["launch.json"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-09-27T05:45:38.712Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ff982c0f","verifiedTreeHash":"dc344a8690f695a423aa3d7b3db8fa939a4c1b9e","at":"2026-09-27T05:45:38.715Z","failedChecks":[]},"seat":{"tokenId":"1433","agentId":"50990"},"live":null}],"reviews":[{"status":"sent","chainId":1,"txHash":"0xf26ca12818c02fdca5fd1d2daadde1bd4e7e8709f5d37ec4bf5936cb0aa8b557","blockNumber":26115346,"sentAt":"2026-10-04T00:17:27.113Z","entries":[]},{"status":"sent","chainId":1,"txHash":"0xe4df615244c887d724064a8f9954aa998c60beefba9dfb4db8ce5611d5c9b2a7","blockNumber":26114129,"sentAt":"2026-10-03T20:13:38.926Z","entries":[{"nodeKey":"adversarial_review","agentId":"50975","value":1,"role":"review:submission"},{"nodeKey":"build_contract_project","agentId":"51358","value":1,"role":"verification:checks"},{"nodeKey":"manifest","agentId":"50990","value":1,"role":"verification:checks"}]}]}