feat(#1167): hive-wide knowledge repo — forge, local clone, bind-mount, webhook
This commit is contained in:
parent
4bb0d7f310
commit
41befe3839
6 changed files with 276 additions and 0 deletions
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue