mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
* fix(board): give Board Program explorers a nothing_to_propose exit Every propose_* verb requires at least one item, so an explorer that legitimately found nothing — Barfly with no worthwhile X conversations, Coroner with no autopsy subject — had no way to close its exploration task. It declined, called i_am_idle(), and the task stayed PENDING forever: the dispatcher re-matched it every tick and respawned the board agent (~$0.61 a spawn, ~3 per 5-minute respawn-breaker cooldown window, indefinitely), and BoardProgramEngine's one-open-cycle dedup wedged that whole program shut, since the ledger row only closes once its exploration task goes terminal. nothing_to_propose(task_id, reason) is the explicit exit. task_id is required rather than inferred: one explorer role owns several independently-cadenced programs (head_marketing owns six) and each assigns its exploration task to the same agent, so several are open at once by design and guessing "the caller's oldest" completes the WRONG cycle — stamping its reason onto an unrelated program's ledger while the task actually being worked stays wedged. Resolution validates the named task exists, carries a registered program source, is assigned to the caller, and is non-terminal, then gates on the program's declared explorer role from the registry, so a program registered later needs no edit here. The reason lands on board_program_cycles (migration 089) and renders into the next cycle's LEARN context, replacing a bare "proposed 0, approved 0" with why. That write runs in its own savepoint: it flushes on the same session as the completion, and a bare try/except around a same-session flush leaves the transaction pending-rollback, so a DB blip there would discard the completion at the post-response commit while the verb reported success. All fourteen exploration prompts offer the exit, pinned by a registry-parametrized test that fails when a future program is unwired. * ci: fire PR checks on slave-based PRs, not master alone All five gating workflows declared `pull_request: branches: [master]`, but every fleet PR targets slave — cell->root, root->slave, and the CEO's own. So `pull_request` never fired for any of them, and their only coverage was the `push` trigger, which is gated on branch PREFIX (feature/bug/chore/docs/hotfix). A branch named anything else got zero checks — not a red run, an absent one — and a PR with no required check present merges on a false green. PR #711 shipped that way on a `fix/` branch. Basing on the branch a PR merges INTO rather than what its head is named makes coverage independent of branch naming, so a non-conforming prefix can only ever cost the redundant push run, never the whole gate. The same five also omitted slave from `push` (ci.yml aside, which added it for the release gate's fail-closed CI read), so the panel suite, both CodeQL analyses, and the e2e smoke never ran on the trunk master is cut from. --------- Co-authored-by: Renn F <rennf93@users.noreply.github.com>
2.0 KiB
2.0 KiB
Verbs available to you (autogenerated source of truth)
Flow verbs
| Verb | Body schema |
|---|---|
i_am_idle |
i_am_idle() |
triage |
triage() |
waive_finding |
waive_finding(finding_id: UUID, note: str) |
Content (do) tools
| Tool | Body schema |
|---|---|
note |
`note(text: str, scope: str = 'note', task_id: UUID |
evidence |
evidence(task_id: UUID) |
dm |
`dm(recipient: str, text: str, task_id: UUID |
read_a2a |
read_a2a(see do_server) |
approve_playbook |
approve_playbook(playbook_id: UUID) |
reject_playbook |
reject_playbook(playbook_id: UUID, reason: str) |
archive_playbook |
archive_playbook(playbook_id: UUID) |
curate_vault |
curate_vault(task_id: UUID, narrative: str) |
propose_postmortem |
`propose_postmortem(incident_summary: str, root_cause: str, failed_stage: str, process_change: ProcessChangeInput, playbook: PostmortemPlaybookInput |
nothing_to_propose |
nothing_to_propose(task_id: UUID, reason: str) |
notify_list |
notify_list(unread_only: bool = True, pending_ack_only: bool = False, limit: int = 20) |
notify_get |
notify_get(notification_id: UUID) |
propose_quality_report |
propose_quality_report(headline: str, items: list[QualityReportItemInput], overall_assessment: str) |
propose_playbook_drafts |
propose_playbook_drafts(drafts: list[PlaybookDraftInput]) |