feat(orchestrator): W1 operator tasks, diff previews and bound commit asks

Operator tasks move from the Inbox into Tasks with the Waits on Operator filter. Review and commit asks carry the staged diff; a file whose old or new blob holds an armour line or a detection-pattern match, or every file when no pattern loads, ships only its path, status, mode and counts. The approval binds to the staged tree id from git write-tree, the encoded request body respects the hub limit, and the hub image ships every client module signed.py loads. Committed below the bar on the operator's word 2026-11-12 (no further per-bundle tests, one gate after the merge): the full hub suite and the W1 e2e never ran, two high MEDUSA rows (sandbox_paths.py FLOOR, permission_hook.py ask POST) wait for their acceptance.

🎯 Fix: 85 %
💥 Break: 12 %
💸 Cost: 30 %
⏱️ Time: 30 %
🛡️ Security: 50 %
🏆 Score: 100
🚦 Gate: ⛔ fix 85 % < 90, break 12 % > 5; security 50 % < 100: ask the operator before the commit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Veen-BirkenbachandClaude Opus 5.5 committed 2026-11-12 16:13:58 +00:00
1 parent fd8fc08603
commit d09ed61161
34 files changed
+2449 -111

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
const Diffs = (() => {
"use strict";
const COLLAPSE = 400;
const QUOTE_LIMIT = 2000;
const HUNK = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
const KINDS = {"+": "add", "-": "del", " ": "ctx"};
function rows(patch) {
const found = [];
let [old, now] = [0, 0];
String(patch).split("\n").forEach((text, index) => {
const line = index + 1;
const hunk = HUNK.exec(text);
if (hunk) {
[old, now] = [Number(hunk[1]), Number(hunk[2])];
found.push({kind: "hunk", line, old: "", new: "", text});
return;
}
const kind = KINDS[text[0]];
if (!kind) {
return;
}
const row = {kind, line, old: kind === "add" ? "" : old, new: kind === "del" ? "" : now, text: text.slice(1)};
old += kind === "add" ? 0 : 1;
now += kind === "del" ? 0 : 1;
found.push(row);
});
return found;
}
const collapsed = (file) => file.additions + file.deletions > COLLAPSE;
function span(numbers) {
const known = numbers.filter((value) => Number.isInteger(value) && value > 0);
return known.length ? [Math.min(...known), Math.max(...known)] : null;
}
function lineSpan(text, quote) {
const full = String(text);
const at = full.indexOf(quote);
if (!quote || at < 0) {
return [1, full.split("\n").length];
}
const from = full.slice(0, at).split("\n").length;
return [from, from + quote.split("\n").length - 1];
}
function quoted(text) {
const clean = String(text).trim();
return clean.length > QUOTE_LIMIT ? `${clean.slice(0, QUOTE_LIMIT)}…` : clean;
}
const feedback = (ref, path, from, to, quote, words) => `Feedback on ${ref} ${path}:${from}-${to}: "${quoted(quote)}" ${String(words).trim()}`;
const feedbackOf = (messages, ref) => messages.filter((message) => String(message.text).startsWith(`Feedback on ${ref} `));
return {COLLAPSE, QUOTE_LIMIT, rows, collapsed, span, lineSpan, quoted, feedback, feedbackOf};
})();
if (typeof module === "object" && module.exports) {
module.exports = Diffs;
}