Skip to content
Getting Started

Getting Started

FORGE is the last category of the CORE console rail. It has exactly one tab, Studio (forgeStudio). Under the FORGE label, the rail shows FORGE’s chat history in place of a list of pages.

Before you start

  • Use the web console. The studio is an iframe, and only a browser can hold one. Any other build of the console shows “The FORGE studio opens in CORE’s web console” and does not draw an empty pane.
  • Sign in to CORE. The /forge/ proxy refuses any request that has no CORE session, even on a console that runs with sign-in disabled. FORGE acts as a named person on GitHub, so it needs a signed-in email. There is no separate FORGE sign-in.
  • FORGE must be wired. The console needs CORE_FORGE_IDENTITY_KEY (the core-system Secret forge-identity-key, minted by core-operator’s provisioner) and a reachable FORGE service. If either is missing, the studio frame shows a “FORGE is not available here” page. See Troubleshooting.

One chat = one project

The owner’s model (2026-09-26): a FORGE chat is a project. A project is one repository, and each component is a lane: a folder that is either a RIVER pipeline or a web app. The lanes are declared in forge.yaml at the repository root.

The rail under FORGE shows:

  1. New chat. This opens the studio on /forge/?chat=new, an empty chat.
  2. The recent chats, newest first, each with a title and an age, plus a Show all control. The row tooltip reads “Project <name>” or “Not created yet”, then the lane count when FORGE sent one, then “App made before chats” for a repository FORGE imported as a one-lane chat.

The list is FORGE’s data, not a CORE store. The console reads it with runink.ui.chat.v1.ChatService/ListChats over gRPC-web, through the same-origin /forge/ proxy, on your CORE session. The component is org-runink/ui’s ChatHistoryList. CORE keeps no copy of your chats and vendors no FORGE-generated code.

The list has three distinct states, and each draws differently:

StateWhat you see
Still readingA loading state
FORGE unreadableThe reason, and a retry
Read, no chatsAn empty list. Start with New chat

Open the studio

Choose a chat

Click New chat, or click a recent chat. The console hands the studio a new ?chat= value, and the frame reloads on it.

Read the header

Above the frame, the page header names what FORGE is showing:

  • For a chat that belongs to a project: the chat title, then “Project <name> · one repo, a folder per lane”.
  • For a new chat, or one with no project yet: “Nothing is created until you approve it in the console.”
  • While FORGE has not yet reported which chat it opened: “Opening the chat…”.

The header and the rail’s selected row follow FORGE’s forge.chat message. That message is only accepted from CORE’s own origin and from the studio iframe’s own window (see API Reference).

Work in FORGE

Everything inside the frame is FORGE. It carries no menu of its own: FORGE’s options live in CORE’s rail. CORE’s code states that nothing is created until you approve it in FORGE’s console. How FORGE proposes and applies steps is FORGE’s own behaviour and is not described here.

Deep links

You can link straight to a chat:

/?tab=forgeStudio&chat=<id>
/?tab=forgeStudio&chat=new

A chat id must match FORGE’s shape, c- followed by 16 hex digits or repo-<app name>. Anything else is dropped. The old tab names forgeApps and forgePipelines are retired, and both redirect to forgeStudio.

The studio iframe itself takes more parameters: ?chat=, ?panel=, the legacy ?app= and ?cmd=. They are listed in the API Reference.

What happens after a brief is filed

FORGE files a brief as a forge-labelled issue in the forged repository. CORE consumes that queue with core-forge-run.yml, the forger:

  • It runs on the schedule 41 3,9,15,21 * * * (every 6 hours) or by workflow_dispatch. It takes the oldest open forge issue in the org, relabels it forge:running, and runs core session start --repo <owner/name> --issue <n> against it.
  • If a PR comes out, the issue gets forge:done and a comment linking the draft PR. If not, it gets forge:failed and a comment saying why. A failed issue is not retried automatically: re-add the forge label to requeue it.
  • The session verifies at CORE_SESSION_VERIFY=build. It rises to test only when a live bubblewrap probe passes on the runner, and the comment says which tier ran.
  • The forger never merges, deploys or touches main, and handles one issue per run.
The forger is disarmed by default. The console roster lists it with Enabled: false. To arm it, set the Actions variable CORE_FORGE_ENABLED=true, or use the forger’s control among the console’s agent controls. A disarmed run reads nothing and writes nothing, and its step summary says “Forger is DISARMED”. See Agent fleet.

Every push to a forged repository is then verified centrally. See Central verification.