CI runs `cargo clippy -- -D warnings`, which already failed on main with
four errors predating this branch:
duplicated attribute src/models.rs, src/config.rs
literal with an empty format src/cli_main.rs (x2)
Both structs carried #[allow(dead_code)] twice; dropped the duplicate.
The println! calls moved the literal into the format string as clippy
suggested. No behaviour change -- output is byte-identical.
Kept separate from the feature commit so it can be dropped or landed on
its own.
Adds POST /api/actions/:id/approve and /reject so a notifier (desktop
popup, chat bot, phone) can resolve an action without driving the web UI
or holding a login session.
Auth is the per-action approve_token already minted at submit time: a
UUIDv4 scoped to exactly one action and delivered only in the approval
notification. The agent API key is deliberately NOT accepted on these
routes -- the agent submits actions, so letting it approve them would
defeat the human-in-the-loop guarantee. The token may be supplied in the
JSON body or as ?token=, matching the existing approve link.
Both endpoints return 401 for an unknown id/token and 409 (with the
current status) if the action is no longer pending, so a notifier can
tell "someone else already handled this" from "this failed".
The notification webhook gains a structured "action" object alongside the
existing "text" field, which is unchanged so current consumers keep
working. Previously the id, command and approve URL were only available
by regexing the human-readable blob.
Also collapses three copies of the actions SELECT and its row mapping
onto ACTION_COLUMNS/row_to_action, and extracts the execute and
reject-chain logic into helpers now shared by the web and API handlers.
Those helpers no longer .unwrap() DB errors while holding the connection
mutex, which would poison it for the life of the process.