Claude a1ea50f816
ci / test (pull_request) Successful in 47s
heartbeat / tick (pull_request_review) Successful in 12s
Taskmaster reroll: haggle to a real Whop checkout, then coach
`taskmaster/`: the factory's Whop coaching app rebuilt so the money is real. The old
version switched to coaching when the member typed "Paid $X via ..." and its webhook
handler only logged invoices.

The character haggles; the deal desk decides. The character never sets a price: it calls
one tool, quote(tier, price, reason), and dealdesk.js answers accept, counter or refuse.
Four rules — the opening is the list price and the desk never quotes above it or walks a
price back up; a quote under the floor is countered at the floor whatever reason came with
it; a step down needs one of four reasons the member gave (scope, urgency, commitment,
pay_now), each worth a slice of the anchor and each spendable once; three rounds, the
opening included. Two refusals are about honesty and spend no round: a reason that reaches
for the member's profile, following, employer, means or country, and invented scarcity or
a fake deadline.

The app decides the mode, never the model. One sheet, two prompts, and the server picks
from whether Whop says the member has paid — a valid membership on prod_EZ7UkE4pkW04U or a
place on a valid pack's seat list. Typing "Paid" changes nothing and a test proves it.

Also: the sealed quote card the model can't edit, the share card, the deal log (openings,
counters, final price, rounds, reasons, outcome, fee and net; never a word the member
wrote, validated so prose can't get in), seat packs in membership metadata with
rate-limited swaps and a buyer view of seats and usage but no chats, the signed payment
webhook, the three experiments bucketed by user, and the Venice voice with one tool, a
per-member limit and no uncensored default.

Nothing created on Whop, as the card requires: the Whop client refuses every write unless
constructed with live: true, and the 75 tests run against an injected fetch with simulated
signed webhooks.

What is missing, and why:

- teahub.xyz is blocked by this container's network policy, so teahubxyz/dealdesk and its
  SKILL.md could not be read. The rules are implemented in taskmaster/src/dealdesk.js
  behind the same seam (openDeal / quote / agree / walkaway), so swapping the import in is
  a one-file change. Someone with network access to Teahub should reconcile the two.
- docs.whop.com is blocked too, so four things stay unconfirmed and each is one line to
  correct: daily billing for the daily and checkins tiers (checkout() refuses to create a
  renewal tier until it is passed dailyBilling: "confirmed", so nothing is built on the
  assumption), the field that keeps an inline plan off the product's public page (HIDDEN in
  whop.js), the webhook's header names and whether the signed string is the body alone or a
  timestamp joined to it (both shapes verify; the names are constants), and how Whop's iOS
  rules treat a one-off checkout, which would change what these tiers may be priced at on a
  phone.
- Where the code lives was the operator's call. It is a top-level taskmaster/ here, beside
  havre/, since GitHub access for this session is scoped to teahubxyz/time alone. Moving it
  to teahubxyz/taskmaster or a shared Whop-apps repo is a directory move; nothing outside
  taskmaster/ depends on it but the one test hook.
- No workflow change is needed: CI's `python3 .github/time/test_time.py` step now runs the
  suite, as it already does for havre/.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KUi5SZq4GBkdHQ2TdhZ3r

Closes #66
2026-10-20 14:15:26 +00:00
2026-10-20 13:14:19 +00:00

time

A Gitea-native agent factory, running on Teahub prod (teahub.xyz). The Gitea repo is the ledger, Gitea Actions are the clock (Time), the worker is a Claude or Venice seat with hands or a Cursor cloud agent, and chat is where you plan.

  • Cards: an issue with a DONE: line, labelled ready.
  • Heartbeat (heartbeat.yml, hourly and whenever a card is labelled ready): moves cards forward. In dry-run (default) it only says what it would do; with TIME_MODE=live it dispatches each card to the worker (TIME_WORKER: a seat such as claude:sonnet or venice:kimi, which edits the repo and opens the PR itself, or a Cursor cloud agent), which opens a PR that closes the card. An optional reviewer (TIME_REVIEW) checks the PR. At most TIME_DAILY_CAP launches a day. Spend governor: every model call is booked to time/ledger/<YYYY-MM>.jsonl (tokens and dollars); once today's spend reaches TIME_DAILY_USD (default 5) or the month's reaches TIME_MONTHLY_USD (default 100), Time stops calling models, opens an andon issue, and a monthly breach also sets TIME_MODE=dry-run. No model decides whether to spend.
  • Mentions (mention.yml): @sonnet, @opus, @kimi, @grok 4.7, @qwen max high in any issue, PR or comment gets that seat's reply.
  • Hands-off (TIME_AUTOMERGE=on): label an issue spec and Time splits it into cards that run one at a time. A card's PR merges itself once the reviewer approves and checks are green, then the next card starts. Objections, red checks and protected paths (workflows, deploy, secrets) go to a human.
  • Venture loop (venture.yml, every 20 min once TIME_VENTURE=on): one venture card a day, or one right away from Actions → venture → Run workflow → "Start a new venture now". It scouts the repos that gained the most stars this week; seats pitch; the board votes (Borda, quorum of two); every board seat writes a launch plan (positioning, first users, pricing, channels, 7-day success and kill lines) and one seat synthesizes them into LAUNCH.md; the worker builds the product as the page on gh-pages (the tool fills the first screen under a slim header with the one signup button; pricing, limits and the why sit below); deterministic checks and headless Chrome (phone and desktop) gate it, with two fix rounds before an andon; GitHub Pages ships it at /ventures/<slug>/. Signups go through an issue form (.github/ISSUE_TEMPLATE/early-access.yml), each one thanked on its issue; after 7 days the count of distinct people decides: build v2, kill, or watch a week more. The studio index lives at /ventures/. Launch posts are drafts for a human; nothing is posted outside the repo.
  • Batches (TIME_VENTURE_BATCH=3, or Run workflow → "batch"): one scout pass, a field of pitches, and the board's top k become venture cards in one milestone, built side by side and launched together. A held child gets one batch retry before it's counted dead; a retro compares the cohort once every child is measured.
  • Seed (seed.yml, manual): land a venture that was built somewhere else. Give it a slug, the URL of a .tgz whose top folder is that slug (or of its parts, in order) and the .tgz's sha256, plus a name and a one-liner for a new venture. seed.py checks the bundle, copies it to ventures/<slug>/ on gh-pages in one commit, adds or refreshes its line in ventures/ventures.json, and asks Teahub pages to pull, so it is live at <slug>.yolopreneur.lol within the minute. Nothing in the bundle runs.
  • Refresh (refresh.yml, manual): for a venture that lives on gh-pages and makes some of its own files (fonts, art, screenshots, generated code). It runs ventures/<slug>/tools/build.sh on the runner, in place and without credentials, then commits what changed to gh-pages in one commit and asks Teahub pages to pull. from takes the folder from another branch first, so a reworked venture lands whole.
  • Backends (optional, CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID): each venture also gets its own Cloudflare Worker, D1 database and Workers AI, serving its Pages folder at <slug>.<TIME_VENTURE_DOMAIN>. The page talks to it through time.js (share links that save a creation, a rate-limited small model, and accounts with passkeys: no passwords, no email); every call degrades gracefully, so products still work on Pages alone. Code: .github/time/cloudflare.py and cloudflare/worker.js.
  • Doctor (doctor.yml, manual): runs the tests and checks label, settings, keys and today's spend.
  • Update (update.yml, weekly or manual): opens a PR with the latest engine from teahubxyz/time, so every project stays on one Time instead of drifting copies.

Setup

Started on GitHub as a proof of concept (teahubxyz/time, now read-only); ported to Gitea 2026-10-14.

Open this repo in Claude Code or Cursor and say "set up Time": the agent follows .claude/skills/time/SKILL.md. The recommended path needs one secret, ANTHROPIC_API_KEY: Claude seats plan, build and review (TIME_WORKER=claude:sonnet, TIME_REVIEW=claude:haiku; haiku, sonnet, opus, fable are the seats, priced in .github/time/seats.json). With VENICE_API_KEY instead, Venice seats do the same (TIME_WORKER=venice:qwen coder, TIME_REVIEW=venice:grok). A Cursor cloud agent can be the worker instead if you have a Cursor API key. The landing page walks through it: https://teahubxyz.github.io/time/

Status

For changes and release history, see CHANGELOG.md.

S
Description
Time: the clock for the factory. Ported from GitHub (PoC) 2026-10-14.
Readme
33 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 62%
JavaScript 36.6%
HTML 1.4%