Commit graph hyperhive/hive-c0re/src/forge/repos.rs
Author SHA1 Message Date
atlas
44572d1e1a fix(#2911): keep the forge token out of argv
`forge_git_url` spliced `core:<token>@` between scheme and authority, and
that URL is a process argument. `/proc/<pid>/cmdline` is mode 0444 —
world-readable — so the core admin token, which provisions every agent's
forge account, was published to any local user for the lifetime of each
git child. Seven call sites built such a URL.

The credential now travels in the environment instead:
`git_command_authed` sets `http.extraHeader` via `GIT_CONFIG_*`, which
git reads exactly like a config file, and `/proc/<pid>/environ` is 0400 —
owner-only. Same credential, materially smaller audience. The remote is a
plain `http://forge/<org>/<repo>.git`, and `forge_git_url` no longer takes
a token, so the old shape cannot be rebuilt by accident.

`knowledge`'s clone was the one place a credentialed URL was stored as a
named remote — git persists the clone URL into `.git/config`, so the
token sat on disk and every later `pull` authenticated from there. That
is the case `forge::repos::push_config` documents as forbidden ("the
tokenised URL ... deliberately never stored as a named remote"). `pull`
now rewrites `origin` to the plain URL first, which also scrubs the
persisted token from existing deployments, and authenticates from the
environment when a token is available. The repo is public, so the pull
still works without one.

Three call sites also stopped spawning `Command::new("git")` directly,
so they honour the `HYPERHIVE_GIT` path the NixOS module bakes in and
the `kill_on_drop` every other git spawn gets.

The two URL-shape tests now assert the *absence* of a credential, and a
new one decodes the header back to `core:<token>` — without that, a
malformed header would leave every forge operation silently anonymous
with the other assertions still green.
2026-08-02 13:21:42 +02:00
atlas
ff8ada77b7 docs: describe the deploy subtree
Rewrite the approval flow's step 4 as the three phases, with the reason
the rollback state is a git ref, and refresh the coordinator's node
inventory + dispatch table. Fix four doc comments that still pointed at
the deleted `run_merge_config_pr`.
2026-07-25 22:55:02 +02:00
damocles
84b750fba5 refactor(#2302): type socket wire fields as ident, validated by serde on deserialize 2026-07-20 21:46:18 +02:00
damocles
bf644cc126 feat(#2302): thread &Ident through agent path builders 2026-07-20 21:46:18 +02:00
atlas
6a4382bee8 fix(#2570): recognize 422 team-already-exists so operators-team provisioning stops warning
Forgejo returns team-already-exists as HTTP 422 ValidationFailed, not
409 Conflict, so the 409-only guard in ensure_operators_team missed it
and logged a spurious warning every boot (and skipped the settings
reconcile). Add a lenient discriminator that also treats a 422 whose
message says already-exists as benign.
2026-07-19 01:11:19 +02:00
damocles
fc00e38490 fix(#2553): mirror agent-config tags + main as separate pushes so a protected-main reject doesn't drop the status tags 2026-07-17 12:02:05 +02:00
iris
9ea6160c94 sweep: wire gateway-nginx reload + config-repo branch-protection into warning banners
Extends the SweepHealth/warnings registry (already landed for
knowledge_pull) to two more background sweeps:

- gateway_nginx::reload_gateway_nginx: raises a warn-level banner
  immediately on the first failed reload (routing changes silently
  not taking effect is user-visible right now, so no debounce).
- forge::repos::ensure_config_repo: raises a crit-level banner
  listing every agent whose config-repo branch protection is
  currently unapplied (security-relevant — bypasses the deploy
  pipeline), clearing agents out of the message as they recover.

Journal warn!/error! logging is left in place; the registry adds a
dashboard-visible signal on top. forge::ensure_all() and
matrix::ensure_all() sweeps are deliberately left for a fast-follow.
2026-07-16 00:05:29 +02:00
damocles
6e0f6893cf fix(#2393): ff-merge config prs via forge api instead of pushing main 2026-07-13 11:18:43 +02:00
atlas
c222418d76 fix(#2380): push_meta drop --force + dashboard warning for non-fast-forward
If the remote is ahead of our local mirror (non-fast-forward), the old
code used --force which silently destroyed remote history. Fix:

- Drop --force from the git push invocation.
- On non-ff exit, detect the condition and return Ok(()) instead of
  bailing (intentional no-op; leaving remote history intact is correct).
- Raise a persistent dashboard warning banner via crate::warnings so the
  operator sees it in the UI rather than having to grep the journal.
- Clear the banner on the next successful push.

Closes #2380.
2026-07-11 14:33:04 +02:00
damocles
cfb84b420a refactor(#2285): drop coordinator 1:1 path accessors, callers use paths:: directly 2026-07-10 20:32:03 +02:00
damocles
17fa4a3ea5 fix(#2311): verify operator branch protection exists on create error instead of failing open 2026-07-10 12:40:03 +02:00
atlas
e9667f9c1a fix(#2287): reconcile team settings on 409 (upsert via org_edit_team)
On 409 (team already exists), list the org teams to find the operators
team id, then unconditionally PATCH to the desired settings via
org_edit_team. This self-heals a team that was created with the wrong
shape by an older code path (missing units, wrong permission) without
touching membership (separate endpoint, operator-managed).

Addresses mara's review: 'shouldnt we get, then change, then update'.
Unconditional PATCH is simpler than GET→diff→conditional PATCH and safe
here since we own units/permission/description fully.
2026-07-10 02:43:37 +02:00
atlas
beaa220dc2 fix(#2287): use is_conflict (409-only) for team create, supply explicit units 2026-07-10 02:43:37 +02:00
atlas
031edbd41f fix(#1868): use HIVE_FORGE_URL for internal forge calls
Replace the hardcoded FORGE_HTTP const with forge_http_base() which
reads HIVE_FORGE_URL from the environment (already set unconditionally
by hive-c0re.nix to http://<forge.domain>). Add forge_git_url() helper
that inserts core:<token> credentials between scheme and authority for
git push/clone URLs.

All call sites updated:
- forge/mod.rs: api() OnceLock + new forge_git_url/forge_http_base fns
- forge/repos.rs: push_meta, push_config, ensure_meta_remote
- forge/pr_merge.rs: tokenised_repo_url delegate + test loosened
- workers/knowledge.rs: clone + push URLs
- socket_server/mod.rs: clone_url in RepoCreated response

No new env var: HIVE_FORGE_URL was already the right knob (mara).

Closes #1868. Closes #2174 (this supersedes the operators-team fix from
the closed #2218, which is re-applied in the ensure_operators_team call
that was already merged separately).
2026-07-09 00:45:13 +02:00
müde
261f02439b fix(forge): review fixes for the forgejo-api port 2026-07-07 14:42:43 +02:00
müde
b8a3927c43 refactor(hive-c0re): port forge module + knowledge hooks to forgejo-api 2026-07-07 09:11:15 +02:00
müde
a17015f01e refactor(hive-c0re): split forge into submodules
mod.rs keeps the shared admin/http helpers + ensure_all/sync_agent;
user/token provisioning, repo/org/mirror ops, and the trust-boundary
PR-merge primitives move to users.rs / repos.rs / pr_merge.rs
2026-07-06 22:08:22 +02:00