From 7d217f82671af13e1e94c686aa1631f820418b04 Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 30 Sep 2026 23:42:15 +0200 Subject: [PATCH] remove the create_repo agent tool mara ruled on #4849 (c88934): "remove create_repo tool". The tool ran in hive-c0re with the hive's core token, so it only ever worked for agents on the hive that runs the forge. Removed: - the create_repo MCP tool and CreateRepoArgs (hive-agent-mcp) - wire variants Request::CreateRepo and Response::RepoCreated (hive-core-agent-sock) - hive-c0re's handle_create_repo, its valid_repo_name check and the dispatch arm - forge::create_agent_repo and apply_operator_branch_protection, which had no other caller, plus AGENTS_ORG and OPERATORS_TEAM, whose only users they were - the tool's docs (docs/tools/forge.md repo management, docs/turn-loop/ mcp.md, the conventions tool-group table) and the doc comments that named it (hive-sock-client's response timeout, ensure_repo_creation_ disabled, the security doc's merge-gate bullet) ToolGroup::Forge is kept with no tools, the same way b88a5b24 kept Lifecycle, so existing meta/capabilities.json grants still parse. Forge state is untouched: existing agents/* repos keep their collaborators and operators-team branch protection. The swarm-controller's own create_repo (config-org repos) is a different path and is unchanged. Closes #4849 --- docs/process/conventions.md | 2 +- docs/tools/forge.md | 15 ++----- docs/trust-boundary/security.md | 8 ++-- docs/turn-loop/mcp.md | 9 +--- hive-agent-mcp/src/mcp/args.rs | 7 --- hive-agent-mcp/src/mcp/mod.rs | 33 ++------------ hive-c0re/src/forge/mod.rs | 21 ++------- hive-c0re/src/forge/repos.rs | 71 +----------------------------- hive-c0re/src/forge/users.rs | 7 ++- hive-c0re/src/socket_server/mod.rs | 41 ----------------- hive-core-agent-sock/src/lib.rs | 13 ------ hive-sh4re/src/permissions.rs | 31 +++++++------ hive-sock-client/src/lib.rs | 4 +- swarm-controller/src/forge.rs | 11 +++-- 14 files changed, 43 insertions(+), 230 deletions(-) diff --git a/docs/process/conventions.md b/docs/process/conventions.md index 7db2237e..dbb69d8e 100644 --- a/docs/process/conventions.md +++ b/docs/process/conventions.md @@ -302,7 +302,7 @@ binary flavor. | `lifecycle` | none — `list_containers` no longer exists, with no replacement; the variant survives only so existing grants parse. | | `approvals` | none — `request_update_meta_inputs` no longer exists, with no replacement. Still a live server-side gate: `cancel_loose_end`'s approval-cancel arm requires it. | | `scheduling` | `request_schedule_prompt`, `fire_schedule_now`, `cancel_schedule`, `edit_schedule`, `list_schedules` *(privileged)* | -| `forge` | `create_repo` — create git repos through hive-c0re (operator-gated merge) | +| `forge` | none — `create_repo` no longer exists, with no replacement; the variant survives only so existing grants parse. | | `web_tools` | none (gates the Claude built-ins `WebFetch`/`WebSearch`, not an MCP tool) | **Always-on tools** — `ToolGroup::ALWAYS_ON_TOOLS` exposes `set_status`, diff --git a/docs/tools/forge.md b/docs/tools/forge.md index 108dfa2d..0e437866 100644 --- a/docs/tools/forge.md +++ b/docs/tools/forge.md @@ -212,18 +212,11 @@ plain comment show under `last comment`, not `reviews`. Agents **can't create repos directly via forge token** — Forgejo disables push-to-create and the agent token doesn't have the Create -scope. Two paths exist depending on where the repo should live: +scope. -**Agent repos (`agents/`)** — Use the `mcp__hyperhive__create_repo` -MCP tool (requires the `forge` tool group). hive-c0re creates the repo in -the c0re-owned `agents/` org, adds you as a write collaborator (not -owner), enables branch protection (operator-team merge approval -required — you can't self-merge), and returns the clone URL immediately. -This is the standard path for agents that need a working repo. - -**Other repos** — Use the CLI verbs below (`repo-create` / `repo-add-collaborator`). -These use the agent's own forge token so the repo lands under the agent's -user account or an org the agent belongs to. +The CLI verbs below (`repo-create` / `repo-add-collaborator`) use the +agent's own forge token, so a repo lands under the agent's user account +or an org the agent belongs to. **`repo-create `** — create a repo under the authenticated user and print its URL. Key flags: diff --git a/docs/trust-boundary/security.md b/docs/trust-boundary/security.md index 29e16635..cf843b05 100644 --- a/docs/trust-boundary/security.md +++ b/docs/trust-boundary/security.md @@ -125,10 +125,10 @@ checkpoints**, not about sandboxing the agent from its own tools: **human (the operator) merges the PR**, keeping a person in the loop on the highest-value action. On the **internal forge this is technically enforced, not just convention**: agents can't create repos (`max_repo_creation = 0`), - so every repo is `core`-created with branch protection **on by default** — - merges restricted to the operators team + a required operators-team approval - (`apply_operator_branch_protection` / the config-repo equivalent) — and an - agent (a write collaborator, not a repo admin) can neither change those + and `main` on an `agent-configs/` repo carries swarm-controller's + branch protection: merge allowlisted to the `operators` team, with one + approval from it. Existing `agents/` repos carry the same merge gate. + An agent (a write collaborator, not a repo admin) can neither change those settings nor merge its own PR. It's **not** set up for external VCS (GitHub etc.), though — there, operator-merge is process + accepted risk, not a technical control. diff --git a/docs/turn-loop/mcp.md b/docs/turn-loop/mcp.md index c54589c7..2db07c13 100644 --- a/docs/turn-loop/mcp.md +++ b/docs/turn-loop/mcp.md @@ -137,13 +137,8 @@ hive_name?, swarm_name?, matrix_accounts? }`. `matrix_accounts` is a [`docs/agent-lifecycle/approvals.md`](../agent-lifecycle/approvals.md). - **Scheduling** (`scheduling`) — scheduled prompts. See [`docs/tools/scheduling.md`](../tools/scheduling.md). -- **Forge repos** (`forge`) — `create_repo` — the only agent path to - create a repo under the `agents/` org (direct forge token creation is - disabled for agents). The repo lands in the c0re-owned `agents` - org; the calling agent gets write collaborator access; the default - branch is branch-protected (operator-team must approve merges, so the - agent can't self-merge). Opt-in; not in any default preset. - See [`docs/tools/forge.md — Repo management`](../tools/forge.md). +- **Forge repos** (`forge`) — carries no MCP tool: `create_repo` no + longer exists, with no replacement; `forge` gates nothing. - **Web egress** (`web_tools`) — enables Claude's built-in `WebFetch` and `WebSearch` tools (not MCP tools; added directly to the `--allowedTools` list). Off by default; add the group in the diff --git a/hive-agent-mcp/src/mcp/args.rs b/hive-agent-mcp/src/mcp/args.rs index 70ab70cb..de4e892e 100644 --- a/hive-agent-mcp/src/mcp/args.rs +++ b/hive-agent-mcp/src/mcp/args.rs @@ -103,13 +103,6 @@ pub struct SetStatusArgs { pub text: String, } -#[derive(Debug, serde::Deserialize, schemars::JsonSchema)] -pub struct CreateRepoArgs { - /// Repo name — a single segment of letters, digits, `-`, `_`, `.` - /// (no leading `-`/`.`). The repo is created as `agents/`. - pub repo: String, -} - #[derive(Debug, serde::Deserialize, schemars::JsonSchema)] pub struct GetAgentMetaArgs { /// Logical name of the agent to query (e.g. `"iris"`, `"manager"`). diff --git a/hive-agent-mcp/src/mcp/mod.rs b/hive-agent-mcp/src/mcp/mod.rs index 2eb85350..497c3506 100644 --- a/hive-agent-mcp/src/mcp/mod.rs +++ b/hive-agent-mcp/src/mcp/mod.rs @@ -24,9 +24,9 @@ mod args; mod render; pub use args::{ - AckUntilArgs, CancelLooseEndArgs, CancelScheduleArgs, CompactArgs, CreateRepoArgs, - EditScheduleArgs, FireScheduleNowArgs, GetAgentMetaArgs, MarkTodosDoneArgs, RecvArgs, - RemindArgs, RequestSchedulePromptArgs, SendArgs, SetStatusArgs, + AckUntilArgs, CancelLooseEndArgs, CancelScheduleArgs, CompactArgs, EditScheduleArgs, + FireScheduleNowArgs, GetAgentMetaArgs, MarkTodosDoneArgs, RecvArgs, RemindArgs, + RequestSchedulePromptArgs, SendArgs, SetStatusArgs, }; pub use render::{annotate_retries, format_ack, format_agent_meta, format_recv}; @@ -441,33 +441,6 @@ impl AgentServer { .await } - #[tool( - description = "Create a git repo through hive-c0re. You CANNOT create repos with your \ - own forge token (creation is disabled) — this is the only path. The repo is created in \ - the c0re-owned `agents` org, you're added as a write collaborator (not owner), and the \ - default branch gets branch protection so merges require an operator-team approval — you \ - cannot merge your own PRs. `repo` is a single name segment (letters, digits, `-`, `_`, \ - `.`). Returns the new repo's full name + clone URL; clone it over \ - `$HIVE_FORGE_URL/agents/.git` and push/open PRs as normal." - )] - async fn create_repo(&self, Parameters(args): Parameters) -> String { - let log = format!("{args:?}"); - run_tool_envelope("create_repo", log, async move { - let (resp, retries) = self - .dispatch(hive_core_agent_sock::Request::CreateRepo { repo: args.repo }) - .await; - let s = match resp { - Ok(hive_core_agent_sock::Response::RepoCreated { - full_name, - clone_url, - }) => format!("created repo {full_name} — clone: {clone_url}"), - other => reply_err(other, "create_repo"), - }; - annotate_retries(s, retries) - }) - .await - } - #[tool( description = "Schedule a reminder that lands in this agent's own inbox at a future \ time (sender will appear as `reminder`). Use for self-paced follow-ups: 'check task \ diff --git a/hive-c0re/src/forge/mod.rs b/hive-c0re/src/forge/mod.rs index 30c64186..3e2f7476 100644 --- a/hive-c0re/src/forge/mod.rs +++ b/hive-c0re/src/forge/mod.rs @@ -17,9 +17,9 @@ pub use pr_merge::{ }; pub use reconcile::{reconcile_config_apply, reconcile_config_status}; pub use repos::{ - clone_config_into_proposed, create_agent_repo, ensure_config_repo, ensure_meta_remote, - ensure_repo, fast_forward_applied_main, fetch_config_main_into_applied, meta_read_access, - push_config, push_meta, shared_docs_access, + clone_config_into_proposed, ensure_config_repo, ensure_meta_remote, ensure_repo, + fast_forward_applied_main, fetch_config_main_into_applied, meta_read_access, push_config, + push_meta, shared_docs_access, }; pub use users::core_token; @@ -112,21 +112,6 @@ const SHARED_ORG: &str = "internal"; /// The shared docs repo inside `SHARED_ORG`. Cloneable by every agent /// at `{forge_http_base()}/internal/docs.git`. const SHARED_DOCS_REPO: &str = "docs"; -/// Forgejo org that owns agent-created repos. Agents can't create -/// repos with their own token (`max_repo_creation = 0`); instead hive-c0re -/// creates them here and adds the requesting agent as a **write** member -/// (not owner/admin). Because the org — not the agent — owns the repo, -/// perms stay c0re-managed and branch protection (referencing -/// [`OPERATORS_TEAM`]) can block the author from merging their own PR. This -/// is the "agents namespace" repos land in by default. The swarm-controller -/// ensures the org itself. -const AGENTS_ORG: &str = "agents"; -/// Operator merge-gate team inside [`AGENTS_ORG`]. Provisioned **empty** by -/// the swarm-controller (so perms can be set before anyone joins); the -/// operator adds herself via the forge UI. Branch protection on agents-org -/// repos references this team by name for the merge/approval whitelist, so -/// the rule never hardcodes a specific reviewer agent (which may not exist). -const OPERATORS_TEAM: &str = "operators"; /// Leak `s` to get a `&'static str` warning `kind` for the small, bounded /// set of boot warnings in [`ensure_all`] keyed by a runtime name (at diff --git a/hive-c0re/src/forge/repos.rs b/hive-c0re/src/forge/repos.rs index 658df56d..db766345 100644 --- a/hive-c0re/src/forge/repos.rs +++ b/hive-c0re/src/forge/repos.rs @@ -18,8 +18,8 @@ use reqwest::StatusCode; use crate::coordinator::Coordinator; use super::{ - AGENTS_ORG, CONFIG_ORG, OPERATORS_TEAM, SHARED_DOCS_REPO, SHARED_ORG, api, core_auth_header, - core_token, forge_git_url, forge_http_base, is_present, + CONFIG_ORG, SHARED_DOCS_REPO, SHARED_ORG, api, core_auth_header, core_token, forge_git_url, + forge_http_base, is_present, }; /// Creation options for an empty repo defaulting to `main`. @@ -659,52 +659,6 @@ fn main_branch_protection_option() -> CreateBranchProtectionOption { } } -/// Apply the operator merge-gate branch protection to `repo`'s default -/// branch: only [`OPERATORS_TEAM`] members can merge, and an -/// approving review from that team is required — so the author (a write-level -/// agent, not in the team) cannot merge its own PR. -/// -/// Idempotent, but **verify-don't-trust**: a create failure is ambiguous — -/// "rule already exists" (success) OR a silent rejection that created NO rule -/// (e.g. a 422 where `OPERATORS_TEAM` doesn't exist in `AGENTS_ORG`). The old -/// code folded 200/409/422 into `Ok` and left the repo unprotected with no -/// error — a fail-open merge gate. So on any create error, GET the `main` rule -/// and only treat it as success if the rule is actually present (the exact fix -/// already applied to [`apply_config_repo_branch_protection`]). -async fn apply_operator_branch_protection(repo: &str, token: &str) -> Result<()> { - let client = api(token)?; - let mut rule = main_branch_protection_option(); - rule.enable_merge_whitelist = Some(true); - rule.merge_whitelist_teams = Some(vec![OPERATORS_TEAM.to_owned()]); - rule.enable_approvals_whitelist = Some(true); - rule.approvals_whitelist_teams = Some(vec![OPERATORS_TEAM.to_owned()]); - rule.required_approvals = Some(1); - rule.block_on_official_review_requests = Some(true); - let Err(create_err) = client - .repo_create_branch_protection(AGENTS_ORG, repo, rule) - .await - else { - tracing::info!(%repo, "forge: applied operator branch protection"); - return Ok(()); - }; - match client - .repo_get_branch_protection(AGENTS_ORG, repo, "main") - .await - { - Ok(_) => { - tracing::debug!( - %repo, create_error = %create_err, - "forge: operator branch protection already present" - ); - Ok(()) - } - Err(check_err) => anyhow::bail!( - "branch protection for {AGENTS_ORG}/{repo} not applied: create failed \ - ({create_err}); GET main rule failed ({check_err}), no `main` rule present" - ), - } -} - /// Apply branch protection to an `agent-configs/` repo's `main` so it /// can serve as the agent-editable, PR-merge config surface: /// - **`main` is never directly pushable** — no push is enabled on the @@ -809,24 +763,3 @@ fn config_repo_protection_edit() -> EditBranchProtectionOption { unprotected_file_patterns: None, } } - -/// Create a repo for `agent` in the c0re-owned [`AGENTS_ORG`] and wire the -/// perms: the org owns it (perms stay c0re-managed), the agent is added -/// as a **write** collaborator (not owner — can push + open PRs but can't -/// bypass branch protection), and the default branch gets the operator -/// merge gate. This is the sanctioned create path now that agents can't -/// create repos directly (`max_repo_creation = 0`). Idempotent. -pub async fn create_agent_repo(agent: &str, repo: &str, core_token: &str) -> Result { - ensure_org_repo(AGENTS_ORG, repo, core_token).await?; - add_collaborator( - AGENTS_ORG, - repo, - agent, - AddCollaboratorOptionPermission::Write, - core_token, - ) - .await?; - apply_operator_branch_protection(repo, core_token).await?; - tracing::info!(%agent, %repo, "forge: created agent repo in {AGENTS_ORG} with operator merge gate"); - Ok(format!("{AGENTS_ORG}/{repo}")) -} diff --git a/hive-c0re/src/forge/users.rs b/hive-c0re/src/forge/users.rs index 82cc027c..0ae8eb47 100644 --- a/hive-c0re/src/forge/users.rs +++ b/hive-c0re/src/forge/users.rs @@ -208,10 +208,9 @@ pub(super) async fn ensure_user_email(name: &str) { } /// Disable direct repo creation for agent `name` by setting -/// `max_repo_creation = 0` on its Forgejo account. Agents must -/// create repos *through hive-c0re* (which owns the perms), never with -/// their own token — a write-scoped token can otherwise create + own -/// repos and self-merge, bypassing the operator-only-merge policy. +/// `max_repo_creation = 0` on its Forgejo account. A write-scoped token +/// can otherwise create + own repos and self-merge, bypassing the +/// operator-only-merge policy. /// /// `max_repo_creation = 0` means `CanCreateRepo()` is false for any /// count (Forgejo: `MaxRepoCreation >= 0 && NumRepos >= MaxRepoCreation`), diff --git a/hive-c0re/src/socket_server/mod.rs b/hive-c0re/src/socket_server/mod.rs index 052efee9..20b5f456 100644 --- a/hive-c0re/src/socket_server/mod.rs +++ b/hive-c0re/src/socket_server/mod.rs @@ -316,7 +316,6 @@ pub(crate) async fn dispatch_shared( |()| hive_core_agent_sock::Response::Ok, ) } - hive_core_agent_sock::Request::CreateRepo { repo } => handle_create_repo(agent, repo).await, hive_core_agent_sock::Request::AckTurn => handle_ack_turn(coord, agent), hive_core_agent_sock::Request::AckUntil { up_to } => handle_ack_until(coord, agent, *up_to), hive_core_agent_sock::Request::RequeueInflight => handle_requeue_inflight(coord, agent), @@ -423,46 +422,6 @@ fn handle_set_status(coord: &Arc, text: &str) -> hive_core_agent_so hive_core_agent_sock::Response::Ok } -/// Validate an agent-supplied repo name: a single safe slug segment, no -/// path traversal. Forgejo validates server-side too, but rejecting early -/// gives a clear message and avoids building odd API paths. -fn valid_repo_name(name: &str) -> bool { - !name.is_empty() - && name.len() <= 100 - && !name.starts_with(['-', '.']) - && name - .chars() - .all(|c| c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.')) -} - -/// `CreateRepo` — create a repo for `agent` *through hive-c0re* in the -/// c0re-owned `agents` org with operator-team branch protection. -/// The sanctioned create path now that agents can't create repos directly. -async fn handle_create_repo(agent: &str, repo: &str) -> hive_core_agent_sock::Response { - if !valid_repo_name(repo) { - return hive_core_agent_sock::Response::Err { - message: format!( - "invalid repo name {repo:?} — single segment of letters, digits, '-', '_', '.' \ - (no leading '-'/'.', max 100 chars)" - ), - }; - } - let Some(core_token) = crate::forge::core_token() else { - return hive_core_agent_sock::Response::Err { - message: "forge unavailable (no core token) — cannot create repo".to_owned(), - }; - }; - match crate::forge::create_agent_repo(agent, repo, &core_token).await { - Ok(full_name) => hive_core_agent_sock::Response::RepoCreated { - clone_url: format!("{}/{full_name}.git", crate::forge::forge_http_base()), - full_name, - }, - Err(e) => hive_core_agent_sock::Response::Err { - message: format!("create repo {repo:?} failed: {e:#}"), - }, - } -} - /// `GetAgentMeta` — identity + live status for `name` (defaults to the /// caller). Reads the live container-view status and the hive/swarm /// display names. diff --git a/hive-core-agent-sock/src/lib.rs b/hive-core-agent-sock/src/lib.rs index bdbd4973..6c047ed1 100644 --- a/hive-core-agent-sock/src/lib.rs +++ b/hive-core-agent-sock/src/lib.rs @@ -83,13 +83,6 @@ pub enum Request { /// per-kind semantics in /// `docs/process/conventions.md::Loose-ends wire shape`. CancelLooseEnd { kind: CancelLooseEndKind, id: i64 }, - /// Create a git repo *through hive-c0re*. Agents can't create - /// repos with their own forge token (`max_repo_creation = 0`); this is - /// the sanctioned path. hive-c0re creates `repo` in the c0re-owned - /// `agents` org, adds the calling agent as a write collaborator (not - /// owner), and applies operator-team branch protection so the author - /// can't merge its own PRs. Returns the new repo's full name. - CreateRepo { repo: String }, /// Mark every message popped since the last `AckTurn` as handled. /// Harness↔broker pairing fired after `TurnOutcome::Ok`. See /// `docs/process/conventions.md::Broker delivery + ack cycle`. @@ -222,12 +215,6 @@ pub enum Response { /// authorized to see — see `ListSchedules`'s own doc comment. /// Returned on the manager socket only. Schedules { schedules: Vec }, - /// `CreateRepo` result: the new repo's full name (`agents/`) - /// and clone URL, so the agent can immediately `git clone` it. - RepoCreated { - full_name: String, - clone_url: String, - }, /// `Recv` result when a graceful stop is pending for this agent /// (set by hive-c0re's `GracefulStop` orchestration). Returned in /// place of `Messages` — it doubles as the inbound fence: the harness diff --git a/hive-sh4re/src/permissions.rs b/hive-sh4re/src/permissions.rs index 76d36377..51781755 100644 --- a/hive-sh4re/src/permissions.rs +++ b/hive-sh4re/src/permissions.rs @@ -165,9 +165,9 @@ pub enum ToolGroup { /// `request_schedule_prompt`, `fire_schedule_now`, `cancel_schedule`, /// `edit_schedule`, `list_schedules` - *(privileged)* Scheduling, - /// `create_repo` — create git repos through hive-c0re (the only path - /// now that agents can't create them directly). Opt-in per - /// agent so the operator controls who can spin up repos. + /// Gates no tool today — `create_repo`, its only member, was removed + /// with no replacement. Kept so existing `meta/capabilities.json` + /// grants still parse; `tools()` returns `&[]`. Forge, /// Gates whether the `bash` MCP server (`mcp__bash__run`/`status`/ /// `kill`) is rendered into the agent's config at all — see @@ -222,8 +222,8 @@ impl ToolGroup { /// The MCP tool names (without the `mcp__hyperhive__` prefix) in this group. /// Returns `&[]` for `WebTools` (it enables Claude built-in tools, not MCP - /// tools — see `builtin_tools()`) and for `Lifecycle` / `Approvals` - /// (their tools were removed); see each variant's doc comment. + /// tools — see `builtin_tools()`) and for `Lifecycle` / `Approvals` / + /// `Forge` (their tools were removed); see each variant's doc comment. #[must_use] pub fn tools(self) -> &'static [&'static str] { match self { @@ -237,8 +237,7 @@ impl ToolGroup { "edit_schedule", "list_schedules", ], - Self::Forge => &["create_repo"], - // All four empty, for four different reasons — see each + // All five empty, for different reasons — see each // variant's own doc comment above. `Execution` grants the // out-of-process `bash` MCP server // (`mcp__bash__run`/`status`/`kill`), gated at config-render @@ -247,13 +246,15 @@ impl ToolGroup { // out-of-process server has no later enforcement point, so // that gate is the actual security boundary. `WebTools` // grants Claude built-in tools, not MCP ones; see - // `builtin_tools()`. `Lifecycle` and `Approvals` each listed - // exactly one tool — `list_containers` and - // `request_update_meta_inputs` respectively — and both tools - // were removed outright; the variants stay so existing - // grants parse, and `Approvals` still gates + // `builtin_tools()`. `Lifecycle`, `Approvals` and `Forge` each + // listed exactly one tool — `list_containers`, + // `request_update_meta_inputs` and `create_repo` respectively + // — and all three tools were removed outright; the variants + // stay so existing grants parse, and `Approvals` still gates // `cancel_loose_end`'s approval-cancel arm server-side. - Self::Lifecycle | Self::Approvals | Self::Execution | Self::WebTools => &[], + Self::Lifecycle | Self::Approvals | Self::Forge | Self::Execution | Self::WebTools => { + &[] + } } } @@ -342,9 +343,7 @@ impl ToolGroup { Self::Scheduling => { "request_schedule_prompt and related — operator-visible scheduled prompts (privileged)" } - Self::Forge => { - "create_repo — create git repos through hive-c0re (operator-gated merge)" - } + Self::Forge => "no tools — vestigial since create_repo was removed", Self::Execution => { "run, status — run shell commands via mcp__bash__run / mcp__bash__status" } diff --git a/hive-sock-client/src/lib.rs b/hive-sock-client/src/lib.rs index ade26ef9..abc62a5c 100644 --- a/hive-sock-client/src/lib.rs +++ b/hive-sock-client/src/lib.rs @@ -51,9 +51,7 @@ const CONNECT_TIMEOUT: Duration = Duration::from_secs(5); /// that has not drained one JSON line in this long has stopped reading. const WRITE_TIMEOUT: Duration = Duration::from_secs(10); -/// Response deadline for every call that does not pass its own. Sized for -/// the slowest non-polling verb: `CreateRepo`, which makes several -/// sequential forge API calls in hive-c0re before it answers. +/// Response deadline for every call that does not pass its own. const DEFAULT_RESPONSE_TIMEOUT: Duration = Duration::from_mins(1); /// What to do when a connect or I/O attempt fails. diff --git a/swarm-controller/src/forge.rs b/swarm-controller/src/forge.rs index 6570a43d..e0a1722b 100644 --- a/swarm-controller/src/forge.rs +++ b/swarm-controller/src/forge.rs @@ -267,12 +267,11 @@ impl Client { /// default branch — only [`OPERATORS_TEAM`] members can merge, and /// an approving review from that team is required, so the agent (a /// write-level collaborator, not in the team) cannot merge its own - /// PR. Mirrors `hive-c0re::forge::repos::apply_operator_branch_protection` - /// exactly (same policy, same verify-don't-trust shape): a create - /// failure is ambiguous (already-exists vs. a silent reject that - /// created no rule), so on any error this GETs the `main` rule and - /// only treats it as success if the rule is actually present — a - /// fail-open merge gate is a security bug, not a shrug. + /// PR. A create failure is ambiguous (already-exists vs. a silent + /// reject that created no rule), so on any error this GETs the + /// `main` rule and only treats it as success if the rule is + /// actually present — a fail-open merge gate is a security bug, + /// not a shrug. /// /// Also push-whitelists [`SWARM_CONTROLLER_FORGE_USER`] alone — /// [`Client::seed_agent_config`]'s initial commit is a direct push to