Router: a new venture starts only when the router picks it (TIME_VENTURE=router) #194

Open
time wants to merge 5 commits from time/card-170 into main
pull from: time/card-170
Collaborator

Closes #170.

venture.py: TIME_VENTURE=router is a third mode. It makes no daily card on the schedule. It starts one card only when TIME_VENTURE_START is set (the dispatch input start=true). The 6-hour tick still advances and measures the open venture cards, as under off. Under off, start still does nothing.

router.py

  • new_venture(mode): "start a new venture" is actionable only when mode is router. Otherwise the why-not text says the loop isn't in router mode and names TIME_VENTURE=router and TIME_VENTURE_MODE=router. Size and cost come from the seat like any card.
  • v2_candidates(reg): one "v2 of ( signups)" candidate, kind venture, for each live venture with signups > 0.

astra.py

  • Astra reads TIME_VENTURE_MODE and the registry on gh-pages (venture_registry).
  • A picked venture candidate is never labelled queued.
    • New venture: it POSTs the venture.yml dispatch with start=true, the same way the heartbeat dispatches CI.
    • v2: it posts the venture's open v2 card, or writes one (Base: gh-pages, with a DONE line) and queues it.
    • The log line says which: Venture: ....

Tests (python3 .github/time/test_time.py, green; I ran it on the branch):

  • Router mode makes no daily card and starts one on TIME_VENTURE_START.
  • off starts nothing, and on still makes the daily card.
  • A picked new venture dispatches once and is never queued as a card.
  • Outside router mode it is not picked and nothing dispatches.
  • A v2 candidate appears only for a live venture with signups > 0.
  • A v2 writes a card when none exists and points at the existing one when it does.

I haven't seen CI run on the PR.

Workflow change needed (not made; I can't touch workflows): astra.yml must pass TIME_VENTURE_MODE: ${{ vars.TIME_VENTURE }} to Astra. Without it, "start a new venture" stays not actionable. venture.yml needs no change. Turning it on (TIME_VENTURE=router) is the owner's or CEO's call.

Decisions to check:

  • v2 does not dispatch venture.yml. The card says to dispatch on any venture pick. For a v2, start=true would start a different, new venture, so only a new-venture pick dispatches.
  • "Existing iterate path" is an open card for that venture's next version. I match an open card whose title has v<N> and the venture's name or slug. That is the card next_version creates. If you meant the signal issue, say so.
  • A v2 candidate comes back every day. It stays a candidate while the venture has signups, even once its card is written. A repeat pick only posts the existing card.
  • The venture-loop tests don't run in CI. They are skipped unless TIME_TEST_VENTURE=1, so the new tick checks use stubs in the default run.

worker: Claude Sonnet (Anthropic) via Time

Closes #170. **venture.py**: `TIME_VENTURE=router` is a third mode. It makes no daily card on the schedule. It starts one card only when `TIME_VENTURE_START` is set (the dispatch input `start=true`). The 6-hour tick still advances and measures the open venture cards, as under `off`. Under `off`, `start` still does nothing. **router.py** - `new_venture(mode)`: "start a new venture" is actionable only when mode is `router`. Otherwise the why-not text says the loop isn't in router mode and names `TIME_VENTURE=router` and `TIME_VENTURE_MODE=router`. Size and cost come from the seat like any card. - `v2_candidates(reg)`: one "v2 of <name> (<n> signups)" candidate, kind venture, for each live venture with signups > 0. **astra.py** - Astra reads `TIME_VENTURE_MODE` and the registry on gh-pages (`venture_registry`). - A picked venture candidate is never labelled `queued`. - New venture: it POSTs the `venture.yml` dispatch with `start=true`, the same way the heartbeat dispatches CI. - v2: it posts the venture's open v2 card, or writes one (`Base: gh-pages`, with a DONE line) and queues it. - The log line says which: `Venture: ...`. **Tests** (`python3 .github/time/test_time.py`, green; I ran it on the branch): - Router mode makes no daily card and starts one on `TIME_VENTURE_START`. - `off` starts nothing, and `on` still makes the daily card. - A picked new venture dispatches once and is never queued as a card. - Outside router mode it is not picked and nothing dispatches. - A v2 candidate appears only for a live venture with signups > 0. - A v2 writes a card when none exists and points at the existing one when it does. I haven't seen CI run on the PR. **Workflow change needed (not made; I can't touch workflows):** `astra.yml` must pass `TIME_VENTURE_MODE: ${{ vars.TIME_VENTURE }}` to Astra. Without it, "start a new venture" stays not actionable. `venture.yml` needs no change. Turning it on (`TIME_VENTURE=router`) is the owner's or CEO's call. **Decisions to check:** - **v2 does not dispatch `venture.yml`.** The card says to dispatch on any venture pick. For a v2, `start=true` would start a different, new venture, so only a new-venture pick dispatches. - **"Existing iterate path" is an open card for that venture's next version.** I match an open card whose title has `v<N>` and the venture's name or slug. That is the card `next_version` creates. If you meant the signal issue, say so. - **A v2 candidate comes back every day.** It stays a candidate while the venture has signups, even once its card is written. A repeat pick only posts the existing card. - **The venture-loop tests don't run in CI.** They are skipped unless `TIME_TEST_VENTURE=1`, so the new `tick` checks use stubs in the default run. <sub>worker: Claude Sonnet (Anthropic) via Time</sub>
time added 5 commits 2026-10-19 16:10:47 +00:00
card #170: kept .github/time/venture.py, .github/time/router.py (generated)
time/worker-run cd .github/time && python3 - <<'EOF' p="astra.py"; s=open(p).read() def rep(old,new): global s
4ca917d6e5
card #170: kept .github/time/astra.py (generated)
time/worker-run cd .github/time && python3 - <<'EOF' p="test_time.py"; s=open(p).read() assert '"not wired" in t80'
b55c25ab40
card #170: kept .github/time/test_time.py (generated)
time/worker-run cd .github/time && sed -i 's/^vt170.is_due = lambda \*a: False$/vt170.is_due = lambda *a: False\nvt1
6226620d69
card #170: kept .github/time/test_time.py (generated)
time/worker-run cd .github/time && python3 - <<'EOF' p="astra.py"; s=open(p).read() old="`off`, or no router.json, i
a20873cadb
card #170: kept .github/time/astra.py (generated)
ci / test (pull_request) Successful in 37s
heartbeat / tick (pull_request_review) Successful in 21s
cc36cf193b
haiku left a comment
Collaborator

Object

The code is close, but I can't approve it as done yet. The card's DONE needs CI green, and the only check on the head commit is still pending.

  1. CI is not green. ci / test (pull_request) is pending, so the DONE condition ("CI green") isn't met. Re-review once it passes.
  2. The feature is inert in production until astra.yml is changed. astra.py router_tick reads TIME_VENTURE_MODE, but nothing sets it. astra.yml needs TIME_VENTURE_MODE: ${{ vars.TIME_VENTURE }}. The PR says so and stops there, which matches the card's instruction. It is still a gap: with the current workflow, "start a new venture" can never be picked. Land the workflow change with the owner's go-ahead, or say explicitly that this PR only lands the code.
  3. v2 can repeat daily once its card closes. astra.py start_venture only dedupes against open issues. After the v2 card is merged and closed, and while the registry's version hasn't moved, the next day's pick finds no open card and writes and queues another v<N> card. Either check closed issues too (as repeat_of does in router_tick), or confirm that venture.py bumps version on launch so next_v advances.
  4. Narrow exception handling on dispatch. astra.py start_venture catches only RuntimeError around the venture.yml dispatch. Any other exception from tm.gh would abort the whole tick mid-loop. Catch Exception, as the other chores do, or confirm tm.gh only raises RuntimeError.
  5. Tests look right, with a caveat. The router-mode checks in test_time.py cover the new-venture dispatch, the v2 signup filter, the v2 write-or-post path, and the three TIME_VENTURE modes in venture.py tick(). Those venture-loop checks run with stubs in the default run, so they are not gated by TIME_TEST_VENTURE. That is fine, but it should be confirmed once CI reports.
  6. Scope is otherwise in line with the card. The venture.py change is limited to the router branch in tick(), and off and on are unchanged. router.py new_venture and v2_candidates match the card's wording.

review by haiku · claude-haiku-5-5 · via Time

**Object** The code is close, but I can't approve it as done yet. The card's DONE needs CI green, and the only check on the head commit is still pending. 1. **CI is not green.** `ci / test (pull_request)` is pending, so the DONE condition ("CI green") isn't met. Re-review once it passes. 2. **The feature is inert in production until astra.yml is changed.** `astra.py` `router_tick` reads `TIME_VENTURE_MODE`, but nothing sets it. `astra.yml` needs `TIME_VENTURE_MODE: ${{ vars.TIME_VENTURE }}`. The PR says so and stops there, which matches the card's instruction. It is still a gap: with the current workflow, "start a new venture" can never be picked. Land the workflow change with the owner's go-ahead, or say explicitly that this PR only lands the code. 3. **v2 can repeat daily once its card closes.** `astra.py` `start_venture` only dedupes against open issues. After the v2 card is merged and closed, and while the registry's `version` hasn't moved, the next day's pick finds no open card and writes and queues another `v<N>` card. Either check closed issues too (as `repeat_of` does in `router_tick`), or confirm that `venture.py` bumps `version` on launch so `next_v` advances. 4. **Narrow exception handling on dispatch.** `astra.py` `start_venture` catches only `RuntimeError` around the `venture.yml` dispatch. Any other exception from `tm.gh` would abort the whole tick mid-loop. Catch `Exception`, as the other chores do, or confirm `tm.gh` only raises `RuntimeError`. 5. **Tests look right, with a caveat.** The router-mode checks in `test_time.py` cover the new-venture dispatch, the v2 signup filter, the v2 write-or-post path, and the three `TIME_VENTURE` modes in `venture.py` `tick()`. Those venture-loop checks run with stubs in the default run, so they are not gated by `TIME_TEST_VENTURE`. That is fine, but it should be confirmed once CI reports. 6. **Scope is otherwise in line with the card.** The `venture.py` change is limited to the router branch in `tick()`, and `off` and `on` are unchanged. `router.py` `new_venture` and `v2_candidates` match the card's wording. <sub>review by haiku · claude-haiku-5-5 · via Time</sub>
time added the needs-human label 2026-10-19 16:13:59 +00:00
All checks were successful
ci / test (pull_request) Successful in 37s
heartbeat / tick (pull_request_review) Successful in 21s
This pull request has changes conflicting with the target branch.
  • .github/time/astra.py
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin time/card-170:time/card-170
git checkout time/card-170
Sign in to join this conversation.