mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix: align auditor channel perms, extend desk gate to tests, drop stale usage-event doc
- permissions: the Auditor is a silent, read-only observer with no say/dm in its verb surface, so can_write_channel now returns False for it — matching the role's real capabilities instead of granting an unreachable channel write (test updated to assert read-only). - Makefile: make lint and make gate now type-check mypy roboco/ tests/, matching make quality / make quality-fast, so the developer-desk gate also catches test type errors before submit (tests/ is already mypy-clean). - docs: CLAUDE.md no longer lists USAGE_UPDATE — only USAGE_SNAPSHOT is published to /ws/system.
This commit is contained in:
@@ -472,7 +472,7 @@ The orchestrator exposes WebSocket endpoints under `/ws` (router in
|
||||
| Endpoint | Purpose |
|
||||
|----------|---------|
|
||||
| `/ws/channels/{id}`, `/ws/agents/{id}`, `/ws/sessions/{id}`, `/ws/notifications/{id}` | Per-resource live streams |
|
||||
| `/ws/system` | Operator/system-wide stream (no per-agent keying) — the rate-limit lifecycle (`RATE_LIMIT_HIT` / `RATE_LIMIT_LIFTED`) and live usage (`USAGE_UPDATE` / `USAGE_SNAPSHOT`, pushed to the usage dashboard) |
|
||||
| `/ws/system` | Operator/system-wide stream (no per-agent keying) — the rate-limit lifecycle (`RATE_LIMIT_HIT` / `RATE_LIMIT_LIFTED`) and live usage (`USAGE_SNAPSHOT`, pushed to the usage dashboard) |
|
||||
|
||||
Server-side events reach these sockets through `roboco/api/websocket_bridge.py`,
|
||||
which subscribes to the `StreamEventBus` and forwards each event to the matching
|
||||
@@ -493,7 +493,7 @@ stand up a parallel endpoint or client stack.
|
||||
`agent_spawn_sessions` → `daily_usage_rollups` → dashboard). Cost uses
|
||||
provider-aware pricing in `roboco/billing/pricing.py` (Anthropic priced;
|
||||
local/Ollama intentionally `$0`). The token sweep also publishes
|
||||
`USAGE_UPDATE`/`USAGE_SNAPSHOT` to `/ws/system`, so the dashboard's
|
||||
`USAGE_SNAPSHOT` to `/ws/system`, so the dashboard's
|
||||
"Token Usage & Cost" panel updates live and falls back to HTTP polling when
|
||||
the stream is down.
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ restart: stop start-example
|
||||
lint:
|
||||
@echo 'Formatting w/ Ruff...' ; echo '' ; uv run ruff format .
|
||||
@echo '' ; echo '' ; echo 'Linting w/ Ruff...' ; echo '' ; uv run ruff check .
|
||||
@echo '' ; echo '' ; echo 'Type checking w/ Mypy...' ; echo '' ; uv run mypy roboco/
|
||||
@echo '' ; echo '' ; echo 'Type checking w/ Mypy...' ; echo '' ; uv run mypy roboco/ tests/
|
||||
@echo '' ; echo '' ; echo 'Finding dead code w/ Vulture...' ; echo '' ; uv run vulture vulture_whitelist.py
|
||||
|
||||
# Fix code
|
||||
@@ -285,7 +285,7 @@ quality-fast:
|
||||
gate:
|
||||
@uv run ruff format --check .
|
||||
@uv run ruff check .
|
||||
@uv run mypy roboco/
|
||||
@uv run mypy roboco/ tests/
|
||||
@uv run xenon --max-absolute B --max-modules A --max-average A roboco/
|
||||
|
||||
# Run all analysis tools
|
||||
|
||||
@@ -215,9 +215,10 @@ class PermissionService(SingletonService):
|
||||
if agent.role == AgentRole.CEO:
|
||||
return True
|
||||
|
||||
# Auditor can write but usually doesn't (to maintain cover)
|
||||
# Auditor is a silent, read-only observer (no say/dm in its verb surface);
|
||||
# deny channel writes so this layer matches the role's actual capabilities.
|
||||
if agent.role == AgentRole.AUDITOR:
|
||||
return True
|
||||
return False
|
||||
|
||||
# Main PM has access to all channels
|
||||
if agent.role == AgentRole.MAIN_PM:
|
||||
|
||||
@@ -65,10 +65,10 @@ def test_ceo_can_write_any_channel(svc: PermissionService) -> None:
|
||||
assert svc.can_write_channel(ceo, "backend-cell")
|
||||
|
||||
|
||||
def test_auditor_can_write_any_channel(svc: PermissionService) -> None:
|
||||
"""Auditor write returns True (cover-maintenance is a convention)."""
|
||||
def test_auditor_cannot_write_any_channel(svc: PermissionService) -> None:
|
||||
"""Auditor is a silent, read-only observer — it cannot write to channels."""
|
||||
auditor = _ctx(AgentRole.AUDITOR)
|
||||
assert svc.can_write_channel(auditor, "backend-cell")
|
||||
assert not svc.can_write_channel(auditor, "backend-cell")
|
||||
|
||||
|
||||
def test_main_pm_can_write_any_channel(svc: PermissionService) -> None:
|
||||
|
||||
Reference in New Issue
Block a user