diff --git a/docs/guides/user/bring-your-own-agent.md b/docs/guides/user/bring-your-own-agent.md index bda86de13..b0cb4d553 100644 --- a/docs/guides/user/bring-your-own-agent.md +++ b/docs/guides/user/bring-your-own-agent.md @@ -86,8 +86,8 @@ image: ghcr.io/fullsend-ai/fullsend-sandbox:latest # Pin to a digest before CI policy: policies/base.yaml providers: - vertex-ai -role: my-agent -slug: my-org-my-agent # GitHub App identity; convention: - (see Custom agent identity) +role: triage # a role your mint SERVES — not the agent's name (see note below) +slug: my-org-my-agent # install-time App discovery only; the mint never reads it trigger: | event.entity.kind == "work_item" && event.transition.kind == "label_changed" @@ -96,6 +96,16 @@ trigger: | timeout_minutes: 15 ``` +> **`role` is not the agent's name.** The agent's name is `name:` in its `.md`; +> `role:` selects which GitHub App and permissions the mint issues. On the +> default (hosted) mint, `role:` must be one of the built-in roles it serves — +> `triage`, `coder`, `review`, `retro`, `prioritize`, `fullsend`. Pick the one +> whose permissions fit what your agent does (a code-writing agent uses +> `role: coder`). A made-up role like `role: my-agent` returns `403` from the +> mint. To use a *new* role or your *own* identity, you need your own mint — +> see [Custom Agent Identity](custom-agent-identity.md). + + **`providers/vertex-ai.yaml`** — provider definition (declares a provider by name and type): ```yaml name: vertex-ai @@ -348,6 +358,7 @@ allowed_remote_resources: |---------|-----| | Agent crashes at 0s | Sandbox can't reach Vertex AI — verify that `providers/vertex-ai.yaml` is listed in your harness `providers:` and that `ANTHROPIC_VERTEX_PROJECT_ID`/`CLOUD_ML_REGION` are set (in your `--env-file` for local runs, or in the workflow `env` block for CI) | | "role field is required" | Add `role:` to harness | +| `403` / "role not allowed" from the mint | Your `role:` is not one the mint serves. On the hosted mint use a built-in role (`triage`, `coder`, `review`, `retro`, `prioritize`, `fullsend`); for a custom role, point `FULLSEND_MINT_URL` at your own mint — see [Custom Agent Identity](custom-agent-identity.md) | | Agent can't find input files | Pre-script output paths must match `host_files` entries | | Provider blocks requests | Check that the required provider profile is listed in `providers:` and exists in the `providers/` directory | | Schema validation fails | Compare the sandbox output (`$FULLSEND_OUTPUT_DIR/.json`) against the schema referenced in `validation_loop` / `FULLSEND_OUTPUT_SCHEMA`; re-run with `--keep-sandbox` to inspect | diff --git a/docs/guides/user/building-custom-agents.md b/docs/guides/user/building-custom-agents.md index 03b0713fa..fad891f1b 100644 --- a/docs/guides/user/building-custom-agents.md +++ b/docs/guides/user/building-custom-agents.md @@ -135,7 +135,7 @@ model: opus effort: high # optional: low, medium, high, xhigh, max (claude runtime only) image: ghcr.io/fullsend-ai/fullsend-sandbox:latest policy: policies/my-agent.yaml -role: my-agent +role: triage # a role the mint serves — not the agent's name (see Custom Agent Identity) providers: - vertex-ai # Required: model access (Anthropic API + GCP) diff --git a/docs/guides/user/custom-agent-identity.md b/docs/guides/user/custom-agent-identity.md index 86ad19380..3775b4710 100644 --- a/docs/guides/user/custom-agent-identity.md +++ b/docs/guides/user/custom-agent-identity.md @@ -1,29 +1,94 @@ # Custom Agent Identity -By default, agents authenticate using shared fullsend GitHub Apps via the `slug` field in the harness. Each agent's `role` maps to a GitHub App installation managed by the hosted mint service. +When an agent acts on GitHub — commits, comments, reviews, status checks — it +does so as a **GitHub App**. Which App, and what that App is allowed to do, is +decided by one field in your harness: **`role`**. -A standalone mint makes sense when: +```yaml +role: triage # ← decides identity AND permissions at the mint +slug: my-org-triage # ← install-time hint only; the mint never reads it +``` -- **Custom permissions** -- your agent needs GitHub App permissions beyond what the shared Apps grant (e.g., write access to packages or deployments). -- **Compliance** -- your organization requires that GitHub App credentials stay within your own infrastructure. -- **Branding** -- you want agent actions (commits, comments, status checks) to appear under your own GitHub App name and avatar. +The mint service maps `role` to a GitHub App (its ID + private key) and to a +permission ceiling, then issues a token scoped to your repo. `slug` only helps +`fullsend github setup` find or name the App at install time — it is **not** +what authenticates your agent, and changing it does not change identity or +permissions. If you set a `role` the mint doesn't serve, you get a `403`, not a +new identity. -If none of these apply, the shared Apps work without extra setup -- set `slug` in your harness and go. To run your own, follow the [Standalone mint guide](../infrastructure/standalone-mint.md). +So the real question is: **whose mint issues your token?** -Once your standalone mint is running, configure your agent to use it: +## Two paths, one decision -1. **Reference your role in the harness:** +| | Default (hosted) mint | Your own mint (standalone) | +|---|---|---| +| **URL** | `https://mint.fullsend.sh` (default) | your `FULLSEND_MINT_URL` | +| **Roles you can use** | a **fixed** built-in set — `triage`, `coder`, `review`, `retro`, `prioritize`, `fullsend` | those built-ins **plus** any custom role you define | +| **Identity** | the shared fullsend App for that role (e.g. `fullsend-ai-triage[bot]`) | **your** GitHub App — your name, your avatar | +| **Custom permissions** | no — each role's ceiling is fixed | yes — `security_events:write`, `deployments:write`, anything the GitHub API allows | +| **Who sets it up** | nobody — it just works | you (create App → install → register the role) | + +**The default mint cannot mint a new identity for you.** It serves a fixed set +of Apps that fullsend operates (see [why](../infrastructure/standalone-mint.md)). +Picking a `role:` it doesn't serve — or a custom `slug:` — will not create one; +it produces the `403` above. + +## Most customization needs no custom identity + +Before reaching for your own mint, check whether you actually need a new +identity. You usually don't: + +- **Changing behavior** — model, timeout, skills, prompt, env — keeps a + built-in `role:`. Use [`base:` composition](customizing-agents.md#configuration-with-base-composition); + the agent still runs as that role's App. +- **A brand-new agent** (its own trigger, scripts, schema) can still run on the + hosted mint — set its `role:` to the built-in role whose permissions match + what it does. A code-writing agent uses `role: coder`; a triage-like agent + uses `role: triage`. The agent's own name lives in `name:` in its `.md`, not + in `role:`. + +> **Rule of thumb.** Pick the built-in role whose permission ceiling is the +> closest fit for what your agent needs to do. You only need your own mint when +> **no** built-in role fits — because you need a distinct identity, or +> permissions no built-in role has. + +## When you do need your own mint + +Choose a standalone mint when one of these is true: + +- **Custom permissions** — your agent needs GitHub App permissions beyond any + built-in role (for example, write access to packages, deployments, or + security events). +- **Custom identity / branding** — you want actions to appear under your own + GitHub App name and avatar, not the shared fullsend App. +- **Compliance** — your organization requires GitHub App credentials to stay + inside your own infrastructure. + +Set it up, then point your repo at it: + +1. **Define the role and App on your mint** — follow the + [Standalone mint guide](../infrastructure/standalone-mint.md): create the + GitHub App, install it, store its PEM, and register the role's permissions + (`CUSTOM_ROLE_PERMISSIONS`, or `fullsend mint add-role`). + +2. **Reference the role in your harness:** ```yaml - role: my-role - slug: my-org-my-role + role: my-role # a role YOUR mint serves + slug: my-org-my-role # install-time App discovery; still not read by the mint ``` -2. **Set `FULLSEND_MINT_URL`** in your repo to point to your standalone mint. +3. **Point your repo at your mint** — set `FULLSEND_MINT_URL` to your mint's + URL. Without this, tokens are requested from the hosted mint, which does not + serve `my-role`. -When configured with `FALLBACK_MINT_URL`, the standalone mint serves custom roles locally while proxying unhandled roles to the hosted mint (see [Standalone mint — Fallback proxy behavior](../infrastructure/standalone-mint.md#fallback-proxy-behavior)). +> **Tip: adopt gradually.** With `FALLBACK_MINT_URL`, your standalone mint +> serves your custom roles locally and proxies the built-in ones to the hosted +> mint — so you can start with a single custom role without disrupting existing +> agents. See [Standalone mint — Fallback proxy behavior](../infrastructure/standalone-mint.md#fallback-proxy-behavior). ## See also - [Bring Your Own Agent](bring-your-own-agent.md) — end-to-end guide for building and registering agents +- [Configuring Agent Behavior](customizing-agents.md) — change model, skills, and env while keeping a built-in role - [Standalone Mint](../infrastructure/standalone-mint.md) — full standalone mint setup guide - [Harness Field Reference](../../reference/harness-reference.md) — complete harness YAML reference including `role` and `slug` diff --git a/docs/guides/user/customizing-agents.md b/docs/guides/user/customizing-agents.md index 38c828d1b..fd5dc8455 100644 --- a/docs/guides/user/customizing-agents.md +++ b/docs/guides/user/customizing-agents.md @@ -263,7 +263,11 @@ Reference the skill in your harness's `skills:` list. The skill is available to ## Agent roles -Each agent role has its own identity, permissions, and purpose: +On the hosted mint, agents run as one of a **fixed** set of built-in roles. +Each role is a GitHub App identity with a fixed permission ceiling. An agent's +name is separate from its role — the `code` and `fix` agents both run as the +`coder` role. To pick a role for a custom agent, or to use your own identity or +a custom role, see [Custom Agent Identity](custom-agent-identity.md). | Role | GitHub App | Purpose | |------|------------|---------| diff --git a/docs/guides/user/customizing-overview.md b/docs/guides/user/customizing-overview.md index aebe39caa..23dd70d62 100644 --- a/docs/guides/user/customizing-overview.md +++ b/docs/guides/user/customizing-overview.md @@ -102,9 +102,10 @@ adding skills via harness, extending the sandbox image, disabling agents. ## Bring Your Own Agent -When you need a completely new agent — with its own trigger, scripts, -output schema, and possibly its own GitHub App identity — build one from -scratch: +When you need a completely new agent — with its own trigger, scripts, and +output schema — build one from scratch. It still runs on the hosted mint if it +assumes a built-in `role:`; a distinct GitHub App identity requires your own +mint (see [Custom Agent Identity](custom-agent-identity.md)): ``` .fullsend/ diff --git a/docs/reference/harness-reference.md b/docs/reference/harness-reference.md index 85a5f76ae..6939e676a 100644 --- a/docs/reference/harness-reference.md +++ b/docs/reference/harness-reference.md @@ -5,10 +5,10 @@ Complete reference for all fields available in a fullsend harness YAML file. For ```yaml # ── Required ────────────────────────────────────────────────── agent: agents/my-agent.md # Path to agent definition -role: my-agent # Role name (lowercase letter first, then a-z, 0-9, _, -; no double hyphens) +role: triage # A role the mint serves (built-in on the hosted mint); not the agent's name. Format: lowercase letter first, then a-z, 0-9, _, -; no double hyphens # ── Identity & metadata ────────────────────────────────────── -slug: my-org-my-role # GitHub App identity (convention: -) +slug: my-org-my-role # install-time App discovery (convention: -); not read by the mint description: One-line summary # Human-readable description doc: docs/agents/my-agent.md # Source-repo-only; not resolved at runtime trigger: "event.entity.kind == 'work_item'" # Optional CEL expression over NormalizedEvent (see CEL Triggers Reference) @@ -126,9 +126,9 @@ security: Most fields are self-explanatory from the inline comments above. This section expands on fields where additional context helps. -**`role`** — The agent's identity within fullsend. Dispatch uses the role to match config-registered agents to built-in defaults (same-name config agents take precedence). The role also determines which GitHub App credentials the mint service issues. +**`role`** — The agent's identity within fullsend. Dispatch uses the role to match config-registered agents to built-in defaults (same-name config agents take precedence). The role also determines which GitHub App credentials **and permissions** the mint service issues. It must be a role the mint serves: on the hosted mint that is the fixed built-in set (`triage`, `coder`, `review`, `retro`, `prioritize`, `fullsend`); custom roles require your own mint. An unserved role returns `403`. See [Custom Agent Identity](../guides/user/custom-agent-identity.md). -**`slug`** — Maps to a GitHub App installation. The `-` convention keeps slugs unique when multiple orgs share a mint. For custom GitHub App identity, see [Custom Agent Identity](../guides/user/custom-agent-identity.md). +**`slug`** — Install-time hint used by `fullsend github setup` to find or name the GitHub App. The `-` convention keeps slugs unique when multiple orgs share a mint. The **mint does not read `slug`** when issuing a token — identity and permissions come from `role`, so changing `slug` alone changes neither. For a custom GitHub App identity, see [Custom Agent Identity](../guides/user/custom-agent-identity.md). **`doc`** — Path to a human-readable document describing the agent's purpose and design. Resolved in the source repo only; the runtime ignores it. Useful for documentation indexes and discoverability.