docs(requirements): record orchestrator phases 5 and 6 in 001

Requirement 001 stays the single place for the Agent Orchestrator, as
its decision 1 asks. Decisions 23 to 38 record the operator's answers of
2026-11-07: phase 5 (console, deny channel, rule requests, composer
with whisper, Hierarchie, separate agent order, Tasks tab, merge flow)
and phase 6 (Firewall with passkey-signed settings writes and groups,
asks and choices as tasks with a choice request per channel, drain /
suspend / resume, agent and node popups with search, animated faces,
fit to window, rename once, the Deutschlandfunk stream and a squelch,
the tree cause, a Ressourcen tab). A second diagram shows the serial
subtrees S1 to S7, and each gets its acceptance criteria and tests.

🎯 Fix: 95 %
💥 Break: 1 %
💸 Cost: 100 %
⏱️ Time: –
🛡️ Security: 100 %
🏆 Score: 94
🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 %

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Veen-BirkenbachandClaude Opus 5.5 committed 2026-11-07 17:55:11 +00:00
1 parent 4540494c30
commit 1d311a3382
1 file changed
+200
+200
View File
@@ -124,6 +124,87 @@ from three views down to any agent, branch or artefact.
22. **Organisation update**: a new skill `kvb-org-update` tells every agent
and client which skills changed and how to use them, as one
`newsletter` per update; phase 1 announces the radio change through it.
23. **Phase 5** (23 to 38 operator-confirmed 2026-11-07): the console output shows under "Ausführen"; a deny picks its
channel (default `post`); agents request auto-approval rules through the
inbox; the rules form and the Ort fields never overlap; the radio plays
with one line per station and highlights the speaking agent; the
operator composer sends text or voice, recorded, transcribed locally with
whisper in the container and kept as audio, to a recipient by `post` or
`call`; a Hierarchie view shows the council offices with appoint and
recall; the agent order (drag list) is separate from task priority (WSJF
plus the operator's pin) and only breaks ties; one Tasks tab holds list,
board and RASCI matrix, the inbox as its "waits on Operator" filter and
the queue state; the merge flow, a pkgmgr-managed YAML per worktree with
several pull sources and push targets, shows in Artifacts and Tasks.
24. **Firewall**: the tab Regeln becomes Firewall and holds every form of
allow-listing: the hub's auto-approval rules (ask, review, decision),
allow and deny command patterns, and the Claude settings permissions
(`allow`, `ask`, `deny`) and sandbox entries. Rejected: a separate
settings page.
25. **Settings writes**: a change to a Claude settings file shows as a diff,
is signed with the passkey and applied by a host executor that verifies
the signature, writes only files of a fixed list (`~/.claude/settings.json`
and `<project>/.claude/settings.json` of the known projects) and keeps a
backup. Rejected: an `operator.py` row only (no one-click path); an agent
writing settings (never).
26. **Groups**: a rule applies to one agent, a named agent group or all
agents; rules form named rule sets that are taken over as a whole for an
agent, a group or all. The Firewall reads the existing settings files and
groups their entries by tool and command prefix by itself.
27. **Decisions are tasks**: asks, rule requests, operator rows and choices
appear only in the Tasks tab, under its "waits on Operator" filter.
Rejected: a Choices column of its own (a choice is a decision the operator
takes, so it is a task).
28. **Request choices**: the Tasks tab has one button per channel, `post` and
`call` with a multi-select of agents, `newsletter`, `broadcast`,
`security`, `mayday` and `pan-pan`, that sends the fixed request "send me
your open decisions as choices" without free text. Agents answer with
`kvb-think-choice` items, shown as choice cards; the operator's click on
an option is the passkey-signed answer.
29. **Night commands**: evening, sunset and sunrise become `drain` (finish the
current task, accept nothing new), `suspend` (park work, write the
handover, idle) and `resume` (continue from the handover). Skills:
`kvb-org-evening` → `kvb-org-drain`, `kvb-org-sunset` → `kvb-org-suspend`,
`kvb-org-sunrise` → `kvb-org-resume`, `kvb-agent-relax` →
`kvb-agent-drain`, `kvb-agent-sleep` → `kvb-agent-suspend`,
`kvb-agent-wakeup` → `kvb-agent-resume`; `night.py` and the Steuerung
menu follow, `kvb-skill-cleanup` removes the old names. Rejected:
sleep / hibernate / wakeup, pause / park / resume.
30. **Agent popup**: a click on an agent opens a fading popup with a simple,
clear layout (face, name, earlier names, offices, tasks, claims,
composer) instead of the Details side panel, which goes.
31. **Node popup**: a click on a node in any graph view enlarges it, marks it
red and opens a slightly transparent popup in the foreground, tied to the
node by a leader line. A search field with suggestions replaces the list
of every node.
32. **Faces**: agents get simple animated 2D faces instead of emojis, built
from independent attributes (shape, colour, eyes, brows, mouth, hair or
headwear, accessory) with at least 1000 combinations, chosen
deterministically from the agent's stable id; the mouth moves while the
agent speaks.
33. **Fit to window**: every view sizes to the window height; no page
scrollbar on `#agents/orbit`.
34. **Rename once**: a name change appears once in the Stream per session
and name pair, never again per state build; earlier names show in the
agent popup.
35. **Radio**: the configured Deutschlandfunk stream
`https://st01.sslstream.dlf.de/dlf/01/high/aac/stream.aac?aggregator=web`
plays (root cause proven first, redirects and `media-src` included). A
squelch control suppresses the radio beep; at 0 no beep plays, music on
or off.
36. **Tree cause**: the tree timer builds pkgmgr from the newest signed tag,
and v2.3.0 has no `branch tree`, so no tree file exists. The Tree names
that cause and the operator step (the pkgmgr release) instead of a bare
"Kein Tree"; with pkgmgr 2.4.0 released the timer writes the file.
37. **Resources**: a tab Ressourcen shows charts on the shared time axis:
tokens per agent and accumulated (from the usage fields of the session
transcripts), and CPU, RAM, disk and load of the host, sampled by a host
unit into the state directory; several values per chart.
38. **Order of phase 6**: serial subtrees, each in its own worktree under
`kvb-org-robot`, merged into master before the next starts: S1 fixes
(fit, rename once, radio, squelch, tree cause) → S2 popups and search →
S3 faces → S4 night commands → S5 Tasks with asks and choices → S6
Firewall → S7 Resources.
## Approach
@@ -173,6 +254,41 @@ flowchart TD
VF -- "👍 fits" --> D1["🏁 Full gate, commit with operator OK, push hand-over"]
```
Phases 5 and 6 (decisions 23 to 38):
```mermaid
flowchart TD
subgraph W["🧩 5 · Inbox, UI, Hierarchie, Tasks"]
W1["🛠️ W1 to W4 in own worktrees"] --> W2["🕵️ Skeptic round, fix round per worktree"]
W2 --> W3{"🧪 Suite, e2e, MEDUSA, score green?"}
W3 -- "🔴 no: fix" --> W2
W3 -- "🟢 yes" --> W4["🔀 Rebase on master, commit, merge one by one"]
end
W4 --> L1
subgraph L["👂 6.0 · Listen and record"]
L1["❓ kvb-think-listen: names, Firewall writes, choices, groups"] --> L2["📋 Decisions 24 to 38 in this file on master"]
end
L2 --> S1
subgraph S["🤖 6.1 to 6.7 · Serial subtrees under kvb-org-robot"]
S1["🩹 S1 fit, rename once, radio, squelch, tree cause"] --> S2["🪟 S2 agent and node popups, search"]
S2 --> S3["🙂 S3 animated faces"]
S3 --> S4["🌙 S4 drain, suspend, resume"]
S4 --> S5["🗳️ S5 Tasks with asks and choices"]
S5 --> S6["🧱 S6 Firewall and settings writes"]
S6 --> S7["📈 S7 Ressourcen charts"]
end
subgraph G["🔁 Each subtree"]
G1["🔴 Red tests"] --> G2["🛠️ Change"]
G2 --> G3{"🧪 Suite, e2e, MEDUSA, score green?"}
G3 -- "🔴 no: fix" --> G2
G3 -- "🟢 yes" --> G4["📸 Screenshots 1920 / 1366 / 390 px"]
G4 --> GF{"💬 Operator feedback?"}
GF -- "✏️ changes" --> G2
GF -- "👍 fits" --> G5["🔀 Commit, merge into master, next subtree"]
end
S7 --> D2["🏁 install-skills-master row, push hand-over"]
```
## Acceptance Criteria
### Radio model
@@ -370,6 +486,85 @@ flowchart TD
- [ ] Every icon element has a `title` and an `aria-label` that carry the
former text (DOM test over every page).
### Phase 5: inbox, UI, Hierarchie, Tasks
- [ ] A deny is refused by the hub unless its passkey proof verifies; the
PermissionRequest hook quotes a deny reason only when it verifies.
- [ ] A rule, also one an agent requested, is stored only with a passkey
assertion the hub verified against the pinned keys.
- [ ] `operator_message(id, text, to)` answers `match` only for a verified
proof whose signed text and recipient equal the arguments.
- [ ] The offices unit and the runner stay off while the installed
`council.py`, `nofollow.py` or `rasci.py` differ from the tree.
- [ ] `rasci.py agents order` writes only `agent-order.json` and no `--prio`.
- [ ] W1 to W4 are merged into master, each commit with its score block.
### Phase 6: fixes (S1)
- [ ] `#agents/orbit` at 1920, 1366 and 390 px has
`document.documentElement.scrollHeight <= innerHeight` (e2e probe).
- [ ] Two state builds with the same claims add no second rename event to
the Stream (unit test on the timeline).
- [ ] The Deutschlandfunk AAC stream plays in Chromium and Firefox through
the radio (e2e with a recorded fixture of its redirect chain) and the
root cause is named in the commit message.
- [ ] With squelch at 0 no beep plays, music on or off (unit test on the
audio scheduler).
- [ ] Without a tree file the Tree names the missing `pkgmgr branch tree`
and the release step.
### Phase 6: popups and search (S2)
- [ ] A click on an agent opens the popup with a fade; Escape and a click
outside close it; the Details side panel no longer exists.
- [ ] A click on a node enlarges it, marks it red and draws a leader line to
a translucent popup; a second click elsewhere restores the node.
- [ ] A search field with suggestions replaces the node chip list; no view
renders more than one chip per search hit.
### Phase 6: faces (S3)
- [ ] The face generator yields at least 1000 distinct attribute
combinations and the same face for the same agent id (unit test).
- [ ] A speaking agent's face animates its mouth; a silent one does not
(DOM test on the class while the radio plays).
### Phase 6: night commands (S4)
- [ ] `kvb-org-drain`, `kvb-org-suspend`, `kvb-org-resume`,
`kvb-agent-drain`, `kvb-agent-suspend` and `kvb-agent-resume` exist;
the old six names exist nowhere in the tree except in the migration
and `kvb-skill-cleanup` history (grep test).
- [ ] The Steuerung menu shows Drain, Suspend and Resume and each needs the
passkey, like the board actions today.
### Phase 6: Tasks with asks and choices (S5)
- [ ] Every pending ask, rule request, operator row and choice card shows in
the Tasks tab under "waits on Operator"; no Choices column exists.
- [ ] Each channel button sends the fixed choice request with no text field;
`post` and `call` take a multi-select of agents.
- [ ] A click on a choice option sends a passkey-signed answer the agent can
check with `operator_message`.
### Phase 6: Firewall (S6)
- [ ] The tab is called Firewall and lists hub rules, allow and deny
patterns and the settings permissions, grouped by tool and prefix as
read from the settings files.
- [ ] A rule or rule set applies to one agent, a named group or all agents.
- [ ] A settings change is written only by the host executor after the
passkey check, only to a listed file, with a backup beside it; a forged,
replayed or unlisted-file job changes nothing (unit tests).
### Phase 6: Ressourcen (S7)
- [ ] The tab shows tokens per agent and accumulated, and CPU, RAM, disk and
load, on the shared time axis, several values per chart.
- [ ] Token counts equal the sum of the transcript usage fields of a fixture
(unit test); host samples come from the host unit's file, not from the
container.
### Tests
- **Unit**
@@ -384,6 +579,8 @@ flowchart TD
item and a branch name with pattern characters are each refused.
- [ ] Orchestrator: the scratch-HOME migration, routing including old
hashes, badge counts.
- [ ] Phase 6: rename-once timeline, squelch scheduler, face generator,
settings writer (forged, replayed, unlisted file), token sums.
- **Integration**
- [ ] Two scratch sessions exchange `post` and `call` through the real hook
entry points (JSON on stdin): the post appears only on the callee's
@@ -403,3 +600,6 @@ flowchart TD
Stream.
- [ ] On fixture data it shows the state icons in the Artifacts Tree and
runs the delete flow: dry-run dialog, signature, result.
- [ ] Phase 6: no page scrollbar on any view, agent and node popups,
choice request and signed answer, Firewall settings diff and
signature, Ressourcen charts, each at 1920, 1366 and 390 px.