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:
1 parent
4540494c30
commit
1d311a3382
1 file changed
+200
@@ -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.
|
||||
Reference in new issue
Block a user