Commit Graph
105 Commits
Author SHA1 Message Date
time 7c37d6d78c card #79: kept .github/time/time.py, .github/time/test_time.py, CHANGELOG.md, README.md (generated)
ci / test (pull_request) Successful in 37s
time/worker-run python3 .github/time/test_time.py >/dev/null 2>&1; echo rc=$?; git status --short
heartbeat / tick (pull_request_review) Canceled after 0s
2026-10-18 07:15:59 +00:00
teahubxyzandClaude Fable 5.1 bed8743c94 checks(): a status from one of Time's own workflows is not a check (#124)
ci / test (push) Successful in 35s
checks(): a status from one of Time's own workflows is not a check (#124)

A seat's review wakes heartbeat.yml during a heartbeat; the concurrency group cancels the run and Gitea records it as a failure on the PR head. Those statuses neither block nor earn a merge; CI decides. Owner-approved merge.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
2026-10-18 05:08:14 +00:00
time b61b185201 Council verdict: TIME_REVIEW takes several seats, votes count per seat, TIME_REVIEW_TIEBREAK on a tie (#122)
ci / test (push) Successful in 34s
Co-authored-by: Time <time@users.noreply.teahub.xyz>
2026-10-18 04:59:25 +00:00
teahubxyz 86b1207c4d Worker: build where the card says (Base: <branch>), finish what it starts (the cap gates launches), oldest card first (#121)
ci / test (push) Successful in 34s
Co-authored-by: teahubxyz <boring+teahub@agentmail.to>
2026-10-18 04:59:23 +00:00
teahubxyz bcdc71383e Claude calls go to Anthropic's own Messages API with prompt caching; the ledger prices cached tokens (#120)
ci / test (push) Successful in 34s
Co-authored-by: teahubxyz <boring+teahub@agentmail.to>
2026-10-18 04:59:20 +00:00
time 7a471e39ca Cards adopt an open PR that already closes them (review and land it instead of dispatching a worker) (#110)
time/worker-run cat > /tmp/edit.py <<'PYEOF' import re, json p = ".github/time/time.py" s = open(p).read() def sub(
ci / test (push) Successful in 35s
Co-authored-by: Time <time@users.noreply.teahub.xyz>
2026-10-18 04:39:49 +00:00
time 1747f07521 Seats review as themselves: TIME_SEAT_<SEAT> token makes the verdict a real Gitea review (#116)
ci / test (push) Successful in 35s
Co-authored-by: Time <time@users.noreply.teahub.xyz>
2026-10-18 04:27:14 +00:00
time f4058061e0 Daily housekeeping: prune merged branches, close spent signals and empty milestones, list the stale (#115)
ci / test (push) Successful in 34s
Co-authored-by: Time <time@users.noreply.teahub.xyz>
2026-10-18 04:27:12 +00:00
teahubxyzandClaude Fable 5.1 4f8eda2483 labs/aicharts: fast mode (Clef first, LLM checks) as demo default (#42)
ci / test (push) Successful in 34s
time/worker-run curl -sS -m 15 https://docs.whop.com/.well-known/skills/index.json | head -c 1500; echo; curl -sS -m
labs/aicharts: fast mode (Clef first, LLM checks) as demo default (#42)

Opened 2026-10-14 by a Claude Code session under the owner's login, which is why it read as the operator's PR for three days. Lab-only and reversible: Clef-flash draws first, the LLM checks in parallel, the chart is redrawn only on disagreement; API callers keep the LLM default. The lab's tests pass on the branch (run 652, "aicharts: all good"); its deploy step cannot run from prod, which holds no Cloudflare secrets, so nothing is deployed by this merge.

Squash-merged by the CEO session on the owner's explicit instruction.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
2026-10-18 00:12:54 +00:00
teahubxyzandClaude Fable 5.1 b539fff1b2 heartbeat: per-seat tokens for haiku, sonnet, opus and fable
ci / test (push) Successful in 35s
One Gitea user per seat (model line); the reviewer's verdict becomes a real review by that seat's own user once #76 lands. TIME_SEAT_CLAUDE stays until then as the umbrella.

On the owner's explicit instruction (CEO session).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
2026-10-17 22:54:56 +00:00
teahubxyzandClaude Fable 5.1 5c8254cc50 TIME_PROTECTED governs every protected path except the workflow directories (#81)
ci / test (push) Successful in 34s
TIME_PROTECTED governs every protected path except the workflow directories (#81)

touches_protected() hard-coded all of .github/ and .gitea/ on top of TIME_PROTECTED, so the engine under .github/time/ could never land without a human. Only the workflow directories stay hard-coded; DEFAULT_PROTECTED is unchanged. With this repo's TIME_PROTECTED narrowed, card PRs under .github/time/ with a trusted Approve and green checks merge via the time bot.

CI green on 3b757fa. Squash-merged by the CEO session on the owner's explicit instruction.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
2026-10-17 20:20:12 +00:00
teahubxyzandClaude Fable 5.1 b53016007a heartbeat: 55-minute job, and the claude seat's token for reviews
ci / test (push) Successful in 34s
The job timeout moves from 20 to 55 minutes: workers can overlap inside one run (#75), and at 20 every in-flight worker died together. TIME_SEAT_CLAUDE reaches the heartbeat so the reviewer can post as the `claude` user once #76 lands; until then it is unused.

Both on the owner's explicit instruction (CEO session).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
2026-10-17 20:16:32 +00:00
timeandClaude Fable 5.1 449f89fc38 Reviewer rule wording; no duplicate "Closes #N" in PR bodies (#74)
ci / test (push) Successful in 35s
Reviewer rule wording; no duplicate "Closes #N" in PR bodies (#74)

Reviewer Approve (haiku) on the diff, CI green on 16b369dd. Engine-only change for card #58; squash-merged by the CEO session on the owner's explicit instruction.

Closes #58

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
Co-authored-by: Time <time@users.noreply.teahub.xyz>
2026-10-17 20:13:25 +00:00
timeandClaude Fable 5.1 0e582aa70b Objections go back to the worker, with the review attached (#59)
ci / test (push) Successful in 35s
time/worker-run cd .github/time && sed -n 80,150p test_time.py; sed -n 455,480p test_time.py; grep -n "claude-sonnet
Objections go back to the worker, with the review attached (#59)

Revise loop for `/time retry`: an open PR's reviewer comments go to the worker on the same branch, open_pr updates the open PR, the card returns to `dispatched`, and verdicts older than the last revision no longer count. Check 55 covers it.

Reviewed: Approve by Time's reviewer (haiku); the two confirmation points answered by the steward. Merged by the CEO session on the owner's explicit clearance after eleven steward sign-offs were blocked by a session permission guard.

Closes #53

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017K4vyY3yUD3GsvoZaAtKkD
Co-authored-by: Time <time@users.noreply.teahub.xyz>
2026-10-17 17:46:39 +00:00
teahubxyzandClaude Opus 5.5 e705ca00ac refresh: rebuild a gh-pages venture in place, from its own tools/build.sh (#67)
ci / test (push) Successful in 34s
refresh: rebuild a gh-pages venture in place, from its own tools/build.sh (#67)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sekpYMwTXuMdza1isMQA1
2026-10-16 05:18:37 +00:00
teahubxyzandClaude Opus 5.5 721212ba7e seed: land a venture built elsewhere on yolopreneur.lol (#64)
ci / test (push) Successful in 35s
time/worker-run git fetch origin gh-pages 2>&1|tail -1; git show FETCH_HEAD:ventures/dollhouse/app.js | sed -n 140,3
seed: land a venture built elsewhere on yolopreneur.lol (#64)

Actions -> seed -> Run workflow with a slug, the URL(s) of a .tgz whose top folder is the slug, and its sha256
(plus a name and a one-liner for a new venture). seed.py checks the bundle, copies it over ventures/<slug>/ on
gh-pages in one commit, adds or refreshes the venture's line in ventures/ventures.json, and the workflow asks
Teahub pages to pull. Nothing in the bundle runs. test_seed.py runs in CI. Merged at the owner's request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K9wtGiGEeq1H5DA3T88PRe
2026-10-15 23:56:46 +00:00
time 1da01fcd68 Review: show the reviewer the PR check statuses (#56)
ci / test (push) Successful in 35s
time/worker-run cat > /tmp/patch.py <<'PYEOF' p = ".github/time/time.py" s = open(p).read() def sub(old, new): g
venture / tick (push) Successful in 3s
Closes #52

Merged by the steward (Claude, for the operator). Review answered on the PR.

Co-authored-by: Time <time@users.noreply.teahub.xyz>
Co-committed-by: Time <time@users.noreply.teahub.xyz>
2026-10-14 21:39:13 +00:00
teahubxyzandClaude Opus 5.5 97b7667970 astra: queue picks instead of labelling them ready, so they run one at a time behind the existing queue
ci / test (push) Successful in 35s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017fTCFiw6ohysUDcWoPsTys
2026-10-14 21:18:36 +00:00
time 195c65cb55 Tests: test_time.py clears the job TIME_* environment before importing time.py (#54)
ci / test (push) Successful in 35s
time/worker-run cd .github/time; python3 - <<'EOF' s=open('time.py').read() s=s.replace('''def review(card: dict, pr
Closes #51

Merged by Claude for the operator (the delegated merger for engine PRs). Reviewer objection answered on the PR: CI was green; the reviewer cannot see checks yet (#52).

Co-authored-by: Time <time@users.noreply.teahub.xyz>
Co-committed-by: Time <time@users.noreply.teahub.xyz>
2026-10-14 21:15:49 +00:00
teahubxyzandClaude Opus 5.5 c2055e85eb time: every write but comments and statuses goes out as the time bot
ci / test (push) Successful in 34s
time/worker-run python3 - <<'EOF' p=".github/time/test_time.py" s=open(p).read() old='import concurrent.futures as c
Gitea 1.24 also refuses the Actions identity label edits (removing a label is a 500), which crashed
promote_next and stalled the queue. gh() now uses TIME_TOKEN for every write except comments (Time's
beats are gitea-actions' comments) and commit statuses; the time user never counts as trusted and
mention replies ignore it; astra.yml gets TIME_TOKEN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017fTCFiw6ohysUDcWoPsTys
2026-10-14 14:02:51 -07:00
teahubxyzandClaude Opus 5.5 f3a841a762 heartbeat: put each secret's comment back on its own line
ci / test (push) Successful in 36s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017fTCFiw6ohysUDcWoPsTys
2026-10-14 20:22:05 +00:00
teahubxyz bbc62970cb time: PRs open and merge as the time bot (TIME_TOKEN); Gitea denies both to the Actions identity
ci / test (push) Successful in 35s
venture / tick (push) Successful in 3s
2026-10-14 13:11:41 -07:00
teahubxyz e12728c5ff hands: list_files resolves the branch to a sha (trees route rejects refs with a slash)
ci / test (push) Successful in 34s
2026-10-14 12:54:22 -07:00
teahubxyz 0eb9234a7e time: every write is a git push (Gitea refuses the Actions token's API writes); ledger appends; one commit per kept batch
ci / test (push) Successful in 35s
time/worker-run sed -n 262,335p .github/time/time.py
2026-10-14 12:51:52 -07:00
teahubxyz 444b01abca astra: daily planning workflow (off until TIME_ASTRA=on)
ci / test (push) Successful in 36s
2026-10-14 19:49:42 +00:00
teahubxyz 4086657dc8 astra: the daily planner (one call a day; queues cards, never spends beyond its call; guardrails in code)
ci / test (push) Has been cancelled
2026-10-14 19:49:35 +00:00
teahubxyz aecc4ee90d ci: don't retest on ledger commits
ci / test (push) Successful in 34s
2026-10-14 19:46:44 +00:00
teahubxyz c92313b62d doctor: the Cursor key is optional when a seat is the worker
ci / test (push) Successful in 34s
venture / tick (push) Successful in 2s
2026-10-14 12:38:27 -07:00
teahubxyz dc2a3e8a05 doctor: ANTHROPIC_API_KEY + spend caps
ci / test (push) Successful in 35s
2026-10-14 19:34:32 +00:00
teahubxyz a871722024 tests: provider routing, ledger booking, Budget, capped beat + andon, claude:sonnet worker
ci / test (push) Has been cancelled
2026-10-14 12:34:10 -07:00
teahubxyz 7c2b6a00a3 venture: ANTHROPIC_API_KEY + spend caps
ci / test (push) Has been cancelled
2026-10-14 19:32:11 +00:00
teahubxyz d05679b11a heartbeat: ANTHROPIC_API_KEY, TIME_DAILY_USD, TIME_MONTHLY_USD
ci / test (push) Has been cancelled
2026-10-14 19:31:54 +00:00
teahubxyz ee0302f763 mention: ANTHROPIC_API_KEY + spend caps
ci / test (push) Has been cancelled
2026-10-14 19:31:41 +00:00
teahubxyz 387fe44e15 time: Claude seats via the Claude API's OpenAI-compatible layer; spend ledger + dollar caps (governor)
ci / test (push) Successful in 37s
2026-10-14 19:25:42 +00:00
teahubxyz 9ffbb793bf seats: Claude seats (haiku, sonnet, opus, fable) with provider and prices
ci / test (push) Successful in 35s
2026-10-14 19:23:25 +00:00
teahubxyz bd6fcd7ed7 time: trust = repo owner, TIME_TRUSTED, or collaborator (the Actions token can't read permissions)
ci / test (push) Successful in 34s
heartbeat / tick (push) Successful in 3s
venture / tick (push) Successful in 3s
2026-10-13 23:58:48 -07:00
teahubxyz 8c874e8115 time: log why a permission lookup failed
ci / test (push) Successful in 34s
2026-10-13 23:57:12 -07:00
teahubxyz c360639456 Port: Time runs on Gitea (teahub.xyz) (#47)
ci / test (push) Successful in 35s
2026-10-14 06:55:19 +00:00
teahubxyzandclaude 8c6ad054b9 security: a real CI check before auto-merge; .github/ always protected (#46)
- checks(): the worker's own time/worker-run status can block or delay a merge but never counts as green
- dispatch_ci(): with no other check on the head, Time runs TIME_CI_WORKFLOW (ci.yml, workflow_dispatch) on the PR branch and waits; beat ci-dispatched, once
- ci.yml accepts workflow_dispatch
- touches_protected(): .github/ is always protected, whatever TIME_PROTECTED says
- labs-aicharts.yml: deploy URL via env, not ${{ }} in the script
- tests: worker-status-only no longer merges; dispatch once; real context merges


Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6

Co-authored-by: claude <noreply@anthropic.com>
2026-10-13 21:33:35 -07:00
teahubxyzandclaude 17e51a6b08 security: harden Time for a public repo (#45)
- beats_of/verdict/retry: trust only github-actions[bot] and owner/member/collaborator authors (forged state and stranger retries on a public repo)
- touches_protected: paginate pull files and include previous_filename
- browser_check: drop .git after clone, serve only the venture folder, Chrome with no network but localhost
- Hands.run: execute in a docker container when a daemon exists (TIME_RUN_IMAGE), host shell fallback
- tests: logins on fake comments, stranger retry/forged beat cases, paginated files fake


Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6

Co-authored-by: claude <noreply@anthropic.com>
2026-10-13 21:24:42 -07:00
teahubxyzandClaude e52e116815 labs/aicharts: show decision confidences, per-request floor, bench user agent (#41)
Live: Clef answered both probes right in ~0.5 s but at 0.21-0.25 confidence, so
the 0.5 floor sent them to the LLM. Expose every confidence and the weakest
question; a request may set its own floor (only changes cost); bench.py takes
clef@0 for calibration and sends a user agent Cloudflare accepts.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 15:31:05 +00:00
teahubxyzandClaude 2d0f997030 labs/aicharts: Jev / Clef decision brains (choice answers -> spec), LLM as the door (#40)
decide.js asks ~10 choice questions in one call (mark, x, measure, agg, series,
order, top, one filter per text column) and assembles the spec; the validator
still checks it. Weakest needed answer < FLOOR, a failed check or a model error
hands the question to the LLM path, and the response says why. Page: brain
picker, latency/confidence line, 'or as <mark>' from the mark probabilities.
bench.py scores brains on 12 fixed questions.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 15:25:17 +00:00
teahubxyzandClaude 3086cb52ff labs/aicharts: fast non-thinking model for specs (#39)
Live: gemma-4 took 70s+ and returned empty content on harder prompts (budget spent
thinking). Llama 3.3 70B fp8-fast answers the spec directly; still overridable.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 14:01:33 +00:00
teahubxyzandClaude 9e065e416d labs/aicharts: plain prompt first, JSON mode only as fallback (#38)
Live, the json_schema decoder filled every step with the same key soup (order, step)
and dropped agg/by. The prompt's grammar + example steers better.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 13:53:14 +00:00
teahubxyzandClaude 165d499644 labs/aicharts: fix model spelling drift, show the model's answer on failure (#37)
First live run: Workers AI answered specs the validator refused (agg spelling).
normalizeSpec fixes case and common aliases only; on a 422 the response
carries model_said (shown, never run). Smoke now fails on a bad spec.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 13:47:49 +00:00
teahubxyzandClaude 8eff78170b labs/aicharts: live at aicharts.<venture domain>, like ventures (#36)
The account has no workers.dev subdomain; use TIME_VENTURE_DOMAIN when set.
Deploy step fails on its own error (pipefail); smoke waits up to 3 min for the cert.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 13:42:56 +00:00
teahubxyzandClaude ba4174326a labs: AICharts demo Worker (NL -> validated chart spec, D1, workers.dev) (#35)
Library (aicharts.js): spec validator, fixed ops (filter/group/sort/bin/limit),
Chart.js config, attach() for existing charts, <ai-chart> element.
Worker: sample orders in D1, schema/sample/aggregates to Workers AI with
structured output + one repair round, saved_charts, per-IP and daily caps.
deploy.py: workers.dev only, no DNS. For teahub matcha/teahub#93.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 13:35:18 +00:00
teahubxyzandClaude 88f9d509ed venture: escalate the second fix round to kimi code, not grok 4.7 (#34)
grok 4.7 fix rounds (28-54 steps, three at once) were most of a quick $20 of Venice
spend in the first live batch. Kimi's code model is a different model from round one's
Qwen Coder, so escalation still gets a fresh attempt, at a fraction of the cost.
TIME_VENTURE_ESCALATE still overrides.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 12:13:57 +00:00
teahubxyzandClaude c6451370a7 venture: children start the tick they're spawned; briefs claim only what the code does (#33)
Two findings from the first live batch (#26):
- its children waited a tick: GitHub doesn't list a card made a moment ago. spawn()
  now hands its cards to the same tick's card loop.
- every fix round was a page claiming what its code didn't do: promised drops, and
  'builds on' the trending repos the brief asked it to name. The brief now says the
  repos are the wave it rides, forbids promised features, and has the worker re-read
  the page against app.js; fix rounds remove a failing claim instead of building.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 02:57:42 +00:00
teahubxyzandClaude a933c17fdb venture: a new batch card runs as a batch, not a single venture (#25)
GitHub returns labels as objects, and a card made a moment ago isn't listed yet, so
the batch card a tick had just made fell through to the single-venture path (live:
#24). Labels are now read by name, and the tests' fake GitHub returns label objects
and holds a new batch card back from listings for a tick, which reproduces #24.


Claude-Session: https://claude.ai/code/session_01VDkN7ukK1kXkqov8FaZxva

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-13 01:47:34 +00:00