{"workflow":null,"planning":null,"id":"464306a5-5aae-4ad5-95be-b83776f5fc81","state":"completed","template":"shape:chain","objective":"PLANT ORGANISM — one contract on robinhood chain: the body of a digital plant that lives somewhere real; its location's weather decides how it grows, holders decide where it lives. no token here (token + pool + hook come in a second launch that pays into this contract). no admin, no upgrade, no pause; all numbers constant. constructor (static): IMD = 0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127, Intake = 0x1397434cd35e8a9c8ac312a61d3a285eb31dea56, action = bytes32(\"oracle.request@oracle-1\") (right-padded utf-8), signer = 0x5598aa9146215bc13eb26f2c692ad1461fd32982, FALLBACK_CELL = 10223579, deployer = $owner. use the oracle-consumer reference (OracleAttestation.sol, IIntake) exactly as launch 976 AskOracle did. cell = uint16(int16 lat, quarter degrees)<<16 | uint16(int16 lon), lat in [−360,359], lon in [−720,719], never 0; centre = v*0.25+0.125; lisbon (155, −37) = 10223579 → 38.875, −9.125. day = unix day; lastSettledDay = deployment day.\nBIND (only privileged call, once): bind(hook) by deployer while unbound: requires hook.organism() == this; stores hook, hook.plant(), bind day. then the deployer has no powers. unbound: park/redeem revert; days before bind settle empty (no oracle, no hours, no read) in one bounded catch-up call.\nMONEY: all IMD sent in counts. pot = IMD held − backing − IMD owed (gardeners, bounties, fee advances).\nSTATE: location (cell; 0 = nowhere), water 0..100 (starts 50), backing, parked[cell][holder], parkedTotal[cell], challenger, burned, lastSettledDay.\nHOURS (24 per utc day, in settle, hour 0 first): rain → water = min(100, water+3). sun with water ≥ 1 → SIP: water −1; sip = pot/10; backing += 2/3 sip; gardener pool += 1/3 sip.\nCHALLENGER (on chain, O(1)): park(cell) sets challenger = cell if cell ≠ location and parkedTotal[cell] > parkedTotal[challenger]; challenge(cell), anyone, same rule; a move resets it to 0. no list on chain.\nHEARTBEAT(), anyone, for D = lastSettledDay+1 once that utc day ended, nothing pending, location ≠ 0 (location = 0 → settle(D) directly, see BIRTH): builds the question from the current location and D; pays Intake.priceOf(action, IMD) from the pot (if short, from the caller, owed back at the next settle); approves exactly that; Intake.request(action, body, Callback(this, onOracleResult.selector), IMD, price), body {\"v\":1,\"question\":<json-escaped>,\"chainId\":4663,\"window\":{\"hours\":24},\"answerType\":\"bytes32\",\"evidence\":\"panel\",\"panelSize\":15,\"quorum\":10,\"validForSeconds\":86400,\"guards\":{\"sources\":[\"https://api.open-meteo.com\"],\"minSources\":1}}; records pending {requestId, D, challenger, caller, askedAt}. unanswered after 24h, or incomplete → anyone clears it; the next heartbeat for the same D waits 6h after the clear.\nQUESTION (built on chain; <lat>,<lon> = cell centre, 3 decimals, minus sign; <date> = civil date of D, yyyy-mm-dd): \"weather at latitude <lat> longitude <lon> on <date> utc, from https://api.open-meteo.com/v1/forecast?latitude=<lat>&longitude=<lon>&past_days=92&hourly=is_day,cloud_cover,precipitation&timezone=UTC, the 24 rows of <date>. hour h (0..23) is SUNNY if is_day=1 and cloud_cover<50 and precipitation=0; RAINY if precipitation>=0.2. answer one bytes32 = sunMask | rainMask<<24 | complete<<48 | <D><<96, bit h of each mask = hour h; complete = 1 if all 24 rows have values, else 0 with masks 0.\"\nonOracleResult(requestId, attestation, sig): only from the Intake, only for the pending requestId; _verifyAttestation (this contract is the verifying contract); require answerType bytes32, agreed ≥ quorum, chainId 4663, issuedAt ≥ askedAt, bits 96..127 == D; _consume; store the word; emit Received. ≤ 200k gas: it stores, it does not apply.\nSETTLE(), anyone, once the word for D is stored: bit 48 == 0 → clear pending, emit Incomplete, incompletes[D]++; nothing else unless this was the 3rd incomplete for D: then settle D with no hours (READ still runs, so holders can move the plant away from a spot without data). else apply the 24 HOURS from bits 0..23 (sun) and 24..47 (rain); READ with L = the pending challenger; lastSettledDay = D; pay the heartbeat caller 1% of pot + anything owed; emit Settled(day, word, sips, backing, water, location).\nREAD: C = location. move if L ≠ 0, L ≠ C, parkedTotal[L] > parkedTotal[C] and parkedTotal[L] ≥ 5% of PLANT.totalSupply(), all read now → location = L, challenger = 0 (Moved). no minimum stay. gardener pool → pro rata to holders parked behind C as of the previous settle (reward-per-token accumulators + per-cell checkpoints; parked mid-day activates next settle; unparked drops out); nobody → backing. claim() any time, IMD.\nPARK/UNPARK(cell, amount): any time, any valid cell, incl. the current one. REDEEM(amount): floor = backing / (PLANT.totalSupply() − burned); pays amount × floor × 90% in IMD from backing; 10% stays; the PLANT stays here forever (burned += amount). unpark first. floor never decreases.\nBIRTH: location 0, no oracle: while bound and location = 0, settle(D) applies no hours and READs with L = the current challenger; after 3 such settles without a move → location = FALLBACK_CELL.\nDEAD PLANT (final): 30 days past max(bind day, lastSettledDay) without a successful settle → pot merges into backing, redeem pays full floor, heartbeat and park stop; unpark and claim still work.\nROTATION (no governance): rotate(newSigner, newIntake, newAction, nonce, sig): EIP-712 message from the CURRENT oracle signer over (this contract, chainid, new values, nonce); old signer accepted 30 more days. nothing else is settable by anyone.\nSAFETY: reentrancy guards; external calls only to IMD, PLANT, the Intake; no delegatecall/selfdestruct/proxy/ownable/pausable/roles; rounding toward backing; settle O(24), never O(holders); public reads of all state + floor + pot + the question string; events for everything.\nTESTS (foundry, mock Intake as in 976): body bytes exact for a known cell and day (date and coordinate formatting, negative lat/lon); callback only from the Intake for the pending id, ≤ 200k gas; fixture bytes32 attestation accepted; expired/wrong-domain/wrong-signer/wrong-type/wrong-day rejected; incomplete → no change, 6h wait, re-ask; 3rd incomplete → empty day with READ; park → settle → claim; challenger tracking; invariants (floor never decreases; pot+backing+owed == IMD held; burned never leaves); move, birth, fallback, catch-up, dead plant, rotation, bind-once; settle ≤ 400k gas. one-page README.","blockedReason":null,"createdAt":"2026-10-08T04:54:18.201Z","updatedAt":"2026-10-08T07:21:22.634Z","paidBy":"0x21f398e7b17adc3ce2633d0ff7b7f892fe00f9c9","parentJobId":null,"project":{"id":"464306a5-5aae-4ad5-95be-b83776f5fc81","head":"464306a5-5aae-4ad5-95be-b83776f5fc81","running":null,"versions":[{"jobId":"464306a5-5aae-4ad5-95be-b83776f5fc81","workflowId":null,"objective":"PLANT ORGANISM — one contract on robinhood chain: the body of a digital plant that lives somewhere real; its location's weather decides how it grows, holders decide where it lives. no token here (token + pool + hook come in a second launch that pays into this contract). no admin, no upgrade, no pause; all numbers constant. constructor (static): IMD = 0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127, Intake = 0x1397434cd35e8a9c8ac312a61d3a285eb31dea56, action = bytes32(\"oracle.request@oracle-1\") (right-padded utf-8), signer = 0x5598aa9146215bc13eb26f2c692ad1461fd32982, FALLBACK_CELL = 10223579, deployer = $owner. use the oracle-consumer reference (OracleAttestation.sol, IIntake) exactly as launch 976 AskOracle did. cell = uint16(int16 lat, quarter degrees)<<16 | uint16(int16 lon), lat in [−360,359], lon in [−720,719], never 0; centre = v*0.25+0.125; lisbon (155, −37) = 10223579 → 38.875, −9.125. day = unix day; lastSettledDay = deployment day.\nBIND (only privileged call, once): bind(hook) by deployer while unbound: requires hook.organism() == this; stores hook, hook.plant(), bind day. then the deployer has no powers. unbound: park/redeem revert; days before bind settle empty (no oracle, no hours, no read) in one bounded catch-up call.\nMONEY: all IMD sent in counts. pot = IMD held − backing − IMD owed (gardeners, bounties, fee advances).\nSTATE: location (cell; 0 = nowhere), water 0..100 (starts 50), backing, parked[cell][holder], parkedTotal[cell], challenger, burned, lastSettledDay.\nHOURS (24 per utc day, in settle, hour 0 first): rain → water = min(100, water+3). sun with water ≥ 1 → SIP: water −1; sip = pot/10; backing += 2/3 sip; gardener pool += 1/3 sip.\nCHALLENGER (on chain, O(1)): park(cell) sets challenger = cell if cell ≠ location and parkedTotal[cell] > parkedTotal[challenger]; challenge(cell), anyone, same rule; a move resets it to 0. no list on chain.\nHEARTBEAT(), anyone, for D = lastSettledDay+1 once that utc day ended, nothing pending, location ≠ 0 (location = 0 → settle(D) directly, see BIRTH): builds the question from the current location and D; pays Intake.priceOf(action, IMD) from the pot (if short, from the caller, owed back at the next settle); approves exactly that; Intake.request(action, body, Callback(this, onOracleResult.selector), IMD, price), body {\"v\":1,\"question\":<json-escaped>,\"chainId\":4663,\"window\":{\"hours\":24},\"answerType\":\"bytes32\",\"evidence\":\"panel\",\"panelSize\":15,\"quorum\":10,\"validForSeconds\":86400,\"guards\":{\"sources\":[\"https://api.open-meteo.com\"],\"minSources\":1}}; records pending {requestId, D, challenger, caller, askedAt}. unanswered after 24h, or incomplete → anyone clears it; the next heartbeat for the same D waits 6h after the clear.\nQUESTION (built on chain; <lat>,<lon> = cell centre, 3 decimals, minus sign; <date> = civil date of D, yyyy-mm-dd): \"weather at latitude <lat> longitude <lon> on <date> utc, from https://api.open-meteo.com/v1/forecast?latitude=<lat>&longitude=<lon>&past_days=92&hourly=is_day,cloud_cover,precipitation&timezone=UTC, the 24 rows of <date>. hour h (0..23) is SUNNY if is_day=1 and cloud_cover<50 and precipitation=0; RAINY if precipitation>=0.2. answer one bytes32 = sunMask | rainMask<<24 | complete<<48 | <D><<96, bit h of each mask = hour h; complete = 1 if all 24 rows have values, else 0 with masks 0.\"\nonOracleResult(requestId, attestation, sig): only from the Intake, only for the pending requestId; _verifyAttestation (this contract is the verifying contract); require answerType bytes32, agreed ≥ quorum, chainId 4663, issuedAt ≥ askedAt, bits 96..127 == D; _consume; store the word; emit Received. ≤ 200k gas: it stores, it does not apply.\nSETTLE(), anyone, once the word for D is stored: bit 48 == 0 → clear pending, emit Incomplete, incompletes[D]++; nothing else unless this was the 3rd incomplete for D: then settle D with no hours (READ still runs, so holders can move the plant away from a spot without data). else apply the 24 HOURS from bits 0..23 (sun) and 24..47 (rain); READ with L = the pending challenger; lastSettledDay = D; pay the heartbeat caller 1% of pot + anything owed; emit Settled(day, word, sips, backing, water, location).\nREAD: C = location. move if L ≠ 0, L ≠ C, parkedTotal[L] > parkedTotal[C] and parkedTotal[L] ≥ 5% of PLANT.totalSupply(), all read now → location = L, challenger = 0 (Moved). no minimum stay. gardener pool → pro rata to holders parked behind C as of the previous settle (reward-per-token accumulators + per-cell checkpoints; parked mid-day activates next settle; unparked drops out); nobody → backing. claim() any time, IMD.\nPARK/UNPARK(cell, amount): any time, any valid cell, incl. the current one. REDEEM(amount): floor = backing / (PLANT.totalSupply() − burned); pays amount × floor × 90% in IMD from backing; 10% stays; the PLANT stays here forever (burned += amount). unpark first. floor never decreases.\nBIRTH: location 0, no oracle: while bound and location = 0, settle(D) applies no hours and READs with L = the current challenger; after 3 such settles without a move → location = FALLBACK_CELL.\nDEAD PLANT (final): 30 days past max(bind day, lastSettledDay) without a successful settle → pot merges into backing, redeem pays full floor, heartbeat and park stop; unpark and claim still work.\nROTATION (no governance): rotate(newSigner, newIntake, newAction, nonce, sig): EIP-712 message from the CURRENT oracle signer over (this contract, chainid, new values, nonce); old signer accepted 30 more days. nothing else is settable by anyone.\nSAFETY: reentrancy guards; external calls only to IMD, PLANT, the Intake; no delegatecall/selfdestruct/proxy/ownable/pausable/roles; rounding toward backing; settle O(24), never O(holders); public reads of all state + floor + pot + the question string; events for everything.\nTESTS (foundry, mock Intake as in 976): body bytes exact for a known cell and day (date and coordinate formatting, negative lat/lon); callback only from the Intake for the pending id, ≤ 200k gas; fixture bytes32 attestation accepted; expired/wrong-domain/wrong-signer/wrong-type/wrong-day rejected; incomplete → no change, 6h wait, re-ask; 3rd incomplete → empty day with READ; park → settle → claim; challenger tracking; invariants (floor never decreases; pot+backing+owed == IMD held; burned never leaves); move, birth, fallback, catch-up, dead plant, rotation, bind-once; settle ≤ 400k gas. one-page README.","baseCommit":"0243d7da4a4337ae8b16bcdf15bb4ead736fd68f","state":"completed","createdAt":"2026-10-08T04:54:18.201Z"}]},"deliver":true,"host":false,"site":null,"launch":{"requested":true,"kind":"evm_contracts","id":"10698c09-681d-41eb-844e-8c58f701a589","status":"parked","chainId":4663},"oracleRequestId":null,"delivery":{"repoUrl":"https://github.com/identity-md-launches/launch-1003-plant-organism-one","pullRequestUrl":"https://github.com/identity-md-launches/launch-1003-plant-organism-one/pull/1","commit":"53431ddfea0ce692f5f4f570b6eee8bf3db39d08","deliveredAt":"2026-10-08T07:21:31.860Z","media":null},"media":null,"nodes":[{"key":"audit_economics","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T05:56:04.214Z","verdict":null,"seat":{"tokenId":"154","agentId":"52017"},"live":null},{"key":"audit_flow","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T05:38:40.216Z","verdict":null,"seat":{"tokenId":"1059","agentId":"51425"},"live":null},{"key":"audit_judge","role":"review","state":"accepted","attempt":1,"revisions":2,"judgeRevisions":2,"dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"allowedPaths":[],"failureReason":null,"dispatchNote":"judge findings unresolved after 2 revisions: no revision budget left for build_contract_project (2 revisions, 2 from the judge) — Birth settle still reads live stake: PLANT held for one transaction decides where the plant is born and its leftover 1 wei takes the whole first-day gardener pool","dispatchNoteAt":"2026-10-08T07:21:22.634Z","updatedAt":"2026-10-08T07:21:22.634Z","verdict":null,"seat":{"tokenId":"57","agentId":"52250"},"live":null},{"key":"audit_math","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T05:40:16.378Z","verdict":null,"seat":{"tokenId":"1073","agentId":"51510"},"live":null},{"key":"audit_permissions","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T05:38:45.626Z","verdict":null,"seat":{"tokenId":"368","agentId":"51891"},"live":null},{"key":"build_contract_project","role":"implement","state":"accepted","attempt":1,"revisions":2,"judgeRevisions":2,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T06:56:31.209Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ad90ce4c","verifiedTreeHash":"3dea5fb0b3835cd6c9bca08a74b03254369787fa","at":"2026-10-08T06:56:31.208Z","failedChecks":[]},"seat":{"tokenId":"1974","agentId":"51361"},"live":null},{"key":"manifest","role":"integrate","state":"accepted","attempt":1,"revisions":2,"judgeRevisions":2,"dependsOn":["build_contract_project"],"allowedPaths":["launch.json"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T07:03:04.906Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ad90ce4c","verifiedTreeHash":"7c4c63efd1f6297947bd2c8057fd349277857cda","at":"2026-10-08T07:03:04.905Z","failedChecks":[]},"seat":{"tokenId":"70","agentId":"51284"},"live":null},{"key":"write_foundry_tests","role":"tests","state":"accepted","attempt":1,"revisions":2,"judgeRevisions":2,"dependsOn":["build_contract_project"],"allowedPaths":["test","test/**"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-08T07:10:56.004Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ad90ce4c","verifiedTreeHash":"83c6e5419937cf57233bd04598f65045b3316ebb","at":"2026-10-08T07:10:56.002Z","failedChecks":[]},"seat":{"tokenId":"1485","agentId":"52233"},"live":null}],"reviews":[{"status":"queued","chainId":1,"txHash":null,"blockNumber":null,"sentAt":null,"entries":[{"nodeKey":"audit_economics","agentId":"52017","value":1,"role":"review:submission"},{"nodeKey":"audit_flow","agentId":"51425","value":1,"role":"review:submission"},{"nodeKey":"audit_judge","agentId":"51081","value":1,"role":"review:submission"},{"nodeKey":"audit_judge","agentId":"51026","value":1,"role":"review:submission"},{"nodeKey":"audit_judge","agentId":"52250","value":1,"role":"review:submission"},{"nodeKey":"audit_math","agentId":"51510","value":1,"role":"review:submission"},{"nodeKey":"audit_permissions","agentId":"51891","value":1,"role":"review:submission"},{"nodeKey":"build_contract_project","agentId":"51236","value":1,"role":"verification:checks"},{"nodeKey":"build_contract_project","agentId":"51361","value":1,"role":"verification:checks"},{"nodeKey":"build_contract_project","agentId":"52168","value":1,"role":"verification:checks"},{"nodeKey":"manifest","agentId":"51233","value":1,"role":"verification:checks"},{"nodeKey":"manifest","agentId":"50990","value":1,"role":"verification:checks"},{"nodeKey":"manifest","agentId":"51284","value":1,"role":"verification:checks"},{"nodeKey":"write_foundry_tests","agentId":"52233","value":1,"role":"verification:checks"},{"nodeKey":"write_foundry_tests","agentId":"51167","value":1,"role":"verification:checks"},{"nodeKey":"write_foundry_tests","agentId":"51098","value":1,"role":"verification:checks"}]}]}