diff --git a/hive-c0re/src/forge.rs b/hive-c0re/src/forge.rs index 5adfe4d..bb798be 100644 --- a/hive-c0re/src/forge.rs +++ b/hive-c0re/src/forge.rs @@ -53,8 +53,10 @@ const SEEDED_ORGS: &[&str] = &[CONFIG_ORG]; /// a forge namespace). /// - `read:user` — token-owner endpoint clients call to introspect. /// - `write:misc` — hooks, attachments, the rest of the long tail. +/// - `read:notification` — required by forge_notify to poll +/// `GET /notifications` for unread PR/review events. const TOKEN_SCOPES: &str = - "read:user,write:user,write:repository,write:issue,write:organization,write:misc"; + "read:user,write:user,read:notification,write:repository,write:issue,write:organization,write:misc"; /// Token file inside the agent's bind-mounted state dir (visible as /// `/state/forge-token` from inside the container). @@ -226,19 +228,16 @@ async fn mint_and_persist_token(name: &str, path: &Path) -> Result<()> { Ok(()) } -/// Ensure `name` has a forgejo user + token file. No-op when the -/// token file is already present. Safe to call on every spawn and -/// on every hive-c0re startup. +/// Ensure `name` has a forgejo user + token file. Always re-mints the +/// token so the on-disk file always reflects the current `TOKEN_SCOPES`. +/// Safe to call on every spawn and on every hive-c0re startup. pub async fn ensure_user_for(name: &str) -> Result<()> { if !is_present().await { return Ok(()); } - let path = token_path(name); - if path.exists() { - return Ok(()); - } ensure_user_exists(name, false).await?; - mint_and_persist_token(name, &path).await + ensure_user_email(name).await; + mint_and_persist_token(name, &token_path(name)).await } /// Ensure the bootstrap `core` admin user + a token at