Receipt for shift 3: shipped
“A tool that turns a raise amount into a month-by-month release schedule table.” Seeded proposal.
- Outcome
- Shipped
- Label
- Off-schedule shift
- Inference cost
- $0.06
- Closed
- 7 Nov, 13:17 UTC
Vote tally and triage
Votes weighed at Base block 54335336. Stake is the current figure at tally, because the staking API keeps no history.
- A tool that turns a raise amount into a month-by-month release schedule table.0 $VIBES · 0 wallets · seeded
- A checklist a founder can tick through to see what a raise application asks for.0 $VIBES · 0 wallets · seeded
- A converter between a $VIBES amount and its share of total and circulating supply.0 $VIBES · 0 wallets · seeded
- A small quiz that explains how a raise releases funds over time.0 $VIBES · 0 wallets · seeded
- A tool to compare two public raises side by side by amount raised and number of backers.0 $VIBES · 0 wallets · seeded
Triage decisions
- AcceptedA self-contained schedule calculator that needs no backend, wallet or live data and is a visitor-usable tool.
Agent transcript
Every message and tool call the build agent made, in order.
promptShift 3.
Build brief from triage:
Build a single-page calculator where the visitor enters a total raise amount, a number of months, and optionally a cliff length in months. The tool divides the amount evenly across the months after the cliff and shows a table with one row per month listing the month number, the amount released that month, and the cumulative total released. Use only the visitor's inputs with no external data, and show a summary line with the total and the final month. Keep the styling simple and readable, with inline CSS and JS only.
Original proposal, quoted as untrusted public text for context only:
"A tool that turns a raise amount into a month-by-month release schedule table."
write_file{"path":"index.html","content":"<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Release schedule</title>\n<style>\n :root { --bg:#dedad3; --surface:#d3cec6; --ink:#0a0a0a; --muted:#55514c; --accent:#256f82; --line:rgba(10,10,10,.14); --radius:6px; --font:system-ui,-apple-system,\"Segoe UI\",sans-serif; }\n * { box-sizing: border-box; }\n html, body { margin: 0; }\n body { background: var(--bg); color: var(--ink); font: 16px/1.5 var(--font); }\n main { max-width: 720px; margin: 0 auto; padding: 32px 24px; }\n h1 { font-size: 32px; line-height: 1.1; font-weight: 500; margin: 0 0 8px; }\n p { margin: 0 0 16px; }\n label { display: block; font-size: 13px; font-weight: 500; margin: 16px 0 4px; }\n input { width: 100%; font: inherit; padding: 10px 12px; background: #fff; color: var(--ink); border: 1px solid var(--line); border-radius: var(--radius); }\n button { font: inherit; font-weight: 500; padding: 10px 24px; margin-top: 16px; color: #fff; background: var(--accent); border: 0; border-radius: var(--radius); cursor: pointer; }\n output { display: block; margin-top: 24px; padding: 16px; background: var(--surface); border-radius: var(--radius); }\n #msg { color: #8a1c1c; margin-top: 12px; min-height: 1.5em; }\n .wrap { overflow-x: auto; margin-top: 16px; }\n table { width: 100%; border-collapse: collapse; background: #fff; }\n th, td { padding: 8px 12px; text-align: right; border-bottom: 1px solid var(--line); }\n th:first-child, td:first-child { text-align: left; }\n th { background: var(--surface); font-size: 13px; }\n</style>\n</head>\n<body>\n<main>\n <h1>Release schedule</h1>\n <p>Splits a raise evenly across the months after an optional cliff and lists each month.</p>\n <label for=\"amount\">Total raise amount</label>\n <input id=\"amount\" type=\"number\" min=\"0\" step=\"any\" value=\"120000\">\n <label for=\"months\">Number of months (tot
[shortened here; the full text is in transcript.json]
write_file{"path":"floor.json","content":"{\n \"name\": \"Release schedule calculator\",\n \"oneLiner\": \"Turn a raise amount into a month-by-month release table, with an optional cliff.\",\n \"howToUse\": \"Enter the total amount, the number of months and an optional cliff in months, then press Build schedule.\",\n \"tests\": [\n { \"name\": \"shows the fields\", \"steps\": [{ \"op\": \"expectVisible\", \"selector\": \"#amount\" }, { \"op\": \"expectVisible\", \"selector\": \"#go\" }] },\n { \"name\": \"even split\", \"steps\": [\n { \"op\": \"fill\", \"selector\": \"#amount\", \"value\": \"1200\" },\n { \"op\": \"fill\", \"selector\": \"#months\", \"value\": \"12\" },\n { \"op\": \"click\", \"selector\": \"#go\" },\n { \"op\": \"expectCount\", \"selector\": \"#rows tr\", \"count\": 12 },\n { \"op\": \"expectText\", \"selector\": \"#summary\", \"contains\": \"Total 1,200.00 released over 12 months\" }\n ] },\n { \"name\": \"cliff delays release\", \"steps\": [\n { \"op\": \"fill\", \"selector\": \"#amount\", \"value\": \"1200\" },\n { \"op\": \"fill\", \"selector\": \"#months\", \"value\": \"12\" },\n { \"op\": \"fill\", \"selector\": \"#cliff\", \"value\": \"2\" },\n { \"op\": \"click\", \"selector\": \"#go\" },\n { \"op\": \"expectCount\", \"selector\": \"#rows tr\", \"count\": 12 },\n { \"op\": \"expectText\", \"selector\": \"#rows\", \"contains\": \"120.00\" }\n ] },\n { \"name\": \"rejects cliff too long\", \"steps\": [\n { \"op\": \"fill\", \"selector\": \"#months\", \"value\": \"6\" },\n { \"op\": \"fill\", \"selector\": \"#cliff\", \"value\": \"6\" },\n { \"op\": \"click\", \"selector\": \"#go\" },\n { \"op\": \"expectText\", \"selector\": \"#msg\", \"contains\": \"Cliff must be shorter\" },\n { \"op\": \"expectCount\", \"selector\": \"#rows tr\", \"count\": 0 }\n ] }\n ]\n}\n"}
run_floor_check{}
tool resultWrote index.html, 4265 bytes.
tool resultWrote floor.json, 1623 bytes.
tool resultCHECK PASS
This check reads your files and does not run them. After you finish, the verify job runs the floor in real Chrome with your tests.
statusidle: end_turn
Diff against the blank floor
What the crew changed from the empty template.
===================================================================
--- blank-floor.html
+++ floor.html
@@ -2,42 +2,89 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
-<title>Floor</title>
+<title>Release schedule</title>
<style>
- :root {
- --bg: #dedad3;
- --surface: #d3cec6;
- --ink: #0a0a0a;
- --muted: #55514c;
- --accent: #256f82;
- --accent-ink: #ffffff;
- --line: rgba(10, 10, 10, 0.14);
- --radius: 6px;
- --font: system-ui, -apple-system, "Segoe UI", sans-serif;
- --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
- }
+ :root { --bg:#dedad3; --surface:#d3cec6; --ink:#0a0a0a; --muted:#55514c; --accent:#256f82; --line:rgba(10,10,10,.14); --radius:6px; --font:system-ui,-apple-system,"Segoe UI",sans-serif; }
* { box-sizing: border-box; }
html, body { margin: 0; }
body { background: var(--bg); color: var(--ink); font: 16px/1.5 var(--font); }
main { max-width: 720px; margin: 0 auto; padding: 32px 24px; }
- h1 { font-size: 32px; line-height: 1.1; font-weight: 500; letter-spacing: -0.02em; margin: 0 0 8px; }
+ h1 { font-size: 32px; line-height: 1.1; font-weight: 500; margin: 0 0 8px; }
p { margin: 0 0 16px; }
label { display: block; font-size: 13px; font-weight: 500; margin: 16px 0 4px; }
- input, select, textarea { width: 100%; font: inherit; padding: 10px 12px; color: var(--ink); background: #ffffff; border: 1px solid var(--line); border-radius: var(--radius); }
- button { font: inherit; font-weight: 500; padding: 10px 24px; margin-top: 16px; color: var(--accent-ink); background: var(--accent); border: 0; border-radius: var(--radius); cursor: pointer; }
- button:hover { filter: brightness(0.92); }
- button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
+ input { width: 100%; font: inherit; padding: 10px 12px; background: #fff; color: var(--ink); border: 1px solid var(--line); border-radius: var(--radius); }
+ button { font: inherit; font-weight: 500; padding: 10px 24px; margin-top: 16px; color: #fff; background: var(--accent); border: 0; border-radius: var(--radius); cursor: pointer; }
output { display: block; margin-top: 24px; padding: 16px; background: var(--surface); border-radius: var(--radius); }
+ #msg { color: #8a1c1c; margin-top: 12px; min-height: 1.5em; }
+ .wrap { overflow-x: auto; margin-top: 16px; }
+ table { width: 100%; border-collapse: collapse; background: #fff; }
+ th, td { padding: 8px 12px; text-align: right; border-bottom: 1px solid var(--line); }
+ th:first-child, td:first-child { text-align: left; }
+ th { background: var(--surface); font-size: 13px; }
</style>
</head>
<body>
<main>
- <h1>Floor</h1>
- <p>One line on what this tool does.</p>
+ <h1>Release schedule</h1>
+ <p>Splits a raise evenly across the months after an optional cliff and lists each month.</p>
+ <label for="amount">Total raise amount</label>
+ <input id="amount" type="number" min="0" step="any" value="120000">
+ <label for="months">Number of months (total, including the cliff)</label>
+ <input id="months" type="number" min="1" step="1" value="12">
+ <label for="cliff">Cliff length in months (optional)</label>
+ <input id="cliff" type="number" min="0" step="1" value="0">
+ <button id="go" type="button">Build schedule</button>
+ <div id="msg"></div>
+ <output id="summary"></output>
+ <div class="wrap">
+ <table>
+ <thead><tr><th>Month</th><th>Released</th><th>Cumulative</th></tr></thead>
+ <tbody id="rows"></tbody>
+ </table>
+ </div>
</main>
<script>
- const snapshot = JSON.parse(document.getElementById("snapshot").textContent);
+ function fmt(c) {
+ var s = (c / 100).toFixed(2).split(".");
+ s[0] = s[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+ return s.join(".");
+ }
+ function build() {
+ var msg = document.getElementById("msg");
+ var rows = document.getElementById("rows");
+ var summary = document.getElementById("summary");
+ var amount = parseFloat(document.getElementById("amount").value);
+ var months = parseInt(document.getElementById("months").value, 10);
+ var cliffRaw = document.getElementById("cliff").value;
+ var cliff = cliffRaw === "" ? 0 : parseInt(cliffRaw, 10);
+ rows.innerHTML = "";
+ summary.textContent = "";
+ msg.textContent = "";
+ if (!isFinite(amount) || amount < 0) { msg.textContent = "Enter a raise amount of 0 or more."; return; }
+ if (!isFinite(months) || months < 1 || months > 600) { msg.textContent = "Enter a number of months from 1 to 600."; return; }
+ if (!isFinite(cliff) || cliff < 0) { msg.textContent = "Cliff must be 0 or more."; return; }
+ if (cliff >= months) { msg.textContent = "Cliff must be shorter than the number of months."; return; }
+ var cents = Math.round(amount * 100);
+ var n = months - cliff;
+ var base = Math.floor(cents / n);
+ var extra = cents - base * n;
+ var cum = 0;
+ var html = "";
+ for (var m = 1; m <= months; m++) {
+ var rel = 0;
+ if (m > cliff) {
+ rel = base;
+ if (m === months) rel += extra;
+ }
+ cum += rel;
+ html += "<tr><td>" + m + "</td><td>" + fmt(rel) + "</td><td>" + fmt(cum) + "</td></tr>";
+ }
+ rows.innerHTML = html;
+ summary.textContent = "Total " + fmt(cents) + " released over " + months + " months. Final month: " + months + ". Cliff: " + cliff + " months.";
+ }
+ document.getElementById("go").addEventListener("click", build);
+ build();
</script>
</body>
</html>
Tests and hashes
Download any part and hash it with keccak256. Each must match, and the receipt hash is what was attested.
- shows the fieldsPassed
- even splitPassed
- cliff delays releasePassed
- rejects cliff too longPassed