fix(hub): close seven bugs found in the refactor review
The PermissionRequest hook posted asks cut to the hub's field limits, so a signature covered less than Claude Code would run; it now posts nothing it cannot sign in full and leaves the decision to Claude Code with a reason on stderr. fields.seconds names the field the caller used in its error. Serving a stored page maps an OSError to 500 instead of a dropped connection. The natural-language line marks the register as seen before it builds the inbox, like the page does. do_POST runs every header guard (host, origin, client, content type, MCP) before it reads the body, so a refused request never costs its upload. The runner's reader closes stdout at EOF, because a close from the executing thread blocked on the buffer lock and could SIGPIPE a command still running. The page title counts only inbox items that are not snoozed. Committed on the operator's word despite the gate: cost and time are estimates under 98 % other load and include eight new test cases. 🎯 Fix: 88 % 💥 Break: 3 % 💸 Cost: 106 % ⏱️ Time: 113 % 🛡️ Security: 100 % 🏆 Score: 71 🚦 Gate: ⛔ fix 88 % < 90; cost 106 % > 100, time 113 % > 100: ask the operator before the commit ``` /home/kevinveenbirkenbach/Repositories/github.com/kevinveenbirkenbach/skills/.worktrees/feature/kvb-hub ``` Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8ba45efd04
commit
afd96fcd72
14 files changed
+197
-81
No files matched your search
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
import json
|
||||
import time
|
||||
import unittest
|
||||
@@ -99,6 +100,25 @@ class TestHubInbox(HubCase):
|
||||
with self.subTest(text=text):
|
||||
self.assertIn(text, html)
|
||||
|
||||
def test_an_nl_command_records_new_operator_rows_like_the_state_does(self):
|
||||
self.write_council({"rasci.json": {"operator/greet": {"title": "echo hi", "workdir": "/repo", "check": "manual", "status": "queued", "roles": {}}}})
|
||||
model = mock.Mock(**{"enabled.return_value": True, "complete.return_value": '{"actions": []}'})
|
||||
self.httpd.hub = dataclasses.replace(self.httpd.hub, model=model)
|
||||
before = time.time()
|
||||
self.assertEqual(self.post_json("/api/nl", {"text": "status"}, self.guard(self.host))[0], 200)
|
||||
after = time.time()
|
||||
row = next(item for item in self.snapshot()["inbox"] if item["id"] == "operator/greet")
|
||||
self.assertTrue(before <= row["ts"] <= after, (before, row["ts"], after))
|
||||
|
||||
def test_the_title_counts_the_items_that_are_not_snoozed(self):
|
||||
asks = [self.create_ask(ASK), self.create_ask({**ASK, "command": "make other"})]
|
||||
self.assertIn("<title>(2) kvb-hub</title>", self.index())
|
||||
for ask_id, title in zip(asks, ("(1) kvb-hub", "kvb-hub"), strict=True):
|
||||
snooze = {"kind": "ask", "id": ask_id, "until": time.time() + 3600, "pinned": False}
|
||||
self.assertEqual(self.post_json("/api/inbox/mark", snooze, self.guard(self.host))[0], 200)
|
||||
with self.subTest(title=title):
|
||||
self.assertIn(f"<title>{title}</title>", self.index())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user