self-tasking engine: persistent queue, idle-impulse + follow-up generators, approval mode
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# SPEC-005 — Self-tasking
|
||||
|
||||
The sigmoid "boreness" loop becomes a persistent task queue (schema
|
||||
v5): generators propose, a scheduler executes — through the normal
|
||||
responder path, so every SAF gate, quota and kill-switch applies.
|
||||
**Default off** (`tasks-enabled`, kitchen stays quiet unless opted
|
||||
in); generators are individually selectable per persona
|
||||
(`tasks-generators`). Marked experimental per plan v4.
|
||||
|
||||
### TSK-01 — Tasks are persistent queue rows (coverage: test)
|
||||
|
||||
A task is a store row: kind, channel, due-at, payload (the prompt the
|
||||
responder will run), state (`queued`/`approval`/`done`/`cancelled`/
|
||||
`failed`). Enqueued tasks survive restarts.
|
||||
|
||||
### TSK-02 — Due tasks run through the responder path (coverage: test)
|
||||
|
||||
The scheduler executes due queued tasks as system messages via the
|
||||
normal respond flow (inheriting budget, gates, envelope), marks them
|
||||
`done`/`failed`, and records the outcome as an observation so memory
|
||||
learns what the bot did on its own.
|
||||
|
||||
### TSK-03 — Off by default (coverage: test)
|
||||
|
||||
Without `tasks-enabled = true` nothing is generated and nothing is
|
||||
executed. A restaurant server does not improvise unless asked to.
|
||||
|
||||
### TSK-04 — Per-channel daily cap (coverage: test)
|
||||
|
||||
At most `tasks-max-per-channel-per-day` (default 2) task executions
|
||||
per channel per day, counted in the ledger; further due tasks stay
|
||||
queued for the next day.
|
||||
|
||||
### TSK-05 — Approval mode (coverage: test)
|
||||
|
||||
With `tasks-approval = true`, generated tasks enter state `approval`
|
||||
and a staff alert announces them; `!bot task-approve <id>` moves them
|
||||
to the queue, `!bot task-cancel <id>` kills them (works for queued
|
||||
tasks too). Staged-rollout path from the review.
|
||||
|
||||
### TSK-06 — Kill-switches govern execution (coverage: test)
|
||||
|
||||
Task execution respects `bot_initiated_allowed()` — `!bot tasks off`,
|
||||
pause, quiet mode and quiet hours all stop the scheduler tick.
|
||||
|
||||
### TSK-07 — Idle-impulse generator (boreness, demoted) (coverage: test)
|
||||
|
||||
When the chat channel has been idle longer than
|
||||
`idle-impulse-hours` (default 12), the generator enqueues one
|
||||
impulse task with the configured boreness prompt — deterministic
|
||||
threshold instead of the old 7-second sigmoid dice loop, bounded by
|
||||
TSK-04. The `on_boreness` loop is gone.
|
||||
|
||||
### TSK-08 — Follow-up generator proposes from memory (coverage: test)
|
||||
|
||||
Periodically (`taskgen-interval-hours`, default 6) the follow-up
|
||||
generator asks `memory-model` (strict structured outputs) whether the
|
||||
recent episodes/facts warrant one follow-up task (channel, prompt,
|
||||
due-in-hours). A null/failed proposal enqueues nothing.
|
||||
@@ -62,6 +62,12 @@ Bot-initiated posts also respect pause/quiet.
|
||||
`!bot pins` answers with all pinned facts and their ids (global +
|
||||
per-channel) — without it, `!bot unpin <id>` required guessing ids.
|
||||
|
||||
### OPS-12 — Task queue surface (coverage: test)
|
||||
|
||||
`!bot tasks` lists open tasks (queued + awaiting approval) with ids;
|
||||
`!bot task-approve <id>` and `!bot task-cancel <id>` manage them
|
||||
(TSK-05). `!bot tasks on|off` stays the kill-switch (OPS-09).
|
||||
|
||||
### OPS-10 — Spend report (coverage: test)
|
||||
|
||||
`!bot spend` answers in the staff channel with today's estimated
|
||||
|
||||
Reference in New Issue
Block a user