sage: row 187 landing, P19 407-410 filed and P19 385 comment 357, #1685 closed (comment 29425), SESSIONS line
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
// Sage, 2026-10-20: row 187 (#1685, Part B step A0) landing. Files Filbert's four row 187 follow-ups as P19
|
||||
// tasks, one each, owner Sage, no due date (the mos-0955 form), then comments on P19 385 with the landing and the
|
||||
// task numbers (mos-0882: every landing gets a Vikunja comment). Sage's own key (bot user 13); the sync key reads
|
||||
// back. No labels, no assignees, no due date, no bucket moves. Refuses if a title exists. Rollback is marking a
|
||||
// new task done; deletion is Jason's or ops-01's. Prints no secret.
|
||||
// Usage: node file-r187-landed.mjs https://tasks.woltje.com SAGE_TOKEN_FILE SYNC_TOKEN_FILE OUT_JSON LANDING_SHA
|
||||
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
||||
const [ORIGIN, KEY, SYNC, OUT, LANDING] = 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");
|
||||
if (!/^[0-9a-f]{9}$/.test(LANDING ?? "")) throw new Error("LANDING_SHA: 9 hex characters");
|
||||
const PROJECT = 19;
|
||||
const SIG = "Created by Sage (T3 1ef1e4f8) with Sage's own key (bot user 13).";
|
||||
const PSIG = "Posted by Sage (T3 1ef1e4f8) with Sage's own key (bot user 13).";
|
||||
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
const ps = (sig, xs) => xs.map((x) => `<p>${esc(x)}</p>`).join("") + `<p>${esc(sig)}</p>`;
|
||||
const SRC = `Filbert's row 187 r1 approve (Gitea #1685), landing ${LANDING}.`;
|
||||
const TAIL = "Owner Sage. No queue row until scheduled (the mos-0955 form). Not live-affecting.";
|
||||
const TASKS = [
|
||||
{
|
||||
title: "stack-release.sh: the proof_for_target comment says a new proof pair goes last (row 187)",
|
||||
description: ps(SIG, [
|
||||
`${SRC} The comment above proof_for_target in scripts/stack-release.sh says a new pair "replaces the pointer's and goes last". The code puts it after the preview flags and before --send and --tester-port, the order webui-service.sh render writes and flags_drift compares (row 187 BUILD.md deviation 2). Found by Sage, non-blocking per Filbert.`,
|
||||
"The fix is one comment line.",
|
||||
TAIL,
|
||||
]),
|
||||
},
|
||||
{
|
||||
title: "docs/TOOLS.md: the row 178 paragraph says stack-release.sh carries the proof pair unchanged (row 187)",
|
||||
description: ps(SIG, [
|
||||
`${SRC} docs/TOOLS.md:904, in the row 178 paragraph, still says stack-release.sh "preserves both flags unchanged on re-pin and rollback". Since row 187, activate sets or drops the pair, and a rollback to a copy without proof support drops it. The row 187 paragraph under "Pinned stack update" is right. Doc-only; no test reads TOOLS.md.`,
|
||||
"Can share a row with the comment fix.",
|
||||
TAIL,
|
||||
]),
|
||||
},
|
||||
{
|
||||
title: "stack-release test gap: no test kills a carried proof pair skipping proof_checks (row 187 M8)",
|
||||
description: ps(SIG, [
|
||||
`${SRC} Filbert's mutant M8 makes a carried pair (the pointer's pair, no pair flags given) skip proof_checks. It survived T53 12/12. BUILD.md says the checks run on a carried pair, so a file moved or chmod-ed since the pair went in refuses before the stop, but no T53 case changes the file between the activate that set the pair and the run that carries it.`,
|
||||
"The fix is a T53 case that sets a pair, chmods the file to 644 or moves it, then plans and runs an activate or rollback that carries it and expects proof-file-invalid with no stop.",
|
||||
TAIL,
|
||||
]),
|
||||
},
|
||||
{
|
||||
title: "stack-release test gap: no test kills dropping the repository case from the proof file check (row 187 M9)",
|
||||
description: ps(SIG, [
|
||||
`${SRC} Filbert's mutant M9 drops the repository case from the realpath check in proof_file_problem. It survived T53 12/12. T53 refuses a proof file inside the copies but has no case for one inside the repository, which webui-service.sh render refuses after the stop.`,
|
||||
"The fix is a T53 case with a mode-600 proof file under the test's repository root that expects proof-file-invalid with no stop.",
|
||||
TAIL,
|
||||
]),
|
||||
},
|
||||
];
|
||||
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, landing: LANDING, created: [], comment385: null, 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();
|
||||
for (const T of TASKS) {
|
||||
const clash = before.filter((t) => t.title === T.title);
|
||||
if (clash.length) throw new Error(`exists: #${clash[0].id}; refusing`);
|
||||
}
|
||||
const t385 = await api("GET", `/api/v2/tasks/385`, undefined, sync);
|
||||
if (t385.status !== 200 || t385.json?.project_id !== PROJECT || !/X-authentik-username from 127\.0\.0\.1/.test(t385.json?.title ?? "")) throw new Error(`task 385: ${t385.status}, not the P19 385 task`);
|
||||
writeFileSync(OUT, "", { flag: "wx" });
|
||||
for (const T of TASKS) {
|
||||
const r = await api("PUT", `/api/v1/projects/${PROJECT}/tasks`, { title: T.title, description: T.description }, key);
|
||||
const c = { title: T.title, status: r.status, id: r.json?.id ?? null, index: r.json?.index ?? null };
|
||||
rec.created.push(c);
|
||||
if (r.status >= 300 || !Number.isSafeInteger(r.json?.id)) { rec.problems.push(`create: ${r.status} ${r.json?.message ?? ""}`); save(); continue; }
|
||||
c.inverse = `mark done: POST /api/v1/tasks/${r.json.id} done true (sage key); delete is Jason's or ops-01's`;
|
||||
const back = await api("GET", `/api/v2/tasks/${r.json.id}`, undefined, sync);
|
||||
Object.assign(c, { readBack: back.status, done: back.json?.done, due: back.json?.due_date ?? null });
|
||||
if (back.status !== 200 || back.json?.title !== T.title || back.json?.project_id !== PROJECT || back.json?.done) rec.problems.push(`create ${r.json.id} read-back differs`);
|
||||
save();
|
||||
}
|
||||
const ids = rec.created.map((c) => c.id).filter(Number.isSafeInteger);
|
||||
if (ids.length === TASKS.length) {
|
||||
const body = ps(PSIG, [
|
||||
`Part B step A0 has landed: row 187 (Gitea #1685) is ${LANDING} on refactor. Filbert approved round 1, and Sage's gate passed (the cli suite and every scripts/test-*.sh). activate now takes --proof-header NAME --proof-file PATH, which writes the pair into the pointer and the Console unit, and --no-proof, which drops it. An activate may name the pointer's copy only to set a pair or to drop one with --no-proof. That makes B3 and the corrected B-R1 (activate <live copy> mosaic-stack --pm --no-proof) possible. The script checks the proof file with stat and realpath, never opens it, and refuses a bad header or file before anything stops.`,
|
||||
"The tool is on refactor only. The live pointer is still 490e2771d3d0. Nothing turned the proof on. That stays Part B, which waits for Jason (J1-J6), and then a re-pin window that Mos checks at A2.",
|
||||
`Filbert's four non-blocking follow-ups are P19 tasks, owner Sage, no due date: #${ids[0]} (stale proof_for_target comment), #${ids[1]} (stale TOOLS.md row 178 paragraph), #${ids[2]} (M8, no test for a carried pair skipping the checks) and #${ids[3]} (M9, no test for a proof file inside the repository).`,
|
||||
]);
|
||||
const c = await api("PUT", `/api/v1/tasks/385/comments`, { comment: body }, key);
|
||||
rec.comment385 = { status: c.status, id: c.json?.id ?? null };
|
||||
if (c.status >= 300 || !Number.isSafeInteger(c.json?.id)) rec.problems.push(`comment 385: ${c.status} ${c.json?.message ?? ""}`);
|
||||
else {
|
||||
const back = await api("GET", `/api/v2/tasks/385/comments?per_page=50`, undefined, sync);
|
||||
const found = list(back.json).find((x) => x.id === c.json.id);
|
||||
Object.assign(rec.comment385, { readBack: back.status, found: Boolean(found) });
|
||||
if (back.status !== 200 || !found) rec.problems.push(`comment 385 read-back: ${back.status}`);
|
||||
}
|
||||
}
|
||||
save();
|
||||
process.stdout.write(JSON.stringify(rec, null, 1) + "\n");
|
||||
if (rec.problems.length) process.exit(2);
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"at": "2026-10-20T10:22:54.778Z",
|
||||
"project": 19,
|
||||
"landing": "9a71e4e80",
|
||||
"created": [
|
||||
{
|
||||
"title": "stack-release.sh: the proof_for_target comment says a new proof pair goes last (row 187)",
|
||||
"status": 201,
|
||||
"id": 407,
|
||||
"index": 240,
|
||||
"inverse": "mark done: POST /api/v1/tasks/407 done true (sage key); delete is Jason's or ops-01's",
|
||||
"readBack": 200,
|
||||
"done": false,
|
||||
"due": "0001-01-01T00:00:00Z"
|
||||
},
|
||||
{
|
||||
"title": "docs/TOOLS.md: the row 178 paragraph says stack-release.sh carries the proof pair unchanged (row 187)",
|
||||
"status": 201,
|
||||
"id": 408,
|
||||
"index": 241,
|
||||
"inverse": "mark done: POST /api/v1/tasks/408 done true (sage key); delete is Jason's or ops-01's",
|
||||
"readBack": 200,
|
||||
"done": false,
|
||||
"due": "0001-01-01T00:00:00Z"
|
||||
},
|
||||
{
|
||||
"title": "stack-release test gap: no test kills a carried proof pair skipping proof_checks (row 187 M8)",
|
||||
"status": 201,
|
||||
"id": 409,
|
||||
"index": 242,
|
||||
"inverse": "mark done: POST /api/v1/tasks/409 done true (sage key); delete is Jason's or ops-01's",
|
||||
"readBack": 200,
|
||||
"done": false,
|
||||
"due": "0001-01-01T00:00:00Z"
|
||||
},
|
||||
{
|
||||
"title": "stack-release test gap: no test kills dropping the repository case from the proof file check (row 187 M9)",
|
||||
"status": 201,
|
||||
"id": 410,
|
||||
"index": 243,
|
||||
"inverse": "mark done: POST /api/v1/tasks/410 done true (sage key); delete is Jason's or ops-01's",
|
||||
"readBack": 200,
|
||||
"done": false,
|
||||
"due": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
],
|
||||
"comment385": {
|
||||
"status": 201,
|
||||
"id": 357,
|
||||
"readBack": 200,
|
||||
"found": true
|
||||
},
|
||||
"problems": []
|
||||
}
|
||||
@@ -1341,3 +1341,4 @@ are never rewritten or removed; corrections are new entries.
|
||||
2026-10-20T09:13:21Z | Darkwing (Opus 5.5, 7525c8e4) | row 186 (#1684, P19 404): the activate plan's backup line says what the run will do, Filbert's N1/N2 on row 185 | landed: 269134d8d (Sage, pushed with 16a936c79, gate node 2681/0 scripts 422/0); candidate 449e91219333 matches the landing; stack-release 132/132, base control red, brief mutants m1-m3 killed; Filbert approve 29419; follow-ups on P19 404 comment 354 (M6 no-store order test, unclean-store form)
|
||||
2026-10-20T09:13:15Z | Sage (Opus 5.5, 1ef1e4f8) | row 186 landing gate and landing (#1684, P19 404) | landed 269134d8d (author Darkwing), patch-id c97b9f6e25cd = r1 candidate 449e9121; gate b367f5730+patch 09:00:20Z-09:08:59Z node 2681/0, scripts 422/0, network removed; queue 2198-2200 in 16a936c79, pushed with Filbert's 3c5da3a91; #1684 closed (29421); P19 404 comment 354 with two follow-ups (M6 gap, store-unclean reading); row 187 handed to Darkwing (sage-1263)
|
||||
2026-10-20T10:13:43Z | Filbert (Opus 5.5, 048f3c63) | row 187 r1 review (#1685, manifest 52a5ecc1d143) | approve, comment 29424, rev 2204; stack-release 144/144 on my slot run; M8 and M9 survived (N1, N2 test gaps); N3 :689 comment and N4 TOOLS.md:904 follow-ups per sage-1272
|
||||
2026-10-20T10:24:26Z | Sage (Opus 5.5, 1ef1e4f8) | row 187 landing gate and landing (#1685, Part B A0) | landed 9a71e4e80 (author Darkwing), patch-id 6b57c47bc661 = r1 candidate 52a5ecc1d143; gate passed 10:21:55Z (cli 446/446, every package and scripts/test-*.sh); queue 652d6f3a8 revs 2201-2206; #1685 comment 29425, closed; P19 407-410 filed, P19 385 comment 357
|
||||
|
||||
Reference in New Issue
Block a user