docs: register Darkwing and Dewey row 121 sessions and the Sage landing; window plan at 3e; P19 task 311

SESSIONS: Darkwing 18:54:54Z and its 18:56:04Z correction, Dewey
19:00:29Z, Sage's landing line. The schema window plan records row 121
landed 2c16d6b93, a rehearsal of the migration on a copy of the backup
(row 121 gate condition 4), and a role_claims check for an open assistant
claim. P19 task 311 holds row 121's follow-ups (sage-0369).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
jason.woltjeandClaude Opus 5.5 committed 2026-10-15 14:07:47 -05:00
1 parent 496e26e0e5
commit f365a1da9d
4 files changed
+104 -1

No files matched your search

@@ -0,0 +1,17 @@
{
"at": "2026-10-15T19:02:03.291Z",
"project": 19,
"created": [
{
"title": "row 121 follow-ups: dead projects setup, threadIdle log dedupe, thread_claims assert, READMEs",
"id": 311,
"index": 152,
"inverse": "mark done: POST /api/v1/tasks/311 done true (pm); delete is Jason's or ops-01's",
"readBack": 200,
"project_back": 19,
"due_back": "0001-01-01T00:00:00Z",
"done": false
}
],
"problems": []
}
@@ -0,0 +1,68 @@
// Sage, 2026-10-15: decision 110. Files one follow-up as a task in project 19 with Sage's own key (bot
// user 13): Dewey's non-blocking notes on row 121 round 2 (#1615, comment 28615) and F6, ruled follow-ups
// in sage-0369. Refuses if the title already exists. The sync key reads it back.
// No labels, no assignees, no bucket moves. Rollback is marking the task done; deletion is Jason's or
// ops-01's. Prints no secret.
// Usage: node file-r121-followups.mjs https://tasks.woltje.com SAGE_TOKEN_FILE SYNC_TOKEN_FILE OUT_JSON
import { readFileSync, writeFileSync, existsSync } from "node:fs";
const [ORIGIN, KEY, SYNC, OUT] = process.argv.slice(2);
if (!/^https:\/\/tasks\.woltje\.com$/.test(ORIGIN)) throw new Error("tasks.woltje.com only");
if (!OUT || existsSync(OUT)) throw new Error("OUT_JSON missing or exists; refusing");
const PROJECT = 19;
const SIG = "Created by Sage (T3 1ef1e4f8) with Sage's own key (bot user 13).";
const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
const p = (...xs) => xs.map((x) => `<p>${esc(x)}</p>`).join("") + `<p>${esc(SIG)}</p>`;
const TASKS = [
{ title: "row 121 follow-ups: dead projects setup, threadIdle log dedupe, thread_claims assert, READMEs",
description: p("Dewey approved row 121 round 2 (#1615) in comment 28615 with three non-blocking notes, and F6 from round 1 (28591) was ruled doc-only. Sage ruled all four follow-ups in sage-0369. Darkwing agreed in their position message of 2026-10-15.",
"N1: the decision-route test setup passes a projects key that project.create never reads without repo (broker.mjs checks projects only when repo is given). Remove the dead key. The row 121 BUILD.md sentence saying the key is needed is wrong; the packet stays as reviewed.",
"N2: the thread launcher logs a threadIdle refusal on every tick. Add a dedupe like the existing refusedThreads one. Touches launcher.mjs and its test only.",
"N3: the bus chief-of-staff test's thread_claims assert dropped decision and reason. Add them back to the SELECT and the expected row. Test only.",
"F6: the seat and bus README edits Dewey raised in round 1. Doc-only, no test reads the changed lines (decision 137).",
"Not in row 121. Needs a queue row and brief before anyone builds it. Darkwing is the natural owner.") },
];
const key = readFileSync(KEY, "utf8").trim(), sync = readFileSync(SYNC, "utf8").trim();
async function api(method, path, body, auth) {
const r = await fetch(ORIGIN + path, { method, headers: { Authorization: `Bearer ${auth}`, "Content-Type": "application/json" }, body: body === undefined ? undefined : JSON.stringify(body), redirect: "error" });
const t = await r.text(); let json = null; try { json = JSON.parse(t); } catch {}
return { status: r.status, json };
}
const list = (j) => j?.items ?? (Array.isArray(j) ? j : []);
async function existing() {
const out = [];
for (let page = 1; page < 20; page++) {
const r = await api("GET", `/api/v2/projects/${PROJECT}/tasks?per_page=50&page=${page}`, undefined, sync);
if (r.status !== 200) throw new Error(`list tasks: ${r.status}`);
out.push(...list(r.json));
if (list(r.json).length < 50) return out;
}
throw new Error("more than 19 pages");
}
const rec = { at: new Date().toISOString(), project: PROJECT, created: [], problems: [] };
const save = () => {
const out = JSON.stringify(rec, null, 1) + "\n";
if (out.includes(key) || out.includes(sync)) throw new Error("secret in the record; not written");
writeFileSync(OUT, out);
};
const before = await existing();
const clash = before.filter((t) => TASKS.some((x) => x.title === t.title));
if (clash.length) throw new Error(`exists: ${clash.map((t) => `#${t.id} ${t.title}`).join("; ")}; refusing`);
writeFileSync(OUT, "", { flag: "wx" });
for (const t of TASKS) {
rec.created.push({ title: t.title });
save();
const body = { title: t.title, description: t.description, ...(t.due ? { due_date: t.due } : {}) };
const r = await api("PUT", `/api/v1/projects/${PROJECT}/tasks`, body, key);
if (r.status >= 300 || !Number.isSafeInteger(r.json?.id)) {
rec.problems.push(`create ${t.title}: ${r.status} ${r.json?.code ?? ""} ${r.json?.message ?? ""}`);
break;
}
Object.assign(rec.created.at(-1), { id: r.json.id, index: r.json.index, inverse: `mark done: POST /api/v1/tasks/${r.json.id} done true (pm); delete is Jason's or ops-01's` });
const back = await api("GET", `/api/v2/tasks/${r.json.id}`, undefined, sync);
Object.assign(rec.created.at(-1), { readBack: back.status, project_back: back.json?.project_id, due_back: back.json?.due_date, done: back.json?.done });
if (back.status !== 200 || back.json?.title !== t.title || back.json?.project_id !== PROJECT || back.json?.done) rec.problems.push(`${t.title} read-back differs`);
}
save();
process.stdout.write(JSON.stringify(rec, null, 1) + "\n");
if (rec.problems.length) process.exit(2);
@@ -11,7 +11,7 @@ the migration from agents/rocko/work/queue-49/r1/MIGRATION.md inserted.
| 49 | #1535 | 3b → 3c, comment cursors and the migrator | landed 3a4afdc03 (Filbert 28579, Darkwing 28587) |
| 123 | #1617 | 3c → 3d, revoke with a reason | landed 89fd2d6fe (Filbert 28578) |
| 132 | #1628 | none, harness tools for the chief | landed 0e947c216 (Filbert 28604, round 2 rebase 28606) |
| 121 | #1615 | 3d → 3e | r1 changes (Dewey 28591); round 2 in progress on 20d2b5788, after 49, 123, 133 and 132 |
| 121 | #1615 | 3d → 3e | landed 2c16d6b93 (Dewey 28591 changes, round 2 approve 28615) |
Update 2026-10-15T18:28Z: row 133 (#1627, no schema step) landed a622f426c
and row 70 landed 73fa83a08. Both are pushed through 20d2b5788. Row 134
@@ -19,6 +19,20 @@ and row 70 landed 73fa83a08. Both are pushed through 20d2b5788. Row 134
is queued and isn't a window prerequisite. Without it, organization.set
fails closed with revision-conflict.
Update 2026-10-15T19:10Z: row 121 landed 2c16d6b93 after Sage's full gate
on d7ebaa9a5 (24 suites, 0 failed). All four schema rows are in, so the
window can go to 3e. Two points from the row 121 packet for the window:
- Row 121's gate condition 4 says the migration runs on a copy of a
schema-current database. Darkwing's packet tests 3d → 3e on a copy of a
3d database, which isn't the live store. So step 3 runs twice: first on
a copy of the step 2 backup, then, only if that passes, on the live
store. The copy run also times the migration.
- Before the migration, Mos checks the live bus's `role_claims` for an
open assistant claim (row 121 BUILD.md, F2). A pre-3e assistant claim
would still be revocable as a role claim after 3e and touch no thread.
If one is open, Mos records it and we decide together before going on.
One window, after all four land. `migrate-schema.mjs` chains the steps in
order, each committed version a resume boundary, so one call takes the live
store from 3b to 3e. Three windows would mean three bus stops for no gain.
+4
View File
@@ -1013,3 +1013,7 @@ are never rewritten or removed; corrections are new entries.
2026-10-15T18:00:14Z | Dewey (Opus 5.5, 84fb346c) | row 133 (#1627) round 2 on 89fd2d6fe per sage-0350 | in review, request comment 28597 to Filbert, revs 1323-1325: packet agents/dewey/work/queue-133/r2 (346347c95, local), candidate 1c0e6f8f, delta.patch empty (r1's patch on the new base matches r2), mutants 5/5 killed with controls passing and targeted gate rc 0 in the sage-0353 slot, released 17:57:43Z
2026-10-15T18:05:08Z | Researcher (Sonnet 5.5, 9bac0794) | row 132 #1628 round 1 build | end_run (role.revoke, reason 1-500, no decision) and change_organization (organization.set) typed tools for roles holding role.end / organization.change; chief bundle manifest lists both in typed and untyped is [] for pi and claude-code (bundle.test.mjs:85); stop-line text varies by end_run; broker.mjs:99 export is the only bus change; revision-read gap left to row 134; 28 of 28 mutants killed, full gate green (business 92, bus 191, plugins 21, tasks 97, cli 195, webui 112, harness 90, seat 132, land-work 84) | in-review move and Filbert request are Sage's (no credential); packet agents/researcher/work/queue-132 (8a73f713c, local, nothing pushed)
2026-10-15T18:26:44Z | Sage (Opus 5.5, 1ef1e4f8) | land rows 133, 70 and 132; row 132 round 2 rebase; row 134 filed | 133 a622f426c (Dewey, Filbert 28600) and 70 73fa83a08 (Filbert 28602) on one gate, 24 suites 0 failed on 4a34fb0d6; 132 rebased unchanged on 73fa83a08 after 133 changed broker.mjs (agents/sage/work/queue-132/r2, 17a66cdb0), gate 24 suites 0 failed, Filbert 28604 and 28606, landed 0e947c216; queue revs 1318-1348 in ab3a57a3c; row 134 P19 task 308; Darkwing's land-work overlapped my 132 gate about 10s, both passed, rerun alone 84/0
2026-10-15T18:54:54Z | darkwing | row 121 (#1615) round 2: rebased on 20d2b5788, targeted gate green, 77 of 77 mutants killed, packet 58e85d0fa + 9d7416196, manifest sha256 710d5086 | in-review move waits on Sage setting reviewers to filbert (queue set refused non-privileged)
2026-10-15T18:56:04Z | darkwing | row 121 (#1615) round 2 correction to my 18:54:54Z line | reviewer stays Dewey (sage-0367); moved to in-review, revs 1349-1350, request comment 28614 posted as darkwing; BUILD.md reviewer name fixed in dd7c22295 and d7ebaa9a5
2026-10-15T19:00:29Z | Dewey (Opus 5.5, 84fb346c) | row 121 (#1615) round 2 review, candidate 710d5086 | approve, comment 28615, rev 1351; single files only (7 files, 0 fail); non-blocking: BUILD.md projects claim, idle-refusal log dedupe, chief-of-staff assert nit; F6 READMEs non-blocking
2026-10-15T19:07:41Z | Sage (Opus 5.5, 1ef1e4f8) | row 121 (#1615) round 2 landing | landed 2c16d6b93 after the full gate on d7ebaa9a5 (24 suites, 0 failed), done rev 1352, sweep 496e26e0e (revs 1349-1352); F6 and Dewey's notes N1-N3 ruled follow-ups (sage-0369), P19 task 311; window plan updated for 3e