feat(#1167): hive-wide knowledge repo — forge, local clone, bind-mount, webhook

This commit is contained in:
damocles 2026-06-03 18:39:47 +02:00 committed by mara
commit 41befe3839
6 changed files with 276 additions and 0 deletions

View file

@ -55,6 +55,11 @@ const SHARED_ORG: &str = "internal";
/// The shared docs repo inside `SHARED_ORG`. Cloneable by every agent
/// at `{FORGE_HTTP}/internal/docs.git`.
const SHARED_DOCS_REPO: &str = "docs";
/// The hive-wide knowledge repo inside `SHARED_ORG`. Bind-mounted
/// read-only into every container at `/hive-knowledge`. Agents
/// contribute by forking + opening PRs; direct writes to main are
/// not granted. See `hive-c0re/src/knowledge.rs`.
const KNOWLEDGE_REPO: &str = crate::knowledge::REPO;
/// Forgejo orgs hive-c0re ensures on startup. The meta repo lives at
/// `core/meta` (the `core` user's own namespace — no org needed).
const SEEDED_ORGS: &[&str] = &[CONFIG_ORG, SHARED_ORG];
@ -606,6 +611,34 @@ pub async fn shared_docs_access(name: &str, core_token: &str) -> Result<()> {
}
}
/// Ensure the `internal/hive-knowledge` repo exists. Called once at
/// startup after `ensure_org(SHARED_ORG)`. Idempotent — `ensure_org_repo`
/// treats 409 as success.
pub async fn ensure_knowledge_repo(core_token: &str) -> Result<()> {
ensure_org_repo(SHARED_ORG, KNOWLEDGE_REPO, core_token).await
}
/// Grant agent `name` read-only collaborator access to
/// `internal/hive-knowledge`. Agents read documents from the bind-mounted
/// clone and contribute by forking + opening PRs — no write to main.
/// Idempotent: HTTP 204 (already a collaborator) is treated as success.
pub async fn knowledge_access(name: &str, core_token: &str) -> Result<()> {
let url = format!(
"{FORGE_HTTP}/api/v1/repos/{SHARED_ORG}/{KNOWLEDGE_REPO}/collaborators/{name}"
);
let body = r#"{"permission":"read"}"#;
let status = forge_http(reqwest::Method::PUT, &url, core_token, body).await?;
match status.as_u16() {
204 => {
tracing::info!(%name, "forge: granted hive-knowledge read access");
Ok(())
}
other => anyhow::bail!(
"PUT {SHARED_ORG}/{KNOWLEDGE_REPO}/collaborators/{name} returned HTTP {other}"
),
}
}
/// Grant agent `name` read-only collaborator access to `core/meta` on
/// the forge so the agent can clone/fetch the meta flake. Idempotent:
/// HTTP 204 (already a collaborator) is treated as success.
@ -785,6 +818,13 @@ pub async fn sync_agent(name: &str, core_token: Option<&str>) {
{
tracing::warn!(%name, error = ?e, "forge: shared_docs_access failed");
}
// Grant read-only access to internal/hive-knowledge so the agent can
// read the bind-mounted knowledge repo and fork it to open PRs.
if let Some(token) = core_token
&& let Err(e) = knowledge_access(name, token).await
{
tracing::warn!(%name, error = ?e, "forge: knowledge_access failed");
}
}
/// Sweep every existing container (manager + sub-agents) and ensure
@ -823,6 +863,14 @@ pub async fn ensure_all() {
if let Err(e) = ensure_shared_docs_repo(token).await {
tracing::warn!(error = ?e, "forge: ensure_shared_docs_repo failed");
}
// Seed the hive-wide knowledge repo.
if let Err(e) = ensure_knowledge_repo(token).await {
tracing::warn!(error = ?e, "forge: ensure_knowledge_repo failed");
}
// Clone knowledge repo locally so it can be bind-mounted into agents.
if let Err(e) = crate::knowledge::ensure_local_clone(token).await {
tracing::warn!(error = ?e, "knowledge: ensure_local_clone failed");
}
if let Err(e) = ensure_core_avatar(token).await {
tracing::warn!(error = ?e, "forge: ensure_core_avatar failed");
}