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(thecore-systemSecretforge-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:
- New chat. This opens the studio on
/forge/?chat=new, an empty chat. - 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:
| State | What you see |
|---|---|
| Still reading | A loading state |
| FORGE unreadable | The reason, and a retry |
| Read, no chats | An 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=newA 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 byworkflow_dispatch. It takes the oldest openforgeissue in the org, relabels itforge:running, and runscore session start --repo <owner/name> --issue <n>against it. - If a PR comes out, the issue gets
forge:doneand a comment linking the draft PR. If not, it getsforge:failedand a comment saying why. A failed issue is not retried automatically: re-add theforgelabel to requeue it. - The session verifies at
CORE_SESSION_VERIFY=build. It rises totestonly 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.
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.