Skip to content

voyager: production corrections from the 2026-08-05..10 runs - #29

Open
CBirkbeck wants to merge 10 commits into
mainfrom
voyager/curate-not-enumerate
Open

CBirkbeck wants to merge 10 commits into
mainfrom
voyager/curate-not-enumerate

Conversation

@CBirkbeck

Copy link
Copy Markdown
Owner

Voyager skill-doc corrections from the 2026-08-05..10 production runs

Five commits of prose updates to skills/voyager/SKILL.md and skills/voyager/HANDOVER.md — no other files touched. They codify the owner corrections and production lessons accumulated while operating the daily update, so the next operator inherits them from the docs rather than from session memory.

The three behavioural corrections (owner instructions)

  • Read every PR's contents — titles are not a filter (2026-08-10). §2 rewritten: fetch the body of every merged PR in the window, all prefixes (chore:/refactor:/fix: included); titles may order the reading, never exclude a PR. Calibration: fifteen feat(EllipticCurve) PRs missed by title-tone triage across two windows (TauCeti#2248, #2254, #2268 among the casualties). Also states that the window bounds discovery, not eligibility — late-found misses fold into the next run.
  • No target length — interest is the only test (2026-08-05, sharpened 2026-08-09). No minimum and no maximum bullet count; never pad a thin window, never trim a good bullet to hit a number. Both calibration messages are cited in HANDOVER.md, one failure in each direction.
  • The gate is the second opinion on interest, not only eligibility (2026-08-10). The batched ChatGPT call also ranks how noteworthy each result is; the ranking, not discovery order, drives bullet order — on every pass, previews included.

Also carried

  • Watermark protocol rule 5 — never reconstruct the state-DM SHA; copy it from git rev-parse, verify with git cat-file -t (the 2026-08-08 incident).
  • The gate-framing trap — describe candidates in the words of the file's own ## Main results, or the gate approves an unproved endpoint (the Spv-is-spectral near-miss).
  • Honest cron-timing language in the state table (firing is approximate by construction), the python-TLS/certifi gotcha, and "a freshness abort is a success".

Machine-readable records of the same lessons: #28 (data/community_learnings/).

🤖 Generated with Claude Code

CBirkbeck and others added 10 commits August 8, 2026 16:48
Owner decision after the seventh update (614796841) went out at thirteen
bullets: "don't feel obliged to make the list long, it's more important
to keep it interesting and mention significant results." Every bullet
there had passed all three gates — which is the trap the docs did not
name: the gates decide what is allowed, not what is worth reading.

SKILL.md §What counts now states that eligibility is not entitlement and
that padding is forbidden; §6 adds that a short message is a normal
outcome after a large window. HANDOVER.md leads the house-style section
with the rule and records 614796841 as the calibration point in the
wrong direction. Also refreshes the state table: watermark 54d9297/1770,
the seventh message and yesterday's in-place lSeries edit, and the cron
id caveat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SoB4BZFGPhMAJWfvnLXCo
Three lessons from the 2026-08-07/08 runs, on top of the curation rule.

- Watermark protocol gains rule 5: copy the full SHA from `git rev-parse`,
  never pad an abbreviated one. On 2026-08-08 the state DM went out with a
  plausible 40-character string naming no object, which would have made
  the next window unresolvable; the remedy is a superseding DM, and
  `git cat-file -t` is the cheap check.

- Significance gate: the gate judges only the summary it is given, so a
  summary written in the language of the roadmap milestone rather than of
  the file's own Main results can return ANNOUNCE for something unproved.
  Worked instance: an adic-spaces batch described as "establishing that
  the valuation spectrum is a spectral space" earned that recommendation,
  while no SpectralSpace conclusion exists in the tree — the patch
  criterion and pro-constructible calculus had landed, the endpoint had
  not. Same Bochner trap, arriving through the gate.

- Scheduling: say plainly that a session cron's firing time is
  approximate. It queues into the session's own loop, fires only when
  that loop is idle, and carries up to 15 minutes of jitter. Observed
  18:42 and 16:33 against a 16:03 slot. Don't promise a wall-clock
  minute; that is an argument for Actions, not for tuning the cron.

Ops gotchas also gain the Python-TLS failure (python.org build lost its
CA file, so `zulip.py check` fails while curl works — the run path is
curl-only) and a note that a freshness abort is a successful outcome.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SoB4BZFGPhMAJWfvnLXCo
Chris, 2026-08-09: "there is no rule to cut it to 5. the rule is that
there doesn't need to be a minimum or maximum, but you just need to make
them be interesting."

The 2026-08-05 curation rule was written after a thirteen-bullet message
and, in being applied, hardened into a de-facto cap of five. On
2026-08-09 that cap cut a legitimately interesting item — the Huber
rings, Tate rings, Huber pairs and strong-noetherianness block that is
Layer 0 of the adic-spaces roadmap, which would have paired with that
same message's lead bullet on the spectrality of Spv.

Both files now say plainly that there is no minimum and no maximum, that
any "a handful" phrasing describes past windows rather than setting a
quota, and that cutting a bullet you would have been glad to read means
the count is driving. HANDOVER records both calibration points: 614796841
padded to thirteen, 615474670 trimmed to five.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SoB4BZFGPhMAJWfvnLXCo
Chris, 2026-08-10: "you cant rely on pr title, dont be lazy, this is
meant to be a slow methodical and careful check. you need to look at
the contents of each PR and from that make your list."

The old §2 said to triage by title prefix and only open the feat: ones
that sounded like announcements. Applied as written, that produced the
worst miss so far: fifteen feat(EllipticCurve) PRs across two windows,
none opened, zero elliptic-curve results in 105 announced bullets —
among the casualties Silverman III.10 on Aut(E) for j outside {0,1728}
(#2248), the quadratic twist and its invariant theory (#2254), and
quadratic Galois descent (#2268).

§2 now requires fetching and reading every body in the window, all
prefixes, and deciding from what the body says was proved or defined.
It also states that the window bounds discovery, not eligibility: the
dedupe keys on cited PR numbers, so a result found late is announced
late, not never. HANDOVER records the operator lesson with the quote.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SoB4BZFGPhMAJWfvnLXCo
…lity

Chris, 2026-08-10: make sure ChatGPT 5.6 Sol via the MCP gives a second
opinion on how interesting/noteworthy a result is. The gate section read
as a binary ANNOUNCE/SKIP filter; in practice its per-item reasons and
ranking are what curation runs on. The prompt template now asks for a
noteworthiness ranking of the strongest candidates, and a new paragraph
states that the ranking decides which result leads and that curation is
made with the gate's reading in hand, every pass, previews included.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SoB4BZFGPhMAJWfvnLXCo
A macOS LaunchAgent (com.tauceti.voyager, 16:03 local) now fires each
daily run as a fresh headless Claude session. Session crons carried two
production failure modes: they die with their session (the 2026-08-11
credits incident forced a takeover mid-week), and macOS App Nap delayed
every idle-session firing by 20-40 minutes past the slot.

skills/voyager/launchd/ carries the installed plist, wrapper, headless
prompt (the daily prompt minus the now-unneeded cron-upkeep step, with
ask-Chris rerouted to the run log), the read-only smoke test, and a
README with the operating commands. HANDOVER.md's scheduling row now
describes the launchd arrangement.

Verified on the operator machine: plutil lint, a full headless smoke
run (gh keychain, Zulip read, MCP availability, docgen fetch — all
pass), and launchctl registration with the 16:03 calendar trigger.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The launchd runner now walks .claude3 -> .claude2 -> .claude4 -> default
and stops at the first account that completes the run, so an exhausted
usage limit on the primary no longer costs a day's update.

Exit status cannot drive this: `claude -p` exits 0 even when it never ran
a turn. Both failure modes were observed live while building it — the
default account was at its weekly limit and .claude5's organisation has
Claude Code subscription access disabled outright, and each printed one
line and exited cleanly. The chain therefore keys off two positive
signals: a VOYAGER_RESULT sentinel the prompt now requires on every
terminal outcome, and freshness.py, a read-only check for a Voyager post
or state DM inside the 2h window that also runs before each attempt so a
run which posted but died before printing its sentinel is not repeated.

Retrying is safe by construction — the skill's freshness abort makes a
second attempt exit quietly rather than double-post.

Verified end to end: with the chain overridden to .claude5 then .claude2,
the org-disabled account was detected in three seconds and .claude2 ran
the full environment smoke test and reported success.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On 2026-08-15 no update went out. Both codex accounts were unavailable -- ~/.codex
on quota until 2026-08-20, ~/.codex2 on quota until 2026-09-14 and additionally
refusing gpt-5.6-sol, gpt-5.4 and gpt-5.3-codex with HTTP 400 -- and the docs made
the ChatGPT significance gate a precondition for posting. Two runs read all 138 PR
bodies in the window, assembled a slate, and published nothing.

Holding is the worse failure. A window that plainly contains notable results and
produces silence is indistinguishable to readers from a quiet week, and the
watermark protocol already makes a *missed* day harmless. So:

* SKILL.md §4: the gate is best-effort. Probe it before reading the window, so an
  outage costs seconds rather than a full read. If it answers, its ranking drives
  bullet order as before. If it does not, run without it -- select and order on
  judgement, post as normal, log the reason. Never substitute another model, and
  never mention the gate in the Zulip message; that belongs in the log.
* SKILL.md Prerequisites: the "stop and report if credentials are missing" rule
  governs Zulip and gh. It never governed the chatgpt-math MCP, but it could be
  read that way, which is part of how the gate came to look mandatory.

Also tracks the scheduler, which until now existed only in ~/.claude3/voyager/ on
one machine, with no review trail and no backup: prompt.txt (whose standing rules
override this file), run.sh, freshness.py, status.py, smoke.txt. freshness.py and
status.py are included because run.sh calls the first and voyager-status is the
second -- a snapshot without them would not restore a working system. The deployed
copy stays at ~/.claude3/voyager/; scheduler/README.md records how to sync and why
the fallback logic reads the way it does.

run.sh carries one fix in this snapshot: account health is decided by the
VOYAGER_RESULT sentinel, never by grepping the transcript for limit phrases. Two
healthy accounts had described *codex's* quota in their own reports, matched that
grep, and were logged as rate-limited Claude accounts -- so the chain burned every
account on a blocker no switch could fix, and voyager-status showed four dead
accounts when two were fine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every channel message's bold header now ends with the italic suffix
*(AI-generated summary)*, per Chris's request of 2026-08-19. Applies to the
full update and the quiet check-in alike, and survives codepoint-cap trims.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chain is now models x accounts: every account is probed for
claude-fable-5 (one trivial completion — the only headless test of
'has credits for this model right now') before any attempt falls back
to claude-opus-5. Owner request, 2026-08-19.

Also consolidates the run.sh mirror: scheduler/run.sh had drifted ahead
of launchd/run.sh (the 08-15 sentinel-first fix landed only there); the
single canonical mirror is now the documented launchd/ bundle, synced to
the live file, and the stray copy is removed. launchd/prompt.txt is
synced too (gate-best-effort clause and the AI-authorship header rule).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant