chore: scrub #NNN issue references from code comments and nix descriptions
Part of the docs-migration chore (issue #708). Remove GitHub issue numbers from inline comments, option descriptions, and rustdoc — these are contextless noise for anyone reading the code without access to the original discussions. Replace with prose that captures the same rationale directly. No functional change. Build still clean (cargo check passes).
This commit is contained in:
parent
083a100ba1
commit
188f3ea5ec
18 changed files with 131 additions and 151 deletions
|
|
@ -1,8 +1,7 @@
|
||||||
// SharedWorker that holds ONE EventSource per stream URL and fans
|
// SharedWorker that holds ONE EventSource per stream URL and fans
|
||||||
// every server-sent event out to every connected tab via MessagePort.
|
// every server-sent event out to every connected tab via MessagePort.
|
||||||
//
|
//
|
||||||
// Problem this solves (#448 — mara: "firefox disconnects bc of too
|
// Problem this solves: every dashboard / agent tab opens its own
|
||||||
// many tabs"): every dashboard / agent tab opens its own
|
|
||||||
// `EventSource('/dashboard/stream')`. Browsers cap concurrent
|
// `EventSource('/dashboard/stream')`. Browsers cap concurrent
|
||||||
// connections per host (~6), and Firefox throttles / disconnects
|
// connections per host (~6), and Firefox throttles / disconnects
|
||||||
// background tabs when many are open. The result: tabs silently
|
// background tabs when many are open. The result: tabs silently
|
||||||
|
|
@ -29,7 +28,7 @@
|
||||||
// re-sync after a reconnect gap.
|
// re-sync after a reconnect gap.
|
||||||
// { kind: 'message', url: '...', data: '<raw SSE data string>' }
|
// { kind: 'message', url: '...', data: '<raw SSE data string>' }
|
||||||
// { kind: 'error', url: '...' } relayed from EventSource.onerror.
|
// { kind: 'error', url: '...' } relayed from EventSource.onerror.
|
||||||
// { kind: 'ping' } #515: heartbeat — fired every
|
// { kind: 'ping' } heartbeat — fired every
|
||||||
// PING_INTERVAL_MS to every
|
// PING_INTERVAL_MS to every
|
||||||
// connected port. The client's
|
// connected port. The client's
|
||||||
// watchdog uses these as
|
// watchdog uses these as
|
||||||
|
|
|
||||||
|
|
@ -475,7 +475,7 @@ window.marked = marked;
|
||||||
// `/agent/<name>/` URLs instead of the direct `http://<host>:<port>/`
|
// `/agent/<name>/` URLs instead of the direct `http://<host>:<port>/`
|
||||||
// TCP fallback — the gateway proxies the prefix to the per-agent
|
// TCP fallback — the gateway proxies the prefix to the per-agent
|
||||||
// harness (TCP via `agent-ports.json` or unix-domain via
|
// harness (TCP via `agent-ports.json` or unix-domain via
|
||||||
// `agent-sockets.json` per #784 / #815). See
|
// `agent-sockets.json`). See
|
||||||
// `docs/web-ui.md::Container row` + `docs/gateway.md::Vhost map`.
|
// `docs/web-ui.md::Container row` + `docs/gateway.md::Vhost map`.
|
||||||
const gatewayLinks = !!(s && s.gateway_enabled);
|
const gatewayLinks = !!(s && s.gateway_enabled);
|
||||||
const ul = el('ul', { class: 'containers' });
|
const ul = el('ul', { class: 'containers' });
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,7 @@ use crate::lifecycle::{self, MANAGER_NAME};
|
||||||
/// either runs the work inline (`InitConfig`, sub-second git ops) or
|
/// either runs the work inline (`InitConfig`, sub-second git ops) or
|
||||||
/// enqueues it into `rebuild_queue` so the dashboard POST returns
|
/// enqueues it into `rebuild_queue` so the dashboard POST returns
|
||||||
/// immediately while the long-running pipeline runs off-thread
|
/// immediately while the long-running pipeline runs off-thread
|
||||||
/// (closes #436 — operator no longer eats a 30-90s spinner on
|
/// (operator no longer blocks on a 30-90s spinner for `ApplyCommit`).
|
||||||
/// `ApplyCommit`).
|
|
||||||
///
|
///
|
||||||
/// Dispatch:
|
/// Dispatch:
|
||||||
/// - `ApplyCommit` → `QueueKind::Rebuild` (~30-90s wall time)
|
/// - `ApplyCommit` → `QueueKind::Rebuild` (~30-90s wall time)
|
||||||
|
|
@ -103,9 +102,9 @@ pub async fn approve(coord: Arc<Coordinator>, id: i64) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Worker entry point for `ApprovalKind::ApplyCommit` queue entries.
|
/// Worker entry point for `ApprovalKind::ApplyCommit` queue entries.
|
||||||
/// Re-fetches the approval row, runs the commit pipeline (same
|
/// Re-fetches the approval row, runs the commit pipeline, and fires
|
||||||
/// shape as the pre-#436 inline path), and fires `ApprovalResolved`
|
/// `ApprovalResolved` + the lifecycle event (`Rebuilt` / `Spawned`
|
||||||
/// + the lifecycle event (`Rebuilt` / `Spawned` for first-spawn).
|
/// for first-spawn).
|
||||||
pub async fn run_approval_apply_commit(
|
pub async fn run_approval_apply_commit(
|
||||||
coord: &Arc<Coordinator>,
|
coord: &Arc<Coordinator>,
|
||||||
queue_entry_id: Option<u64>,
|
queue_entry_id: Option<u64>,
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ pub const SOCKET_FILENAME: &str = "web.sock";
|
||||||
/// sub-agent that hasn't flipped the option yet.
|
/// sub-agent that hasn't flipped the option yet.
|
||||||
///
|
///
|
||||||
/// Renamed from `.bound` (legacy) to match the `hyperhive-` prefix
|
/// Renamed from `.bound` (legacy) to match the `hyperhive-` prefix
|
||||||
/// convention for all harness-written state files (#838). `build_map`
|
/// convention for all harness-written state files. `build_map`
|
||||||
/// checks both names during the transition window so existing containers
|
/// checks both names during the transition window so existing containers
|
||||||
/// don't lose gateway routing before their next rebuild.
|
/// don't lose gateway routing before their next rebuild.
|
||||||
pub const READY_MARKER: &str = "hyperhive-socket-bound";
|
pub const READY_MARKER: &str = "hyperhive-socket-bound";
|
||||||
|
|
|
||||||
|
|
@ -526,8 +526,8 @@ impl Broker {
|
||||||
/// ids the harness pulled via `recv_batch`) and `requeue_inflight`
|
/// ids the harness pulled via `recv_batch`) and `requeue_inflight`
|
||||||
/// (which puts inflight-but-unacked rows BACK on the queue). This
|
/// (which puts inflight-but-unacked rows BACK on the queue). This
|
||||||
/// is the destructive "drain everything for this agent" path the
|
/// is the destructive "drain everything for this agent" path the
|
||||||
/// dashboard surfaces as the side-panel "mark all read" button
|
/// dashboard surfaces as the side-panel "mark all read" button.
|
||||||
/// (#559). Backs `POST /api/agent/{name}/mark-all-read`.
|
/// Backs `POST /api/agent/{name}/mark-all-read`.
|
||||||
pub fn mark_all_read(&self, recipient: &str) -> Result<u64> {
|
pub fn mark_all_read(&self, recipient: &str) -> Result<u64> {
|
||||||
let mut inflight = self.inflight.lock().unwrap();
|
let mut inflight = self.inflight.lock().unwrap();
|
||||||
let conn = self.conn.lock().unwrap();
|
let conn = self.conn.lock().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,7 @@ pub enum DashboardEvent {
|
||||||
/// immediately and runs the `nix flake update` + agent-rebuild
|
/// immediately and runs the `nix flake update` + agent-rebuild
|
||||||
/// ripple in a background task — this event lets the META INPUTS
|
/// ripple in a background task — this event lets the META INPUTS
|
||||||
/// panel show a disabled "updating…" state for that whole window
|
/// panel show a disabled "updating…" state for that whole window
|
||||||
/// instead of looking idle (issue #259). Emitted by
|
/// instead of looking idle. Emitted by
|
||||||
/// `Coordinator::meta_update_guard` / `MetaUpdateGuard::drop` only
|
/// `Coordinator::meta_update_guard` / `MetaUpdateGuard::drop` only
|
||||||
/// when the active-run count crosses 0, so concurrent updates flip
|
/// when the active-run count crosses 0, so concurrent updates flip
|
||||||
/// the flag exactly once.
|
/// the flag exactly once.
|
||||||
|
|
@ -198,8 +198,8 @@ impl DashboardEvent {
|
||||||
/// Snake-case identifier matching this variant's serde `tag`
|
/// Snake-case identifier matching this variant's serde `tag`
|
||||||
/// (e.g. `Sent` → `"sent"`, `ContainerStateChanged` →
|
/// (e.g. `Sent` → `"sent"`, `ContainerStateChanged` →
|
||||||
/// `"container_state_changed"`). Lets `/dashboard/stream`'s
|
/// `"container_state_changed"`). Lets `/dashboard/stream`'s
|
||||||
/// `?kinds=` filter (#408) decide whether to forward a frame
|
/// `?kinds=` filter decide whether to forward a frame without
|
||||||
/// without paying the JSON-serialise cost first.
|
/// paying the JSON-serialise cost first.
|
||||||
///
|
///
|
||||||
/// Keep in sync with `#[serde(rename_all = "snake_case", tag =
|
/// Keep in sync with `#[serde(rename_all = "snake_case", tag =
|
||||||
/// "kind")]` on `DashboardEvent` — if a new variant lands above,
|
/// "kind")]` on `DashboardEvent` — if a new variant lands above,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//! Pre-apply validation for agent `flake.lock` files (closes part of #317).
|
//! Pre-apply validation for agent `flake.lock` files.
|
||||||
//!
|
//!
|
||||||
//! Every `request_apply_commit` lands a `proposal/<id>` tag in the
|
//! Every `request_apply_commit` lands a `proposal/<id>` tag in the
|
||||||
//! agent's applied repo before the operator sees the approval. We
|
//! agent's applied repo before the operator sees the approval. We
|
||||||
|
|
@ -8,11 +8,10 @@
|
||||||
//! directive in `flake.nix` and would inflate meta's lock with
|
//! directive in `flake.nix` and would inflate meta's lock with
|
||||||
//! duplicates after deploy.
|
//! duplicates after deploy.
|
||||||
//!
|
//!
|
||||||
//! Per mara's scope note on #317 (comment 4189): the check runs on
|
//! The check runs on the agent repo, not meta, and catches *new*
|
||||||
//! the agent repo, not meta, and catches *new* violations only.
|
//! violations only. Existing agents whose lock already has duplicates
|
||||||
//! Existing agents whose lock already has duplicates are out of
|
//! are out of scope here and get a coordinated config-change pass via
|
||||||
//! scope here and get a coordinated config-change pass via the
|
//! the manager instead.
|
||||||
//! manager instead.
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
//! sockets, background sweepers. `hivectl` (sibling bin under
|
//! sockets, background sweepers. `hivectl` (sibling bin under
|
||||||
//! `src/bin/hivectl.rs`) reuses a thin subset (`forge`, `matrix`,
|
//! `src/bin/hivectl.rs`) reuses a thin subset (`forge`, `matrix`,
|
||||||
//! `lifecycle`) to expose host-side administration verbs — manually
|
//! `lifecycle`) to expose host-side administration verbs — manually
|
||||||
//! provisioning forge / matrix users for an agent, etc. (#655).
|
//! provisioning forge / matrix users for an agent, etc.
|
||||||
//!
|
//!
|
||||||
//! Every module is re-exported `pub` so anything in the crate is
|
//! Every module is re-exported `pub` so anything in the crate is
|
||||||
//! addressable from either binary; the lib doesn't have a curated
|
//! addressable from either binary; the lib doesn't have a curated
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ pub fn check_size(label: &str, body: &str) -> Result<(), String> {
|
||||||
/// scrolling chunk.
|
/// scrolling chunk.
|
||||||
pub const STATUS_MAX_CHARS: usize = 200;
|
pub const STATUS_MAX_CHARS: usize = 200;
|
||||||
|
|
||||||
/// Validate a `set_status` payload (#720). Single-line + bounded so
|
/// Validate a `set_status` payload. Single-line + bounded so
|
||||||
/// callers can't dump multi-paragraph session reports into the
|
/// callers can't dump multi-paragraph session reports into the
|
||||||
/// dashboard chip. Whitespace trim is done by the caller before the
|
/// dashboard chip. Whitespace trim is done by the caller before the
|
||||||
/// store-to-disk step — we run validation on the trimmed form so
|
/// store-to-disk step — we run validation on the trimmed form so
|
||||||
|
|
@ -70,8 +70,7 @@ pub fn check_status_text(text: &str) -> Result<(), String> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
// Newline / carriage-return: status is a single-line chip on the
|
// Newline / carriage-return: status is a single-line chip on the
|
||||||
// dashboard. A multi-line argus session report is the canonical
|
// dashboard. Multi-line session reports should go to a state file.
|
||||||
// failure mode from #720.
|
|
||||||
if trimmed.contains('\n') || trimmed.contains('\r') {
|
if trimmed.contains('\n') || trimmed.contains('\r') {
|
||||||
return Err(
|
return Err(
|
||||||
"set_status text must be a single line — write multi-line context to \
|
"set_status text must be a single line — write multi-line context to \
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ pub async fn sync_agents(
|
||||||
// the gateway picks up at runtime without needing a
|
// the gateway picks up at runtime without needing a
|
||||||
// nixos-rebuild. The gateway container bind-mounts
|
// nixos-rebuild. The gateway container bind-mounts
|
||||||
// /var/lib/hyperhive/ and a systemd path unit fires
|
// /var/lib/hyperhive/ and a systemd path unit fires
|
||||||
// `nginx -s reload` when this file changes (#869). Same
|
// `nginx -s reload` when this file changes. Same
|
||||||
// best-effort + non-fatal shape.
|
// best-effort + non-fatal shape.
|
||||||
if let Err(e) = crate::gateway_nginx::write(&agent_names) {
|
if let Err(e) = crate::gateway_nginx::write(&agent_names) {
|
||||||
tracing::warn!(error = ?e, "gateway_nginx::write failed (non-fatal)");
|
tracing::warn!(error = ?e, "gateway_nginx::write failed (non-fatal)");
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
||||||
HostRequest::SetParent { child, new_parent } => {
|
HostRequest::SetParent { child, new_parent } => {
|
||||||
tracing::info!(%child, ?new_parent, "set_parent");
|
tracing::info!(%child, ?new_parent, "set_parent");
|
||||||
// `reparent_with_notify` wraps `topology::set_parent`
|
// `reparent_with_notify` wraps `topology::set_parent`
|
||||||
// with the three notification messages (#743) + the
|
// with the three notification messages + the
|
||||||
// ContainerView rescan. Idempotent same-parent calls
|
// ContainerView rescan. Idempotent same-parent calls
|
||||||
// skip both the messages and the disk write per the
|
// skip both the messages and the disk write per the
|
||||||
// topology fast-path.
|
// topology fast-path.
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ let
|
||||||
# Filter to a set of top-level subtree roots — keeps the rendered docs
|
# Filter to a set of top-level subtree roots — keeps the rendered docs
|
||||||
# focused on hyperhive's surface instead of NixOS's 10k+ default
|
# focused on hyperhive's surface instead of NixOS's 10k+ default
|
||||||
# options. Root choice matters: see docs/gotchas.md::Nix options
|
# options. Root choice matters: see docs/gotchas.md::Nix options
|
||||||
# reference for the post-#615 services.hyperhive consolidation history.
|
# reference for the services.hyperhive consolidation history.
|
||||||
pickSubtrees =
|
pickSubtrees =
|
||||||
options: roots:
|
options: roots:
|
||||||
let
|
let
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ in
|
||||||
canonical readable identity. Exposed to agents as
|
canonical readable identity. Exposed to agents as
|
||||||
`HYPERHIVE_HIVE_NAME`; surfaced in the dashboard chrome and
|
`HYPERHIVE_HIVE_NAME`; surfaced in the dashboard chrome and
|
||||||
per-agent system prompt when set. Null falls back to the
|
per-agent system prompt when set. Null falls back to the
|
||||||
pre-#701 behaviour (chrome shows the domain, prompt doesn't
|
default behaviour (chrome shows the domain, prompt doesn't
|
||||||
mention a hive name).
|
mention a hive name).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
@ -141,7 +141,7 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
hyperhive workspace package. Provides `/bin/hive-c0re`
|
hyperhive workspace package. Provides `/bin/hive-c0re`
|
||||||
(coordinator daemon + admin-socket CLI) and `/bin/hivectl`
|
(coordinator daemon + admin-socket CLI) and `/bin/hivectl`
|
||||||
(operator-facing host CLI for ad-hoc administration; #655).
|
(operator-facing host CLI for ad-hoc administration).
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
frontend = lib.mkOption {
|
frontend = lib.mkOption {
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ let
|
||||||
hyperhiveDomain = config.services.hyperhive.domain;
|
hyperhiveDomain = config.services.hyperhive.domain;
|
||||||
|
|
||||||
# ROOT_URL forgejo advertises in clone links + outbound URLs. When
|
# ROOT_URL forgejo advertises in clone links + outbound URLs. When
|
||||||
# served behind the gateway (#749 — mara verdict at issue:9609,
|
# served behind the gateway, `cfg.domain` doubles as both the
|
||||||
# sub-domain over sub-path), `cfg.domain` doubles as both the
|
|
||||||
# forgejo `DOMAIN` setting AND the gateway vhost server-name, so
|
# forgejo `DOMAIN` setting AND the gateway vhost server-name, so
|
||||||
# ROOT_URL just uses it directly (drops the port suffix when the
|
# ROOT_URL just uses it directly (drops the port suffix when the
|
||||||
# gateway is on the canonical port 80). When direct (gateway off
|
# gateway is on the canonical port 80). When direct (gateway off
|
||||||
|
|
@ -83,18 +82,16 @@ in
|
||||||
Public hostname for the forge. Doubles as both the forgejo
|
Public hostname for the forge. Doubles as both the forgejo
|
||||||
`DOMAIN` setting (clone URLs forgejo advertises) AND the
|
`DOMAIN` setting (clone URLs forgejo advertises) AND the
|
||||||
gateway vhost server-name when `behindGateway = true`
|
gateway vhost server-name when `behindGateway = true`
|
||||||
(#749, mara verdict at issue:9609 — sub-domain over sub-path).
|
(sub-domain routing — see `docs/gateway.md`).
|
||||||
|
|
||||||
Defaults to `forge.''${services.hyperhive.domain}` when the
|
Defaults to `forge.''${services.hyperhive.domain}` when the
|
||||||
hive-domain is set (idiomatic sub-domain shape — `forge`
|
hive-domain is set (idiomatic sub-domain shape — `forge`
|
||||||
labelled under the hive's bare domain), falling back to
|
labelled under the hive's bare domain), falling back to
|
||||||
`localhost` otherwise (pre-#749 direct-on-port behaviour).
|
`localhost` otherwise (direct-on-port behaviour).
|
||||||
|
|
||||||
Set to a full hostname (`git.example.com`,
|
Set to a full hostname (`git.example.com`,
|
||||||
`forge.internal.lan`, etc.) for a bespoke vhost shape — the
|
`forge.internal.lan`, etc.) for a bespoke vhost shape — the
|
||||||
full domain goes here, no separate sub-domain-label option
|
full domain goes here, no separate sub-domain-label option.
|
||||||
(mara on #754:9684 — "specify full forge domain in options
|
|
||||||
instead").
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -120,8 +117,7 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Serve forgejo through the hive-gateway nginx as a sub-domain
|
Serve forgejo through the hive-gateway nginx as a sub-domain
|
||||||
vhost (`server_name = cfg.domain`) instead of directly on
|
vhost (`server_name = cfg.domain`) instead of directly on
|
||||||
`httpPort` (#749, mara verdict at issue:9609 — sub-domain
|
`httpPort` (sub-domain routing — see `docs/gateway.md`).
|
||||||
over sub-path).
|
|
||||||
|
|
||||||
When `true`:
|
When `true`:
|
||||||
- The gateway adds a `server { server_name = ''${cfg.domain}; }`
|
- The gateway adds a `server { server_name = ''${cfg.domain}; }`
|
||||||
|
|
@ -137,11 +133,10 @@ in
|
||||||
gateway is running (e.g. an external git client that doesn't
|
gateway is running (e.g. an external git client that doesn't
|
||||||
traverse the gateway).
|
traverse the gateway).
|
||||||
|
|
||||||
The mara-call on #749:9609 picks sub-domain over sub-path for
|
Sub-domain routing is the preferred shape for forge + matrix
|
||||||
forge + matrix (both are external standard apps with sub-domain-
|
(both are external standard apps with sub-domain-native config
|
||||||
native config defaults). Per-agent UIs stay on sub-path
|
defaults). Per-agent UIs stay on sub-path (`/agent/<name>/`)
|
||||||
(`/agent/<name>/`) because they're hyperhive-internal +
|
because they're hyperhive-internal + already base-path-aware.
|
||||||
already base-path-aware via #731.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -171,18 +166,18 @@ in
|
||||||
example = true;
|
example = true;
|
||||||
description = ''
|
description = ''
|
||||||
Open `httpPort` + `sshPort` in the host firewall. Off by
|
Open `httpPort` + `sshPort` in the host firewall. Off by
|
||||||
default (#651, secure-by-default): the forge is reachable
|
default (secure-by-default): the forge is reachable from the
|
||||||
from the host + every agent container via `localhost` either
|
host + every agent container via `localhost` either way
|
||||||
way (shared netns), so the firewall opens only matter for
|
(shared netns), so the firewall opens only matter for access
|
||||||
access from outside the host. Flip to `true` when you want
|
from outside the host. Flip to `true` when you want the
|
||||||
the operator's browser / external git clients to hit the
|
operator's browser / external git clients to hit the forge
|
||||||
forge directly. (The container shares host netns, so this
|
directly. (The container shares host netns, so this is the
|
||||||
is the only firewall layer that matters.)
|
only firewall layer that matters.)
|
||||||
|
|
||||||
**Breaking change as of #651**: this used to default to
|
**Breaking change**: this used to default to `true`. If you
|
||||||
`true`. If you relied on the old default for external
|
relied on the old default for external reach, add
|
||||||
reach, add `services.hyperhive.forge.openFirewall = true;`
|
`services.hyperhive.forge.openFirewall = true;` to your host
|
||||||
to your host config before rebuilding.
|
config before rebuilding.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -117,20 +117,19 @@ in
|
||||||
(`@argus:<server_name>`) and room ID minted on this
|
(`@argus:<server_name>`) and room ID minted on this
|
||||||
homeserver. CRITICAL: must be stable from day one because
|
homeserver. CRITICAL: must be stable from day one because
|
||||||
it's embedded irrevocably in the identifiers. Defaults to
|
it's embedded irrevocably in the identifiers. Defaults to
|
||||||
`services.hyperhive.domain` (the bare hive domain — per mara
|
`services.hyperhive.domain` (the bare hive domain). Combined
|
||||||
on #660). Combined with the `.well-known/matrix/{client,server}`
|
with the `.well-known/matrix/{client,server}` routes the
|
||||||
routes the hive-gateway serves at that domain (also #660),
|
hive-gateway serves at that domain, clients auto-discover the
|
||||||
clients auto-discover the actual matrix endpoint without
|
actual matrix endpoint without needing a subdomain. Override
|
||||||
needing a subdomain. Override here only if you need a
|
here only if you need a different server_name shape (e.g.
|
||||||
different server_name shape (e.g. `matrix.<domain>` if you
|
`matrix.<domain>` if you want the subdomain split, or
|
||||||
want the subdomain split, or `chat.example.org` for a
|
`chat.example.org` for a bespoke hostname).
|
||||||
bespoke hostname).
|
|
||||||
|
|
||||||
**Breaking change as of #660**: this used to default to
|
**Breaking change**: this used to default to
|
||||||
`matrix.''${services.hyperhive.domain}`. matrix IDs embed
|
`matrix.''${services.hyperhive.domain}`. matrix IDs embed
|
||||||
the server_name irrevocably, so existing homeservers must
|
the server_name irrevocably, so existing homeservers must
|
||||||
set `services.hyperhive.matrix.serverName = "matrix.''${services.hyperhive.domain}";`
|
set `services.hyperhive.matrix.serverName = "matrix.''${services.hyperhive.domain}";`
|
||||||
explicitly to preserve their pre-#660 user / room IDs
|
explicitly to preserve their existing user / room IDs
|
||||||
before rebuilding.
|
before rebuilding.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
@ -160,15 +159,15 @@ in
|
||||||
description = ''
|
description = ''
|
||||||
Public hostname for the matrix homeserver behind the gateway.
|
Public hostname for the matrix homeserver behind the gateway.
|
||||||
Defaults to `matrix.''${services.hyperhive.domain}` (sub-domain
|
Defaults to `matrix.''${services.hyperhive.domain}` (sub-domain
|
||||||
shape per mara on #749:9609). Set to `null` to skip the gateway
|
shape — see `docs/gateway.md`). Set to `null` to skip the
|
||||||
vhost (tuwunel stays direct on `httpPort`). See
|
gateway vhost (tuwunel stays direct on `httpPort`). See
|
||||||
`docs/gateway.md` for the vhost map + matrix discovery flow,
|
`docs/gateway.md` for the vhost map + matrix discovery flow,
|
||||||
and the federation port-8448 caveat at the bottom of that doc.
|
and the federation port-8448 caveat at the bottom of that doc.
|
||||||
|
|
||||||
Note: `gatewayHost` is the API listener hostname (where nginx
|
Note: `gatewayHost` is the API listener hostname (where nginx
|
||||||
proxies `/_matrix/*`); `serverName` is the matrix-identifier
|
proxies `/_matrix/*`); `serverName` is the matrix-identifier
|
||||||
domain embedded irrevocably in user/room IDs (per #660
|
domain embedded irrevocably in user/room IDs (default = bare
|
||||||
default = bare hive-domain). The two are distinct.
|
hive-domain). The two are distinct.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -177,18 +176,18 @@ in
|
||||||
default = false;
|
default = false;
|
||||||
example = true;
|
example = true;
|
||||||
description = ''
|
description = ''
|
||||||
Open `httpPort` in the host firewall. Off by default (#651,
|
Open `httpPort` in the host firewall. Off by default
|
||||||
secure-by-default): the homeserver is reachable from the
|
(secure-by-default): the homeserver is reachable from the
|
||||||
host + every agent container via `localhost` either way
|
host + every agent container via `localhost` either way
|
||||||
(shared netns), so the firewall open only matters for
|
(shared netns), so the firewall open only matters for access
|
||||||
access from outside the host. Flip to `true` when announcing
|
from outside the host. Flip to `true` when announcing the
|
||||||
the homeserver to other hives or when an external matrix
|
homeserver to other hives or when an external matrix client
|
||||||
client needs to reach the client-server API directly.
|
needs to reach the client-server API directly.
|
||||||
|
|
||||||
**Breaking change as of #651**: this used to default to
|
**Breaking change**: this used to default to `true`. If you
|
||||||
`true`. If you relied on the old default for external reach,
|
relied on the old default for external reach, add
|
||||||
add `services.hyperhive.matrix.openFirewall = true;` to
|
`services.hyperhive.matrix.openFirewall = true;` to your host
|
||||||
your host config before rebuilding.
|
config before rebuilding.
|
||||||
|
|
||||||
Note: federation (the matrix-spec well-known port 8448) is
|
Note: federation (the matrix-spec well-known port 8448) is
|
||||||
intentionally not opened here. tuwunel serves the federation
|
intentionally not opened here. tuwunel serves the federation
|
||||||
|
|
@ -260,8 +259,8 @@ in
|
||||||
type = lib.types.package;
|
type = lib.types.package;
|
||||||
default = fluffychat-web-fixed;
|
default = fluffychat-web-fixed;
|
||||||
defaultText = lib.literalMD ''
|
defaultText = lib.literalMD ''
|
||||||
`pkgs.fluffychat-web` + #685 `postInstall` patch (adds the
|
`pkgs.fluffychat-web` with a `postInstall` patch that adds
|
||||||
three files `flutter341.buildFlutterApplication` skips).
|
the three files `flutter341.buildFlutterApplication` skips.
|
||||||
'';
|
'';
|
||||||
description = ''
|
description = ''
|
||||||
Static web client dist served at `matrix.<hive>/`. Override
|
Static web client dist served at `matrix.<hive>/`. Override
|
||||||
|
|
@ -275,9 +274,9 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
# serverName must exist (mara on #548 — irrevocably embedded in
|
# serverName must exist (irrevocably embedded in user/room IDs);
|
||||||
# user/room IDs); gatewayHost may not be "" (argus 🟡 on #764 —
|
# gatewayHost may not be "" (same footgun as forge.domain —
|
||||||
# same footgun as forge.domain). docs/matrix.md::Assertion
|
# nginx rejects an empty server_name). docs/matrix.md::Assertion
|
||||||
# rationale.
|
# rationale.
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
|
|
@ -307,9 +306,9 @@ in
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
# Activation-time token generation (argus #565: the bind-mount
|
# Activation-time token generation — without this the bind-mount
|
||||||
# would otherwise hand tuwunel an empty file on first boot and
|
# would hand tuwunel an empty file on first boot and break every
|
||||||
# break every registration until restart). Idempotent;
|
# registration until restart. Idempotent;
|
||||||
# docs/matrix.md::Provisioning flow.
|
# docs/matrix.md::Provisioning flow.
|
||||||
system.activationScripts.hive-matrix-register-token = lib.stringAfter [ "var" ] ''
|
system.activationScripts.hive-matrix-register-token = lib.stringAfter [ "var" ] ''
|
||||||
tokenFile=${lib.escapeShellArg (toString cfg.registrationTokenFile)}
|
tokenFile=${lib.escapeShellArg (toString cfg.registrationTokenFile)}
|
||||||
|
|
@ -358,13 +357,13 @@ in
|
||||||
# LoadCredential below copies the host file into a
|
# LoadCredential below copies the host file into a
|
||||||
# 0400 dynamic-user-owned path; tuwunel reads from there.
|
# 0400 dynamic-user-owned path; tuwunel reads from there.
|
||||||
registration_token_file = "/run/credentials/tuwunel.service/registration_token";
|
registration_token_file = "/run/credentials/tuwunel.service/registration_token";
|
||||||
# E2EE disabled in initial rollout (#548); re-enable at #551.
|
# E2EE disabled in initial rollout; tracked in the issue tracker.
|
||||||
allow_encryption = false;
|
allow_encryption = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
# Keeps DynamicUser=true + PrivateUsers=true intact — no
|
# Keeps DynamicUser=true + PrivateUsers=true intact — no
|
||||||
# host-side chown :tuwunel / GID-pin gymnastics needed (#644 /
|
# host-side chown :tuwunel / GID-pin gymnastics needed.
|
||||||
# iris on 8043). See `man systemd.exec` → LoadCredential.
|
# See `man systemd.exec` → LoadCredential.
|
||||||
systemd.services.tuwunel.serviceConfig.LoadCredential = [
|
systemd.services.tuwunel.serviceConfig.LoadCredential = [
|
||||||
"registration_token:${toString cfg.registrationTokenFile}"
|
"registration_token:${toString cfg.registrationTokenFile}"
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{ pkgs, lib }:
|
{ pkgs, lib }:
|
||||||
# hive-forge — Forgejo CLI wrapper for hyperhive (closes #280).
|
# hive-forge — Forgejo CLI wrapper for hyperhive.
|
||||||
#
|
#
|
||||||
# Previously a ~600-line bash script. Rewritten as a proper Rust
|
# Previously a ~600-line bash script. Rewritten as a proper Rust
|
||||||
# binary in `/hive-forge` so we get:
|
# binary in `/hive-forge` so we get:
|
||||||
|
|
@ -7,8 +7,7 @@
|
||||||
# reading the case statement),
|
# reading the case statement),
|
||||||
# - one reqwest client with consistent error surfaces (no more
|
# - one reqwest client with consistent error surfaces (no more
|
||||||
# `curl --fail-with-body` repeated per verb),
|
# `curl --fail-with-body` repeated per verb),
|
||||||
# - sane shell quoting (no more HEREDOC-eaten-by-positional traps
|
# - sane shell quoting (no more HEREDOC-eaten-by-positional traps),
|
||||||
# like #379),
|
|
||||||
# - and a single test surface.
|
# - and a single test surface.
|
||||||
#
|
#
|
||||||
# This Nix file is now a thin extractor: it pulls just the
|
# This Nix file is now a thin extractor: it pulls just the
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
# Agent user metadata (#658). `userName` defaults to `"agent"` when
|
# Agent user metadata. `userName` defaults to `"agent"` when the
|
||||||
# the meta-flake doesn't inject the per-agent override (stand-alone
|
# meta-flake doesn't inject the per-agent override (stand-alone
|
||||||
# `nixos-rebuild` against `nixosConfigurations.agent-base` works
|
# `nixos-rebuild` against `nixosConfigurations.agent-base` works
|
||||||
# without erroring on a missing per-agent name). `homeDir` derives
|
# without erroring on a missing per-agent name). `homeDir` derives
|
||||||
# from `userName` to keep them coupled.
|
# from `userName` to keep them coupled.
|
||||||
|
|
@ -29,7 +29,7 @@ in
|
||||||
# only opts in from its own `agent.nix`.
|
# only opts in from its own `agent.nix`.
|
||||||
imports = [ ./weston-vnc.nix ];
|
imports = [ ./weston-vnc.nix ];
|
||||||
|
|
||||||
# Per-agent unix user the harness + co-process daemons run as (#658).
|
# Per-agent unix user the harness + co-process daemons run as.
|
||||||
# Defaults to `"agent"` so a standalone evaluation (e.g.
|
# Defaults to `"agent"` so a standalone evaluation (e.g.
|
||||||
# `nix flake check` against `nixosConfigurations.agent-base`) builds
|
# `nix flake check` against `nixosConfigurations.agent-base`) builds
|
||||||
# cleanly; the meta-flake's per-agent module rebinds this to the
|
# cleanly; the meta-flake's per-agent module rebinds this to the
|
||||||
|
|
@ -83,22 +83,17 @@ in
|
||||||
When `true`, set `HIVE_WEB_SOCKET=/run/hive-agent/${userName}/web.sock`
|
When `true`, set `HIVE_WEB_SOCKET=/run/hive-agent/${userName}/web.sock`
|
||||||
on the harness service env, which makes `web_ui::serve` bind a
|
on the harness service env, which makes `web_ui::serve` bind a
|
||||||
`UnixListener` at that path instead of the legacy TCP listener
|
`UnixListener` at that path instead of the legacy TCP listener
|
||||||
on `HIVE_PORT`. Closes the third hop of the #784 rollout: PR
|
on `HIVE_PORT`.
|
||||||
#800 added the harness-side opt-in, #809 / #813 added the c0re
|
|
||||||
bind-mount + JSON-map plumbing, this is the per-agent flip
|
|
||||||
that activates the unix-domain path.
|
|
||||||
|
|
||||||
Default `false` so an agent's web UI keeps binding TCP until
|
Default `false` so an agent's web UI keeps binding TCP until
|
||||||
the per-agent flip is explicit. Rollout shape:
|
the per-agent flip is explicit. Rollout shape:
|
||||||
|
|
||||||
1. flip one canary agent (atlas volunteered) to `true` via its
|
1. flip one canary agent to `true` via its `agent.nix`;
|
||||||
`agent.nix` once #813 lands;
|
|
||||||
2. validate the gateway's `proxy_pass http://unix:.../web.sock`
|
2. validate the gateway's `proxy_pass http://unix:.../web.sock`
|
||||||
end-to-end against that canary (atlas's step 3);
|
end-to-end against that canary;
|
||||||
3. flip remaining agents per-agent as the gateway side soaks;
|
3. flip remaining agents per-agent as the gateway side soaks;
|
||||||
4. eventually drop this option once every agent's on unix +
|
4. eventually drop this option once every agent is on unix and
|
||||||
atlas's gateway is the only path — step 4 of #784 drops the
|
the TCP fallback is removed from the harness.
|
||||||
harness's TCP fallback at the same time.
|
|
||||||
|
|
||||||
Sub-agent-only by design: the manager's UI serves at `/` via
|
Sub-agent-only by design: the manager's UI serves at `/` via
|
||||||
the c0re dashboard upstream, not via `/agent/<name>/`, so this
|
the c0re dashboard upstream, not via `/agent/<name>/`, so this
|
||||||
|
|
@ -128,9 +123,6 @@ in
|
||||||
it's exposed so a standalone `nixos-rebuild` against
|
it's exposed so a standalone `nixos-rebuild` against
|
||||||
`nixosConfigurations.manager` keeps working without the
|
`nixosConfigurations.manager` keeps working without the
|
||||||
meta-flake wrapper around it.
|
meta-flake wrapper around it.
|
||||||
|
|
||||||
Closes #671: harness + manager templates merged into a
|
|
||||||
single `harness-base.nix` driven by this option.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -267,8 +259,8 @@ in
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = ''
|
description = ''
|
||||||
Enable per-agent matrix integration via `hive-matrix-mcp`
|
Enable per-agent matrix integration via `hive-matrix-mcp`.
|
||||||
(#548 phase 3). When true (the default), the harness:
|
When true (the default), the harness:
|
||||||
|
|
||||||
- runs `hive-matrix-daemon` as a systemd unit that holds a
|
- runs `hive-matrix-daemon` as a systemd unit that holds a
|
||||||
matrix-sdk Client + sync against the homeserver at
|
matrix-sdk Client + sync against the homeserver at
|
||||||
|
|
@ -276,8 +268,8 @@ in
|
||||||
in-host tuwunel from `nix/modules/hive-matrix.nix`). The
|
in-host tuwunel from `nix/modules/hive-matrix.nix`). The
|
||||||
daemon auto-skips when `<state>/matrix-token` is missing,
|
daemon auto-skips when `<state>/matrix-token` is missing,
|
||||||
and a `systemd.paths` watcher restarts it the moment
|
and a `systemd.paths` watcher restarts it the moment
|
||||||
hive-c0re provisions the token (mirrors `matrix-avatar-sync`
|
hive-c0re provisions the token (same path-trigger shape
|
||||||
shape from #571).
|
as `matrix-avatar-sync`).
|
||||||
- exposes the matrix tool surface (send_message, send_dm,
|
- exposes the matrix tool surface (send_message, send_dm,
|
||||||
send_reaction, send_reply, mark_read, list_rooms,
|
send_reaction, send_reply, mark_read, list_rooms,
|
||||||
list_room_members, read_room) to claude via an auto-injected
|
list_room_members, read_room) to claude via an auto-injected
|
||||||
|
|
@ -577,9 +569,8 @@ in
|
||||||
# all contributions across modules into one file. Loaded via
|
# all contributions across modules into one file. Loaded via
|
||||||
# `$BASH_ENV` for non-interactive shells (claude's `Bash` tool
|
# `$BASH_ENV` for non-interactive shells (claude's `Bash` tool
|
||||||
# runs `bash -c`) and via `programs.bash.interactiveShellInit`
|
# runs `bash -c`) and via `programs.bash.interactiveShellInit`
|
||||||
# for interactive shells. Generic by design (mara on #779) so
|
# for interactive shells. Generic by design so future hooks
|
||||||
# future hooks don't need to either rename this file or invent
|
# don't need to rename this file or invent a parallel dispatcher.
|
||||||
# a parallel dispatcher.
|
|
||||||
options.hyperhive._bashEnvFragments = lib.mkOption {
|
options.hyperhive._bashEnvFragments = lib.mkOption {
|
||||||
type = lib.types.lines;
|
type = lib.types.lines;
|
||||||
default = "";
|
default = "";
|
||||||
|
|
@ -606,7 +597,7 @@ in
|
||||||
anything else) invokes `cargo` inside this container.
|
anything else) invokes `cargo` inside this container.
|
||||||
Saves tokens + context — the verbose default output floods
|
Saves tokens + context — the verbose default output floods
|
||||||
the response window with per-crate progress lines that
|
the response window with per-crate progress lines that
|
||||||
carry no signal beyond the warning/error summary (#777).
|
carry no signal beyond the warning/error summary.
|
||||||
|
|
||||||
Implementation: contributes a `cargo` shell function to
|
Implementation: contributes a `cargo` shell function to
|
||||||
`/etc/hyperhive/bash-env.sh` (see `hyperhive._bashEnvFragments`).
|
`/etc/hyperhive/bash-env.sh` (see `hyperhive._bashEnvFragments`).
|
||||||
|
|
@ -742,10 +733,10 @@ in
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
# Post-#658 first-boot migration to the per-agent unix user —
|
# First-boot migration to the per-agent unix user — creates the
|
||||||
# creates the home dir, chowns the bind-mounted state +
|
# home dir, chowns the bind-mounted state + `~/.claude/`, and
|
||||||
# `~/.claude/`, and (marker-guarded) moves any leftover
|
# (marker-guarded) moves any leftover `/root/.claude` content
|
||||||
# `/root/.claude` content from the pre-#658 root-run shape. See
|
# from the previous root-run shape. See
|
||||||
# `docs/persistence.md::First-boot agent-user migration` for the
|
# `docs/persistence.md::First-boot agent-user migration` for the
|
||||||
# step-by-step rationale; this script implements it.
|
# step-by-step rationale; this script implements it.
|
||||||
system.activationScripts.hive-agent-user-migrate = lib.stringAfter [ "users" "specialfs" ] ''
|
system.activationScripts.hive-agent-user-migrate = lib.stringAfter [ "users" "specialfs" ] ''
|
||||||
|
|
@ -772,8 +763,8 @@ in
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Auto-inject the matrix MCP entry when matrix is enabled (#548
|
# Auto-inject the matrix MCP entry when matrix is enabled.
|
||||||
# phase 3). Operator can override or disable by setting their own
|
# Operator can override or disable by setting their own
|
||||||
# `extraMcpServers.matrix` (nix submodule merge takes the operator's
|
# `extraMcpServers.matrix` (nix submodule merge takes the operator's
|
||||||
# value) or by flipping `hyperhive.matrix.enable = false`.
|
# value) or by flipping `hyperhive.matrix.enable = false`.
|
||||||
hyperhive.extraMcpServers = lib.mkIf config.hyperhive.matrix.enable {
|
hyperhive.extraMcpServers = lib.mkIf config.hyperhive.matrix.enable {
|
||||||
|
|
@ -781,9 +772,9 @@ in
|
||||||
command = "${pkgs.hyperhive}/bin/hive-matrix-mcp";
|
command = "${pkgs.hyperhive}/bin/hive-matrix-mcp";
|
||||||
args = [ ];
|
args = [ ];
|
||||||
# Same socket path the hive-matrix-daemon service binds
|
# Same socket path the hive-matrix-daemon service binds
|
||||||
# via its `RuntimeDirectory = "hive-matrix"` (#658). Keeps
|
# via its `RuntimeDirectory = "hive-matrix"`. Keeps the
|
||||||
# the bridge + daemon in sync without baking the new path
|
# bridge + daemon in sync without baking the path into
|
||||||
# into the Rust default — the env override wins for both.
|
# the Rust default — the env override wins for both.
|
||||||
env.HIVE_MATRIX_SOCKET = "/run/hive-matrix/socket";
|
env.HIVE_MATRIX_SOCKET = "/run/hive-matrix/socket";
|
||||||
allowedTools = [ "*" ];
|
allowedTools = [ "*" ];
|
||||||
};
|
};
|
||||||
|
|
@ -798,18 +789,18 @@ in
|
||||||
source = config.hyperhive.icon;
|
source = config.hyperhive.icon;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Cargo `--message-format short` injector (#777). Contributes a
|
# Cargo `--message-format short` injector. Contributes a `cargo`
|
||||||
# `cargo` shell function to `hyperhive._bashEnvFragments`; the
|
# shell function to `hyperhive._bashEnvFragments`; the bash-env
|
||||||
# bash-env infrastructure below packages that into a single file
|
# infrastructure below packages that into a single file sourced
|
||||||
# sourced by both non-interactive and interactive shells.
|
# by both non-interactive and interactive shells.
|
||||||
# `command cargo …` falls back to the un-wrapped binary in PATH
|
# `command cargo …` falls back to the un-wrapped binary in PATH
|
||||||
# (the rust toolchain's cargo — either from `environment.systemPackages`
|
# (the rust toolchain's cargo — either from `environment.systemPackages`
|
||||||
# or from whatever `nix develop` shell the agent's working in).
|
# or from whatever `nix develop` shell the agent's working in).
|
||||||
hyperhive._bashEnvFragments = lib.mkIf config.hyperhive.cargo.shortMessages ''
|
hyperhive._bashEnvFragments = lib.mkIf config.hyperhive.cargo.shortMessages ''
|
||||||
# Auto-injects --message-format short on cargo compile
|
# Auto-injects --message-format short on cargo compile
|
||||||
# subcommands so per-crate progress lines don't flood
|
# subcommands so per-crate progress lines don't flood
|
||||||
# claude's context (#777). Bypassed when the caller
|
# claude's context. Bypassed when the caller already passes
|
||||||
# already passes --message-format (any form).
|
# --message-format (any form).
|
||||||
cargo() {
|
cargo() {
|
||||||
# Strip leading +toolchain selectors (cargo +nightly …).
|
# Strip leading +toolchain selectors (cargo +nightly …).
|
||||||
local pre=()
|
local pre=()
|
||||||
|
|
@ -915,7 +906,7 @@ in
|
||||||
# feature hook's snippet into scope without touching
|
# feature hook's snippet into scope without touching
|
||||||
# `/etc/profile` (login-only). Interactive shells source the
|
# `/etc/profile` (login-only). Interactive shells source the
|
||||||
# same file via the `interactiveShellInit` hook below so
|
# same file via the `interactiveShellInit` hook below so
|
||||||
# behaviour matches across both modes (#777).
|
# behaviour matches across both modes.
|
||||||
BASH_ENV = "/etc/hyperhive/bash-env.sh";
|
BASH_ENV = "/etc/hyperhive/bash-env.sh";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1185,9 +1176,9 @@ in
|
||||||
fi
|
fi
|
||||||
TOKEN=$(cat "$TOKEN_FILE")
|
TOKEN=$(cat "$TOKEN_FILE")
|
||||||
# Local tuwunel reachable on shared host netns at the
|
# Local tuwunel reachable on shared host netns at the
|
||||||
# default matrix-spec port. Override via the future
|
# default matrix-spec port. Override via
|
||||||
# `hyperhive.matrix.url` if the operator ever runs the
|
# `hyperhive.matrix.url` if the operator runs the
|
||||||
# homeserver elsewhere (deferred to #548 phase 4).
|
# homeserver elsewhere.
|
||||||
MATRIX_URL=http://localhost:8008
|
MATRIX_URL=http://localhost:8008
|
||||||
# whoami → user_id. Needed to scope the avatar set call.
|
# whoami → user_id. Needed to scope the avatar set call.
|
||||||
# Tolerant of the homeserver being unreachable (`-f` makes
|
# Tolerant of the homeserver being unreachable (`-f` makes
|
||||||
|
|
@ -1320,13 +1311,13 @@ in
|
||||||
HIVE_ROLE = config.hyperhive.role;
|
HIVE_ROLE = config.hyperhive.role;
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs config.hyperhive.web.useUnixSocket {
|
// lib.optionalAttrs config.hyperhive.web.useUnixSocket {
|
||||||
# Per-agent unix-socket flip for the web UI (#784 phase 2
|
# Per-agent unix-socket path for the web UI. When set,
|
||||||
# step 2c). When set, the harness's `web_ui::serve` binds
|
# the harness's `web_ui::serve` binds a `UnixListener`
|
||||||
# a `UnixListener` at this path instead of TCP. Path
|
# at this path instead of TCP. Path matches
|
||||||
# matches `hive_c0re::agent_sockets::socket_path_for(name)`
|
# `hive_c0re::agent_sockets::socket_path_for(name)` so
|
||||||
# so the lifecycle bind-mount (#813) and the gateway's
|
# the lifecycle bind-mount and the gateway's upstream
|
||||||
# upstream config all derive from the same canonical
|
# config all derive from the same canonical
|
||||||
# `/run/hive-agent/<name>/web.sock` shape — no triangulation.
|
# `/run/hive-agent/<name>/web.sock` shape.
|
||||||
HIVE_WEB_SOCKET = "/run/hive-agent/${userName}/web.sock";
|
HIVE_WEB_SOCKET = "/run/hive-agent/${userName}/web.sock";
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs isManager {
|
// lib.optionalAttrs isManager {
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
# effect unconditionally — any Wayland client launched by any
|
# effect unconditionally — any Wayland client launched by any
|
||||||
# systemd service in this container automatically connects to
|
# systemd service in this container automatically connects to
|
||||||
# this compositor instead of failing or starting a second
|
# this compositor instead of failing or starting a second
|
||||||
# isolated display. Closes #540 (double-screen: VNC shows blank
|
# isolated display (fixes double-screen: VNC showing blank
|
||||||
# weston desktop while services render on a different seat).
|
# weston desktop while services render on a different seat).
|
||||||
exec ${pkgs.weston}/bin/weston \
|
exec ${pkgs.weston}/bin/weston \
|
||||||
--config="$WESTON_INI" \
|
--config="$WESTON_INI" \
|
||||||
|
|
@ -118,13 +118,13 @@
|
||||||
# container so Wayland clients (e.g. bitburner started via
|
# container so Wayland clients (e.g. bitburner started via
|
||||||
# `systemd.services.*` in agent.nix) can find the compositor
|
# `systemd.services.*` in agent.nix) can find the compositor
|
||||||
# without per-service wiring. `systemd.globalEnvironment` is the
|
# without per-service wiring. `systemd.globalEnvironment` is the
|
||||||
# correct path (established by #608 for HYPERHIVE_STATE_DIR) —
|
# correct path — it sets DefaultEnvironment in systemd.conf,
|
||||||
# it sets DefaultEnvironment in systemd.conf, reaching all units
|
# reaching all units started by PID 1. `environment.variables`
|
||||||
# started by PID 1. `environment.variables` goes to /etc/environment
|
# goes to /etc/environment (PAM sessions only) and is NOT visible
|
||||||
# (PAM sessions only) and is NOT visible to systemd service units.
|
# to systemd service units. Without these vars a service starting
|
||||||
# Without these vars a service starting a Wayland client would either
|
# a Wayland client would either fail to connect (libwayland falls
|
||||||
# fail to connect (libwayland falls back to a headless display) or
|
# back to a headless display) or open a second compositor — VNC
|
||||||
# open a second compositor — VNC shows a blank desktop (#540).
|
# shows a blank desktop.
|
||||||
systemd.globalEnvironment = {
|
systemd.globalEnvironment = {
|
||||||
WAYLAND_DISPLAY = "wayland-0";
|
WAYLAND_DISPLAY = "wayland-0";
|
||||||
XDG_RUNTIME_DIR = "/run/user/0";
|
XDG_RUNTIME_DIR = "/run/user/0";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue