Every Forge repository has its own durable, multi-turn agent. A repository agent can read only that repository, and every run is pinned to the exact source SHA recorded when Forge accepts the message. Reusing a thread continues the conversation; it does not widen the agent to other repositories.
V1 ships Instant generally and keeps Workspace Alpha behind an explicit repository/user allowlist:
.git mutation, runs server-declared tests in both the execution sandbox and
a fresh trusted checkout, rebuilds the change from the accepted SHA, then
publishes the fenced agent/* branch and one deduplicated draft Forge pull
request. Forge is both the Git remote and pull-request host; Workspace does
not require or contact GitHub.
This profile is visible and runnable only for users with repository write
permission plus agent:write who also match the server-owned Alpha
allowlist. Everyone else continues to see the non-runnable adapter state.Instant can inspect and explain code but cannot claim to implement, execute, test, or publish a change. Only the allowlisted Workspace Alpha path has that authority.
Thread IDs are readable handles:
agent_thread_0123456789abcdef0123456789abcdefOmit thread_id when creating a thread and Forge assigns one. Supplying a valid
thread ID lets an integration choose a stable conversation handle. Every
message creates its own agent_message_... and agent_run_... records.
The repository-agent API does not use Idempotency-Key. A client that needs
retry correlation supplies client_message_id on a message. Reusing that ID
with the same normalized message, source, and execution request returns the
existing run; reusing it with different input returns 409 message_conflict.
All responses use Cache-Control: private, no-store.
GET /api/repos/:owner/:repo/agent/execution-profiles
POST /api/repos/:owner/:repo/agent/threads
GET /api/repos/:owner/:repo/agent/threads
GET /api/repos/:owner/:repo/agent/threads/:thread_id
POST /api/repos/:owner/:repo/agent/threads/:thread_id/messages
GET /api/repos/:owner/:repo/agent/threads/:thread_id/events?after=:cursor
POST /api/repos/:owner/:repo/agent/threads/:thread_id/archiveCreate a thread:
curl -X POST "$FORGE_URL/api/repos/OWNER/REPO/agent/threads" \
-H "Authorization: Bearer $FORGE_TOKEN" \
-H 'Content-Type: application/json' \
--data '{}'Send an Auto message. Auto starts with the least-privileged useful profile, which is Instant in V1:
curl -X POST "$FORGE_URL/api/repos/OWNER/REPO/agent/threads/$THREAD_ID/messages" \
-H "Authorization: Bearer $FORGE_TOKEN" \
-H 'Content-Type: application/json' \
--data '{
"message":"Explain the authentication boundary.",
"client_message_id":"slack-event-019f1234",
"execution":{"mode":"auto","max_compute":"workspace"}
}'Use an explicit least-privilege ceiling when an integration never wants a future escalation:
{
"message": "Which module owns token validation?",
"execution": { "mode": "instant", "max_compute": "instant" }
}The API returns 202 only after the user message, queued run, frozen source
SHA, queued event, and dispatch outbox row are committed together. The movable
repository UI polls the cursor event API and refreshes the authoritative thread
view until the run is terminal.
The headless sf agent commands use the same repository-agent API and durable
contracts as the repository UI. Inspect live tier availability before choosing
compute:
sf agent profiles OWNER/REPO --jsonAn omitted thread creates one and returns its durable handle. Keep that handle to move down to an Instant answer or up to an allowlisted Workspace run without forking the conversation:
sf agent message OWNER/REPO \
--message "Explain the publication fence" \
--mode instant \
--client-message-id example-instant-001 \
--json
sf agent message OWNER/REPO \
--thread agent_thread_0123456789abcdef0123456789abcdef \
--message "Implement the focused regression and run its test" \
--mode workspace \
--source-ref refs/heads/main \
--client-message-id example-workspace-001 \
--jsonsf agent view returns the authoritative messages, runs, approvals, artifacts,
and receipts. sf agent events resumes normalized events after a cursor.
Cancellation and approval resolution require the exact repository/thread/run
identity and explicit confirmation. The CLI never accepts model endpoints,
provider credentials, output refs, or other authority that belongs to Forge.
Forge also exposes the same authority through the official MCP TypeScript SDK:
POST /mcp/agents
Authorization: Bearer <Forge PAT or agent service-principal key>The Phase 1 server supports MCP 2026-07-28 and the SDK's stateless fallback for older Streamable HTTP clients. It exposes four tools:
forge_agent_message creates or continues a thread and accepts one Instant
run. If thread_id is omitted, Forge assigns it.forge_agent_get_thread reads the authoritative messages and runs.forge_agent_list_threads lists recent threads for one repository.forge_agent_list_events reads durable events after a cursor.MCP is an adapter, not a second agent runtime. The tools call the same
protocol-neutral service as REST, use the same repository grants, and return
the same agent_thread_..., agent_run_..., source SHA, receipt, and event
records. A repo-bound token cannot name another repository to widen authority.
The message tool returns after durable acceptance. Poll the thread or events tool for completion. MCP Tasks, OAuth discovery, resource templates, and change subscriptions are planned next; Phase 1 intentionally does not pretend that a long-lived run is synchronous.
The dispatcher leases one queued run at a time per thread. Before inference it materializes the exact source and then atomically reserves bounded platform spend. It sends Workers AI only bounded repository text and recent completed conversation messages; provider logging is disabled when the configured AI Gateway is used. Prompts and completions are not stored in usage or receipt rows.
On success, one D1 batch records:
message.completed and run.completed events;The public receipt includes the resolved compute profile and backend, driver, model, estimated input/output tokens and cost, coarse compute usage, runner version, and a SHA-256 receipt digest. Worker CPU is reported as zero when the runtime cannot measure it; Forge does not invent precision.
If a dispatch lease expires before inference starts, the minute reconciler may
retry it. Inside one already-authoritative run, Instant retries exactly one
normalized provider timeout after a bounded jittered delay. Both calls keep the
same run/turn cache identity, input metering is conservative across attempts,
and run.completed records provider_attempts. Permanent provider errors,
invalid output, grounding failures, and persistence failures are never retried.
If the second provider attempt is still ambiguous, Forge marks the reservation
ambiguous and fails the run; the outbox never creates a second run.
Workspace publication stays entirely inside Forge. The trusted publisher
rechecks the accepted source ref against its exact SHA, reconstructs the one
agent/<thread>/<run> commit, and records the branch, native pull request,
artifacts, events, run settlement, and immutable publication receipt. The
branch and pull request are fenced by the same source-SHA comparison. A moved
base fails closed, and a cancellation that wins after branch creation removes
the unpublished branch before the outbox becomes cancelled.
The created pull request is a real Forge draft with preview deployment
suppressed. Forge refuses to merge it while draft is true; an authorized
reviewer can mark it ready through the pull-request update API before merging.
Replaying a completed publication returns its durable result without creating
another branch or pull request. No GitHub App, installation, token, API call,
or mirror commit participates in this path.
The browser uses the signed-in Forge session. External integrations should use a Forge personal access token or an agent service-principal API key. Service principals have explicit per-repository grants, separately rotatable keys, and audit attribution suitable for future Slack, Discord, and email connectors.
Relevant permissions are:
agent:read for threads, events, runs, and receipts;agent:message for appending messages;agent:run for creating threads and other run controls;agent:cancel and agent:approve control interruptible Workspace runs and
explicit approvals;agent:write is required in addition to repository write permission for
Workspace Alpha; agent:configure remains reserved.Thread, run, message, approval, event, reservation, and receipt records all retain repository scope. Caller-supplied account IDs, provider credentials, models, URLs, headers, or raw compute resources are never accepted.
The repository Code page includes a movable, resizable agent panel. Open it
with the Agent shortcut or Command+. / Control+.. The panel exposes Auto and
Instant, labels Workspace as coming soon, shows live durable events, and renders
the terminal execution receipt. It is shown only to signed-in users and pins
each message to the branch currently selected in the repository browser. Only
the last thread handle, an unaccepted draft, and panel geometry are stored in
browser memory; conversation content stays in Forge.
Workspace Alpha reuses the same thread, message, run, event, approval, artifact, and receipt contract. General availability remains blocked on broader policy, operational, and abuse-resistance evidence; the Alpha allowlist must not be removed merely because the private execution path exists.
The first production dogfood policy is intentionally narrower than the general
Workspace contract: only the Forge repository, the owning Forge user,
scripts/runner-release-inputs.test.mjs, and its offline Node test command are
admitted. Repository and runner carry the same checked-in policy, and release
contracts test that they cannot drift independently. Expanding the repository,
user, path, command, or dependency-host set requires a reviewed source change
and new exact-version releases of both authority boundaries.