Files
jason.woltjeandClaude Sonnet 5.5 486c4aad34 research: row 102 build packet, row 88 follow-up N1-N4 (#1596)
Header sentence, line 13 wrap, bidi escapes in three files, inertCheck U+200E/U+200F. Patch and evidence only; the change is not applied to the tree.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-13 16:12:24 -05:00

83 lines
5.6 KiB
Diff
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
diff --git a/packages/conversation/tests/flows.test.mjs b/packages/conversation/tests/flows.test.mjs
index acd84aa35..e1bbce8fa 100644
--- a/packages/conversation/tests/flows.test.mjs
+++ b/packages/conversation/tests/flows.test.mjs
@@ -492,7 +492,7 @@ test("terminal: engine control characters are made visible; a lost connection re
const h = await started();
try {
const term = new Terminal({ client: h.client });
- h.engine.script([{ text: "\x1b]52;c;ZXZpbA==\x07 bell‮", stop: "stop" }]);
+ h.engine.script([{ text: "\x1b]52;c;ZXZpbA==\x07 bell\u202e", stop: "stop" }]);
await term.key("go\r");
await receiptState(h.client, term.lastReceipt.id, "finished");
await until(() => term.transcript.lines().some((l) => l.includes("bell")), 2000, "the reply");
diff --git a/packages/tasks/src/fields.mjs b/packages/tasks/src/fields.mjs
index 1c1d61fbc..e790430f0 100644
--- a/packages/tasks/src/fields.mjs
+++ b/packages/tasks/src/fields.mjs
@@ -2,7 +2,10 @@ import { readFileSync } from 'node:fs';
import { TASK_VERBS } from '../../bus/src/broker.mjs';
// Row 61 (#1550): the slice 1 field table as data, in ../fields.json. The Field table in
// docs/plans/2026-10-04_slice-1.md is the reviewed prose it must match, and tests/fields.test.mjs
-// checks that prose and this table against what the verbs do. Two layers, as lead decision 113 rules:
+// checks that prose and this table against what the verbs do. For the prose, it reads the rows of
+// the Field table and requires that every field name in a row is a label here and that the
+// task verbs a row names are exactly the verbs this table lists for that field.
+// Two layers, as lead decision 113 rules:
// - `verbs`: the writer verbs.mjs checks before anything else. `pm` is the pm definition
// (field-writer otherwise), `assigned` a role whose bot is an assignee (not-assigned
// otherwise), `any` no writer check.
diff --git a/packages/tasks/tests/fields.test.mjs b/packages/tasks/tests/fields.test.mjs
index ef81f3385..1c2e396d4 100644
--- a/packages/tasks/tests/fields.test.mjs
+++ b/packages/tasks/tests/fields.test.mjs
@@ -10,7 +10,8 @@ import { loadFields, checkFields, FieldTableError, FIELDS_FILE } from '../src/fi
import { TASK_VERBS } from '../../bus/src/broker.mjs';
import { loadRole } from '../../business/src/index.mjs';
// Row 61 (#1550): fields.json, and the Field table in docs/plans/2026-10-04_slice-1.md, against what
-// the verbs in src/verbs.mjs do, with the role files as given. The writer layer is read from the table; whether a write needs a decision, and who
+// the verbs in src/verbs.mjs do, with the role files as given. The writer layer is read from the
+// table; whether a write needs a decision, and who
// resolves it, from roles/*.json as the business loader reads them (lead decision 113). A version 1
// file, the researcher's, grants nothing. Neither expectation is written out here, so a change to
// the table, the prose, a role file or the verbs that leaves them disagreeing fails this file.
diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js
index 108df3b98..0cc841bbc 100644
--- a/packages/webui/src/public/bus.js
+++ b/packages/webui/src/public/bus.js
@@ -10,7 +10,7 @@
const esc = v => String(v ?? '').replace(/[&<>"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
// The CHAT-02 rules: C0 controls show as control pictures, C1 and bidi controls as
// [U+XXXX]. Newlines and tabs stay. Markdown stays as its source.
- const CONTROL = /[\u0000-\u0008\u000b-\u001f\u007f]/g, UNSEEN = /[\u0080-\u009f؜‎‏‪-‮⁦-⁩]/g;
+ const CONTROL = /[\u0000-\u0008\u000b-\u001f\u007f]/g, UNSEEN = /[\u0080-\u009f\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g;
const inert = v => String(v ?? '').replace(CONTROL, c => c === '\u007f' ? '␡' : String.fromCharCode(0x2400 + c.charCodeAt(0))).replace(UNSEEN, c => `[U+${c.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}]`);
const txt = v => esc(inert(v)); // every agent-, tracker- or bus-authored string goes through this
const announce = text => { $('announce').textContent = text; };
diff --git a/packages/webui/tests/bus-browser.test.mjs b/packages/webui/tests/bus-browser.test.mjs
index 106a8dd26..bf09119f1 100644
--- a/packages/webui/tests/bus-browser.test.mjs
+++ b/packages/webui/tests/bus-browser.test.mjs
@@ -108,7 +108,7 @@ test('S5 pages in a browser: real broker rows, inert text, Copy, routes, failure
assert.equal(await b.evaluate('!!window.injected'), false, where);
assert.equal(await b.evaluate('document.querySelectorAll("#bus-view script, #bus-view img, #bus-view iframe, #bus-view object, #bus-view embed, #bus-view svg, #bus-view style, #bus-view link").length'), 0, where);
const shown = await text('#bus-view');
- assert.doesNotMatch(shown, /[\u0000-\u0008\u000b-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/, where);
+ assert.doesNotMatch(shown, /[\u0000-\u0008\u000b-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/, where);
};
const noOverflow = async where => {
for (const width of [320, 1440]) {
diff --git a/packages/webui/tests/bus.test.mjs b/packages/webui/tests/bus.test.mjs
index 6fb74ccec..d1bb55e42 100644
--- a/packages/webui/tests/bus.test.mjs
+++ b/packages/webui/tests/bus.test.mjs
@@ -17,7 +17,7 @@ import { startServer } from '../src/serve.mjs';
import { BusReadError, busReader, humanCall } from '../src/bus.mjs';
import { close } from './fixture.mjs';
-const HOSTILE = '<img src=x onerror="window.injected=true"> ‮evil';
+const HOSTILE = '<img src=x onerror="window.injected=true"> \u202eevil';
const at = '2026-10-08T12:00:00.000Z';
const businesses = {
demo: {