Merge feature/workbench-w1-operator-tasks into unify/skills-20261112

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:23:36 +00:00
commit eb4a335984
34 files changed
+2449 -111

No files matched your search

+7 -2
View File
@@ -3,6 +3,7 @@ from __future__ import annotations
import time
from .choosing import EVERYONE, answer_text
from .diffs import store_diff, valid_diff
from .errors import Conflict, Missing, ToolError
from .fields import (
COMMAND_LIMIT,
@@ -60,12 +61,16 @@ def option_of(option: object) -> dict:
class Asking:
def ask(self, body: bytes) -> dict:
payload = decode(body)
diff = valid_diff(payload.pop("diff")) if "diff" in payload else None
expect(payload, ("tool", *ASK_TEXTS, "timeout"))
values = {name: bounded(payload, name, limit) for name, limit in ASK_TEXTS.items()}
lifetime = seconds(payload, "timeout", ASK_LIFETIME)
created = time.time()
fields = {**values, "tool": field(payload, "tool").strip(), "status": "pending", "decided": None, "proof": None}
record = self.asks.add({**fields, "created_ts": created, "expires": created + lifetime})
fields = {**values, "tool": field(payload, "tool").strip(), "status": "pending", "decided": None, "proof": None, "diff_files": None if diff is None else len(diff)}
ask_id = self.asks.fresh()
if diff is not None:
store_diff(self.reviews.pages, "ask", ask_id, diff)
record = self.asks.insert(ask_id, {**fields, "created_ts": created, "expires": created + lifetime})
self.automate("ask", record)
return {"id": record["id"], "status": record["status"]}
+67
View File
@@ -0,0 +1,67 @@
from __future__ import annotations
import json
import re
from pathlib import Path
from .errors import Missing, ToolError
from .records import read_json, write_atomic
from .signed import limits
DIFF_LIMIT = limits.DIFF_LIMIT
DIFF_BODY_LIMIT = limits.DIFF_BODY_LIMIT
FILE_CAP = limits.FILE_CAP
PATH_LIMIT = limits.PATH_LIMIT
STATUSES = ("A", "M", "D", "R", "B")
DIFF_KEYS = ("path", "status", "mode", "additions", "deletions", "patch", "note")
NOTES = ("", limits.WITHHELD)
MODE = re.compile(r"[0-7]{6}(?: => [0-7]{6})?")
DIFF_SUFFIX = {"review": ".review-diff.json", "ask": ".ask-diff.json"}
def counted(value: object) -> bool:
return isinstance(value, int) and not isinstance(value, bool) and value >= 0
def diff_entry(entry: object) -> dict:
if not isinstance(entry, dict) or set(entry) != set(DIFF_KEYS):
raise ToolError(f"every diff entry must be an object with exactly {', '.join(DIFF_KEYS)}")
path, patch, mode = entry["path"], entry["patch"], entry["mode"]
if not isinstance(path, str) or not 0 < len(path) <= PATH_LIMIT or entry["status"] not in STATUSES:
raise ToolError(f"a diff path must be 1 to {PATH_LIMIT} characters and its status one of {', '.join(STATUSES)}")
if not isinstance(mode, str) or not MODE.fullmatch(mode):
raise ToolError("mode must be a git file mode, or old => new for a changed one")
if not counted(entry["additions"]) or not counted(entry["deletions"]) or not isinstance(patch, str) or (entry["status"] == "B" and patch):
raise ToolError("additions and deletions must be counts, patch text, empty for a binary file")
if entry["note"] not in NOTES or (entry["note"] and patch):
raise ToolError(f"note must be empty or {limits.WITHHELD!r}, the latter with an empty patch")
return {key: entry[key] for key in DIFF_KEYS}
def valid_diff(value: object) -> list[dict]:
"""Returns:
The review diff of requirement 003, checked: at most FILE_CAP
entries, and at most DIFF_LIMIT bytes of JSON-encoded patch text in
all, the bound the requesting script keeps.
"""
if not isinstance(value, list) or len(value) > FILE_CAP:
raise ToolError(f"diff must be a list of at most {FILE_CAP} files")
entries = [diff_entry(entry) for entry in value]
if sum(len(json.dumps(entry["patch"], ensure_ascii=False).encode("utf-8")) for entry in entries) > DIFF_LIMIT:
raise ToolError(f"the patches of a diff must stay within {DIFF_LIMIT} bytes")
return entries
def diff_bytes(diff: list[dict]) -> bytes:
return json.dumps({"diff": diff}, ensure_ascii=False).encode("utf-8")
def store_diff(folder: Path, kind_name: str, item_id: str, diff: list[dict]) -> None:
write_atomic(folder / f"{item_id}{DIFF_SUFFIX[kind_name]}", diff_bytes(diff))
def stored_diff(folder: Path, kind_name: str, item_id: str) -> dict:
data = read_json(folder / f"{item_id}{DIFF_SUFFIX[kind_name]}") if kind_name in DIFF_SUFFIX else None
if not isinstance(data, dict) or not isinstance(data.get("diff"), list):
raise Missing(item_id)
return {"kind": kind_name, "id": item_id, "diff": data["diff"]}
+3 -2
View File
@@ -5,14 +5,15 @@ import math
import re
from .errors import ToolError
from .signed import limits
WAIT_CAP = 300
TEXT_LIMIT = 20_000
COMMAND_LIMIT = 4000
PATH_LIMIT = 4096
PATH_LIMIT = limits.PATH_LIMIT
NAME_LIMIT = 120
COUNT = re.compile(r"[0-9]{1,12}")
PATH = re.compile(r"/[^\x00-\x1f\x7f]{0,4095}")
PATH = re.compile(rf"/[^\x00-\x1f\x7f]{{0,{PATH_LIMIT - 1}}}")
LINE = r"(?=[^\x00-\x1f\x7f]*\S)[^\x00-\x1f\x7f]{{1,{0}}}"
ORDER_NAME = re.compile(r"(?![\s-])[^,\x00-\x1f\x7f]{1,200}")
FIELDS = {
+6 -1
View File
@@ -6,6 +6,7 @@ from collections.abc import Callable
from http import HTTPStatus
from urllib.parse import urlsplit
from .diffs import DIFF_BODY_LIMIT
from .engines import STT_LIMIT
from .exchange import PLAIN_CSP, Exchange
@@ -56,6 +57,7 @@ BOARD_SIGN_ROUTE = "/api/board/sign"
SETTINGS_SIGN_ROUTE = "/api/settings/sign"
CHOICES_ROUTE = "/api/choices"
CHOICES_SIGN_ROUTE = "/api/choices/sign"
DIFF_ROUTE = re.compile(r"/api/diffs/(review|ask)/([0-9a-f]{16})")
WAV_POSTS = (STT_ROUTE, VOICE_ROUTE)
ACTION_POSTS = ("/api/rules", "/api/nl", SETTINGS_ROUTE, TTS_ROUTE, STT_ROUTE, SIGN_ROUTE, RULE_SIGN_ROUTE, CLEANUP_ROUTE, OFFICES_ROUTE, TASKS_ROUTE, VOICE_ROUTE, MESSAGE_SIGN_ROUTE, SETTINGS_SIGN_ROUTE, CHOICES_ROUTE, CHOICES_SIGN_ROUTE)
@@ -83,10 +85,13 @@ class Handler(Exchange):
cleanup = CLEANUP_STATE.fullmatch(path)
office = OFFICE_STATE.fullmatch(path)
voice = VOICE_ITEM.fullmatch(path)
diff = DIFF_ROUTE.fullmatch(path)
if self.host() is None:
self.send_text(HTTPStatus.FORBIDDEN, "forbidden host")
elif path == "/":
self.index()
elif diff:
self.answer(lambda: hub.diff_of(diff.group(1), diff.group(2)), HTTPStatus.OK)
elif vendored and vendored.group(1) in VENDOR:
self.vendored(*VENDOR[vendored.group(1)])
elif voice and voice.group(2):
@@ -237,7 +242,7 @@ class Handler(Exchange):
def do_POST(self) -> None:
path = urlsplit(self.path).path
length = self.body_length({UPLOADS: UPLOAD_LIMIT, STT_ROUTE: STT_LIMIT, VOICE_ROUTE: STT_LIMIT}.get(path, BODY_LIMIT))
length = self.body_length({UPLOADS: UPLOAD_LIMIT, STT_ROUTE: STT_LIMIT, VOICE_ROUTE: STT_LIMIT, "/mcp": DIFF_BODY_LIMIT, "/api/asks": DIFF_BODY_LIMIT}.get(path, BODY_LIMIT))
if length is None:
return
host = self.host()
+4 -3
View File
@@ -19,16 +19,17 @@ SNOOZE_LIMIT = 8 * 86400
class Inbox:
def inbox(self, now: float, tasks: dict[str, dict], directory: Directory) -> list[dict]:
claims = read_claims(self.council)
base = {"agent": "", "to": "", "detail": "", "green": False, "gate": "", "score": "", "warnings": [], "options": [], "recommended": "", "command": "", "directory": "", "sha256": "", "runnable": False, "deniable": False, "job": None, "rule": None, "dry_run": None}
base = {"agent": "", "to": "", "detail": "", "green": False, "gate": "", "score": "", "warnings": [], "options": [], "recommended": "", "command": "", "directory": "", "sha256": "", "runnable": False, "deniable": False, "job": None, "rule": None, "dry_run": None, "diff": None}
items = []
for review in self.reviews.pending():
created = iso_epoch(review["created"]) or now
gate = review.get("gate", "")
fields = {"title": review["title"], "detail": review["branch"], "green": gate == "pass", "gate": gate, "score": review.get("score", ""), "directory": review["worktree"]}
agent = review.get("agent", "")
fields = {"title": review["title"], "detail": review["branch"], "green": gate == "pass", "gate": gate, "score": review.get("score", ""), "directory": review["worktree"], "agent": agent, "to": requester_of(claims, agent)[0], "diff": review.get("diff_files")}
items.append({**base, "kind": "review", "id": review["id"], "ts": created, **fields})
for ask in (ask for ask in self.asks.pending() if ask["expires"] > now):
warnings = signing.warnings(ask["command"])
fields = {"title": f"{ask['tool']}: {ask['command'][:200]}", "agent": directory.now(ask["session"]), "to": requester_of(claims, ask["session"])[0], "green": not warnings, "warnings": warnings, "deniable": True}
fields = {"title": f"{ask['tool']}: {ask['command'][:200]}", "agent": directory.now(ask["session"]), "to": requester_of(claims, ask["session"])[0], "green": not warnings, "warnings": warnings, "deniable": True, "diff": ask.get("diff_files")}
items.append({**base, "kind": "ask", "id": ask["id"], "ts": ask["created_ts"], **fields, "command": ask["command"], "directory": ask["cwd"]})
for decision in self.decisions.pending():
recommended = decision.get("recommended", "")
+7 -1
View File
@@ -110,11 +110,17 @@ class Reviews(Ledger):
def stored(self, review_id: str, suffix: str) -> Path:
return self.pages / f"{review_id}{suffix}"
def submit(self, fields: dict[str, str], page: bytes, files: list[dict]) -> dict:
def submit(self, fields: dict[str, str], page: bytes, files: list[dict], attached: dict[str, bytes]) -> dict:
"""Args:
attached: further files written before the review shows, by
suffix.
"""
with self.changed:
review_id = self.fresh()
write_atomic(self.stored(review_id, ".html"), page)
write_atomic(self.stored(review_id, ".json"), json.dumps({"files": files}).encode("utf-8"))
for suffix, data in attached.items():
write_atomic(self.stored(review_id, suffix), data)
return self.insert(review_id, {**fields, "files": len(files), "status": "pending", "decided": None})
+13 -5
View File
@@ -6,16 +6,18 @@ import stat
import time
from pathlib import Path
from .diffs import DIFF_SUFFIX, diff_bytes, stored_diff, valid_diff
from .errors import Conflict, Missing, ToolError
from .fields import WAIT_CAP, bounded, decode, expect, field, seconds
from .review_page import review_files
from .signed import review_signed
from .signed import limits, review_signed
PAGE_LIMIT = 32 << 20
NOTES_LIMIT = 100_000
NOTES_LIMIT = limits.NOTES_LIMIT
SCORE_LIMIT = 500
GATES = ("pass", "fail")
REQUEST = ("repo", "worktree", "branch", "tree", "title", "page", "notes", "gate", "score")
OPTIONAL = ("agent", "diff")
LISTED = ("id", "created", "worktree", "branch", "tree", "title")
STATE = ("id", "status", "tree", "decided")
@@ -55,7 +57,7 @@ class Reviewing:
return data
def request(self, arguments: dict) -> dict:
expect(arguments, REQUEST)
expect(arguments, (*REQUEST, *(name for name in OPTIONAL if name in arguments)))
fields = {name: field(arguments, name) for name in ("repo", "worktree", "branch", "tree", "title")}
notes = arguments["notes"]
if not isinstance(notes, str) or len(notes) > NOTES_LIMIT:
@@ -63,12 +65,18 @@ class Reviewing:
if arguments["gate"] not in GATES:
raise ToolError("gate must be pass or fail")
score = " ".join(bounded(arguments, "score", SCORE_LIMIT).split())
agent = field(arguments, "agent").strip() if "agent" in arguments else ""
diff = valid_diff(arguments["diff"]) if "diff" in arguments else None
page = self.read_page(field(arguments, "page"))
extra = {"notes": notes, "gate": arguments["gate"], "score": score}
review = self.reviews.submit({**fields, "title": fields["title"].strip(), **extra}, page, review_files(page))
extra = {"notes": notes, "gate": arguments["gate"], "score": score, "agent": agent, "diff_files": None if diff is None else len(diff)}
attached = {} if diff is None else {DIFF_SUFFIX["review"]: diff_bytes(diff)}
review = self.reviews.submit({**fields, "title": fields["title"].strip(), **extra}, page, review_files(page), attached)
self.automate("review", review)
return {"id": review["id"], "status": review["status"], "url": self.url()}
def diff_of(self, kind_name: str, item_id: str) -> dict:
return stored_diff(self.reviews.pages, kind_name, item_id)
def review_proof(self, review_id: str) -> dict:
review = self.reviews.get(review_id)
if review is None:
+1
View File
@@ -30,6 +30,7 @@ def client_module(name: str, uses: dict[str, ModuleType]) -> ModuleType:
return module
limits = client_module("hub_limits", {})
signing = client_module("signing", {})
passkey = client_module("passkey", {"signing": signing})
verifier = client_module("verifier", {"signing": signing, "passkey": passkey})
+1 -1
View File
@@ -51,7 +51,7 @@ INDEX_CSP = (
def badges(inbox: list[dict], claims: list[dict], jobs: list[dict], now: float) -> dict[str, int]:
return {
"inbox": sum(1 for item in inbox if not item["until"]),
"tasks": sum(1 for item in inbox if not item["until"]),
"agents": len({claim["agent"] for claim in claims if claim["beat"] is not None and claim["beat"] >= now - ACTIVE}),
"artifacts": sum(1 for job in jobs if job["status"] in JOB_OPEN),
}