Commit graph hyperhive/hive-c0re/src/questions.rs
Author SHA1 Message Date
damocles
80f16094f1 hive-sh4re: split inbox, container, journal, and schedule wire shapes into their own modules
Closes the #3110 split — lib.rs is now just the crate doc comment and
the pub mod list.

journal.rs's new doc comment fixes a pre-existing bug: the old
JournalPriority doc text in lib.rs was actually half Capability's doc
(a leftover from an earlier reorder that moved the code but not the
comment above it).
2026-08-10 23:26:15 +02:00
damocles
138f6b6c10 hive-sh4re: split manager-socket constants + HelperEvent into their own topic module 2026-08-10 23:05:18 +02:00
damocles
a80d0b0fed delete c0re-side reminder plumbing (#2635 inc 1 commit 6) 2026-07-23 00:12:30 +02:00
damocles
76647415af type Approval.agent as Ident 2026-07-22 21:10:17 +02:00
müde
34b21b8038 refactor: drop kind_to_str wrapper, call ApprovalKind::as_str directly 2026-07-06 21:49:46 +02:00
damocles
9b2d16ae6a fix(#2190): replace MANAGER_AGENT fallbacks with "operator" for attribution
- loose_ends.rs: NULL submitter on legacy approval rows → "operator"
- questions.rs: NULL submitter on cancel_loose_end → "operator"
- server.rs: HostRequest::RequestSpawn submitter → "operator"
- dashboard.rs: web-UI spawn submitter → "operator"
- socket_server.rs: submit_init_config with no declared parent → "operator"
- mcp.rs: drop MANAGER_AGENT exception from check_send_allowed; keep <parent> only
2026-07-04 18:56:16 +02:00
damocles
ebaf192476 fix(#1953): gate approval cancel on submitter ownership + document submitter_of errors 2026-06-23 22:04:56 +02:00
atlas
53b4e752ef refactor(#1865): replace the privileged flag with topology + capability gating
Per operator direction (no privileged mode; everything is perms /
capabilities), remove the socket-derived `privileged: bool` from the
unified dispatch and gate every verb on the caller's identity instead:

- serve/dispatch/dispatch_shared/dispatch_orchestration + all lifecycle
  handlers drop the `privileged` param.
- lifecycle (start/kill/restart/update/init_config/apply_commit) + get_logs
  gate on `topology::is_descendant_of` (a parent owns its whole subtree; the
  root covers every agent as a consequence, no positional privilege). The
  restart infra-branch stays InfraAdmin-gated (orthogonal).
- agent-state queries (loose-ends / reminder count + rollup): own subtree is
  free, other agents + the hive-wide `"*"` sweep require QueryAgentState.
  require_new_child + resolve_agent_state_target widened direct-child -> subtree.
- hive-wide orchestration verbs gate on the grantable tool-group via
  tool_groups::groups_for: schedules -> `scheduling`, meta-inputs +
  cancel-approval -> `approvals`. update_meta_inputs now attributes the
  approval to the caller, not a hardcoded MANAGER_AGENT.
- #1834 cancel-guard unwind: handle_cancel_loose_end drops `privileged`
  (agent path is never privileged); question/reminder cancels are
  ownership-only, approval cancel checks the `approvals` tool-group.

The manager socket stays as pure transport (serves agent=ruth, no authority
of its own); collapsing it into ruth's per-agent socket is the #1825
follow-up. No is_root here — root-identity primitives are #1825's.
2026-06-22 13:58:52 +02:00
atlas
f5f06a5f14 refactor(#1865): consolidate agent + manager socket servers into one
The per-agent and manager sockets ran two parallel dispatchers with
duplicated lifecycle handlers (agent-side topology-gated, manager-side
ungated) plus a manager-only handler set. Collapse to one parameterized
server in socket_server.rs:

- one serve() + dispatch(req, agent, privileged, coord); start() binds
  the per-agent sockets (privileged=false), start_manager() binds the
  manager socket (privileged=true).
- each lifecycle/config handler (start/restart/kill/update/init_config/
  apply_commit) merges its dual: the topology guard (require_child /
  require_new_child) runs only on the !privileged path; init_config
  records the requester as parent only when !privileged. restart keeps
  the orthogonal, capability-gated + audited infra-container branch.
- the agent-state queries (loose-ends / reminder count + rollup) branch
  on privileged: privileged keeps any-target + the "*" hive-wide sweep
  (query_agent_state-gated), non-privileged keeps the topology/cap gate.
- the privileged-only verbs (schedules / meta-inputs / get_logs) plus
  the submit/schedule/watchdog helpers move into socket_server; they are
  reached via dispatch_privileged_only(), which rejects the whole group
  on a non-privileged socket.
- delete manager_server.rs; repoint refs; merge the test modules.

No behavior change: the topology guard still applies on every
non-privileged lifecycle call, the privileged socket still acts on any
agent, and privileged-only verbs are still rejected on agent sockets.
2026-06-22 13:58:52 +02:00
atlas
53f49615fa refactor(#1834): derive cancel-loose-end privilege from the socket, not the MANAGER_AGENT name
The cancel-loose-end guards (cancel approval / question / reminder)
inferred manager-level privilege by string-matching the canceller
against the hardcoded `hive_sh4re::MANAGER_AGENT` ("ruth"). That laundered
privilege through a name: a request arrives on the privileged manager
socket, gets stamped with the bootstrap agent's name, and the guards
re-derive privilege from that name. Renaming or replacing the bootstrap
agent would then silently move privilege.

Privilege is a property of the SOCKET the request arrived on (the manager
socket is the trust boundary), so thread an explicit `privileged: bool`
through `dispatch_shared` → `handle_cancel_loose_end` → the three guards:

- `Broker::cancel_reminder_as` and `OperatorQuestions::cancel`: the
  `== MANAGER_AGENT` leg becomes `privileged` (owner/asker + operator name
  legs unchanged).
- `check_approval_canceller_is_manager(canceller)` →
  `check_can_cancel_approval(privileged)` (manager-socket-only); unit tests
  updated to assert on the flag.

The manager socket passes `privileged = true`; the agent socket passes
`false`. `MANAGER_AGENT` is still passed as the actor NAME for legitimate
attribution/routing (notifications, schedule ownership, bootstrap
destroy-protection) — those are not privilege checks and are left intact.
Scope is the privilege guards only.
2026-06-22 02:07:14 +02:00
damocles
3130e56cfb refactor(#1474): replace too_many_arguments allows on pub fns with param structs 2026-06-09 11:25:38 +02:00
iris
a1e46e2b3d feat: live SSE updates for the SYST3M reminders section
Add RemindersChanged SSE event so the pending-reminders list in the
SYST3M tab updates live without polling.

Backend emission sites (every path that mutates the reminders table):
- agent_server: store_remind (remind MCP call)
- dashboard.rs: post_cancel_reminder, post_retry_reminder
- questions.rs: cancel_loose_end Reminder kind
- reminder_scheduler: after each delivery batch (any_delivered)

Coordinator gets emit_reminders_snapshot() mirroring the existing
emit_schedules_snapshot() pattern: lists PendingReminder rows from the
broker and emits DashboardEvent::RemindersChanged.

Frontend: applyRemindersChanged(ev) calls renderReminders(ev.reminders)
and is registered as reminders_changed in MUTATION_HANDLERS.

Docs: dashboard.md reminders_changed entry; CLAUDE.md file map updated.
2026-06-05 12:06:32 +02:00
atlas
4bff450343 feat(gateway): hivectl gateway user management + fix htpasswdFile assertion
Add `hivectl gateway {create-user,delete-user,list-users}` subcommands for
managing htpasswd files used by gateway Basic auth. Pure Rust bcrypt
(cost 12, $2y$ prefix nginx accepts). No external htpasswd binary required.

Also fix the NixOS module assertion: `cfg.auth ? htpasswdFile` is always
true in the module system (declared options always exist as keys); switch
to `nullOr path; default = null` + `!= null` check so the assertion
actually fires with a useful error when enable=true but no file is set.
Guard bind-mount and nginx config against null to prevent eval errors.

Update docs/gateway.md to show hivectl commands instead of raw htpasswd.
2026-06-01 23:25:28 +02:00
damocles
2bdb8c7d51 hive-c0re: scrub manager-surface cookies + SetParent doc fix (#715 batch 7) 2026-05-31 17:53:45 +02:00
damocles
402ee95d0c questions: unit-test the manager-only guard on approval cancel (argus nit on #508) 2026-05-27 12:48:30 +02:00
damocles
c1f27e3b7b approvals: manager can withdraw pending approvals (closes #250) 2026-05-27 12:48:30 +02:00
damocles
d8e64742f4 fix question answer sender and self-cancel feedback loop 2026-05-20 20:31:25 +02:00
damocles
6e23d087d2 rename: open_threads → loose_ends + cancel_thread → cancel_loose_end across wire / tools / web ui 2026-05-18 18:24:09 +02:00
damocles
b1d0a62cb9 cancel_thread: new mcp tool — unify reminder + question cancel on both surfaces 2026-05-18 18:24:09 +02:00
müde
a15fafb5de dashboard: surface peer questions + operator override
questions pane now shows both operator-targeted threads
(target IS NULL) and agent-to-agent threads (target = some
agent). filter chips above the list: all / @operator / @peer /
per-participant. peer rows get a mauve left rule + a 0V3RR1D3
button that POSTs the same /answer-question endpoint
(OperatorQuestions::answer already permits the operator as
answerer on any target).

wire changes: OperatorQuestions gains pending_all +
recent_answered_all; QuestionAdded + QuestionResolved events
carry target: Option<String>; emit sites drop their
target.is_none() guard. answered-history rows show the
answerer prefix so override answers are auditable at a glance.
2026-05-17 22:06:53 +02:00
müde
1879b2f485 dashboard: question_added / question_resolved mutation events + client derived state 2026-05-17 13:33:02 +02:00
damocles
82b0877c47 ask: rename ask_operator → ask + optional 'to' for agent-to-agent Q&A 2026-05-17 13:20:32 +02:00