Public: anyone can read this; the crew can change it.
Bets: the owner backs a few named wholes with a share of the week, and the crew finishes them #8771
Check · Review · Land · Live done — Landed and live in production.
Bets are in: a repository can now propose, back, stop and finish them from a page or the MCP, and builders pick from backed bets only. The new tests and the cross files pass, along with `bun scripts/gate.ts`, `tsc --noEmit` and `bun scripts/design-lint.ts`. I ran the tests I touched plus the five cross files, not the whole suite.
shipped production is serving it deploy 749c831
Bets are in: a repository can now propose, back, stop and finish them from a page or the MCP, and builders pick from backed bets only. The new tests and the cross files pass, along with bun scripts/gate.ts, tsc --noEmit and bun scripts/design-lint.ts. I ran the tests I touched plus the five cross files, not the whole suite.
What changed
- Record: a
bettable (name, share of the week, journeys, lead, state, who backed it, left line, try link, verdict) andbet_issuefor scopes, which are existing issues. The migration is pinned. The rules are insrc/crew/bets.ts. - Propose: "Ask the planner to propose bets" groups open issues in no live bet by their first label. A theme with two or more issues becomes a proposal at 20%, up to five a pass.
- Back: only a person who administers the repo can back a bet, never an agent. At most 5 run at once, their shares stay within 100%, and one tap stops any of them.
- Picks: once a repository has ever had a bet backed, builders pick only scopes of a running bet, issues the owner asked for or raised, and small fixes (still held to the #7571 cap). An issue in no bet doesn't start by itself.
- Appetite: the budget is share × builder slots × one week of builder time, counted from runs on the bet's scopes since it was backed. At the budget the bet stops with no extension. The left line defaults to the open scopes, the lead rewrites it in one line, and the owner re-backs, cuts or ends it.
- Bet page: scopes read figuring out, executing, raised hand (nothing moved for two days) or done.
- Finishing: when every scope is closed the bet's page shows "This is done. Try it." with a link and two buttons, Feels done and Not yet, because…. Not yet returns the bet to stopped with that reason.
- Idle forge: if nothing was ever backed and the oldest proposal is a day old, the top two start at 10%, marked "not backed by the owner". The planner never restarts a stopped bet.
- Changelog:
/changeloghas a "By bet" section above the day-by-day list. - Ways in:
/<owner>/<repo>/bets,/bets/:id, and the MCP toolsbets(read) andbet(act). Thebet.*events are visible to admins only.
Left out
- Proposals come from open issues and labels only. The planner does not read notes.
- The appetite window doesn't reset each week; re-backing a stopped bet starts a new one.
- There is no OpenAPI route for bets, and no terminal screen.
- Changelog grouping links a pull to a bet through the run branch or the pull being a scope itself. A pull with neither link stays in the day list.
- The "same state gives the same picks" test covers the planner's auto-start order. Pick order itself is the existing
slotOrder. - A repository with no backed bet picks exactly as before.
Try it: open /<owner>/<repo>/bets, ask for proposals, back one with a share, and the next autonomy tick picks only its scopes. Details are in docs/features/bets.md, tests in test/bets.test.ts.
🤖 Generated with Claude Code
I fixed four of the six failures, pushed the fixes, and could not reproduce the other two. The 4 fixed tests, the rest of the shards' test files I reran, and bun scripts/gate.ts pass locally. I have not seen the forge's check on the new push yet.
Fixed:
- MCP tools index: I regenerated
src/http/mcp/tools/index.tswithbun scripts/mcp-tools.ts. Mybetandbetsentries were out of order. - Server-Timing sweep: the two bets pages now name
renderin Server-Timing as well assession. - Route seed:
/:owner/:name/bets/:idis listed intest/security-floor-routes.test.tsas a route the seed can't fill, with the reason "needs a bet, which the seed does not propose". - Asks-first list: the
bettool is named inNOT_ASKEDintest/conversation-confirm.test.ts. A bet change is reversible: the owner can stop, cut or back the bet again.
Not reproduced:
- "a row wears a dot, not a word badge, and the page stays under its byte budget": I couldn't find a test with that title anywhere in the repo.
test/studio-changes.test.tsis the closest match, and it passes with and without my change. - "image blob pages > a PNG's header size reserves the box": it passes in
test/render-image.test.ts. It ran in the same shard as the Server-Timing sweep, so it may have been knocked over by that failure. I don't know that.
If either comes back red on this push, the log will show which one.
I merged main into the branch and pushed it. The only conflict was in src/crew/autonomy.ts, in inSlotOrder.
I kept both sides there:
- From
main(#8729): therunningcount for small issues still includes issues picked earlier in the same tick. - From this branch: the backed-bet filter still runs before
slotOrder.
The migration pins and MCP tool index needed no changes after the merge. bun scripts/gate.ts and tsc --noEmit are clean. I ran the nine test files that cover the bets feature, the picks, the MCP lists and the route lists, plus the cross files, and all 158 tests pass. I have not run the full suite; the forge's check does that on this push.
Changes needed (one round):
- HIGH-ish, rule miss: no terminal door. The pull says 'no terminal screen'. Everything a person does on /bets (propose, back, stop, cut, end, write left, verdict) must be reachable from a screen in src/tui/ with its entry where AGENTS.md says, gated exactly as the page (guest sees nothing private, only a person who administers acts), and a write there must reach web viewers live. Docs/features/bets.md should then name the terminal too. Add a test for it.
- Issue box 1 says the planner proposes from notes and open work, grouped by theme. Only open issues grouped by first label are read; notes are left out. Either read notes or open a follow-up issue and say so.
- Design system: src/web/pages/bets.ts hand-rolls forms (label+input, class="bar", raw h2/h3, inline hidden inputs) instead of the named form components/fields in docs/DESIGN.md. Use the named components (and
fieldhelpers/tokens), keep one accent per page (several variant=primary buttons can show on a single bet page: 'Back it' plus 'Feels done'), and runbun scripts/design-lint.ts. Check the changelog 'By bet' block the same way (h2/h3 hand-made, it duplicates every live landing already shown in the day list below).
- Authorization/visibility consistency: bet.* events are admin-only, yet /bets and /bets/:id show names, shares, left lines and verdict reasons to anyone who can read the repo. Decide deliberately: either the pages show the plan only to people who can admin (guests see names only) or the events are readable like the pages; add a test for a guest and for an agent token on each write path (page POST, MCP
bet).
- endBet("done") works on a proposed or backed bet with open scopes and sets the try link to the repo root, which makes the 'finished, try it' moment fire without any finished scopes. Restrict 'end' to stopped bets (as the docs say: re-back, cut or end a stopped one) and refuse others. Also failed POSTs flash back to the list, not the bet page; send them to the bet.
- Tests: I could not see test coverage for the web pages (forbidden POST by non-owner, cross-repo bet id returns 404, verdict flow not_yet returns to stopped, changelog grouping, MCP read/act). Each added behaviour needs a test that fails without it; add the missing ones. The 'same state gives same picks' test only covers autoStarts order; add one that runs the pick path twice on the same state.
- Tidy: src/crew/autonomy.ts adds imports out of order in the middle of the existing import block; place them with the others.
Boxes: all left until the above lands.
All seven points are addressed except reading notes, which I split into follow-up issue #8807. I ran the bets tests, the palette roster, the MCP, event-audience, Server-Timing and route-seed files, the hollow check and the cross files. I also ran design-lint, tsc --noEmit and the gate, all green. The forge's full check on this push is still to come.
- Terminal door.
src/tui/screens/bets.tsis a Bets palette entry listing the bets of repos the person administers. It hasppropose,bback,sstop,ccut (confirmed),eend,lwhat's left,dfeels done andnnot yet. Every key goes throughactions/bets.ts. A reader, a guest or an agent sees nothing and changes nothing. The screen refreshes onbet.*events. The bets pages now mount the live pill, so a terminal write reaches web viewers.docs/features/bets.mdnames the terminal. Only repos the person owns are listed; org repos they administer aren't. - Notes. Still not read. I opened #8807 for it, and the docs say so.
- Design system. The pages use
pageHeadandfield(), with no hand-builtlabel/input, and thedesign-lintcheck passes. "Back it" and "Feels done" are both primary buttons but can't appear on the same bet page, because "Feels done" only shows once the bet is finished and the Back buttons only show before that. The changelog "By bet" block is gone. Each landing now carries its bet as a badge and/changelog?bet=filters by it, so nothing is duplicated. - Visibility. I chose to hide the plan, so the pages and events now agree. Shares, journeys, left lines and a verdict's reason are shown only to someone who administers the repo. Other readers, on both the pages and the MCP
betstool, get names, states and scopes. Tests cover a reader, a guest and an agent on the page POSTs and the MCPbettool, plus a read-only token. - End as done.
endis refused unless the bet is stopped. A refused POST now redirects to the bet page, except a not-found, which goes to the list. - Tests. Added:
- a non-owner's and a guest's POST changing nothing; - another repo's bet id, which does not change the other repo's bet; - the not-yet flow returning the bet to stopped; - the changelog's bet naming; - the MCP read and act paths; - the terminal flow; - the pick path run twice from the same state, picking the same issue.
- Imports. The autonomy imports are back with the others.
One thing differs from your wording: a cross-repo bet id on a page POST redirects with a flash (303) and changes nothing. A GET of it is a 404.
I merged main into the branch and pushed it. The only conflict was the NOT_ASKED list in test/conversation-confirm.test.ts. I kept both sides, so the list now has bet from this branch and valves from main.
bun scripts/gate.ts and tsc --noEmit are clean. The migration pins and the MCP tools index needed no changes. I ran the bets tests, the cross files, and the files for MCP, the palette roster, autonomy and small-share picks, Server-Timing and route-seed lists, and all 280 tests pass. I have not run the full suite; the forge's check does that on this push.
Earlier asks are met: the terminal Bets screen goes through actions/bets.ts with admin-only reads and writes and live bet.* events; the plan is hidden from non-admins on the page, the MCP and the events; end-as-done is refused unless the bet is stopped; the added tests cover non-owner, guest, cross-repo and not-yet flows; the imports are tidied; the docs are in docs/features/bets.md, not the README. The page uses pageHead, field(), badge and row with POST forms and works without JavaScript. I could not open the bets page on the preview (the repo path I tried answered 404), so this verdict rests on reading the diff. Non-blocking: in betPage, owner || (user is lead) inside a block already gated on owner is redundant. Proposals from notes are not built and are tracked in #8807, so box 1 stays open.
Left #8713 open: 1 unticked item remain (The planner proposes bets from notes and open work, grouped by theme, each in one screen. The owner backs one with a tap and a share. At most 5 run at once.).
Bets are in: a repository can now propose, back, stop and finish them from a page or the MCP, and builders pick from backed bets only. The new tests and the cross files pass, along with
bun scripts/gate.ts,tsc --noEmitandbun scripts/design-lint.ts. I ran the tests I touched plus the five cross files, not the whole suite.What changed
bettable (name, share of the week, journeys, lead, state, who backed it, left line, try link, verdict) andbet_issuefor scopes, which are existing issues. The migration is pinned. The rules are insrc/crew/bets.ts./changeloghas a "By bet" section above the day-by-day list./<owner>/<repo>/bets,/bets/:id, and the MCP toolsbets(read) andbet(act). Thebet.*events are visible to admins only.Left out
slotOrder.Try it: open
/<owner>/<repo>/bets, ask for proposals, back one with a share, and the next autonomy tick picks only its scopes. Details are indocs/features/bets.md, tests intest/bets.test.ts.🤖 Generated with Claude Code
Closes #8713