Housekeeping: a null page is an empty one (#182)
ci / test (push) Successful in 37s
sync / sync (push) Successful in 4s

Housekeeping: a null page is an empty one (#182)

Gitea answers an issue nobody reacted to with null; the signal step failed on it today.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
This commit was merged in pull request #182.
This commit is contained in:
teahubxyzandClaude Opus 5.5 committed 2026-10-19 13:47:24 +00:00
1 parent 805e20d695
commit d235afb7f3
3 files changed
+5 -3

No files matched your search

+1
View File
@@ -22,6 +22,7 @@
- One venture a day, built for quality. The day's card starts only once every other venture card is launched or held, so one venture at a time gets the day's worker runs and budget; the seats pitch a field of `TIME_VENTURE_FIELD` (6) in rounds, each told what is already pitched, and the board picks one from it (it was one pitch per seat); `claude:opus` builds (`BUILDER`, and `TIME_VENTURE_WORKER` on teahubxyz/time); and the judge scores the product 1–10 as a stranger would. A page under the bar (`TIME_VENTURE_BAR`, 8) gets a polish round with the judge's top three changes; fix and polish rounds share `TIME_VENTURE_FIXES` (now 3); polish never takes the last round, which stays free to fix whatever a polish broke; then a page under the bar launches with its score in the launch post, so quality never holds a launch for a human, only a broken page does. An open batch card runs only while batches are on (`TIME_VENTURE_BATCH`) or once it has Time's beats: batch #26, migrated from GitHub with none, had started a three-venture batch on a single-venture day.
- The venture loop runs on Teahub with Claude seats. Fable chairs (synthesizes `LAUNCH.md`, writes the launch drafts, judges the build); haiku, sonnet and opus pitch, vote and write plans; `claude:sonnet` builds and `claude:opus` takes the second fix round. `TIME_WORKER` is no longer coerced to a Venice seat, which is how a Claude-configured factory kept spending Venice credits on venture builds; any `claude:` or `venice:` spec is taken as given. The port to Gitea: the scout asks GitHub's public search unauthenticated (the forge has no repository search, and no token of ours goes to GitHub); venture, batch and signal cards are listed through `tm.issues` (Gitea's `pull_request: null` had kept every card out) and created with label ids; reactions answered with null and Gitea's 50-row pages are handled; a `/time retry` counts from a trusted login (Gitea has no `author_association`); signups are the form's Venture field, or the prefilled `Early access: <name>` title on a body the form wrote when the field was left empty, never the owner, Time's users or a seat; there is no Pages API to call, and each venture is served at `https://<slug>.<TIME_VENTURE_PAGES_DOMAIN>/` (`yolopreneur.lol`). The domain's root is the Pages branch's `ventures/`, whose index is the hand-made yolopreneur.lol portfolio reading `ventures.json`: the loop writes `ventures.json` (now with `shot`, `sheet` and `source` at launch, which the portfolio shows) and writes its own list page only where the page is its own, instead of replacing the site's front page on its first save. Links point at the forge (`/src/branch/`, `/raw/commit/`). Astra never queues the loop's own issues.
- Claude calls go to Anthropic's own Messages API with prompt caching. The tools and system prompt are one cache breakpoint and the conversation so far the other, so each step of a worker run pays for the context the step before already sent at a tenth of the price (the OpenAI-compatible endpoint has no caching: a failed 43-step run cost $2.80, most of it the same context re-sent 43 times). The engine still speaks the OpenAI shape inside; an assistant turn that issued tool calls goes back exactly as the API gave it. The ledger prices cached tokens (`cached`, `written` on the line). `TIME_ANTHROPIC_API=compat` goes back to the old endpoint without a code change.
- Housekeeping reads a null page as an empty one. Gitea answers an issue nobody reacted to with `null`, not `[]`, so the signal step failed (`'NoneType' object is not iterable`) on 2026-10-19, the first day a signal issue reached its 7-day window; the fake forge in `test_housekeeping.py` now answers the same way.
- The second fix round escalates to a different model from the first round: `claude:opus` with the Claude seats (it was `venice:kimi code`, and grok 4.7 before that). `TIME_VENTURE_ESCALATE` overrides it.
### Added