From 4ca917d6e58dc6ae6fae9efdf21f0a1e6be6b1e8 Mon Sep 17 00:00:00 2001 From: Time Date: Mon, 19 Oct 2026 16:09:04 +0000 Subject: [PATCH] card #170: kept .github/time/venture.py, .github/time/router.py (generated) --- .github/time/router.py | 25 ++++++++++++++++++++++++- .github/time/venture.py | 6 ++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/time/router.py b/.github/time/router.py index e48153c..090b481 100644 --- a/.github/time/router.py +++ b/.github/time/router.py @@ -38,7 +38,30 @@ DONE = re.compile(r"^\s*DONE:", re.M | re.I) NEW_VENTURE = {"key": "venture:new", "n": None, "title": "Start a new venture: research, pick, build and launch one page", "body": "The venture loop (venture.py): one venture, researched and picked by the lead, built and judged.", "labels": [], "lined_up": False, "actionable": False, "kind": "venture", "unblocks": 0, "created": "", - "why_not": "not wired to the router yet; the venture loop is paused (TIME_VENTURE=off)"} + "why_not": "the venture loop isn't in router mode (TIME_VENTURE=router, and Astra needs TIME_VENTURE_MODE=router)"} + + +def new_venture(mode: str) -> dict: + """"Start a new venture": actionable only when Astra is told the loop is in router mode (the loop then starts a card + only when asked). Its size and cost come from the seat like any card's.""" + return {**NEW_VENTURE, "actionable": True, "why_not": ""} if mode == "router" else dict(NEW_VENTURE) + + +def v2_candidates(reg: dict) -> list[dict]: + """A "v2 of " for every live venture with signups: the studio's next version of what people asked for.""" + out = [] + for v in reg.get("ventures") or []: + try: + signups = int(v.get("signups") or 0) + except (TypeError, ValueError): + continue + if v.get("status") != "live" or signups <= 0 or not v.get("slug"): + continue + name = _txt(v.get("name") or v["slug"], 60) + out.append({**NEW_VENTURE, "key": f"venture:v2:{v['slug']}", "title": f"v2 of {name} ({signups} signups)", + "body": _txt(f"{v.get('one_liner', '')} Next: {v.get('next', '')}", 400), "actionable": True, "why_not": "", + "slug": v["slug"], "name": name, "next_v": int(v.get("version") or 1) + 1}) + return out def _num(v, default: float, lo: float = 0.0, hi: float = 100.0) -> float: diff --git a/.github/time/venture.py b/.github/time/venture.py index 20c94af..48298cc 100644 --- a/.github/time/venture.py +++ b/.github/time/venture.py @@ -39,6 +39,9 @@ Measure: after 7 days, distinct people who signed up or 👍'd the signal issue, lines: iterate (a v2 card), kill, or watch one more week and then park. Batch (TIME_VENTURE_BATCH=k, off by default): one card scouts and pitches a field, the board's top k become cards in one milestone, launched together after a hold, with one batch retry for a held child and a cohort retro (see "batches" below). +TIME_VENTURE=router (a third mode beside on / off): no daily card on the schedule; a card starts only when asked + (TIME_VENTURE_START, the dispatch input start=true), which is how Astra's router starts a venture. The tick still + advances and measures the open venture cards, as under off. Nothing is posted outside the repo: launch posts are drafts for the chair. """ from __future__ import annotations @@ -2025,6 +2028,9 @@ def tick() -> int: except Exception as e: # noqa: BLE001 chores never block the cards print("chores failed:", e) fresh, yes = [], ("1", "true", "yes") + if env("TIME_VENTURE", "off") == "router" and env("TIME_VENTURE_START", "").lower() in yes: + # router mode: no daily card; Astra's pick (venture.yml dispatched with start=true) starts one, the tick below advances it + fresh.append(new_card(next_title({c["title"] for c in venture_cards("all")}))) if env("TIME_VENTURE", "off") == "on": asked_batch = env("TIME_VENTURE_BATCH_START", "").lower() in yes if batch_size() or asked_batch: # batches replace the daily single card