Commit graph

11 commits

Author SHA1 Message Date
müde
600ed509f4 forge: ensure core/meta repo + mirror meta commits to forge
startup sweep adds ensure_repo('meta', core_token) after the orgs
so the first push isn't a 404. meta::git_commit now calls
forge::push_meta after every successful commit — token-in-URL
`git push http://core:$token@localhost:3000/core/meta.git` —
gated on the core token file existing (no-op when forge isn't
seeded). push failures log warn, don't bubble up.

no tea needed on the host; git is already on the hive-c0re service
PATH via /run/current-system/sw.
2026-05-17 01:52:00 +02:00
müde
411cf86632 nix fmt + rustfmt sweep 2026-05-17 01:40:28 +02:00
müde
266c2c7a77 dashboard: meta flake inputs UI + sequential rebuild loop
new section 'M3T4 1NPUTS' between approvals and message flow:
one row per input in meta/flake.lock (hyperhive first, then
agent-<n> alphabetically). each row shows the input name, the
first 12 chars of the locked sha, a relative timestamp from
locked.lastModified, and the original.url when available.
checkbox per row; submit button is disabled until at least one
box is checked; submitting confirms then POSTs the selected
names to /meta-update.

backend:
- meta::lock_update(inputs: &[String]) — runs 'nix flake update
  <names>' in the meta dir, commits the lock change with a
  combined message ('lock update: hyperhive, agent-coder').
  preserves the existing META_LOCK serialization. existing
  lock_update_for_rebuild / lock_update_hyperhive stay for
  their single-input callers.
- POST /meta-update — comma-separated 'inputs' form field
  (JS joins checkboxes since axum::Form doesn't natively
  decode repeated keys); spawns a background task that runs
  the lock update + per-agent rebuild loop. hyperhive
  selection fans out to all agents; agent-<n> selection only
  rebuilds <n>. each rebuild fires Rebuilt to the manager
  exactly like dashboard / admin-CLI / auto-update.

rebuild loop is sequential — auto_update::run too (was
parallel via tokio::spawn). parallel rebuilds collide on
nix-store's sqlite cache ('sqlite db busy, not using cache')
and the meta META_LOCK contention. nix-daemon serializes the
heavy build steps anyway, so this isn't a throughput loss.
2026-05-16 03:38:07 +02:00
müde
7276e6d5d9 git identity: shorten to 'c0re' across all helpers
lifecycle::GIT_{NAME,EMAIL}, meta::GIT_{NAME,EMAIL}, and the
inline strings migrate.rs uses for its bootstrap commits all
move from 'hive-c0re' / 'hive-c0re@hyperhive' to 'c0re' /
'c0re@hyperhive'. shows up shorter in git log everywhere
(applied + meta repos).
2026-05-16 03:02:44 +02:00
müde
78f21ccc5d meta: serialize all ops behind a tokio mutex + clear stale lock at startup
journal showed three concurrent rebuilds racing on the meta
repo's .git/index.lock — auto_update::run kicks off parallel
tokio::spawn for every stale agent, each rebuild eventually
calls into meta::sync_agents / lock_update_for_rebuild which
do git add + commit, git isn't safe across concurrent processes
on the same .git/, and one of the failing-mid-write children
left index.lock behind. subsequent ops blocked until somebody
rm'd it manually.

fix: static META_LOCK (tokio::sync::Mutex<()>) acquired at the
top of every public meta function. concurrent rebuilds take
turns on meta ops; the actual nix build (nixos-container update)
releases the lock first and runs without it, so parallel agent
builds still parallelize on nix-daemon's own concurrency model.

migrate::run additionally clears /var/lib/hyperhive/meta/.git/
index.lock on startup if it exists — we just booted, nothing
of ours is holding it. covers the 'previous crash left a stale
lock' case the user just hit so the daemon recovers without
manual intervention.
2026-05-16 02:44:39 +02:00
müde
50ef806266 operator pronouns: configurable free-text, threaded into prompts
new NixOS module option services.hive-c0re.operatorPronouns
(free text, default 'she/her', example 'they/them'). hive-c0re
takes it as a CLI flag (--operator-pronouns, lib.escapeShellArg'd
in the systemd unit), stores it on Coordinator, threads it into
the meta flake's mkAgent so each agent's systemd service gets
HIVE_OPERATOR_PRONOUNS set. the harness reads the env at boot
and substitutes {operator_pronouns} into the agent / manager
system prompt alongside {label}. nix string is escaped against
backslash + double-quote so non-ascii / quoted values
round-trip safely. prompt addendum: both agent.md and
manager.md mention the operator's pronouns up front so claude
uses them naturally in third-person reference. propagates on
next ↻ R3BU1LD (meta lock bump, no per-agent approval).
2026-05-16 02:05:22 +02:00
müde
63e8a98df2 meta: stage before lock, single commit per change
git+file://'s dirty-tree fetcher reads tracked + staged content
from the index (not the working tree, not untracked files). so
staging is enough to make a new flake.nix or flake.lock visible
to nix without committing first. sync_agents now stages flake
.nix, runs lock, stages the resulting flake.lock, then commits
both together in a single 'regenerate meta flake' (or 'seed
meta from N agents') commit — no more two-commit churn.

prepare_deploy applies the same trick to the two-phase deploy:
runs nix flake update, stages flake.lock so nixos-container
update sees it, doesn't commit yet. finalize_deploy commits
with the deployed/<id> message on build success; abort_deploy
git-restores the staged lock back to HEAD on failure. meta
history continues to record only successful deploys (and now
one commit per success instead of one + amend).
2026-05-16 01:02:47 +02:00
müde
220e9b4af6 meta: commit before lock — git+file:// only sees tracked files
runtime error on first deploy attempt: 'source tree referenced
by git+file:///var/lib/hyperhive/meta does not contain
/flake.nix'. cause: sync_agents wrote flake.nix then ran
'nix flake lock' against a directory nix had just discovered
as a git repo (auto-upgraded to git+file://), which only sees
TRACKED content. fresh flake.nix was untracked, so nix saw an
empty source tree.

fix: commit flake.nix before locking. sync_agents now does
write → init (if first) → git add + commit → nix flake lock
→ commit lock if changed. two commits per change — one
'regenerate meta flake' and one 'lock update' — instead of
one combined; cleaner history.

same git+file:// gotcha bit the two-phase deploy: prepare_
deploy used to write the lock without committing, expecting
nixos-container update to read the working tree. it doesn't —
it reads the tracked commit. prepare_deploy now commits with
a placeholder 'deploy <n> (building)' message; finalize_deploy
amends to 'deploy <n> deployed/<id> <sha12>' on success;
abort_deploy git-reset --hard HEAD~1's it on failure. meta
history still records only successful deploys.
2026-05-16 00:59:35 +02:00
müde
87c7b05b05 meta: use 'nix flake update <input>' instead of removed --update-input
current nix CLI removed 'nix flake lock --update-input X' in
favour of 'nix flake update X'. switch all three call sites
(prepare_deploy, lock_update_for_rebuild,
lock_update_hyperhive). 'nix flake lock' with no args still
works for the seed path in sync_agents — it resolves missing
inputs without bumping existing ones.
2026-05-16 00:49:22 +02:00
müde
4cb529351e lifecycle::rebuild through meta
rebuild now does sync_agents (idempotent — no-op when the
rendered flake matches disk; recovers from a divergent meta
repo on the side) followed by lock_update_for_rebuild which
relocks just this agent's input and commits the lock change
if any. flake ref for nixos-container update flips from
applied/<n>#default to meta#<name>. new helper
meta::lock_update_for_rebuild is single-phase (no separate
finalize): rebuild has no failure-revert semantics — it always
wants the latest applied/<n>/main. spawn already syncs meta
before container create; rebuild now picks up the meta side
on every manual ↻ R3BU1LD.
2026-05-16 00:28:26 +02:00
müde
92822efe16 meta: new hive-c0re module owns /var/lib/hyperhive/meta/
leaf module with no runtime callers yet (every public item is
#[allow(dead_code)] until lifecycle / actions / auto_update
rewire to use it). API surface:

- sync_agents — idempotent: render flake.nix for the given
  agent set, git-init on first call, nix flake lock, commit if
  anything changed.
- prepare_deploy / finalize_deploy / abort_deploy — two-phase
  for the request_apply_commit path. prepare runs nix flake
  lock --update-input agent-<n> without committing; finalize
  commits with a 'deploy <n> deployed/<id> <sha12>' message;
  abort git-restores the lock so a failed build leaves no
  orphan commit.
- lock_update_hyperhive — one-shot for the auto-update path.

flake.nix template defines mkAgent that pulls each agent's
nixosModules.default from its input and wraps with the
identity / HIVE_PORT / HIVE_LABEL / HIVE_DASHBOARD_PORT
module — what setup_applied used to generate inline. nix
invocations carry --extra-experimental-features as a belt
in case flakes aren't enabled in nix.conf.
2026-05-16 00:22:37 +02:00