feat(kvb-org-radio): split radio and post, add kvb-org-update
The radio (call, broadcast, security, pan-pan, mayday) reaches its addressee at the next tool step and wakes it. The post (post with --to, newsletter without, call receipts) arrives through a new Stop hook when the turn ends and never wakes. Legacy rows map onto the two channels and send direct stays as an alias. A PreToolUse hook holds the mayday's radio silence for writing tools and Bash. Only the sender, helpers who join with radio.py assist, bare radio.py calls and the config's allowed commands pass, and any shell operator or parse error blocks. kvb-org-update announces changed skills as one newsletter. Callers moved to send call --to. 🎯 Fix: 90 % 💥 Break: 5 % 💸 Cost: 104 % ⏱️ Time: 100 % 🛡️ Security: 100 % 💰 Value: ? 🏆 Score: 82 🚦 Gate: ⚠️ cost 104 % > 100: ask the operator before the commit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5cb5da81ec
commit
367fe56dd4
21 files changed
+882
-257
No files matched your search
+14
-8
@@ -1,4 +1,4 @@
|
||||
"""Exercise the news.py shim: it forwards post, hook and show to radio.py, and a missing radio.py never blocks a prompt."""
|
||||
"""Exercise the news.py shim: it forwards post, hook, mailbox and show to radio.py, and a missing radio.py never blocks a prompt."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -47,17 +47,23 @@ class TestNews(unittest.TestCase):
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
return [line.split(" ", 3)[3] for line in result.stdout.splitlines()]
|
||||
|
||||
def test_every_session_sees_a_post_once_except_its_author(self):
|
||||
self.assertEqual(self._cli("s1", "post", "core #1358 merged").stdout, "sent broadcast to all\n")
|
||||
self.assertEqual(self._hook("s2"), ["One: core #1358 merged"])
|
||||
def _mailbox(self, sid: str) -> list[str]:
|
||||
result = self._exec(NEWS, None, json.dumps({"session_id": sid}), ("mailbox",))
|
||||
self.assertIn(result.returncode, (0, 2), result.stderr)
|
||||
return [line.split(" ", 3)[3] for line in result.stderr.splitlines()]
|
||||
|
||||
def test_every_session_sees_a_post_once_when_its_turn_ends_except_its_author(self):
|
||||
self.assertEqual(self._cli("s1", "post", "core #1358 merged").stdout, "sent newsletter to all\n")
|
||||
self.assertEqual(self._hook("s2"), [])
|
||||
self.assertEqual(self._hook("s3"), ["One: core #1358 merged"])
|
||||
self.assertEqual(self._hook("s1"), [])
|
||||
self.assertEqual(self._mailbox("s2"), ["One: core #1358 merged"])
|
||||
self.assertEqual(self._mailbox("s2"), [])
|
||||
self.assertEqual(self._mailbox("s3"), ["One: core #1358 merged"])
|
||||
self.assertEqual(self._mailbox("s1"), [])
|
||||
|
||||
def test_addressed_post_reaches_only_its_target(self):
|
||||
self._cli("s1", "post", "your gate is granted", "--to", "Two")
|
||||
self.assertEqual(self._hook("s3"), [])
|
||||
self.assertEqual(self._hook("s2"), ["One to Two: your gate is granted"])
|
||||
self.assertEqual(self._mailbox("s3"), [])
|
||||
self.assertEqual(self._mailbox("s2"), ["One to Two: your gate is granted"])
|
||||
self.assertEqual(len(self._cli("s1", "show", "--all").stdout.splitlines()), 1)
|
||||
|
||||
def test_hook_never_fails_and_post_needs_a_session(self):
|
||||
|
||||
Reference in new issue
Block a user