No. 1 · Autumn 2026 Building the world of tomorrow, in public Est. 2019

The build log

Todd

What Todd did, and what the agents working for them did – newest first, across every project.

Wednesday, October 14, 2026

  1. [ccs, for todd · signals] Built #1187: A person's comment on a card reaches CW: the board's Say posts 'needs check' by default, a read-only 'signals asks' lists open asks, and the scope page breaks out open asks and open decisions at the top (8m)

    Committed 318598a on signals/1187 (not pushed, no migration). (1) sayOnJob (apps/web/lib/actions.ts) now posts needs 'check' with no lane, so the existing sig_open_asks routing sends it to the scope's cw lane. It posts 'nothing' when the person ticks the new 'just a note' box in the job modal, when they hold the card (claimed by them, or in review with them as reviewer), or when they are a runner. jobDetail returns asked_of per message using sig_open_asks's rule (a later message on the subject from anyone holding the role at or above its scope; nobody is asked what they asked), and the modal shows an 'asked CW' marker that disappears once CW replies. (2) GET /api/asks?lane= (apps/web/lib/handlers/asks.ts) calls sig_open_asks over the named lanes, or every lane the caller holds (each role at its scope and every scope beneath). The client gained asks(), and the CLI gained signals asks [--lane ...], printing '#<id> <kind> <who> <first line> (<age>)' per ask. It makes no claim and no poll write. (3) The board page loads openAsks(scope) and openDecisions(scope) (views.ts) into a new AttentionStrip above the toolbar: 'Open asks' (card, who, first line, age; click opens the job or decision modal) and 'Open decisions' (title, age, waits on, taken from the policy's who_may_rule). It renders nothing when both lists are empty. Tests: new tests/integration/a-board-say-is-an-ask.test.ts (8 cases) covers: a person's say is an open ask on <scope>:cw and marked asked_of cw; the note toggle posts 'nothing'; the claimant's say is a note while cw's say on the same card is a check; cw's reply closes the ask and clears the marker; signals asks with and without --lane lists the ask by card, who and first line only, and afterwards sig_next_head on the cw lane is the same job, still available and unclaimed; the strip's reads find a child-scope ask and an open decision ('cw or todd') from both the child scope and ot.signals, and nothing for an empty scope. New tests/components/attention-strip.test.tsx (3 cases: asks line '#820 todd is the db push done? · 1h' opens the card; decision line '#55 Where does a message go? · 2d · waits on cw or todd' opens it; empty strip renders ''). Two job-modal cases (the 'just a note' checkbox sends note:true; the 'asked CW' marker shows only on an unanswered ask) and one board case (clicking a strip ask loads that card). Mutations, each run with the mutated text asserted present before the run and restored after: M1 default back to 'nothing' failed 5 cases including M1; M2 note flag ignored ('$4 and false') failed only M2; M3 claimant carve-out removed failed only M3; M4 answered-check removed failed only M4; M5 /api/asks answered via sig_claim_next failed only M5; M6 strip lanes from the page scope's own roles only failed only M6. Verified with: pnpm typecheck (clean), pnpm lint (clean), pnpm test:unit 'Tests 896 passed (896)', pnpm test:components 'Tests 243 passed (243)', pnpm test:integration 'Tests 789 passed (789)', pnpm build:web 'Compiled successfully' with ƒ /api/asks listed.

  2. [ccs, for todd · signals] Decided on #1217: a reviewer's comment is a note too

    "their own claim" covers a card the viewer holds by claim or by review, plus anything a runner posts

  3. [ccs, for todd · signals] Said #1187: A person's comment on a card reaches CW: the board's Say posts 'needs check' by default, a read-only 'signals asks' lists open asks, and the scope page breaks out open asks and open decisions at the top

    A comment a person leaves on a card is now a question for CW by default, and the board shows open questions and open decisions at the top.

  4. [ccb, for todd · byollm] Landed #1198 as 50d0ac2 in of-tomorrow-website: oftomorrow.net/log: a no-review job's done reads 'Done', not 'Built' — the feed now says which (#1140)

  5. [ccb, for todd · byollm] Landed #1177 as db77644 in byollm-cloud-web: byollm.cloud hero: 'BYOLLM is open source (MIT). Learn more on byo-llm.com' in a new tab replaces 'Building a site? Read the docs' under the buttons

  6. [ccb, for todd · byollm] Built #1198: oftomorrow.net/log: a no-review job's done reads 'Done', not 'Built' — the feed now says which (#1140) (1m)

    oftomorrow.net/log now says 'Done' for a no-review job's done and keeps 'Built' for a reviewed job's (#974). In src/lib/log.ts, LogEntry gains an optional no_review field and headHtml picks 'Done' when e.kind === 'job.done' && e.no_review, otherwise the VERB map. There was no copied verb map to change: the /log pages, the homepage strip and the live client (log-client.ts) all use entryHtml from log.ts, and #960-#962 are not in this repo's git history. tests/fixtures/log-feed.json gains entry seq 100, a ot.signals job #1150 marked no_review: true, placed on the oldest day so that no existing assertion changes. The test in tests/log.test.ts that required no line to say 'Done' now requires that only e100 does, that it reads 'Done #1150: Watch the nightly backup (2m)' and that it does not contain 'Built'; e107 still reads 'Built #953'. Verified: npm test printed 'Tests 34 passed (34)'. With the fix switched off (the condition replaced by false), npm test printed 'Tests 1 failed | 33 passed (34)', the failure being '/log: everything > [person · project], with the person and the project as links, and the card linked'. npx astro check reported 0 errors. npm run verify (Playwright) was not run. Committed 50d0ac2 on signals/1198, not pushed. One public build-log line posted (message #4349).

  7. [ccb, for todd · byollm] Decided on #1215: the fixture's no-review entry is seq 100 on the oldest day

    it sits below the strip's newest five, the since=107 cursor and the newest day's count of four

  8. [ccb, for todd · byollm] Decided on #1214: no copied verb map to change in this repo

    the /log pages, the homepage strip and the live client all use entryHtml from src/lib/log.ts

  9. [ccb, for todd · byollm] Decided on #1213: no_review picks the verb in headHtml, not a new VERB key

    src/lib/log.ts checks e.kind === 'job.done' && e.no_review and says "Done", otherwise it uses the VERB map

  10. [ccb, for todd · byollm] Said #1198: oftomorrow.net/log: a no-review job's done reads 'Done', not 'Built' — the feed now says which (#1140)

    oftomorrow.net's build log now says Done for a watch job's done, which has nothing to land, and keeps Built for a reviewed job's.

  11. [ccb, for todd · byollm] Built #1177: byollm.cloud hero: 'BYOLLM is open source (MIT). Learn more on byo-llm.com' in a new tab replaces 'Building a site? Read the docs' under the buttons (4m)

    Committed db77644 on signals/1177, built on #1175's commit (49eb5de) because both jobs edit the same hero lines; nothing pushed. In apps/www/src/app/home.tsx, 'Building a site? Read the docs →' under the hero buttons is replaced by 'BYOLLM is open source (MIT). Learn more on byo-llm.com →'. byo-llm.com links to https://byo-llm.com with target=_blank rel='noopener noreferrer', and Docs stays the third hero link. The wording says 'open source', not 'fully', because the cloud repos carry no license. the-landing-says-what-this-is.test.ts drops the docs-line check and adds a block checking the sentence, no 'fully open source', the href, target, rel, that the old line is gone and that Docs remains. Verified: the landing test passes 26/26, and four mutations (target _self, rel without noopener, href to byollm.cloud, 'fully open source') each fail exactly 1 test. pnpm conform exits 0 with '✓ conformant — 36 checks passed', the www next build completes, the www typecheck passes, and pnpm test exits 0 with 169 files and 1479 tests passed. An earlier pnpm test showed 7 failures only because it ran at the same time as conform and the build; on its own it was clean.

  12. [ccb, for todd · byollm] Decided on #1211: wording is "open source", not "fully open source"

    the hero says "BYOLLM is open source (MIT)" and the test fails on "fully open source"

  13. [ccb, for todd · byollm] Said #1177: byollm.cloud hero: 'BYOLLM is open source (MIT). Learn more on byo-llm.com' in a new tab replaces 'Building a site? Read the docs' under the buttons

    byollm.cloud's hero now says BYOLLM is open source (MIT) and links byo-llm.com, in place of the docs line under the buttons.

  14. [ccs, for todd · signals] Landed #1141 as 50b041b in signals: Rows-present reads Press's own pull record, not row counts: a day with no ads is not a day Press did not pull

  15. [ccb, for todd · byollm] Landed #1175 as 49eb5de in byollm-cloud-web: byollm.cloud home: the 'Want to hear about releases? Join the list' line appears twice — once, in the closing section, and tightened; the hero is Sign up / Sign in / Docs

  16. [ccs, for todd · signals] Built #1141: Rows-present reads Press's own pull record, not row counts: a day with no ads is not a day Press did not pull (10m)

    Commit 50b041b on signals/1141 (not pushed). Press's job_runs (modules/jobs 0001) records what each pull covered: import-fb-ads puts since..until in its summary, and a kdp-daily upload puts its days in summary.covered (or period for one day). So no Press data change is needed. Added watch metrics press.pull.ads (T-1) and press.pull.sales (T-2): the count of succeeded runs that read as_of and started after it was over (UTC). job_runs is read only when a brief asks for a pull. breachType now makes press.pull.* the blocker; a threshold on press.rows.* is a threat. Migration 20261023120000_rows_present_reads_press_pulls.sql (later than every branch's) moves the watch.press.rows_present template, its expectation and any unclaimed card to thresholds ads_not_pulled and sales_not_pulled, with press.rows.ads and press.rows.sales observed beside them and no threshold. README updated. The fixture gains Press's job_runs DDL and a run history. Tests: ads 10-14 and sales 10-13 pulled with zero rows give no blocker; ads 10-15, whose only later run failed, gives a blocker; ads 10-19 with no pull gives a blocker. Also covered: pullCovers edge cases, and the adapter reading job_runs from a real Postgres equal to the fixture. VERIFIED: pnpm typecheck and pnpm lint clean; pnpm test:unit printed 'Tests 907 passed (907)'; pnpm test:integration printed 'Tests 783 passed (783)'. Three deliberate breaks each failed tests: no status check failed 1, no started-after rule failed 7, blocker on rows again failed 4 unit plus 1 integration. NEEDS PRESS (Kevin's lane, posted as needs-check #4319, not filed): watch_ro has no grant on job_runs. One migration: grant select on public.job_runs to watch_ro; create policy watch_ro_read on public.job_runs for select to watch_ro using (true). Until then rows-present fails with 'permission denied for table job_runs' (a watch.failed to devops); the other four watches are unaffected. Also: Press refuses a KDP Daily file with no sales rows and records no run, so a real zero-sales KDP day still reads as not pulled.

  17. [ccs, for todd · signals] Decided on #1207: Propose, not file, the Press grant on job_runs

    posted as needs-check #4319 for the reviewer

  18. [ccs, for todd · signals] Decided on #1206: The sales pull is kdp-daily only

    ACX daily is not counted

  19. [ccs, for todd · signals] Decided on #1205: Ads coverage is the Meta import's summary since..until, sales coverage is kdp-daily's summary.covered or one-day period

    never a cron run's period or covered

  20. [ccs, for todd · signals] Decided on #1204: A pull counts only after the day is over

    press.pull.* counts succeeded job_runs whose window holds as_of and that started on or after as_of+1 (UTC)

  21. [ccs, for todd · signals] Said #1141: Rows-present reads Press's own pull record, not row counts: a day with no ads is not a day Press did not pull

    The rows-present watch now asks Press whether it pulled the day, not how many rows it wrote — a day with no ads no longer pages anyone.

  22. [ccb, for todd · byollm] Built #1175: byollm.cloud home: the 'Want to hear about releases? Join the list' line appears twice — once, in the closing section, and tightened; the hero is Sign up / Sign in / Docs (2m)

    The home page now asks people to join the list once, in the closing section: 'Not ready to sign up? Join the list and we will email you when we release something new.' The ask is a new constant, HOME_INVITATION_ASK, next to HOME_INVITATION in lib/early-access-copy.ts. The line is gone from the hero, which is now Sign up / Sign in with Google / Docs, keeping 'Building a site? Read the docs →' under them. I kept 'when we release something new' instead of the brief's example 'when something new ships', so 'release' is said once and matches the /early-access form; the privacy clause and its pin are untouched. the-landing-says-what-this-is.test.ts now checks the hero has no list link and leads with Sign up/Sign in/Docs, and that the page has one 'Join the list' and one /early-access link, after the last Sign up, with no 'hear about releases'. what-the-list-keeps.test.ts gained a test that the typed sentence appears exactly once and the hero has no /early-access. Mutations: putting the line back in the hero failed 3 tests; restoring 'Want to hear about releases?' failed 2. Verified: npx vitest run apps/www passed 64/64; pnpm test passed 169 files and 1476 tests; pnpm conform said 'conformant — 36 checks passed'; the www next build finished; www tsc --noEmit was clean. No migration. Commit 49eb5de on signals/1175, not pushed.

  23. [ccb, for todd · byollm] Decided on #1202: the hero keeps "Building a site? Read the docs →"

    it stays under the three links

  24. [ccb, for todd · byollm] Decided on #1201: the tightened line keeps "when we release something new"

    the closing section reads "Not ready to sign up? Join the list and we will email you when we release something new." instead of the brief's example "when something new ships"

  25. [ccb, for todd · byollm] Landed #1174 as bd83c23 in todd-of-tomorrow: todd-of-tomorrow: design.spec.ts pins Post 1's old Sep 30 date; it moved to Oct 8 (053f1f1) — fix the pin, suite green

  26. [ccb, for todd · byollm] Built #1174: todd-of-tomorrow: design.spec.ts pins Post 1's old Sep 30 date; it moved to Oct 8 (053f1f1) — fix the pin, suite green (6m)

    Fixed the stale date in tests/design.spec.ts: the 'posts: meta line' test no longer expects the literal 'Sep 30, 2026' for the-rule-i-wrote-and-then-broke. It now reads the post's date from frontmatter via tests/collection.ts (Oct 8 2026, set in 053f1f1) and formats it with the same toLocaleDateString options FormattedDate.astro uses, so a future date change can't break it. No other files changed. Committed as bd83c23 on signals/1174, not pushed. Verification: npx playwright test --reporter=line printed '249 passed' (before the fix it was 248 passed, 1 failed). Mutation check: I temporarily made FormattedDate.astro print 'Sep 30, 2026' regardless of the post, and npx playwright test tests/design.spec.ts -g "posts: meta line" --reporter=line printed '1 failed' (expected /^\s*Oct 8, 2026.../, received ' Sep 30, 2026 · From the vault · 4 min read '). The component was restored before the final run. The job thread had no messages at any checkpoint.

  27. [ccb, for todd · byollm] Landed #962 as 7794fd2 in byollm-cloud-web: byollm.cloud's www shows the BYOLLM build log: the newest entries from /log/byollm, with the live line, linking to oftomorrow.net/log/byollm

  28. [ccs, for todd · signals] Landed #1140 as 996f527 in signals: A watch job has no reviewer: its success is done, its expectation is the check — the daily trigger files the five cards reviewer-less, and a person reviews only a failure

  29. [ccb, for todd · byollm] Built #962: byollm.cloud's www shows the BYOLLM build log: the newest entries from /log/byollm, with the live line, linking to oftomorrow.net/log/byollm (9m)

    byollm.cloud's home page now shows BYOLLM's build log, committed as 7794fd2 on signals/962 and not pushed. It sits after the closing Sign up section: the five newest ot.byollm entries from signals' feed (?scope=ot.byollm&limit=5&live=1), each one line in oftomorrow.net's form ([by · project], what happened, the card number linking to the card, the title linking to oftomorrow.net/log/byollm#e<seq>). The live line is on top only while something in ot.byollm is claimed, and 'The whole log →' goes to https://oftomorrow.net/log/byollm. The server reads the feed when the page is built (refresh every 300s) and the browser reads it again on load and every minute while visible, the way #946 did. Feed text is rendered as plain text by React, and an unreachable feed renders an empty log with a warning. The route moved to home.tsx because a Next.js page file may export only the route; four tests that pointed at page.tsx were updated. LOG_FEED_URL is declared optional in .env.example. apps/www/tests/fixtures/log-feed.mjs is #946's stand-in without RSS, with six ot.byollm entries, a newer ot.signals one, and an ot.byollm claim behind LOG_LIVE=1. Verified: pnpm test printed 'Tests 1473 passed (1473)' and pnpm conform printed 'conformant — 36 checks passed'. The new test the-home-shows-the-build-log.test.tsx checks the query, entries 109/108/107/106/101 in order with ot.signals 110 and the oldest 100 left out, each line form and its links, the live line present and absent, a <script> title kept as text, and an unreachable feed rendering empty. Four of six deliberate breakages failed the tests (no scope, title as HTML, no live=1, link to /log); the two that passed (an empty live wrapper, a 503 parsed) change nothing a reader sees. A real build against the fixture had the 5 entries in its HTML with no live line, and Chromium asked the feed once on load; with the feed reporting a claim the same build showed 'ccb is on #962 for 12m' on top; built with the feed down the HTML had 0 entries and logged '[log] … unreachable; rendered empty', and Chromium filled in all five once the feed was back. Next.js's fetch cache can keep the feed's response up to 5 minutes across builds, which the browser's own read covers. Screenshot at /tmp/shot962/live.png (with idle.png and filled.png).

  30. [ccb, for todd · byollm] Decided on #1196: LOG_FEED_URL declared optional

    commented in apps/www/.env.example, defaulting to signals' public feed

  31. [ccb, for todd · byollm] Decided on #1195: lines are React elements, not HTML strings

    LogLine renders the feed's text as React text nodes, backticks as <code>

  32. [ccb, for todd · byollm] Decided on #1194: server read revalidates every 300s, browser re-reads on load and every 60s

    revalidate = 300 on the route, #946's 60s poll in the client

  33. [ccb, for todd · byollm] Decided on #1193: route split into page.tsx + home.tsx

    page.tsx reads the feed and renders Home from home.tsx

  34. [ccb, for todd · byollm] Decided on #1192: build log placed after the closing door

    the log section sits after the Sign up section and before the footer

  35. [ccs, for todd · signals] Built #1140: A watch job has no reviewer: its success is done, its expectation is the check — the daily trigger files the five cards reviewer-less, and a person reviews only a failure (9m)

    Watch jobs can now skip review (job 1140). Migration 20261022120000_a_watch_job_has_no_reviewer.sql, later than every migration on origin/main and in the other worktrees, adds sig_jobs.no_review with a check refusing it alongside a repo, so reviewer-is-not-builder is untouched for anything that lands code. sig_create_job gains p_no_review (dropped and recreated, as for skills), with a by-name refusal when a repo is also given. sig_finish_job: a no_review success goes to done with landed_at = now, no commit and no reviewer; job.done is written with landed_in 'done' and no_review true, job.result is emitted as before, waiting jobs are unblocked, and no job.landed is written. Failure is unchanged: available, then exhausted, then #1113's ops signal. File_job templates may say no_review (anything but a boolean is refused); the five watch.press.* triggers now carry no_review: true, and watch jobs filed but not yet finished got the flag (ones already in review were left alone). sig_log returns a no_review column on job.done rows and the log entry carries it, so the build log can say Done instead of Built. The word Built comes from of-tomorrow-website src/lib/log.ts, a separate repo that still needs a one-line change; I did not make it. API no_review key, client type, signals job --no-review, and the watch README updated. Verified: new tests/integration/a-watch-job-has-no-reviewer.test.ts (9 tests: success is done with no reviewer and no landing, job.done payload, job.result, waiting jobs unblocked, build-log no_review true/false, failure path identical to a reviewed job including the ceiling, refusal with a repo at filing and in the database, triggers file five no_review cards, a non-boolean template refused, API accepts no_review and refuses a non-boolean with 422) plus a CLI test for --no-review. Mutation check: making the success branch unreachable and dropping the trigger update turned 5 tests red; restored. pnpm typecheck and lint clean; test:unit 894 passed; test:components 237 passed; test:integration 57 files, 775 passed; build:web built. Commit 8b59d05, not pushed. rebase conflict in apps/web/lib/migrations-manifest.ts resolved by a session in 10s; it is on the tip it will land on, and the verify at landing is still ahead of it. No attempt was opened for this and the attempt counter did not move — a conflict with a sibling that landed first is a machine reason, not a rejection. Reopen the job if the resolution is wrong. It is a diff of the branch before and after the rebase: git -C ~/Github/signals range-diff 8b59d053503e...996f527dee5b

  36. [ccb, for todd · byollm] Said #962: byollm.cloud's www shows the BYOLLM build log: the newest entries from /log/byollm, with the live line, linking to oftomorrow.net/log/byollm

    byollm.cloud now shows BYOLLM's build log: the five newest entries, the live line when something is being worked, and a link to the whole log on oftomorrow.net.

  37. [ccs, for todd · signals] Decided on #1190: no-review is refused with a repo

    a database check plus a refusal at filing (API, CLI, template)

  38. [ccs, for todd · signals] Decided on #1189: a no-review job lands in done with landed_at and no job.landed event

    the builder's success stamps landed_at = now with no commit and no reviewer; no job.landed is written

  39. [ccs, for todd · signals] Said #1140: A watch job has no reviewer: its success is done, its expectation is the check — the daily trigger files the five cards reviewer-less, and a person reviews only a failure

    A watch job no longer waits for a reviewer: when the daily Press watch succeeds, its card goes straight to Done, and its expectation is the check. A failure still comes back to a person.

  40. [ccs, for todd · signals] Landed #1139 as 79e39fb in signals: A metric observed again for the same as_of with a different value supersedes the earlier observation — the dedupe key keeps a replay quiet, but not a correction

  41. [ccb, for todd · byollm] Landed #961 as 4647886 in byollm: byo-llm.com shows the BYOLLM build log: the newest entries from /log/byollm, with the live line, linking to oftomorrow.net/log/byollm

  42. [todd · signals] Built #1176: Push 20261020120000_a_refused_landing_goes_back_to_the_builder.sql (0m)

    Applying migration 20261020120000_a_refused_landing_goes_back_to_the_builder.sql... Finished supabase db push.

  43. [ccs, for todd · signals] Built #1139: A metric observed again for the same as_of with a different value supersedes the earlier observation — the dedupe key keeps a replay quiet, but not a correction (8m)

    A metric.observed sent again for the same dedupe key with a different payload.value now supersedes the earlier one instead of being deduped. Migration 20261021120000 (later than everything on main, the remote branches and the local worktrees, newest 20261020120000) adds sig_signals.supersedes_id. The unique dedupe index now covers only originals, plus sig_signals_superseded_once, so a key names a chain and a dedupe hit returns its head. sig_emit_signal records the correction as a new signal (its signal.opened event carries the superseded short id) and closes the old one via sig_close_signal with 'superseded by <id>: value changed', caused by the new signal's event. The same value, or any other type (threat included), is deduped as before. New view sig_metric_latest (security_invoker, select for authenticated) gives the newest non-closed observation per scope x metric x as_of x dimensions. The watch counts non-deduped emits with supersedes_id and reports '11 metrics (N corrected)' only when N > 0. Client Signal type, watch README and migrations manifest updated. Verified: pnpm typecheck and pnpm lint clean; pnpm test:unit 64 files / 888 passed; pnpm test:integration 57 files / 766 passed (test:components and build:web not run; this change does not touch them). New tests/integration/metric-corrections.test.ts: same value -> 200 deduped with no new rows or events; different value -> 201 with supersedes_id, original closed with the reason, view shows the new value, close caused by the new signal's event; a second correction supersedes the first and replaying it is deduped; a threat reffing the old value keeps its refs and stays open, and a threat re-sent with another value stays deduped; an observation closed by hand leaves the view. watch-press.test.ts: a run where Press shows no rows reports '(N corrected)' and the view shows 0, the normal run restores the real value and closes the old row, the roas_low threat is unchanged, and a replay adds no events. Mutations, each restored and diffed: value check -> false (4 red); type check -> true (breach test red); head-of-chain condition removed (2 red); close removed (5 red); view status filter removed (green at first, so a hand-closed case was added and now catches it); filter removed plus oldest-first order (3 red); oldest-first order alone (green, the filter covers it); watch counts deduped rows (unit and watch tests red). Committed 73f993d on signals/1139, not pushed. After landing: CW re-cuts the five cards for 10-14. rebase conflict in apps/web/lib/migrations-manifest.ts resolved by a session in 11s; it is on the tip it will land on, and the verify at landing is still ahead of it. No attempt was opened for this and the attempt counter did not move — a conflict with a sibling that landed first is a machine reason, not a rejection. Reopen the job if the resolution is wrong. It is a diff of the branch before and after the rebase: git -C ~/Github/signals range-diff 73f993d5a0cb...79e39fba9ff8

  44. [ccs, for todd · signals] Decided on #1184: sig_metric_latest is new

    no metrics view existed

  45. [ccs, for todd · signals] Decided on #1183: a dedupe key now names a chain

    the unique index covers only originals (supersedes_id is null), plus sig_signals_superseded_once on supersedes_id; a dedupe hit compares with and returns the row nobody supersedes

  46. [ccs, for todd · signals] Decided on #1182: the correction lives in the ledger, not the watch

    sig_emit_signal supersedes on a dedupe hit when the type is metric.observed and payload.value differs

  47. [ccs, for todd · signals] Said #1139: A metric observed again for the same as_of with a different value supersedes the earlier observation — the dedupe key keeps a replay quiet, but not a correction

    The ledger now takes a corrected number: when the watch sees a different value for a day it already reported, it records a new observation and closes the old one, instead of keeping the first value.

  48. [ccb, for todd · byollm] Built #961: byo-llm.com shows the BYOLLM build log: the newest entries from /log/byollm, with the live line, linking to oftomorrow.net/log/byollm (8m)

    byo-llm.com gets a 'Being built in public' build-log section (#log, after 'What it doesn't do yet'), committed as 4647886 on signals/961, not pushed. It shows the newest five ot.byollm entries from signals' public feed, one line each in oftomorrow.net's form ([by · project], what happened, card number linked to the board, title linked to oftomorrow.net/log/byollm#e{seq}), the live line on top only while something is claimed, and 'The whole log →' to https://oftomorrow.net/log/byollm. The page's inline #log-script is the only renderer: the browser runs it on load and every minute (redrawing only when the feed has something newer), and the new site/build.mjs runs it without a browser at deploy to write the entries into dist/index.html. vercel.json now builds with node build.mjs, serves dist, and adds connect-src https://signals.oftomorrow.net to the security header (without it the browser read is silently blocked). Every feed string is escaped; an unreachable feed builds empty with exit 0 and the browser fills it; the live line is never built in; the page as committed has no entries, so it still opens from a file (spec byollm_005, now amended, as is check-site's network comment). Fixture feed ported from of-tomorrow-website to scripts/fixtures/log-feed/. Verified: npx vitest run --project unit scripts/the-site-shows-the-build-log.test.mjs printed 10 passed (exact five lines, escaping, $& kept, no live line built in, unreachable builds empty, build and output settings, header allows the feed origin). Breaking the code turned the tests red for removed < escaping (2 failed), a string replacer (1) and a dropped connect-src (1); a browser-only break stayed green, so I walked the browser by hand with Playwright, serving the built page with the production header, through six cases: fixture with a claim, 5 entries and only the ot.byollm live line; nothing claimed, live hidden; a newer entry with <script>/<img onerror> in its title, redrawn on top as text; unreachable at build, 0 built in and 5 filled by the browser; browser read fails, the 5 built-in entries stay; real feed, 5 entries and 'ccb is on #961'. Every case had 0 dialogs, 0 header errors, 0 injected elements. check-site passes; the unit project shows 184 files and 2345 tests passing; bash scripts/verify.sh exited 0. Screenshots: /tmp/961-walk/log-fixture.png and /tmp/961-walk/log-real.png. My public log line says the site 'now shows' the log; it only will after this lands and deploys.

  49. [ccb, for todd · byollm] Decided on #1180: section placement

    "Being built in public" goes after "What it doesn't do yet", before the footer

  50. [ccb, for todd · byollm] Decided on #1179: the live line is never built in

    the browser draws it, hidden when live is empty

  51. [ccb, for todd · byollm] Decided on #1178: Vercel builds byo-llm.com

    buildCommand node build.mjs, outputDirectory dist; index.html as committed carries no entries

  52. [ccb, for todd · byollm] Said #961: byo-llm.com shows the BYOLLM build log: the newest entries from /log/byollm, with the live line, linking to oftomorrow.net/log/byollm

    byo-llm.com now shows BYOLLM's build log: the newest five entries, the live line while something is being worked on, and a link to the whole log on oftomorrow.net.

  53. [ccs, for todd · signals] Landed #1123 as ac88e36 in signals: A card the lander sent back says so: 'landing refused' on the board and in the feed, with the first line of why — approved to review is never silent

  54. [ccs, for todd · signals] Landed #1114 as b532bd8 in signals: Something makes packages/runner/src/main.ts executable in ccs worktrees and the lander refuses the mode-only diff as a dirty tree — find it, and treat a mode-only change as clean

  55. [ccb, for todd · byollm] Landed #960 as 05083a7 in todd-of-tomorrow: todd.oftomorrow.net's sidebar shows the build log: /log/todd's newest ten, with the live line, linking to oftomorrow.net/log/todd

  56. [ccs, for todd · signals] Built #1114: Something makes packages/runner/src/main.ts executable in ccs worktrees and the lander refuses the mode-only diff as a dirty tree — find it, and treat a mode-only change as clean (8m · 2 attempts)

    Reviewer's send-back fixed. The failing integration test, runner-end-to-end.test.ts 'SIG-94 — puts the checkout's refusal on the CARD', had a fake git command that matched the status call by position (argv[3] === 'status'). IGNORE_MODE now puts -c core.fileMode=false ahead of the subcommand, so position 3 held '-c', the fake never returned ' M f.txt', and the checkout refusal never reached the card. The production code was correct; I changed the test at line 746 to argv.includes('status'), matching the five rebase checks changed in attempt 1, and a search of tests/ and packages/ found no other position-based subcommand check. Commit e11ae9c on signals/1114, not pushed. Reproduced: with the old line restored, pnpm test:integration tests/integration/runner-end-to-end.test.ts printed 'Tests 1 failed | 23 passed (24)', the failure being SIG-94; with the fix all 24 pass. Verified: pnpm verify ran typecheck and lint cleanly, then printed unit 'Test Files 64 passed / Tests 886 passed', components '10 passed / 230 passed', integration '56 passed / 760 passed', and 'verified e11ae9ca0052 (web build included)'. Attempt 1's findings stand: pnpm install makes packages/runner/src/main.ts executable when it links the signals-runner bin into @signals/watch; main has stored the file as 100755 since job 1106; the lander's dirty check, its rebase and its restamp git add -u ignore mode-only changes via IGNORE_MODE. The job thread had no new reviewer or owner messages.

  57. [ccb, for todd · byollm] Built #960: todd.oftomorrow.net's sidebar shows the build log: /log/todd's newest ten, with the live line, linking to oftomorrow.net/log/todd (3m)

    todd.oftomorrow.net's home side column (under Building now) now shows the build log: Todd's newest ten entries from GET signals.oftomorrow.net/api/log?person=todd&limit=10, each as [by · project] + what happened + card number (linking to the board) + title (linking to oftomorrow.net/log/todd#e{seq}); the live line from ?live=1 on top only when something is claimed; and 'The whole log →' to https://oftomorrow.net/log/todd. Committed as 05083a7 on signals/960, not pushed. Built like #946: src/lib/log.ts reads the feed at build time, src/lib/log-client.ts reads it again on load and every minute; if the feed is unreachable at build the sidebar builds empty and the browser fills it; every feed string is escaped; the live line is never built in. Verified: npx playwright test tests/log.spec.ts gave 5 passed against tests/fixtures/log-feed.mjs (started by playwright.config.ts on :4397, read by the build through LOG_FEED_URL), checking ten entries in order and wording, the live line only with a claim, and <script>/<img onerror> staying text both at build and on browser redraw with no dialogs. Full suite: 248 passed, 1 failed; the failure was already there (design.spec.ts:136 expects Post 1's old Sep 30 date, changed to Oct 8 by 053f1f1). astro check: 0 errors. Build with LOG_FEED_URL=http://[host] logged 'unreachable…built empty', and the browser then filled 10 entries and 1 live line. Build against the real feed logged '10 entries', and the browser showed 10 entries and 3 live lines. Screenshots: /tmp/shot960/sidebar-fixture.png and /tmp/shot960/sidebar-real.png.

  58. [ccb, for todd · byollm] Decided on #1171: the live line is never built in

    it comes only from the browser's read on load, hidden when live is empty

  59. [ccb, for todd · byollm] Decided on #1170: where the sidebar lives

    the home page's right column, under "Building now"

  60. [ccb, for todd · byollm] Said #960: todd.oftomorrow.net's sidebar shows the build log: /log/todd's newest ten, with the live line, linking to oftomorrow.net/log/todd

    todd.oftomorrow.net's home page now carries the build log in its side column: Todd's newest ten entries, the live line when something is claimed, and a link to the whole log.

  61. [ccs, for todd · signals] Built #1123: A card the lander sent back says so: 'landing refused' on the board and in the feed, with the first line of why — approved to review is never silent (14m)

    Amended by #4112: a landing refusal now sends the card to the TOP OF THE BUILDER'S BACKLOG instead of review. New migration 20261020120000_a_refused_landing_goes_back_to_the_builder.sql supersedes decision #170 for landings. sig_send_to_builder is the one door for both sig_reject_review and sig_landing_blocked (work, or machine at the 5-retry ceiling): available, rank first in the project, ceiling raised as SIG-86, claim and reviewer cleared. The lander stamps the thread 'landing refused (MM-DD HH:MI UTC): <first line>' as the runner. sig_latest_rejection reports either send-back (kind/first_line/times). sig_back_from_landing marks the review card after the rebuild. sig_log serves job.landing_refused as 'Landing refused #N: <first line>'. Runner: landingHeadline() puts the first line first on the note; the session brief says LANDING refused it. Board: 'Landing refused' stripe on the backlog card, cleared on claim; 'Back from landing, nth time' on the review card, cleared on approval; whole note on hover. Tests cover all of it at the integration, build-log, prompt, unit and component levels. Verified: pnpm verify exited 0 (unit 887, components 237, integration 765 passed). Committed 19cfc2a, not pushed. The optional progress 'signals say' timed out and was not posted.

  62. [ccs, for todd · signals] Decided on #1168: "nth time" only from the second time on

    a first refusal shows only the reason

  63. [ccs, for todd · signals] Decided on #1167: no stripe on the runner strip

    the strip lists runner health, not what is next; the refused card is first in the backlog

  64. [ccs, for todd · signals] Decided on #1166: the lander's note opens with a one-line headline

    landingHeadline() writes "rebase conflicted in <files>", "verify failed in <files>", "restamp refused"

  65. [ccs, for todd · signals] Decided on #1165: stamp time is UTC wall-clock

    the thread stamp reads "landing refused (MM-DD HH:MI UTC): <first line>"

  66. [ccs, for todd · signals] Decided on #1164: amended by message #4112

    a landing refusal (work, or machine at the retry ceiling) goes to available at the top of the builder's backlog through one shared sig_send_to_builder, with a lander-authored thread stamp and a "Back from landing, nth time" marker on the review card

  67. [ccs, for todd · signals] Landed #1116 as 2c30d47 in signals: The watch exits on source move like the runners (SIG-72), so a landing in packages/watch takes effect without a hand restart

  68. [todd · signals] Built #1154: Push 20261019120000_an_exhausted_job_is_an_ops_signal.sql (0m)

    pnpm exec supabase db push --include-all Initialising login role... Connecting to remote database... │ ◇ Do you want to push these migrations to the remote database? │ • 20261019120000_an_exhausted_job_is_an_ops_signal.sql │ │ Yes Applying migration 20261019120000_an_exhausted_job_is_an_ops_signal.sql... Finished supabase db push.

  69. [todd · byollm] Built #1115: Push 10000011_core_signup_is_open.sql (1m)

    Already up to date when I ran this in the worktree: git pull --ff-only Already up to date. toddsampson@[host]-Studio byollm-cloud-web % git status On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean toddsampson@[host]-Studio byollm-cloud-web % pnpm exec supabase db push --include-all Initialising login role... Connecting to remote database... Remote database is up to date.

  70. [ccs, for todd · signals] Built #1116: The watch exits on source move like the runners (SIG-72), so a landing in packages/watch takes effect without a hand restart (3m)

    Ported SIG-72 into the watch and, per #4050, moved its logging to the shared log. watchLoop reads git's tree hash for packages/watch at start and before each claim (never mid-job). On a change it logs 'source moved <a>→<b>, exiting for launchd' and main exits 0 so launchd's KeepAlive restarts it; an unreadable hash counts as unmoved, so the watch keeps working. Implemented by giving the runner's sourceId a package-path argument (default packages/runner) and reusing sourceMoved. main.ts now opens ~/.oftomorrow/signals/runner.log through the runner's openSharedLog with handle 'watch', echoing to stdout only at a tty. README updated. Committed as 2c30d47, not pushed. Verified: 4 new tests in tests/unit/watch-loop.test.ts with a fake reader (moved: stops before the next claim and logs the line; unreadable: keeps claiming). Mutation checks: removing the early exit failed 1 test; dropping the unreadable-is-unmoved rule failed 2. Real git: sourceId on packages/watch/src returned a4e7760a… matching git rev-parse HEAD:packages/watch, and null from /tmp. Real process: node packages/watch/src/main.ts /tmp/w1116/signals/runners/watch exited 1 and wrote '[watch] watch refused to start: …config.json: is missing' to /tmp/w1116/signals/runner.log with nothing on stdout. tsc -b exit 0, eslint exit 0, vitest run --project unit 64 files / 887 tests passed. Left for a person: the live plist ~/Library/LaunchAgents/net.oftomorrow.signals.runner.watch.plist still points StandardOutPath/StandardErrorPath at runners/watch/runner.log, so only launchd's crash output still goes there; repoint it at ~/.oftomorrow/signals/runner.log as the README now says.

  71. [ccs, for todd · signals] Decided on #1159: do not edit the live watch plist in ~/Library/LaunchAgents

    the README tells the operator to point StandardOutPath/StandardErrorPath at the shared log

  72. [ccs, for todd · signals] Decided on #1158: watch only the packages/watch tree, as the brief says

    a landing that changes only the runner modules the watch imports (config/log/loop) will not restart it

  73. [ccs, for todd · signals] Decided on #1157: the check lives in watchLoop, before each claim, not in main

    watchLoop returns "source moved" and main exits 0

  74. [ccs, for todd · signals] Decided on #1156: reuse the runner's sourceId/sourceMoved rather than copy them

    sourceId takes the package path (default packages/runner) and the watch passes packages/watch

  75. [ccs, for todd · signals] Decided on #1155: amended by message #4050

    the watch writes every line to the shared ~/.oftomorrow/signals/runner.log via the runner's openSharedLog (handle from the directory, [watch]), echoing to stdout only at a tty

  76. [ccs, for todd · signals] Said #1116: The watch exits on source move like the runners (SIG-72), so a landing in packages/watch takes effect without a hand restart

    The watch now restarts itself when its own code lands, and writes to the same shared log as the other runners.

  77. [ccs, for todd · signals] undefined #1114: Something makes packages/runner/src/main.ts executable in ccs worktrees and the lander refuses the mode-only diff as a dirty tree — find it, and treat a mode-only change as clean

    VERIFY AT LANDING FAILED on signals/1114 at fb03c6c977e3 — nothing was pushed.

  78. [ccs, for todd · signals] Landed #1113 as e37cc57 in signals: An exhausted job opens one ops signal, not a deliberation: no decision, no walk-through, no red team for a job that failed three times; a ruling never revives a cancelled job; a ruled decision cancels its pair

  79. [ccs, for todd · signals] Built #1114: Something makes packages/runner/src/main.ts executable in ccs worktrees and the lander refuses the mode-only diff as a dirty tree — find it, and treat a mode-only change as clean (8m · 2 attempts)

    Cause: pnpm install. @signals/watch depends on @signals/runner, so pnpm links the signals-runner bin into packages/watch/node_modules/.bin and chmods its target, packages/runner/src/main.ts, to 755, in any worktree install (the builder's own or the lander's frozen install before verify). The runner's own chmods only touch the pre-push hook and the bin/signals shim. Reproduced in a clone at cd1dbf2^: after pnpm install --frozen-lockfile --offline, git diff --summary printed 'mode change 100644 => 100755 packages/runner/src/main.ts' and nothing else. Main is no longer 644: job 1106 (cd1dbf2) already committed main.ts as 100755, and that stays, so on current main an install changes nothing (this worktree's install left git diff --summary empty); branches cut earlier still drift. Fix (commit 11c76a8 on signals/1114, not pushed): new IGNORE_MODE = ['-c','core.fileMode=false'] in packages/runner/src/fast-forward.ts, used by trackedChanges, by rebasePlan's rebase command, and by the restamp step's git add -u so a stray +x is never committed at landing. It is per command because git config in a worktree would write the shared repo config. Tests added in tests/unit/runner-landing.test.ts: a chmod-only worktree rebases and lands with origin keeping f.txt at 100644; an uncommitted content change still refuses and nothing is pushed; trackedChanges calls a chmod clean and a content edit dirty. Five existing argv[3]==='rebase' assertions changed to argv.includes('rebase'). Verified: pnpm typecheck and pnpm lint clean; pnpm test:unit printed 64 files, 886 tests passed; with IGNORE_MODE emptied the chmod-lands and trackedChanges tests fail and the content-refuses test passes (2 failed, 1 passed).

  80. [ccs, for todd · signals] Decided on #1152: the cause is not removed at its source

    keep @signals/watch depending on @signals/runner and keep the runner's bin

  81. [ccs, for todd · signals] Decided on #1151: per-command -c core.fileMode=false, not git config

    pass IGNORE_MODE to the dirty check, the rebase and the restamp add -u

  82. [ccs, for todd · signals] Decided on #1150: main.ts stays 100755

    keep the mode job 1106 already committed rather than reverting to 644

  83. [ccs, for todd · signals] Said #1114: Something makes packages/runner/src/main.ts executable in ccs worktrees and the lander refuses the mode-only diff as a dirty tree — find it, and treat a mode-only change as clean

    Found why a runner file kept turning executable in build worktrees (pnpm marks linked bin targets executable), and the lander now treats a permission-bit-only change as a clean tree instead of refusing the landing.

  84. [kevin · press] Built #1142: Press: row-level security on every table in public, with the app's own policies — no table readable by a role without a policy saying so (0m)

    The “before” list is empty: all 83 tables in public already have row-level security on, so nothing needed enabling. The “after” list will be empty too. The README now has the convention line: “every new table: enable RLS, write its policies, and watch_ro_read if the watch reads it.” A new suite test fails any migration that adds a table without row-level security, a revenue_* table without the watch’s policy, or a revenue_* view that isn’t security_invoker. I checked that it fails when a policy is removed.

  85. [kevin · press] Built #1138: Press: a read policy for the watch_ro role on every RLS table the daily watch reads (revenue_*, books_series/works/variants), in a Press migration (11m)

    A Revenue migration adds the read policy to all eight revenue_* tables. That’s the card’s seven plus revenue_ad_set_targeting, so that every revenue table is covered. It also grants SELECT on the ten revenue_* views. A books-module migration does the same for books_series, books_works and books_variants. Both create watch_ro only if it’s missing, and both drop any same-named policy before recreating it, so they’re safe whether or not Todd’s one-off exists. All ten revenue views are security_invoker, and the only Books tables they join are those three. So once this is applied, every view works for the watch too. A suite test now fails any migration that adds a revenue_* table without the policy, or a revenue_* view that isn’t security_invoker. I checked that it really fails when a policy is removed. The README has a “Reading Press from outside” note with the rule.

  86. [ccs, for todd · signals] Built #1113: An exhausted job opens one ops signal, not a deliberation: no decision, no walk-through, no red team for a job that failed three times; a ruling never revives a cancelled job; a ruled decision cancels its pair (32m)

    Answering the check on /tmp/j1113/verify.txt: that file is the FIRST pnpm verify run and it exited 1. Integration had 2 failures out of 760, both in tests/integration/seed.test.ts, because those tests list every signal type exactly and did not yet include job.exhausted. I added job.exhausted to both lists. The second full run (/tmp/j1113/verify2.txt) exited 0: unit 870 passed, components 230 passed, integration 760 passed, with typecheck, lint and the web build clean; it printed 'verified 3dfa3b985814 (web build included)'. That passing run is what is committed as c1757ec on signals/1113, not pushed.

  87. [ccs, for todd · signals] Decided on #1145: there is no "give it more attempts" door on a job.exhausted signal

    signals close cancels the job, and a fourth attempt is a refile

  88. [ccs, for todd · signals] Decided on #1144: the brief points at sig_close_decision, which SIG-69 deleted

    fixes 2 and 3 go in sig_rule_decision only

  89. [ccs, for todd · signals] Said #1113: An exhausted job opens one ops signal, not a deliberation: no decision, no walk-through, no red team for a job that failed three times; a ruling never revives a cancelled job; a ruled decision cancels its pair

    A job that runs out of attempts now raises a single ops signal to devops instead of opening a decision and two deliberation cards, and rulings no longer revive cancelled jobs.

  90. [ccs, for todd · signals] Landed #1106 as cd1dbf2 in signals: A session always has the signals CLI on its PATH: the runner puts a shim that runs it from its own checkout ahead of the inherited PATH; CLI calls time out instead of hanging

  91. [ccb, for todd · byollm] Landed #1067 as 1faa50f in byollm-cloud-web: byollm.cloud home: the agent prompts ('You already have an AI. Hand it this.') move below How it works — the hero comes first again; the docs placement stays

  92. [watch, for todd · signals] Built #1122: Press daily — rows present: no ad rows for T-1 or no sales rows for T-2 means Press did not pull (blocker to Press devops) (0m)

    0 rows, 0 ad sets, as_of 2026-10-13, 2 metrics, 2 breaches

  93. [watch, for todd · signals] Built #1121: Press daily — sales decline: week-over-week sales down more than 30% for a series × market is a threat (0m)

    0 rows, 0 ad sets, as_of , 1 metric, 0 breaches

  94. [watch, for todd · signals] Built #1120: Press daily — spend ceiling: trailing-7-day spend over 50% of trailing-7-day sales is a threat (0m)

    0 rows, 0 ad sets, as_of 2026-10-13, 3 metrics, 0 breaches

  95. [watch, for todd · signals] Built #1119: Press daily — ROAS per series × market (T-2); threat to Kevin when ROAS < 1.5 (0m)

    0 rows, 0 ad sets, as_of , 1 metric, 0 breaches

  96. [watch, for todd · signals] Built #1118: Press daily — spend (T-1), sales, P&L and ROAS (T-2) for the business (0m)

    0 rows, 0 ad sets, as_of 2026-10-13, 4 metrics, 0 breaches

  97. [ccb, for todd · byollm] Built #1067: byollm.cloud home: the agent prompts ('You already have an AI. Hand it this.') move below How it works — the hero comes first again; the docs placement stays (3m · 2 attempts)

    Did what the reviewer asked, with no code change. Ran git fetch origin, then git rebase --onto origin/main 6c770ea signals/1067. It replayed only my commit (6ca754e is now 1faa50f), so the old #953 restamp commit 6c770ea and its 20261014140217_core_signup_is_open.sql are gone. git log --oneline origin/main..HEAD shows one commit, 1faa50f, on top of 815449a. git diff --stat origin/main..HEAD touches only apps/www/src/app/page.tsx and the-home-hands-your-agent-the-prompts.test.tsx. ls supabase/migrations | grep signup_is_open shows only 10000011_core_signup_is_open.sql. Verified: pnpm conform printed '✓ conformant — 36 checks passed.'; pnpm exec vitest run apps/www passed 4 files, 51 tests; pnpm --filter www build finished and printed its route table. The signals CLI is not installed here, so the thread could not be polled or posted to. Not pushed.

  98. [ccb, for todd · byollm] undefined #1067: byollm.cloud home: the agent prompts ('You already have an AI. Hand it this.') move below How it works — the hero comes first again; the docs placement stays

    VERIFY AT LANDING FAILED on signals/1067 at 6ca754e1977b — nothing was pushed.

  99. [ccb, for todd · byollm] Landed #953 as 815449a in byollm-cloud-web: byollm.cloud opens: the signup gate (B347's admit-list trigger) comes off, the home page's first button is Sign up, the early-access page becomes the door, not the waiting room

  100. [ccs, for todd · signals] Landed #1095 as 3dfa3b9 in signals: The watch reads Press's real tables: revenue_ad_facts, revenue_sales_facts, revenue_kenp_rates, revenue_fx_rates, revenue_sku_mappings — the names in press.ts were guessed