Requirement 001 phase 6, S5:
- Tasks tab: every pending ask, rule request, operator row and choice
card shows under "waits on Operator"; a choice request goes out on a
fixed channel button, post and call with an agent multi-select, and a
click on an option sends a passkey-signed answer the agent checks with
operator_message. The unsigned /api/decisions/<id>/choose route is
gone, and a decision, choice answer or choice recipient whose name
holds "*" is refused, so a signed answer never reaches every agent.
- Gantt view: one bar per task from start to end (running to now), one
arrow per explicit, branch-base and queue-order edge, hatched forecast
bars (always, points only, real only) from the median duration or
points times median hours per point.
- rasci.py set --after/--drop-after stores task dependencies and refuses
unknown tasks and cycles.
- Estimation toggle (No estimate default, Story points) is stored in the
hub settings; burndown and burnup per whole register, list filter or
one agent or line, counting tasks or summing complexity with the
unestimated tasks as their own line.
- New skill kvb-org-queue-estimate: "Request estimates" (story points
mode, passkey-signed board action) or the skill sends exactly one
newsletter listing every unestimated task with its RASCI parties; a
party name that is no plain name shows as "unnamed party".
- Business value per task or in bulk is stored only with a verified
passkey assertion over the exact ids and values; WSJF uses it instead
of the median. The task list sorts by every decision-50 mode both ways.
- e2e: the walk's pending ask lives an hour instead of 60 s, and the
CDP and BiDi drivers retry removing the browser profile while the
browser exits (ENOTEMPTY).
Evidence: make test 709 OK, ruff and markdownlint clean
(/tmp/s5-make-test-fix-2.log); e2e 26 OK in Chromium and Firefox
(/tmp/s5-e2e-fix-2.log); MEDUSA 50 files, an independent skeptic
rejected four holes (unsigned choose route, unsigned estimates request,
free-text party names, "*" recipients incl. normalizer bypasses), all
fixed and re-verified, the 8 remaining pattern hits accepted, rescan 0
open.
🎯 Fix: 92 %
💥 Break: 4 %
💸 Cost: 100 %
⏱️ Time: –
🛡️ Security: 100 %
🏆 Score: 88
🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 %
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a Tasks tab that lists the kvb-org-rasci register next to the inbox
and the heavy-job queue, in list, board and RASCI matrix views, each
task with its roles, WSJF, open work and the merge flow of its worktree.
- Task priority pins and WSJF estimates are signed with the operator's
passkey and applied by the runner through rasci.py; the hub verifies
the signature itself before it queues a job or logs the change, the
runner verifies it again and runs only the checked argv, from /, with
a pinned PATH and a 30 s process-group limit.
- The runner refuses task changes into a council that is a symlink, not
owned by its uid or given by a relative path, and while the installed
council.py, nofollow.py or rasci.py differ from the tree.
- Only tasks the hub can sign whole are editable (task slug and length).
- Page lookups keyed by register text use Object.hasOwn, so a status or
party named like an Object.prototype member cannot break the views.
- The inbox screen renders through the tasks screen, so its task filter
shows with "Wartet auf Operator" pressed.
Tests: 604 unit tests OK, e2e 15/15 OK (Chromium and Firefox).
🎯 Fix: 93 %
💥 Break: 5 %
💸 Cost: 100 %
⏱️ Time: –
🛡️ Security: 100 %
🏆 Score: 88
🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 %
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>