{"workflow":null,"planning":null,"id":"88af5a8c-2e49-4266-ab48-04ae593392fc","state":"completed","template":"skill:build-website","objective":"Add a website for this project's deployed vault, BaskVault at 0x518aa023c1b982a0a64b207b7d3a19bf973796e1 on Robinhood Chain (chain id 4663). The project is called Basket Protocol; use that as the site title. Its token is Basket, ticker BASK. Do not change or redeploy any contract. Simplest site that does what is written here; add no page or feature it does not state.\n\nRules. Static site: public RPC reads and wallet transactions only; the wallet must be on chain 4663 to send. Read every address outside this launch from the vault's views. Make few RPC calls: use the vault's aggregate views, and Multicall3 if it exists on the chain. Write \"Stock Tokens\" (never \"tokenized ...\"); no Robinhood name, logo or ticker beyond the chain's name. Show a Stock Token by its symbol() only, never its name(). Text read from chain, such as a feed's description(), is shown exactly as it is. Take every function name, struct field and reason code from the deployed ABI and the repository README, not from this text.\nAny read can revert or run out of gas (allAssets and depositStatus call every feed): give each read a gas limit of 10,000,000 (with 25 stocks, allAssets, depositStatus and previewDeposit each need over 1,000,000, and about 3,000,000 with 64), and send those three each as its own eth_call, never inside a Multicall3 batch; show what failed as \"unreadable\" and keep the rest of the page working. If allAssets() fails, read assetCount(), assets(i), managed(token) and totalOwed(token) one by one and each feed's latestRoundData() directly.\nBanner on every page: \"Not for US persons. Stock Tokens are not offered in the United States and are restricted in other countries. Basket Protocol is not affiliated with the issuer of Stock Tokens.\"\n\nPages.\n1. Vault. The vault has no NAV view: compute NAV on the page as the sum of managed x answer / 1e8 over every asset that is not retired, and NAV per BASK as NAV / totalSupply(). Show both, and NAV against NAV_CAP; mark them stale when a held stock's price is more than 26 hours old. Each stock: symbol, price, age of the price, share of NAV, status (open, closed or retired), on probation or not, short or not, amount owed. Say once that a retired stock counts 0 in NAV and for new deposits but is still paid out on redemption. For each open stock, whether it takes deposits now, from depositStatus(token) (it needs a listed token; the zero address always reads \"not listed\"); if not, the reason in plain words and the stock at fault (none when the returned address is zero). State the hours: Monday to Friday, 15:30 to 19:30 UTC, closed on US market holidays.\n2. Deposit. Choose an open stock and an amount; show the preview, the 0.5% fee and the BASK received (if previewDeposit reverts with DepositUnavailable(reason, asset), show that reason in plain words, not \"unreadable\"; the NAV, per-stock and daily caps appear only this way); approve, then deposit with minSharesOut 0.5% under the preview and a 10-minute deadline. Next to the button: \"Deposits are credited at the on-chain feed price, which can differ from the market by about 0.5% either way.\"\n3. Redeem. Enter BASK; show every stock amount from the preview, retired stocks included, and the 0.5% fee; redeem with each minimum 0.1% under the preview and a 10-minute deadline. Whenever a wallet is connected, not only after a redeem, list every stock, retired ones included, where owed(wallet, token) is above zero (wallet first, token second), each with a claim button that calls claim(token, to); to is the connected wallet unless the user enters another address (never the zero address), which is needed when the token refuses the wallet. A claim fails while the issuer pauses the stock; say it can be retried later. Say plainly that redemption is always open and pays a share of every stock.\n4. Owner. Visible to everyone; each button works only for the wallet the contract allows and shows who that is: owner() for everything except close and pause (owner() or guardian()), Cancel (see below), accept ownership (pendingOwner()) and Execute (anyone).\n   - Launch: a box to paste lines of \"TICKER tokenAddress feedAddress\" and a button that lists them all in one transaction. Then a table of what is listed: token symbol, the feed's description() and its current price side by side, so each pairing can be checked. Then \"Finalize genesis\", with a confirmation that it cannot be undone, that listed stocks can never be removed, and that deposits open 72 hours later.\n   - Later: forms to propose a new stock, a replacement feed, a band re-centre, reopening a stock, retiring a closed stock, a new guardian and a higher NAV cap (typed in dollars and sent as dollars x 1e18). Retire asks for confirmation that it cannot be undone: the stock is closed for good and counts 0 for new deposits, while redemption still pays it out, so new depositors take a share of its value from current holders. A list of pending proposals, read in pages with pendingProposals, showing what each does (for a new stock or a replacement feed: the token's symbol, the new feed's description() and its current price side by side, so the pairing can be checked before anyone executes it) and when it can be executed. Before showing Execute (anyone may press it), simulate the call; if it would revert, show the reason instead of the button. Cancel for the owner, or the guardian except on a new-guardian proposal.\n   - Controls: close a stock, pause and unpause deposits, lower the NAV cap (typed in dollars and sent as dollars x 1e18; this also cancels every pending raise), set the fee recipient (once, with a warning that it is final), transfer and accept ownership (with a warning that the new owner must not be the guardian).\n5. Losses. For each stock that is short, retired ones included: the shortfall, and the flag and recognise buttons anyone can press, with the date recognition becomes possible.\n\nCheck before delivery: every button reaches the right function with the right arguments against the deployed contract on a local fork or the live chain in read-only mode; the page works with no wallet connected; nothing is hidden from visitors who are not the owner.\n\nThe look: Grocery store theme to match the name Basket: shopping-basket and shelf price-tag motifs, warm fresh colours; still clean and easy to read, with numbers and warnings kept plain.","blockedReason":null,"createdAt":"2026-10-07T15:38:06.239Z","updatedAt":"2026-10-07T16:35:08.609Z","paidBy":"0x30b57ecf51d19abced7f6f70974e6fbb6f3b9da3","parentJobId":"9d7bffba-141b-4e33-be9c-1bfa450d9384","project":{"id":"9d7bffba-141b-4e33-be9c-1bfa450d9384","head":"23842d8f-4cdf-4f06-be9d-9f68a265120c","running":"15696011-9cac-4cd3-832c-edcfc310743a","versions":[{"jobId":"9d7bffba-141b-4e33-be9c-1bfa450d9384","workflowId":null,"objective":"Basket Protocol vault: an index vault for Stock Tokens on Robinhood Chain (chain id 4663). Contracts only: no launch token, pool or website. BASK is the vault's own ERC-20 share (18 decimals). Write \"Stock Tokens\", never \"tokenized\"; no Robinhood name, logo or ticker beyond the chain's name.\nToken name: Basket\nToken symbol: BASK\nTotal supply: 0 at deployment, no cap: deposit mints, redeem burns\n\nBUILD RULES\n- Simplest code that satisfies this text: add no feature, role, setting or safeguard.\n- solc 0.8.26, optimizer on, 200 runs, evm cancun, bytecode_hash none; custom errors.\n- If BaskVault exceeds 24,000 bytes of runtime, move views into BaskLens(address vault = $contract:BaskVault); never drop a check.\n- Constructors call no other contract. Time is block.timestamp, never block.number.\n- No proxy, delegatecall, selfdestruct, rescue or sweep. User-facing state changes are nonReentrant and emit events.\n\nMANIFEST\n1. BaskVault(address owner_, address guardian_): owner_ = 0x30B57ECf51D19ABcED7F6f70974e6fBb6f3b9Da3, guardian_ = 0x5ed39AF86f2C00ad99913B5d727bD68f2A904B68, written as these literals. Reverts if either is zero or they are equal.\nSTOCK_FACTORY = 0x4783C67b63dE2B358Ac5951a7D41F47A38F3C046 is a source constant.\n\nOutside contracts (on chain 4663 only; tests mock exactly these functions under test/; no fork tests, no vm.env):\n- Stock Token: ERC-20, 18 decimals, uid() returns bytes32, oraclePaused() returns bool.\n- STOCK_FACTORY.tokenAddress(bytes32 uid) returns address.\n- Feed: Chainlink proxy: decimals() is 8, aggregator() returns address, latestRoundData(); answer = USD per whole token.\n\nASSETS: a list of (token, feed, open, retired, minAnswer, maxAnswer, listedAt), at most 64, empty at deployment, never removed. managed[token] is the accounting balance: value never uses balanceOf and tokens sent directly are ignored.\nListing checks, at proposal and again at execution: token not listed; token.decimals() == 18; STOCK_FACTORY.tokenAddress(token.uid()) == token; feed.decimals() == 8; feed.aggregator() != 0; feed not used by another asset; answer > 0. On listing open = true, minAnswer = answer / 4, maxAnswer = answer * 4.\nGenesis: until the owner calls finalizeGenesis() (once, needs 3 or more assets), proposeAsset(token, feed) and proposeAssets(tokens[], feeds[]) list at once and deposits are impossible. Deposits open 72 hours after finalizeGenesis().\nOwner proposals (genesis listing is direct): list an asset; replace an asset's feed (feed checks and new answer inside the band, both times); re-centre a band on the answer at execution, under 26 hours old; reopen an asset (cancelled by any later close); retire an asset (closed both times); replace the guardian; raise NAV_CAP. A proposal waits 7 days, then anyone may execute it; it lapses 7 days later; the owner may cancel it, as may the guardian unless it replaces the guardian. One listing or feed replacement executes per 24 hours. An asset listed after genesis is on probation for 30 days. A retired asset is closed for good, skipped by every deposit check, 0 in NAV.\n\nPRICE is valid only if the feed read succeeds, answer > 0, minAnswer <= answer <= maxAnswer, updatedAt <= now, now - updatedAt <= 26 hours, and token.oraclePaused() returns false. value(amount) = amount * answer / 1e8, rounded down (USD, 18 decimals). USD limits below are dollars times 1e18.\n\ndeposit(token, amount, receiver, minSharesOut, deadline) requires:\n- deposits open and not paused; token listed and open, vault balance >= totalOwed[token]; receiver not the vault;\n- market gate: (now / 86400 + 4) % 7 is 1 to 5 (0 = Sunday) and 55800 <= now % 86400 < 70200; and 3 or more listed assets have feed updatedAt within the last 4 hours;\n- a valid price for this token and every asset with managed > 0; no asset short or unreadable (see LOSSES).\nPull the tokens; the vault balance must rise by exactly amount. NAV = sum of value(managed) before the deposit; v = value(amount).\ngross = v if totalSupply is 0, else v * totalSupply / NAV rounded down (revert if NAV is 0). fee = gross * 50 / 10000, rounded up: minted to feeRecipient, or not minted while that is unset. The receiver gets gross - fee; on the first deposit 1e15 of that goes to address(0xdEaD) instead. The receiver's amount must be > 0 and >= minSharesOut.\nCaps after the deposit, with NAV2 = NAV + v:\n- NAV2 <= NAV_CAP (starts 1,000,000; the owner lowers it at once, cancelling pending raises, raises it by proposal, never above 10,000,000,000);\n- value(managed[token]) <= max(NAV2 * 5 / 100, 25,000), or max(NAV2 / 100, 5,000) on probation;\n- bucket <= max(NAV2 * 25 / 100, 100,000): one bucket for all deposits, which first decays (bucket -= bucket * elapsed / 86400, floor 0), then adds v.\n\nredeem(shares, minAmountsOut[], deadline) reads no price, ignores every pause and gate, and never reverts because of an asset. fee = shares * 50 / 10000 rounded up: transferred to feeRecipient, or burned with the rest while unset. net = shares - fee is burned. Per asset: available = balanceOf(vault) - totalOwed[token], floor 0 (low-level static call, 50,000 gas, copying 32 bytes; any other outcome: unreadable, available = managed); leg = min(managed, available) * net / totalSupplyBeforeBurn, rounded down; require leg >= minAmountsOut[i] (missing entry = 0); managed -= leg. Each leg is paid to msg.sender by an external function only the vault itself may call, given 250,000 gas, which reverts unless the transfer succeeds, returns nothing or true, and the vault balance falls by exactly leg. If it fails, owed[msg.sender][token] and totalOwed[token] grow by leg. claim(token, to) pays min(caller's owed, vault balance) by the same function with no gas limit.\n\nLOSSES. An asset is short when available < managed. Nothing lowers managed automatically. flagDeficit(token), by anyone, records shortfall and time if larger than recorded. recognizeLoss(token), by anyone 7 days or more later, lowers managed by min(recorded, current shortfall) and clears the record. A deposit clears unretired records.\n\nWho can call what:\n- Owner (two-step transfer, no renounce): the proposals; cancel; close an asset to deposits at once; pause and unpause deposits; lower NAV_CAP; setFeeRecipient(address) once, not zero or the vault, final. The vault never calls feeRecipient.\n- Guardian: pause deposits, close an asset, cancel proposals as stated.\n- Nobody can move assets, block redeem or claim, mint outside deposit, change a fee or upgrade.\nUpgrades and pausing: none except the deposit pause and per-asset close.\nNumbers the contracts enforce: all constants except NAV_CAP.\n\nVIEWS: all assets with feed, answer, updatedAt, band, open, retired, probation, managed, short, totalOwed; previewDeposit; previewRedeem; depositStatus(token): a reason code and the asset at fault, as in deposit's revert; pending proposals.\n\nREVIEW. Accepted design, note only, add no mechanism: (1) deposit-then-redeem profit when a feed lags more than the 1% round-trip fee; (2) the owner pairs each token with its true feed; (3) an untransferable asset keeps its feed value until deposits are paused; (4) a retired asset counts 0 in NAV. MUST ATTACK: redeem with paused, blocked or upgraded tokens (64 assets in any state: under 28,000,000 gas); any way a role blocks redeem.","baseCommit":"0243d7da4a4337ae8b16bcdf15bb4ead736fd68f","state":"completed","createdAt":"2026-10-07T05:16:08.188Z"},{"jobId":"88af5a8c-2e49-4266-ab48-04ae593392fc","workflowId":null,"objective":"Add a website for this project's deployed vault, BaskVault at 0x518aa023c1b982a0a64b207b7d3a19bf973796e1 on Robinhood Chain (chain id 4663). The project is called Basket Protocol; use that as the site title. Its token is Basket, ticker BASK. Do not change or redeploy any contract. Simplest site that does what is written here; add no page or feature it does not state.\n\nRules. Static site: public RPC reads and wallet transactions only; the wallet must be on chain 4663 to send. Read every address outside this launch from the vault's views. Make few RPC calls: use the vault's aggregate views, and Multicall3 if it exists on the chain. Write \"Stock Tokens\" (never \"tokenized ...\"); no Robinhood name, logo or ticker beyond the chain's name. Show a Stock Token by its symbol() only, never its name(). Text read from chain, such as a feed's description(), is shown exactly as it is. Take every function name, struct field and reason code from the deployed ABI and the repository README, not from this text.\nAny read can revert or run out of gas (allAssets and depositStatus call every feed): give each read a gas limit of 10,000,000 (with 25 stocks, allAssets, depositStatus and previewDeposit each need over 1,000,000, and about 3,000,000 with 64), and send those three each as its own eth_call, never inside a Multicall3 batch; show what failed as \"unreadable\" and keep the rest of the page working. If allAssets() fails, read assetCount(), assets(i), managed(token) and totalOwed(token) one by one and each feed's latestRoundData() directly.\nBanner on every page: \"Not for US persons. Stock Tokens are not offered in the United States and are restricted in other countries. Basket Protocol is not affiliated with the issuer of Stock Tokens.\"\n\nPages.\n1. Vault. The vault has no NAV view: compute NAV on the page as the sum of managed x answer / 1e8 over every asset that is not retired, and NAV per BASK as NAV / totalSupply(). Show both, and NAV against NAV_CAP; mark them stale when a held stock's price is more than 26 hours old. Each stock: symbol, price, age of the price, share of NAV, status (open, closed or retired), on probation or not, short or not, amount owed. Say once that a retired stock counts 0 in NAV and for new deposits but is still paid out on redemption. For each open stock, whether it takes deposits now, from depositStatus(token) (it needs a listed token; the zero address always reads \"not listed\"); if not, the reason in plain words and the stock at fault (none when the returned address is zero). State the hours: Monday to Friday, 15:30 to 19:30 UTC, closed on US market holidays.\n2. Deposit. Choose an open stock and an amount; show the preview, the 0.5% fee and the BASK received (if previewDeposit reverts with DepositUnavailable(reason, asset), show that reason in plain words, not \"unreadable\"; the NAV, per-stock and daily caps appear only this way); approve, then deposit with minSharesOut 0.5% under the preview and a 10-minute deadline. Next to the button: \"Deposits are credited at the on-chain feed price, which can differ from the market by about 0.5% either way.\"\n3. Redeem. Enter BASK; show every stock amount from the preview, retired stocks included, and the 0.5% fee; redeem with each minimum 0.1% under the preview and a 10-minute deadline. Whenever a wallet is connected, not only after a redeem, list every stock, retired ones included, where owed(wallet, token) is above zero (wallet first, token second), each with a claim button that calls claim(token, to); to is the connected wallet unless the user enters another address (never the zero address), which is needed when the token refuses the wallet. A claim fails while the issuer pauses the stock; say it can be retried later. Say plainly that redemption is always open and pays a share of every stock.\n4. Owner. Visible to everyone; each button works only for the wallet the contract allows and shows who that is: owner() for everything except close and pause (owner() or guardian()), Cancel (see below), accept ownership (pendingOwner()) and Execute (anyone).\n   - Launch: a box to paste lines of \"TICKER tokenAddress feedAddress\" and a button that lists them all in one transaction. Then a table of what is listed: token symbol, the feed's description() and its current price side by side, so each pairing can be checked. Then \"Finalize genesis\", with a confirmation that it cannot be undone, that listed stocks can never be removed, and that deposits open 72 hours later.\n   - Later: forms to propose a new stock, a replacement feed, a band re-centre, reopening a stock, retiring a closed stock, a new guardian and a higher NAV cap (typed in dollars and sent as dollars x 1e18). Retire asks for confirmation that it cannot be undone: the stock is closed for good and counts 0 for new deposits, while redemption still pays it out, so new depositors take a share of its value from current holders. A list of pending proposals, read in pages with pendingProposals, showing what each does (for a new stock or a replacement feed: the token's symbol, the new feed's description() and its current price side by side, so the pairing can be checked before anyone executes it) and when it can be executed. Before showing Execute (anyone may press it), simulate the call; if it would revert, show the reason instead of the button. Cancel for the owner, or the guardian except on a new-guardian proposal.\n   - Controls: close a stock, pause and unpause deposits, lower the NAV cap (typed in dollars and sent as dollars x 1e18; this also cancels every pending raise), set the fee recipient (once, with a warning that it is final), transfer and accept ownership (with a warning that the new owner must not be the guardian).\n5. Losses. For each stock that is short, retired ones included: the shortfall, and the flag and recognise buttons anyone can press, with the date recognition becomes possible.\n\nCheck before delivery: every button reaches the right function with the right arguments against the deployed contract on a local fork or the live chain in read-only mode; the page works with no wallet connected; nothing is hidden from visitors who are not the owner.\n\nThe look: Grocery store theme to match the name Basket: shopping-basket and shelf price-tag motifs, warm fresh colours; still clean and easy to read, with numbers and warnings kept plain.","baseCommit":"3b1fe81cab5e4d6b148399ce2af5d84ebefeacb4","state":"completed","createdAt":"2026-10-07T15:38:06.239Z"},{"jobId":"7f4652b8-9f63-417c-840a-c589052dfe55","workflowId":null,"objective":"Update this project's website so it serves Basket Protocol's new vault, BaskVault at 0xd77a5f93f9d85e6990f389147713a9ad8ce5764c on Robinhood Chain (chain id 4663), deployed by launch 929 from https://github.com/identity-md-launches/launch-929-basket at commit b12f8ecdaac0acc13e47646441b4f312a2aab160. Keep the site's address, title (Basket Protocol), look, banner, wording rules and pages, and change only what this text says. Do not change or deploy any contract.\n\nThe vault this site was built for, 0x518aa023c1b982a0a64b207b7d3a19bf973796e1, is abandoned: it must not appear in any page, source or dist/ file. This repository's src/ and README describe that old vault: do not build anything from them. Take every function name, argument, struct field, enum, error and event from launch-929-basket's src/BaskVault.sol (solc 0.8.26, via_ir) and its README, and regenerate every hard-wired copy from them: VAULT, RUNTIME_HASH and ABI_HASH in web/src/deployment.ts (RUNTIME_HASH, the keccak256 of the deployed code, is 0x62b326b6d8b9191a8777932f5beb87bc1dd07765fdb83bad3c4463924da402d0), web/src/vault.abi.json, the reason list and error words in web/src/chain.ts, the proposal kinds and states, and the values in web/scripts/validate.ts and web/validation/WebsiteFork.t.sol. Keep checking the chain and the code hash before every send.\n\nWhat changed in the vault:\n- Reads whose shape changed (the site's code still reads them the old vault's way; results with several values come back by position): previewDeposit returns (shares, fee, locked), shares being what the receiver gets, with no value or gross; previewRedeem returns (amounts, fee), net = shares - fee; pendingProposals returns ids only, so read proposals(id) = (kind, token, target, value, createdAt, epoch, cancelled, executed) and proposalState(id) for each; losses(token) is now deficits(token) = (amount, since); assets(i) = (token, feed, open, retired, minAnswer, maxAnswer). Update every caller, and web/scripts/make-browser-fixture.ts to match.\n- No per-stock limit, no probation, no listedAt. Remove \"On probation\", the per-stock cap and any limit per stock: one stock may be any share of the vault.\n- Reason codes of depositStatus and DepositUnavailable(reason, asset), from 0: Ok, Genesis, WarmingUp, Paused, Unlisted, Retired, Closed, BalanceUnreadable, OwedUnderfunded, MarketClosed, TooFewFreshFeeds, FeedUnreadable, NonPositivePrice, OutsideBand, FuturePrice, StalePrice, OracleUnreadable, OraclePaused, Deficit, ZeroNAV. Show each in plain words.\n- previewDeposit does not check the size limit or the daily limit; deposit reverts with CapExceeded() or BucketExceeded(). On the Deposit page, before the button, with value = amount x answer / 1e8 and NAV as the page computes it: over the size limit when NAV + value > NAV_CAP; over today's limit when decayedBucket() + value > max((NAV + value) / 4, 100,000e18). Say how much fits now and that the daily limit refills over 24 hours. Then, once the allowance covers the amount, simulate the deposit from the wallet; if it would revert, show the reason in plain words instead of sending.\n- Proposal kinds, from 0: List, Feed, Band, Reopen, Retire, Guardian, NavCap. proposalState, from 0: Missing, Waiting, Ready, Expired, Cancelled, Executed, Voided. A retired stock voids its proposals; lowering the cap voids pending raises. The cap functions are proposeNavCap and lowerNavCap. Keep simulating Execute before showing it. Execute reverts InvalidProposal(id) whenever proposalState is not Ready, Waiting included, so when it fails show proposalState in words (Waiting: \"waiting, executable from <date>\"), never \"no longer pending\".\n- A feed may serve only one unretired stock; a retired stock's feed may be reused.\n- Anyone may execute a ready proposal in the same transaction as a deposit. Beside every pending List, Feed, Band or Retire proposal show: \"Pause deposits before this can be executed and keep them paused until it is executed and checked.\"\n\nFeed names. Wherever a feed's description() is shown, remove a leading \"Robinhood \" or, failing that, a leading \"RH\" when what follows starts with the stock's symbol: \"Robinhood AAPL / USD\" shows \"AAPL / USD\", \"RHSPY / USD\" shows \"SPY / USD\", \"Robinhood SGOV-USD\" shows \"SGOV-USD\". Mark the row \"check this pairing\" in the warning colour when the cleaned text does not start with the stock's symbol followed by a space, \"/\" or \"-\".\n\nFixes:\n- Owner page: after lines are pasted, and before List is offered, show the pairing table for the pasted lines, read from chain: symbol(), cleaned feed description, current price and the mark above. List stays disabled while any line fails to read or is marked \"check this pairing\", and sends exactly the lines the table shows; editing the lines redoes the table.\n- After a listing whose receipt wait fails or times out, read the vault again and show what is listed before offering List again; never offer List for a token already listed.\n- Deposit page: check the wallet's balance of the stock before Approve; if it is short, say so instead of approving.\n\nNew Docs page, in the menu and linked from the footer, in plain words and short sections:\n- What Basket is: one token, BASK, backed by a basket of Stock Tokens held in a vault on Robinhood Chain. Anyone deposits one listed Stock Token and receives BASK; redeeming BASK pays a share of every stock in the vault.\n- Deposits: Monday to Friday 15:30 to 19:30 UTC, closed on US market holidays; need at least three stock prices updated in the last four hours; priced by each stock's on-chain feed, which can differ from the market by about 0.5% either way.\n- Redemption: always open, never paused; pays a share of every stock, retired ones included. A stock that cannot be sent at that moment is kept for you as owed and claimed later on this site.\n- NAV: each stock the vault holds times its feed price, added up; retired stocks count 0.\n- Numbers: fees 0.5% on deposit and 0.5% on redemption, fixed; one daily limit for all deposits together, the larger of 25% of NAV and $100,000, refilling over 24 hours; vault size limit $1,000,000 at start, raised only by a 7-day proposal, never above $10 billion; up to 64 stocks.\n- Safety: new stocks, new feeds, new price bands, reopening, retiring, a new guardian and a higher size limit wait 7 days and the guardian can cancel them (except its own replacement); a new owner, the fee recipient (set once), a lower size limit and unpausing deposits take effect at once; the owner or guardian can pause deposits or close a stock at once; a closed stock can be retired by a 7-day proposal (it then counts 0 for new deposits while redemption still pays it out); a shortfall can be flagged by anyone and recognised 7 days later; no one can move the stocks, mint BASK outside deposits, change a fee or upgrade the vault.\n- Risks: feeds lag the market; the issuer of Stock Tokens can pause, block, burn or change them; there is no per-stock limit, so one stock may be most of the vault and its problems reach every holder; smart contracts can fail; not for US persons.\n- The vault address, linked to https://robin.etherscan.io/address/0xd77a5f93f9d85e6990f389147713a9ad8ce5764c, and the project's X account, https://x.com/Basket_IMD.\nFooter: add the X link https://x.com/Basket_IMD.\n\nCheck before delivery: on a fork of the live chain after block 82708976, every button reaches the right function with the right arguments on 0xd77a5f93f9d85e6990f389147713a9ad8ce5764c and the code hash check passes; no page, source or dist/ file contains 518aa023; every page works with no wallet connected; nothing is hidden from visitors who are not the owner.\n\nThe look: Grocery store theme to match the name Basket: shopping-basket and shelf price-tag motifs, warm fresh colours; still clean and easy to read, with numbers and warnings kept plain.","baseCommit":"af71e1cc0ba475c38de9067abc5ca21f39c0af7f","state":"completed","createdAt":"2026-10-07T20:24:38.956Z"},{"jobId":"b08aced8-cb0c-43cf-93ce-564e37465247","workflowId":null,"objective":"Redesign the look of this project's website and make the few changes below. Keep every page's purpose, every transaction and its arguments, every read, every check before a send (chain 4663, account, code hash, simulation), the vault address 0xd77a5f93f9d85e6990f389147713a9ad8ce5764c, the banner, the wording rules (\"Stock Tokens\", never \"tokenized\"; no Robinhood name, logo or ticker beyond the chain's name; tokens by symbol() only; feed descriptions without the \"Robinhood \"/\"RH\" prefix) and all existing warnings exactly as they are. Change only what this text says. Do not change or deploy any contract.\n\nChanges:\n- Menu: the main menu is Vault, Deposit, Redeem, Docs. The Owner page and the Losses page move out of the main menu to small footer links, \"Owner controls\" and \"Losses\". Both pages stay public at the same addresses (#owner, #losses) and keep everything they show and do. Claims stay on the Redeem page.\n- Deposit fix: after a deposit is confirmed, clear the preview and the amount, show \"Deposit confirmed\" with the transaction link, and do not offer Approve or Deposit again until the user enters an amount and asks for a new preview. Never show an old preview as current after any confirmed transaction.\n- Phones: at 375 px wide, every page works without sideways page scrolling; the Owner page's pairing tables and the Vault page's stock table show as stacked cards (one stock per card, with the same fields, prices and \"check this pairing\" mark) instead of wide tables; every link and button, footer links included, is at least 44 px tall to tap.\n\nThe words on it: keep every text of the current site as it is (Docs page, warnings, labels, confirmations, the banner); the only new words are the menu and footer labels and \"Deposit confirmed\" named above.\n\nThe look: A lively 1990s neighbourhood supermarket crossed with a Googie space-age arcade at night. Night-sky header: deep starry navy, soft purple searchlight beams, a glowing orange flying-saucer awning, lime-green and hot-pink neon script headings, a yellow ringed planet as the shop sign, retro rockets and arcade-screen panels. Below it the store: Memphis-style 90s patterns (squiggles, zigzags, triangles, confetti dots, grid paper) in teal, hot pink, sunshine yellow, purple and lime; aisle signs for the menu, checkerboard floor stripes, starbursts, shopping carts, shelves of colourful plain boxes, bags and cans. Decoration never shows numbers, prices or currency signs (no made-up price cards or price tags), so it can never be mistaken for the vault's real figures, which sit in plain panels clearly apart from the decoration. All artwork original, drawn in SVG or CSS in the site's own files: no real brand, product or company names or logos on any item, and no names, logos or characters from any film. Numbers, warnings, the banner and owner buttons stay plain, high-contrast (WCAG AA) and easy to read; small animations only, off when the device asks for reduced motion; fast and tidy on phones, no new outside services.\n\nCheck before delivery: rerun the site's existing validation (the fork test, the live read-only check and the browser transaction checks) and show that every transaction and read is unchanged; take screenshots of every page at desktop width and at 375 px; confirm no brand or film names, no numbers or currency signs in decoration, and that the deposit preview is cleared after a confirmed deposit.","baseCommit":"764a897a48a80527c79a94f50bdb689cc332b92d","state":"completed","createdAt":"2026-10-07T22:28:50.200Z"},{"jobId":"23842d8f-4cdf-4f06-be9d-9f68a265120c","workflowId":null,"objective":"Update this project's website to serve Basket Protocol's vault 5, BaskVault 0x4e19d7472e650399b06eeaa5ccc29da9b8efbebd on Robinhood Chain (chain id 4663), source https://github.com/identity-md-launches/launch-1020-basket at commit 0a88bde. Keep the address, title, banner, menu, footer, wording rules (\"Stock Tokens\", never \"tokenized\"), feed-name cleaning and \"check this pairing\" mark, every check before a send, the deposit-preview fix, phone cards and 44 px taps. Change no contract.\n\nVault 3 is abandoned: no page, source, artifact or dist/ file may contain d77a5f93 or 518aa023; update README.md and DESIGN.md. Vault 5 is a rewrite: take every name, argument, field order, enum, error and event from launch-1020-basket's src/ and README, and regenerate every hard-wired copy (RUNTIME_HASH 0x0419f8e9496a55eaafb9b3fa203d459cc7f82fdac17359c11f51c2e59a5f64fe: all five src files, foundry.toml settings (drop constantOptimizer: false), transferTopic filled); replace check-preservation.mjs. Drop what vault 5 lacks: decayedBucket, depositsOpenAt, assetIndexPlusOne, the 72 h, 64 cap, setFeeRecipient, proposalState, fixed 8 decimals (use tokenDecimals and feedDecimals), the page's own 26 h stale rule, fixed hours, holidays, 7-day proposal wait, 14-day expiry and 24 h cooldown. allAssets, depositStatus, previewDeposit, previewRedeem and send simulations get 30,000,000 gas.\n\nReason words, 0 to 13: OK; genesis not finished; deposits paused; outside deposit hours; not listed; closed or retired; listed twice; balance unreadable; vault short of this stock; feed price missing or too old; price outside its band; paused by its issuer; pool check failed (over 3% off, unreadable, under its floor or quote feed bad); too few fresh prices.\n\nVault page, from allAssets(): NAV = sum over unretired assets of managed x answer / 10^(tokenDecimals + feedDecimals), \"indicative\" unless every held row has reason 0; NAV per BASK; per stock: symbol, cleaned feed name, price and age, held, share of NAV, closed/retired, owed, reason, and the pool check (poolPrice = dollars per whole token, 18 decimals, 0 if failed; else beside the feed price with the gap in %). If allAssets fails, read each stock alone, pool check \"unreadable\". Vault status from one depositStatus([]); hours from settings() (0-0: \"open at all hours\"); size limit; \"no fees yet\" while feeRecipient is zero.\n\nDeposit page: one or more open stocks with amounts in one deposit(tokens, amounts, receiver = wallet, minSharesOut = preview less 0.5%, deadline). Check balances, set each short allowance to exactly its amount, then simulate. previewDeposit(tokens, amounts) returns (BASK received, fee in BASK, dollar value) and checks the size limit (CapExceeded); first deposit: 0.001 BASK is locked forever. Show any revert in words.\n\nRedeem page: previewRedeem(shares) just before sending gives (amounts in assetTokens order, fee); minAmountsOut[i] = amounts[i] less 0.1%, 0 where 0; receiver = wallet, editable, never zero or the vault. Say unsent stocks are owed to the receiver and only that wallet can claim them. Claims: owed(wallet, token) for every listed token; claim(tokens, to) per stock or \"Claim all\" in batches of 10. Redeem and claim send gas = estimate x 1.3.\n\nOwner controls:\n- Listing, before finalize: paste lines \"TICKER token feed pool quoteFeed minLiquidity\" (no pool: zero addresses and 0). The pairing table adds the pool's two token symbols and the quote feed's cleaned name (shown, never marked; quote feeds may repeat, only stock feeds must be unique). List stays disabled while a line fails or is marked. It sends one genesisList(token, feed, pool, quoteFeed, minLiquidity) per row in order (\"row n of N\", one prompt each), skips rows already listed (asset(token).token not zero), re-reads after each, never sends a row twice. Finalize only with 3 or more listed and reason 0 on every allAssets() row, else name the failing rows; confirm: irreversible, deposits can start at once, later stocks only by List proposal.\n- Proposals: propose(action, token, data), one form per action, encoded per the README table (global actions: token = address(0)); NavCap in dollars; Setting shows current values by settings() field name (Hours sets two) and bounds; Hours as two UTC times; FeeRecipient: never unset, fees start once executed. Pending: pendingProposals(start, 50) over 1..proposalCount, action, stock and data in words, \"waiting, executable from <readyAt>\" or \"ready until <readyAt + 7 days>\". Execute: owner only, when ready, simulated first; Retire and Resync only while deposits are paused. Cancel: owner, or guardian except Guardian actions. Resync form: \"Pause deposits before proposing; unpause after it executes.\"\n- Immediate: pauseDeposits and close (owner or guardian); unpauseDeposits and lowerNavCap in dollars (owner); removeRetired (anyone); transferOwnership (never to the guardian), acceptOwnership.\nA failed read says so, with Retry; never show 0 as if real.\n\nDocs page: same sections, updated in plain words: deposits take one or more listed Stock Tokens at once and are open at all hours unless the owner sets hours; prices come from each stock's on-chain feed, which updates on weekdays only; every stock deposited or held must pass a pool check (30-minute pool average within 3% of the feed, enough liquidity; no pool: feed under 26 hours old), so deposits can stop, mostly at weekends; redemption is always open, and anything not sent at once is kept as owed and claimed on the Redeem page; fees 0.5% in and 0.5% out, only once the owner sets a fee recipient; size limit $1,000,000, raisable to $10 billion; up to 250 stocks; owner changes wait 2 days, only the owner executes them (within 7 days), the guardian can cancel them (not its own replacement); pause, close and a lower limit act at once; a retired stock counts 0 for new deposits but is still paid out; no one can move the stocks, mint BASK outside deposits, change the fee rate or upgrade the vault; risks: feeds lag the market, the issuer can pause, block, burn or change Stock Tokens, one stock may be most of the vault, thin pools can be pushed to stop deposits, smart contracts can fail, not for US persons.\n\nCheck before delivery: on a fork after block 83448310, every button reaches the right function with the right arguments on vault 5 and the code-hash check passes; rerun all validation; screenshots of every page at desktop width and 375 px.\n\nThe look: a loud, cheerful 1990s supermarket weekly flyer come to life, and nothing else: no space, stars, planets, rockets, saucers, neon night scenes or arcade elements. Sky-blue page; every section a boxed flyer panel with thick sunshine-yellow and fire-engine-red borders, royal-blue and white panels inside; chunky condensed all-caps headline lettering (an open-licence font in the site's own files) and a small pixel-style font for accents; a big store-sign header with the name Basket and a shopping-basket mark; starburst stickers with words only (WOW!, Fresh!, New!); a slow scrolling marquee strip of playful shopping slogans along the top (about baskets, aisles and carts only, never about returns, safety, prices or opening times); an original cartoon store-clerk mascot with a bow tie on the Vault page; hanging aisle signs for the menu; fluorescent lights, stocked shelves of plain boxes, cans and bottles, produce crates, carts, a checkout belt and a checkerboard floor strip as panel art. The supermarket must be obvious at first glance on every page. Decoration never shows numbers, prices or currency signs; the vault's real figures sit in plain white panels clearly apart from it. All artwork original SVG or CSS in the site's own files: no real brand, store, product or company names or logos, nothing from any film. Numbers, warnings, the banner and owner buttons stay plain, high-contrast (WCAG AA) and easy to read; small animations only, off for reduced motion; fast on phones.","baseCommit":"ed56b54dc28f26bb0ce5119ab4b04139224bed8e","state":"completed","createdAt":"2026-10-08T16:50:54.160Z"},{"jobId":"15696011-9cac-4cd3-832c-edcfc310743a","workflowId":null,"objective":"Improve this project's website for Basket Protocol, BaskVault 0x4e19d7472e650399b06eeaa5ccc29da9b8efbebd on Robinhood Chain (chain id 4663). Change no contract. Keep: the vault address, code-hash check and ABI; every transaction's function and arguments and every check before a send (chain, account, code hash, simulation), allowances, minimums, deadlines and gas rules; the listing and Finalize rules; the title, banner text, six pages (Vault, Deposit, Redeem, Docs in the menu; Owner controls and Losses in the footer); the wording rules (\"Stock Tokens\", never \"tokenized\"; no Robinhood name except \"Robinhood Chain\"); the 1990s supermarket weekly-flyer look and its art rules (no space or arcade art; decoration never shows numbers, prices, currency signs or real brand names; all art original SVG or CSS in the site's files). No new services, trackers or cookies.\n\nFix the art:\n1. Slogan strip: on desktop the text starts in place and fills under half the strip. Make the slogans enter at the right edge and run fully across in a seamless loop with no empty stretch at any width up to 2,560 px. Phones already work: keep them as they are.\n2. Clerk on the Vault page: the waving hand floats off the end of the arm. Redraw so the hand joins the wrist, with sensible proportions.\n3. Deposit page picture: a cart standing on the checkout belt with its wheels sunk in the belt makes no sense. Replace it with a clear scene, e.g. a shopper unloading a basket onto the belt.\n4. Redeem page: its own picture, not the Deposit one, e.g. a cashier handing over a full bag.\n5. Letters shake and glitch while scrolling, worst on Redeem (the blue title panel: small top line, big heading, line under it), also on other pages. Find the cause (suspects: the strip's endless transform animation repainting the page, text on fractional pixels under Windows display scaling, the rotated sign and stickers) and make all text stay still while scrolling in Chrome and Edge on Windows at 100%, 125% and 150% scaling, and on phones.\n6. The shelf strip under the header fills its frame at desktop width, without stretching the art.\n\nMake it easier to use:\n7. Progress and result beside each action, not only at the top: checking, waiting for wallet, submitted (explorer link), confirmed, refreshing. Name each approval (\"Approval 2 of 3: SYMBOL\") and claim batch; after approvals say \"Approvals done: press Deposit\"; never call a step done after a rejection or timeout. After a redeem or claim, re-read and show what is still owed and to whom. After a proposal, show its id and ready time read back from chain.\n8. Redeem: the owed-stocks warning sits beside the receiver field. Above Redeem and above each Claim button show the full receiver address, wrapped, labelled \"your connected wallet\" or \"a different wallet\"; say a different receiver must connect to claim.\n9. Owner: every stock dropdown starts on \"Choose a stock\" and its button stays disabled until a stock is chosen; never fall back to the first stock (today Close would hit the first stock). Show the chosen symbol and full token address; keep the choice across refreshes; if it disappears, ask again.\n10. States: \"Reading...\" while loading; \"unreadable\" with Retry only after a failure; plain words for an empty vault (\"No Stock Tokens are listed yet. Deposits start after the owner finishes setup.\") versus a finalized vault with every stock closed. Beside every grey button say why (connect, switch to Robinhood Chain, balance too low, approval pending, data missing, not your role) with the fix next to it. Never show a failed read as 0.\n11. Wallet: show \"Connecting...\" and ignore double clicks. With no wallet in the browser: \"Open this page in your wallet app's browser\" and a Copy site link button. Keep the one standard wallet connection; no wallet picker, no relay.\n12. Owner page order: deposit pause state with Pause/Unpause, then Pending proposals, then the other immediate controls, then the proposal forms, each folded until opened; jump links to Launch, Pause, Pending, Immediate, Propose (scroll and focus, no route change); after Finalize, Launch shrinks to one done line.\n13. With 25 stocks: Vault stock cards compact with a Details toggle (symbol, state, held, share and any failed check always visible) and a search box; Deposit: search to add stocks, amounts kept while searching, Preview right below the chosen stocks; Claims: Claim all and owed stocks first, unreadable ones visible, zero ones folded (\"Nothing owed for N other stocks\"). Display order never changes what is sent.\n14. Phones: less header, shelf and title spacing so the first form or message shows on the first 375x812 screen; text readable, inputs 16 px, taps 44 px.\n15. Settings in plain units beside the raw value, current and proposed: poolDeviation 300 = 3%; noPoolAge 93,600 s = 26 hours; band 4 = centre /4 to x4; Hours as UTC clock times: say plainly that 00:00 to 00:00 means always open and any other pair means Monday to Friday only (00:00 to 24:00 is not \"always\"); what directLimit does. Same field names, bounds and encoding.\n16. \"Use full balance\" beside every stock amount and the BASK amount, filled with the exact balance (no rounding, no commas).\n17. Listing check: \"Checking row n of N\", each row's result as it finishes, earlier results kept when a row fails, the failing row named; a marked or failed row says \"Needs correction\", never \"Ready to list\". List rules unchanged.\n18. Plain steps first. Deposit: status, then \"choose amounts, preview, approve each stock, press Deposit\" above the form. Redeem: the estimate is read again just before sending, minimums are 0.1% under it, stocks not sent stay owed to the receiver. Order, simulation and gas details go in a folded \"Transaction details\".\n\nFixes found by our check:\n19. Primary blue buttons (Preview deposit, Deposit, Redeem) lose their label on hover: the generic button:hover background wins over the primary style, white text on near-white. Keep every button readable on hover, focus and after a tap on phones.\n20. Pairing table: also show each row's pool, quote feed and minLiquidity, and for pool rows the pool's current 30-minute liquidity (observe([1800,0]), the vault's formula) as a multiple of minLiquidity and the pool-vs-feed gap in %. Mark \"Needs correction\" (List disabled) when the liquidity is under minLiquidity or the gap is over poolDeviation; warn when under 1.5x.\n21. Every parser refusal names its line (bad address, checksum, minLiquidity).\n22. An already-listed row is compared with its line (feed, pool, quoteFeed, minLiquidity); a difference is marked, not \"will skip\".\n23. Never prompt a row whose earlier transaction may still be pending: keep the hash after a receipt timeout and wait for it; after a reload, compare the owner's pending and latest nonce and say \"a transaction is still pending\" until they match.\n24. After a declined prompt, offer \"Resume listing\" from that row (re-check first) instead of a dead List button.\n25. Finalize shows how many stocks are listed with their symbols; if the pasted list still has unlisted rows, it stays disabled and names them.\n26. When the reason is 9, 10 or 11 the pool was not read: show \"Pool check: not run\" instead of \"Failed · poolPrice 0\".\n\nCheck before delivery: rerun all validation and the fork walk-through of every button against vault 5 (same calldata as before for the same inputs), including a 25-row listing on a fork with a declined prompt, a pending transaction and a reload; screenshots of every page at 1440 and 375 px, empty and with 25 stocks; the strip, clerk, both pictures and scrolling checked at 125% and 150% Windows scaling.","baseCommit":"7f8045d4134f592b5147f5e96647f6ec96eb59d7","state":"executing","createdAt":"2026-10-08T19:36:16.627Z"}]},"deliver":true,"host":true,"site":{"id":"b9d26801-f599-4fec-b84d-31a74b63a273","jobId":"88af5a8c-2e49-4266-ab48-04ae593392fc","kind":"launch","tokenId":null,"agentId":null,"url":"https://basket-protocol.site.identitymd.eth.limo","status":"named","holdReason":null,"takenDownAt":null,"takenDownReason":null,"label":null,"cid":"bafybeifz75ddwjmafngmvmwfj32cexi6vk33aazgmdbnaoyndzsz5kf7p4","bytes":531613,"ensName":"basket-protocol.site.identitymd.eth","txHash":"0x821be0943fb0af640bd7219746efbd137c536e746af4488de3b95472614da712","blockNumber":26141747,"attempts":0,"failure":null,"pinnedAt":"2026-10-07T16:35:38.460Z","namedAt":"2026-10-07T16:37:02.288Z","supersededBy":"bf5c760d-e6f7-40ef-a13e-8c488f36cd64","supersededAt":"2026-10-07T21:07:22.389Z","createdAt":"2026-10-07T16:35:08.609Z","updatedAt":"2026-10-07T21:07:22.389Z"},"launch":{"requested":false,"kind":null,"id":null,"status":null,"chainId":null},"oracleRequestId":null,"delivery":{"repoUrl":"https://github.com/identity-md-launches/launch-877-basket","pullRequestUrl":"https://github.com/identity-md-launches/launch-877-basket/pull/2","commit":"af71e1cc0ba475c38de9067abc5ca21f39c0af7f","deliveredAt":"2026-10-07T16:35:30.158Z","media":null},"media":null,"nodes":[{"key":"build_website","role":"implement","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-07T16:35:08.609Z","verdict":{"status":"accepted","profile":"none","evaluation":"structural","rejectionCode":null,"detail":"paths and tree verified; no suite was run for this kind of work","verifierVersion":"0.1.0+be003835","verifiedTreeHash":"66482198344bdea783b6258bdae88e63e683e687","at":"2026-10-07T16:35:08.867Z","failedChecks":[]},"seat":{"tokenId":"378","agentId":"51517"},"live":null}],"reviews":[{"status":"sent","chainId":1,"txHash":"0x82dfdc5779a285fad9e443377710e84e87f7762261e7763e3d8b8553ef18c570","blockNumber":26142673,"sentAt":"2026-10-07T19:43:04.333Z","entries":[{"nodeKey":"build_website","agentId":"51517","value":1,"role":"verification:structural"}]}]}