feat(board): session attention, Discord rows, task attribution and relaunch activity (rows 18, 22, #1511, #1512)

One cumulative control-board, webui and seat state. The four rows edit the
same files (scan.mjs, page.html, README.md, app.js), so they land together,
each on its own receipt:

- Row 18, Discord connector rows on the board (#1509): R3 approved by
  Darkwing and Dewey, Gitea comment 26257, manifest 254403b8. Jason
  accepted the visual test.
- Row 22, board attention status (#1503): Filbert approved R1, comment
  26248, manifest e40b58ec; restart receipt 26249.
- #1511, task attribution (row 6 code phase): R2 approved by Filbert and
  Dewey, manifest d4c96395. docs/TOOLS.md carries the approved --by usage
  line (tools-usage.patch 86bcba3c).
- #1512, relaunch activity (row 6 pilot): R1 approved by Darkwing and
  Dewey, candidate manifest 47769fad. All seven source files match it.

Row 16, internal development bootstrap (#1510): the seven files outside
shared records match Filbert's R1 pins, receipt 26204 (agents/researcher/*,
scripts/test-darkwing-launch.mjs, the bootstrap plan).

packages/webui/src/public/app.js is committed at its #1512 R1 pin ce7d79a4.
The working copy holds Dewey's unreviewed return-flow candidate on top of
that, and it stays uncommitted.

Also: the four row briefs and Darkwing's evidence records under
agents/darkwing/work, including the 2026-09-26 tree manifest and the #1512
re-run against 21e3e908. Serial acceptance command: 397/397, three runs.
The failures that only show when tests run concurrently are in #1509 engine
tests, and they reproduce on clean HEAD.

Suites on the exact staged tree: config 24, task 90, foundation 43,
conductor 17, release 14, auth 15, discord 63; package union 397/397
(serial); test-darkwing-launch 5/5.

Shared records (BUILD-LOG, QUEUE, CURRENT, DEFERRED, SESSIONS, AGENTS.md,
agents/README.md) follow in Sage's records commit.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-09-26 14:54:18 -05:00
co-authored by Claude Opus 5.5
parent 21e3e908b6
commit af4203ca92
67 changed files with 2417 additions and 78 deletions
+28 -1
View File
@@ -29,12 +29,16 @@ test('browser edge states: loading, empty, malformed, stale, hostile/long values
assert.equal(await b.evaluate('document.querySelector("#waiting-count").textContent'), '0');
assert.equal(await b.evaluate('document.documentElement.dataset.palette'), 'harbor');
const agent = 'agent"[\\<script>', project = '__proto__';
const rec = { agent, project, state: 'waiting', waitingOnYou: true, task: 'Long '.repeat(300), workspace: '/' + 'path/'.repeat(100), taskSource: 'registration', lastActivity: '2026-09-01', lastAssistantText: '<img src=x onerror=alert(1)>', registered: { alive: true, tmux: { session: agent } } };
const rec = { agent, project, state: 'waiting', waitingOnYou: true, task: 'Long '.repeat(300), workspace: '/' + 'path/'.repeat(100), taskSource: 'registration', taskSetBy: '<img src=x onerror=alert(2)>', lastActivity: '2026-09-01', lastAssistantText: '<img src=x onerror=alert(1)>', registered: { alive: true, tmux: { session: agent } } };
index = { sessions: [rec], counts: { waiting: 1 } };
await b.evaluate('document.querySelector("#refresh").click()'); await wait('document.querySelectorAll("table.sessions [data-open]").length===1');
await b.evaluate('document.querySelector("table.sessions [data-open]").click()');
assert.equal(await b.evaluate('document.querySelector("#inspector-title").textContent'), agent);
assert.equal(await b.evaluate('document.querySelectorAll("#inspection img").length'), 0);
// #1511: a hostile setter value is text, in the table and the inspector.
assert.equal(await b.evaluate('document.querySelectorAll("img").length'), 0);
assert.match(await b.evaluate('document.querySelector("#inspection").textContent'), /Task set by\s*<img src=x onerror=alert\(2\)> \(as claimed/);
assert.match(await b.evaluate('document.querySelector("table.sessions td.task").textContent'), /set by <img src=x onerror=alert\(2\)>/);
assert.equal(await b.evaluate('document.documentElement.scrollWidth<=innerWidth'), true);
await b.evaluate('document.querySelector("#reply").focus()'); await b.call('Input.insertText', { text: 'original draft' });
await b.evaluate('document.querySelector(".reply-form").requestSubmit();document.querySelector(".reply-form").requestSubmit()');
@@ -50,6 +54,29 @@ test('browser edge states: loading, empty, malformed, stale, hostile/long values
await b.evaluate('document.querySelector("#refresh").click()'); await wait('!document.querySelector("#refresh").disabled');
assert.equal(await b.evaluate('!!document.querySelector("#reply")'), false);
assert.match(await b.evaluate('document.querySelector("#inspection").textContent'), /reply needs a registered seat/);
// #1511: attribution never enables a reply: a setter with no registration at all still gets no form.
const savedRegistration = index.sessions[0].registered;
index.sessions[0].registered = null; index.sessions[0].taskSetBy = 'someone';
await b.evaluate('document.querySelector("#refresh").click()'); await wait('!document.querySelector("#refresh").disabled');
assert.equal(await b.evaluate('!!document.querySelector("#reply")'), false);
assert.match(await b.evaluate('document.querySelector("#inspection").textContent'), /Task set by\s*someone/);
// R1-U1: null means not applicable (task not selected from a registration); it is never shown as "unknown",
// and a previous setter never lingers after the transition.
index.sessions[0].registered = savedRegistration; index.sessions[0].taskSetBy = null;
await b.evaluate('document.querySelector("#refresh").click()'); await wait('!document.querySelector("#refresh").disabled');
assert.match(await b.evaluate('document.querySelector("#inspection").textContent'), /Task set by\s*not applicable \(task is not from a registration\)/);
assert.equal(await b.evaluate('document.querySelector("#inspection").textContent.includes("someone")'), false);
assert.doesNotMatch(await b.evaluate('document.querySelector("#inspection").textContent'), /Task set by\s*unknown/);
assert.equal(await b.evaluate('document.querySelector("table.sessions td.task").textContent.includes("set by")'), false);
// A selected legacy registration (record predates taskSetBy) reads "unknown", distinct from not applicable.
index.sessions[0].taskSource = 'registration'; index.sessions[0].taskSetBy = 'unknown';
await b.evaluate('document.querySelector("#refresh").click()'); await wait('!document.querySelector("#refresh").disabled');
assert.match(await b.evaluate('document.querySelector("#inspection").textContent'), /Task set by\s*unknown \(as claimed by the caller, not verified\)/);
assert.equal(await b.evaluate('document.querySelector("#inspection").textContent.includes("not applicable")'), false);
assert.match(await b.evaluate('document.querySelector("table.sessions td.task").textContent'), /set by unknown/);
index.sessions[0].taskSource = 'first-user-message'; index.sessions[0].taskSetBy = null;
await b.evaluate('document.querySelector("#refresh").click()'); await wait('!document.querySelector("#refresh").disabled');
assert.equal(await b.evaluate('document.querySelector("#inspection").textContent.includes("set by unknown")'), false);
index.sessions[0].registered.alive = true;
await b.evaluate('document.querySelector("#refresh").click()'); await wait('!!document.querySelector("#reply")');
assert.match(await b.evaluate('document.querySelector("#reply").value'), /newer/);