Operations · 6. Explorer, Studio, Site map and the graphs

These are the surfaces that are not about a specific subsystem: search, building, finding and looking. This chapter is reference. Studio is the largest and comes first.

6.1 Studio: what it is, and where its four sections live

Studio is the console's builder. It lives at #/canvas/studio and is reached two ways: the Studio button beside the theme control in the expanded rail, or the Studio row in the account menu (shell.html:3658, shell.html:3733).

Inside it, a four-button segmented control is the primary navigation. Each section is deep-linkable with ?sub= (render.js:7377):

SectionHashWhat it is for
Board#/canvas/studioCompose a board of tiles: notes, live API read-outs, same-origin embeds
Pages#/canvas/studio?sub=pagesDefine workspaces and the pages inside them
Integrations#/canvas/studio?sub=integrationsThe one actionable integrations home: connect, install, grant, invoke, revoke
Library#/canvas/studio?sub=libraryThe curator-signed catalogue of boards, designs, workspaces and packs

Any other ?sub= value falls back to Board (shell.html:5403).

The destination is named canvas for historical reasons, Board, Graph and Tree used to live here before they moved into Rings. Every #/canvas/board|graph|tree link redirects; #/canvas/studio is stable.

6.2 Studio › Board: the tile studio

Open this to build a dashboard. You drag tiles onto a snapping canvas, bind some of them to live daemon reads, and the layout persists daemon-side as a fact (render.js:6084).

Boards are stored under console:tileboard:<id> and reusable tile configurations under console:tiledesign:<slug>, both with key doc/def (render.js:5516). Everything is a fact, so an agent can write one via MCP.

The tile kinds

Twelve kinds ship (render.js:5538):

KindBodyWhat it is
NotestandardTitle, sub, body text
Projectstandard-
Serverstandard-
Storagestandard-
Clientstandard-
Outputstandard-
BoxblankA container to group tiles visually
Web embediframeA same-origin, root-relative path only
API tileroute-boundReads a daemon GET route and renders it with a preset
Text searchfixed routeA search read-out
Corpus statusfixed routeCorpus health
Receiptsfixed routeRecent receipts
Extensionsfixed routeInstalled extensions

Two legacy kinds were dropped and render an honest unsupported note rather than mis-rendering: 3D model tiles and PDF document tiles (render.js:5556).

A web tile may embed only a same-origin, root-relative path. External URLs, protocol-relative //host, javascript: and data: are all rejected (render.js:5581). The stated alternative is to ingest the data and bind an API tile.

An API tile may bind only to a route in the generated GET allowlist. Arbitrary strings are rejected before any fetch (api.js:958).

The toolbar

ControlDefaultWhat it does
Toggle libraryshownShows or hides the left palette of tile kinds and saved designs
Zoom out / Zoom in-Canvas zoom
Fit-Fits all tiles
Toggle gridonShows the 20px snap grid
Live chip-The live-tile stream state, from /v1/events/stream
Board settings-Opens the settings modal
Export-Builds a portable, signed pack from this board and downloads it
Import-Applies a Studio pack. Operator posture only; read-only otherwise
?-How to publish a pack
Save-Saves the board now. Operator posture only

Autosave runs 1.5 seconds after any move, resize or edit; Save is the manual override (render.js:5522).

Board settings

FieldDefaultOptions
Board titleempty-
Descriptionempty-
Grid2016, 20, 24, 32, 40
Refresh-Off · Live · 30s · 60s · 5m (render.js:5530)
Accent-The theme accent tokens

Live streams via /v1/events/stream with a targeted refetch on relevant events; the numeric options are poll intervals; Off is manual.

The tile inspector

Select a tile and the right panel becomes its editor. With nothing selected: Select a tile to edit it. Add tiles from the library on the left.

ControlApplies toNotes
Bring front / Send backAny tileZ-order
Save as designAny tileSaves the configured tile as a reusable design in the library
Delete tileAny tileDanger-styled
Same-origin pathWeb tilePlaceholder /console
Daemon GET routeAPI tileA datalist of the known literal GET routes. Free text is validated against it
Token budgetAPI tileShown only for routes that accept one, /v1/activity, /v1/facts, /v1/context (render.js:5527)
PresetAPI tilestat · list · sparkline · gauge · badge
RefreshAPI tileThe same five options as the board
JSON pathAPI tileWhich field to read out of the response
LimitList presetDefault 7

That budget field is the operationally important one: budgets are mandatory on retrieval reads, so the editor surfaces the field exactly where it applies and hides it where it would be ignored.

Drag from a tile's link handle onto another to create a link. Selecting a link gives a label field, a Make one-way / Make two-way toggle and Delete link.

Export and import

Export opens a modal with pack id (pre-filled studio.<slug>), name, version (0.1.0), publisher passport fingerprint and summary, then Build + download.

Import takes a .json file and shows what it would write before Apply to this board, which is operator-only.

6.3 Studio › Pages: workspaces

Open this to reshape the console's navigation. A workspace is a named set of destination groups and the pages inside them; built-ins render from the registry until you take control (render.js:7442).

The page states its own storage contract in a footer line: entities console:workspace:<uid> and console:page:<uid>, key def, canonical key-sorted JSON. An agent can generate identical workspaces via PUT /v1/facts or MCP store_fact, the console is one writer of that format, not the only one.

Layout is a tree on the left and an editor on the right.

ControlWhereWhat it does
+ New workspaceHeaderCreates from a starter template, remix, not blank
Workspace rowTreeSelects a workspace for editing
+ pageUnder a workspace's groupAdds a page of any registry type
Page rowTreeSelects a page. A forked built-in carries a forked badge
revertOn a forked built-inReverts to the registry version. The fork is reversible by design

Editing a workspace gives its title, sub-line, icon (from a fixed set of fourteen glyphs) and destination groups. Editing a page gives its title, sub, destination and config, plus a raw-JSON escape hatch that preserves unknown keys, so a page written by a newer agent is not silently stripped when you edit it in the console.

In customer posture the whole surface is browsable and a banner says: Read-only, operator posture required to create, edit, fork or revert. Everything below is live and browsable.

6.4 Studio › Integrations: the actionable home

This is the only place in the console where an integration is actually connected, installed, granted, invoked or revoked. Both System pages link here rather than restating flows they cannot run (render.js:8624).

Four sections, each with a one-sentence statement of what it is:

SectionThe sentence it leads with
ConnectorsCredentials are sealed daemon-side. The console posts them once and never reads them back
PacksInstall is not grant, a pack does nothing until a passport grant names its capabilities
Extensions + catalogCommunity extensions, installed from a curator-signed index the daemon re-verifies locally against its trusted keyring
Trusted keysThe Ed25519 keyring every signed manifest verifies against

The distinction in the Packs line is the one operators get wrong. Installing a pack grants nothing. A grant is a separate, passport-scoped action.

Cards in the section, in order: GitHub connector, OpenAI connector, packs, installed extensions with per-extension grant panels, the catalogue browser with a per-entry safety scorecard, and the trusted-key list with an add form.

In customer posture the whole surface is live and read-only, with a banner: Read-only, customer posture. Status is live; connect, install, grant, invoke and revoke need operator posture.

Every write here goes through the same gated client and the same bound-passport requirement as everywhere else.

6.5 Studio › Library: the signed template catalogue

Open this to install a board, design, workspace or pack somebody else built (render.js:8951).

Two routes back it: GET /v1/studio/library returns the daemon's cached, signature-verified index joined against what is already installed, and POST /v1/studio/library/{id}/install is the single mutation.

Entries are grouped by kind: Boards · Designs · Workspaces · Packs (render.js:8686).

Three refusals are built into this surface and each is worth knowing (render.js:8671):

1. There is no Refresh button. The daemon has no fetch-index route; the cache is populated by corecruxctl studio sync. The surface names the command rather than offering a control that would do nothing.

2. The tier chip is advisory. A Pro or Team chip is echoed from the catalogue, not enforced locally. The daemon stamps every response tier_enforcement: "advisory" and never gates an install on it. The chip's tooltip says so verbatim (render.js:8690). Do not read a tier chip as a local entitlement check.

3. Install results are rendered in the response's own shape, the written entities, the collision remaps (from → to) and the provenance block, and errors verbatim. A 404, 409 or 403 each carries the daemon's own detail string.

An install can only add. A colliding id is remapped, never overwritten. The header says so.

6.6 The three former Canvas views: Board, Graph, Tree

These are Rings tabs 7 to 9 (chapter 3 §3.6), and also available as workspace page types.

Board: the size-adaptive dashboard

A registry of eighteen widgets composes onto a tile canvas, with the set chosen by viewport width (render.js:3402).

TierWidthWidgets shown
xs< 720px4: glance tiles, Needs you, Fleet, Activity
s< 1600px+ Token burn, ExecPlans
m< 2560px+ Token usage, Facts, Engine, Fleet dashboard
l< 3840px+ Projects, Sessions, Tenants, Live board
xl≥ 3840px+ Passports, Gates, Orchestrators, Integrations

A very short viewport steps down one tier. Below 640px the canvas falls through to a plain stack (render.js:3447).

ControlDefaultWhat it does
Edit layoutoff (Locked)Off, tiles cannot be dragged or resized, reading never moves a tile. On, they can (render.js:2989)
Click a tile-Expands it in place
Drag the canvas-Pans
Resize handleEdit mode onlyResizes

Positions persist per tier under a storage key of board-<tier>, so a 4K layout and a laptop layout do not fight. The meta line under the board states the tier, the widget count and the grammar.

Graph: the relation graph

Real edges only. An edge exists only when both endpoints resolved to a node (render.js:3497). Seven feeds compose it: projects, work, pending gates, passports, live coordination sessions, per-project repositories and saved sessions (render.js:4502).

ControlWhat it does
Click a nodeOpens the inspector
PinKeeps the inspector loaded when you click empty space or navigate
CloseCloses the inspector and unpins
Deep link ?focus=<type>:<id>Opens focused on that node

The work feed is capped at 80 items, active-first and deterministic, because source=all can exceed a thousand and an illegible graph is worse than a partial one. The focused node is always kept, and a note under the stage states honestly: showing N of M work items, active first (render.js:4564).

Tree: the plan tree

Project → ExecPlan → Milestone → live session, from /v1/projects, /v1/work and /v1/coord/active (render.js:4662).

A session row carries its announced milestone, its declared paths (up to four) and its held leases inline, each lease showing its mode and reason.

ControlDefaultWhat it does
Kind chipsall onFilter by node kind
State chipsall onFilter by work state
FilteremptyFree text across label, id and slug
Node expandnativeNodes with children are <details>, no JavaScript needed

Two markers matter. A plan whose daemon hash and local hash disagree carries a hash-state chip with the mismatch in its tooltip. A session announcing an execplan_slug that resolves to no work item is marked unresolved: <slug> (render.js:4621); that is a real coordination problem, surfaced rather than swallowed.

Each feed that fails emits its own notice with a machine-readable reason, distinguishing "coordination is off" from "coordination errored" from "unreachable" (render.js:4582).

6.7 Explorer: searching the corpus

Open this to search. It is a destination with no sub-pages: Explorer is a search box (render.js:12642).

It starts vertically centred and un-centres once results render, the layout is the state indicator.

ControlDefaultWhat it does
Search queryempty250 ms debounce, then searches
Backend toggleLocalLocal is daemon retrieval; the other is the daemon-mediated engine
Budget field1500Relabels with the backend (below)

The budget field is two different controls wearing one input (render.js:12681):

BackendLabelMeaningCap
Localtoken budgetRetrieval token budget, default 1500none
MediatedNumber of Resultstop_k, default 850

Switching backend re-runs the search if there is a query. Both are reads, so Explorer is visible in every posture.

Results are cards: title, snippet, source, score (colour-toned) and tenant, real fields only. Clicking one opens it on its own page with a ← Back to results button. The detail view says plainly that full detail is sourced from the engine's Ask surface and that wiring is in progress.

Failures are specific rather than generic: a 404 on the mediated backend says WikiCrux search unavailable, engine mediation off; a 404 locally says Search unavailable, feature off.

A query typed into the topbar search field is carried straight in and executed on arrival.

6.8 Site map: every surface, one click away

Open this when you cannot find something. It is a map derived from the live page registry, so it cannot drift from the navigation (render.js:10461).

One section per destination, accent-coloured, each node an <a> to a registered route showing the page name, what it is for, and its literal hash route.

ElementWhat it means
YOU ARE HEREThe card matching the hash you navigated from, tracked on every hash change
Numbered steps 1–4The recommended first-run path: Rings → Sessions → Facts → Receipts (render.js:10349)
OPERATOR badgeLane weights · Pending mints · Raw JSON-RPC
FEATURE-GATED badgeIdentity
ENGINE OFF badgeMediation

The map is posture-aware: operator-only pages are omitted for a customer, and Pro-only pages are omitted entirely, so every rendered node resolves to a live route in your current posture. There are no dead nodes.

The footer prints the honest count, N destinations · M surfaces, and states that the map is derived from the registry.

A WebGL explorer over the enwiki-prose link graph, through the daemon's read-only mediation proxy (render.js:12789).

This destination is capability-gated on the daemon's runtime plan. It does not appear in the rail, the site map or the phone sheet unless the daemon reports console_link_graph as available (shell.html:4118). A deep link to #/linkgraph on a daemon without the proxy fails to an honest empty state naming CORECRUXD_CORECRUX_GRAPH_BASE_URL (render.js:12797).

ControlDefaultWhat it does
From articleemptyPath start, e.g. Dog
To articleemptyPath end, e.g. Barack Obama
Find path-Resolves both titles, then requests a path with max_hops=6
Enter, in either field-Same as Find path
Click a node-Expands its 1-hop ego network, budgeted at 400 nodes / 1,500 edges / degree cap 40

The header stat line carries the graph's own numbers and, when present, the build digest of the CoreCrux graph artefact, artefact provenance, so you can say which build you were looking at.

Errors are specific: a 503 renders Link graph unavailable, the CoreCrux graph is not built/enabled upstream, distinct from an unreachable backend (render.js:12782).

The WebGL renderer is a separate ES module, dynamically imported only when this pane opens, resolving three through the shell's import map to an already-vendored copy. No external request is made (shell.html:62).

6.10 Explore: the reader surface

Switching the workspace to Explore replaces the rail with a document tree and the content region with a reading column and an evidence panel (render.js:10076).

Eleven surfaces sit under it (render.js:9108). Their honesty status is published in the source as a per-surface manifest, and it matters (pages.js:2061):

SurfaceStatusBacked by
ProofRealTenants + facts + activity
WatchReal/v1/activity
AskRealPOST /v1/query/text-search
Living ObjectsReal/v1/admin/projections/artifacts/{id}/state
DependenciesRealPOST /v1/query/graph-expand
SignalsDemo surfaceNo endpoint: fixture only, and chipped
Receipt DiffReal/v1/activity
SourcingDemo surfaceNo endpoint: fixture only, and chipped
LanesReal/v1/console/corecrux/lane-weights
DomainsReal/v1/features/capabilities/analysis/coverage
ReverseDemo surfaceNo endpoint: fixture only, and chipped

Three of the eleven are demo-only. They render a fixture behind the demo flag and nothing otherwise. Every one carries a demo chip. Reading a number off Signals, Sourcing or Reverse and treating it as your data would be a mistake, and the chip is there to stop you.

Real-backed surfaces use their fixture only as an empty or degraded fallback; live data always wins.

The reader also carries bundled daemon reference documents, which are genuinely shipped with the build and need no endpoint (render.js:9008).

6.11 Failure states across these surfaces

What you seeWhat it is
Studio Board: Save and Import greyedCustomer posture
Studio Board: a tile says "not supported in the console"A 3D-model or PDF tile from an older board
Studio Board: a route will not bind to an API tileIt is not in the generated GET allowlist
Studio Library: emptyThe cache has never been synced. Run corecruxctl studio sync
Studio Library: a Pro chip on an entry you can installCorrect. The tier is advisory; the catalogue server enforces it
Graph: "showing N of M work items"The 80-item cap. Not an error
Graph: "Graph unavailable"One of the seven feeds threw. Check /v1/projects first
Tree: unresolved: <slug>A session announced a plan slug that no work item matches
Explorer: "engine mediation off"CORECRUXD_ENGINE_BASE_URL unset
Link graph: not in the railThe capability is not available. Check System › Settings › Runtime capabilities
Explore: a surface with a demo chipIt is a fixture. There is no endpoint behind that surface

Sources