---
name: stele-resources
description: Use this skill when working in a knowledge/resource repository published by **Stele** (a self-hosted GitHub-to-internal-site renderer at `*.stele.axelerant.tech`). Covers how to organize artifacts (folders, naming, dating, versioning), the `.stele.yml` configuration reference, supported file formats (`.md`, `.html`, `.tsx`/`.jsx`), landing-page resolution, the React runtime's fixed library set, the `build:` step (LikeC4, D2, and Graphviz are pre-installed; other tools are not), themes (the `guide` look with its generated sidebar, for Markdown and opt-in HTML), and the `ask:` block that gives a directory an assistant answering from its documents. Trigger this whenever you see a `.stele.yml` file anywhere in the repo, files like `.c4`/`.likec4`/`.d2`, or React artifacts (`.tsx`/`.jsx`) intended for direct rendering — even if the user doesn't mention Stele by name. Also use it for any "where should I put this artifact" or "add this analysis/diagram/deck/ADR/runbook" task in a Stele-published repo. And use it when the user wants the live link to something pushed to such a repo, or wants a new repository published on Stele.
---

# Stele Resource Repositories

This repository is published as an internal site by **Stele**: every push to the tracked branch is rendered at `<slug>.stele.axelerant.tech`. Authoring artifacts and committing them is the entire publishing flow — there is no separate build, deploy, or upload step.

Knowledge-style repositories ("resources") collect research, analyses, diagrams, decks, ADRs, runbooks, and standalone interface artifacts so they can be discovered, updated, and shared across teams. Source code for the systems being analysed lives in other repositories.

## Your job in this repository

Most requests are one of:

1. **Add** a new artifact (research, analysis, diagram, deck).
2. **Update** an existing artifact.
3. **Find** existing knowledge to answer a question.

For (1) and (2), **confirm folder placement with the user before writing files unless they've already specified a path.** The folder choice determines who finds the artifact later — don't guess silently. If the user says "put it in `commerce/billing/`", just do it; don't make them confirm the path they already gave you. For (3), search across the whole repo; folders are organisational, not isolating.

If a request needs application code, ask the user to point you at the right system repository — do **not** fabricate code references from artifact descriptions in this repo.

## Links to what you pushed, and onboarding (Stele MCP tools)

Stele runs an MCP server at `https://stele.axelerant.tech/mcp`. When it is connected, you have tools that act on Stele as the user:

- **`resolve_links`** — after you push a new or changed artifact, call it with the site's slug and the repository paths you touched to get the live URLs and page titles, and give them to the user. Do this instead of building `https://<slug>.stele.axelerant.tech/...` by hand: it knows the rendered route (landing pages, dropped extensions) and reports `NOT_FOUND` for a path the latest sync does not contain yet. A sync takes under a minute after a push, so `NOT_FOUND` straight after pushing usually means wait and retry, not a wrong path.
- **`get_sync_status`** — when a pushed change does not show up, check whether the site serves your commit yet (`lastSync.commit`) and whether the newest sync is queued, running or failed, rather than retrying `resolve_links` blind.
- **`onboard_repo`** — when the user wants a repository published and it is not on Stele yet. Once per repository; if the site already exists, use `resolve_links`.
- **`list_viewers`, `invite_viewers`, `remove_viewer`** — a site's viewer list. Read their descriptions before promising anyone access: a listed person gets in only on a site whose access is `restricted`, `invited` or `link` (never `internal`) and only once signed in.
- **`set_access`, `get_share_token`, `rotate_share_token`** — who can open a site (`restricted`: only the viewer list, staff included; `internal`: everyone at Axelerant; `invited`: Axelerant plus the list; `link`: the above plus anyone with the share link), and its share link, which lets anyone holding it read the whole site without signing in. Use them only when the user asks to change who can open a site, to share it outside Axelerant, or to stop sharing it. Never write a share link into the repository.

**Check before you rely on them.** The server is optional and many users have not connected it. You have it if tools named `resolve_links` and `onboard_repo` from a server called `stele` are in your tool list (in Claude Code: `mcp__stele__resolve_links`). If they are not there, do not claim a link is live and do not pretend to onboard anything. Say where the file will render once synced (see "Landing-page resolution" and "Intra-repo linking" below), and suggest the user connect the server by following <https://stele.axelerant.tech/docs/mcp>. In Claude Code that is `claude mcp add --transport http --scope user stele https://stele.axelerant.tech/mcp`, then `/mcp` to sign in. If the tools are listed but calls fail because the server needs authentication, ask the user to run `/mcp` and authenticate **stele**.

**Read [`references/mcp.md`](references/mcp.md)** for each tool's arguments, results and errors, and how to find a repository's slug.

## Organising the repo

Knowledge is typically organised along two axes: the **team** that owns it (engineering, marketing, design, product, business) and the **system or domain** it concerns. Each artifact has a primary axis — pick that one.

### Choosing a folder for new content

**Create new folders (top-level or nested) whenever an existing one is a poor fit.** Do not jam unrelated artifacts into a folder just because it exists. Propose, confirm, create.

Decision order, then ask the user to confirm:

1. **System / domain-specific?** Use `<system>/` — e.g. `commerce/`, `billing/`, `auth/`.
2. **Team-specific and cross-system?** Use `<team>/` — e.g. `marketing/`, `design/`, `engineering/`, `product/`.
3. **Cross-cutting reference** spanning systems and teams (architecture views, business priorities, decks)? Use a top-level folder named for the artifact's purpose (e.g. `architecture/`, `priorities/`, `decks/`).

When proposing a new top-level folder, state what kind of content it is meant to hold so the user can correct the framing.

### Subfolders are first-class

When a folder starts accumulating artifacts on distinct sub-topics, **group them into subfolders** instead of letting the parent flatten into a dumping ground. Triggers:

- Multi-file artifact (a diagram with sources and exports → its own subfolder).
- A topic likely to grow (`<system>/<topic>/` with multiple related write-ups).
- A team folder gaining multiple initiatives (one subfolder per initiative).

Propose the subfolder name to the user along with the file placement. Confirm before creating.

### Naming and dating

- **kebab-case** for folders and files (`frontastic-analysis.md`, not `Frontastic Analysis.md`).
- **Date-stamp** point-in-time artifacts with `**Date:** YYYY-MM-DD` near the top of the file.
- For React artifacts versioned over time, use a `-vN.tsx` suffix (`audit-v3.tsx` → `audit-v4.tsx`).

## Updating existing artifacts

Before creating a new file, **search for an existing artifact on the same topic** and prefer updating it.

- **Refresh in place** — same scope, new findings: edit the file, bump the date.
- **New version** — meaningfully different scope or a snapshot worth preserving: create a new file alongside the old (`overview-v2.md`, `audit-v4.tsx`). Do not delete the old version unless asked.

If unsure whether the work supersedes or sits alongside, ask.

## Stele rendering

### Supported file types

| Extension | Rendered as |
|---|---|
| `.md` | GitHub-flavoured Markdown — tables, task lists, syntax highlighting, Mermaid code blocks, heading anchors, and GitHub alerts (`> [!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, `[!CAUTION]`) drawn as callouts. YAML frontmatter is not printed as text; `owner`, `type`, `applies_to` and `last_verified` appear as a strip under the title, and the fields below change how the page is drawn. |
| `.html` / `.htm` | Served inside an iframe that shares the site's origin. Sibling assets (images, CSS, JS, fonts) resolve via relative links, and `fetch()` of sibling data files (JSON, CSV) works. Plain relative links to other pages (`<a href="pricing.html">`) are rewritten by Stele to the page's rendered URL and open as a whole page, so the address bar, refresh and Back work — do **not** add a `top.history.replaceState()` snippet or `target="_top"` by hand. |
| `.tsx` / `.jsx` | Standalone React components. Must `default-export` a component with no required props. Compiled at sync time. |

Anything else (PNG, PDF, CSV, JSON, fonts, etc.) is served as a static asset at its repo path. Files larger than 25 MB are excluded.

### Landing-page resolution

For the site root and for every directory the user navigates into, Stele picks a landing page in this order:

1. A `landing` path specified in the directory's `.stele.yml` — wins over everything else
2. `index.html`
3. `index.htm`
4. `index.jsx`
5. `index.tsx`
6. `index.md`
7. `README.md` (case-insensitive)
8. A Markdown file with `stele.landing: true` (or nested `stele: { landing: true }`) in its frontmatter; only the boolean `true` counts

If none resolve, the directory returns a 404, unless the directory is a collection (below), whose generated list then becomes the landing. A freshly initialised repo with only a top-level `README.md` renders that file at `/` immediately. If you want to override the natural `README.md`/`index.*` choice for a folder, the cleanest way is `.stele.yml` `landing:`.

### Intra-repo linking

Use normal relative links — Stele rewrites them to the rendered URLs:

```markdown
See the [overview](./overview.md) for details.
Check the [audits](../audits/) directory.
```

Links to non-renderable assets (images, PDFs, ZIPs) serve the file directly. External URLs pass through unchanged. `#anchor` links are left as written: in Markdown they scroll to the heading slug; in an HTML page Stele makes them scroll the iframe (next section). **Cross-repository links are not rewritten** — they pass through as authored.

### HTML pages run inside a sandboxed srcdoc iframe

Each `.html` page is put into a Stele page as `<iframe srcdoc>`, sandboxed with `allow-scripts allow-same-origin allow-top-navigation-by-user-activation allow-popups allow-popups-to-escape-sandbox`. Write it as an ordinary static page; Stele handles the frame. What that means for an author:

- **The document is `about:srcdoc`, in the site's origin.** Relative URLs resolve against the page's URL, so sibling assets and `fetch()` work. `location` inside the frame is `about:srcdoc` and `location.hash` is empty; the real URL is `top.location`, which a script may read (same origin).
- **Links to other pages** are rewritten to their rendered URL with `target="_top"`, query and fragment kept. A `<base href>` turns the rewrite off for the whole page.
- **`#id` links and deep links work.** Stele scrolls the frame to the element with that `id` (or `<a name>`) when the page opens at `/page#id`, when a same-page `#id` link is clicked (the fragment goes into the address bar), and on Back and Forward. Content a script renders after load is waited for, for up to ten seconds or until the reader scrolls. A click your own script handles with `preventDefault()` is left to it.
- **`target="_blank"` opens a new tab**, not sandboxed.
- **Do not add frame boilerplate**: no `top.history.replaceState()`, no hand-written `target="_top"`, no script that mirrors or reads the hash to scroll. Pages that carry it from before keep working, but it is no longer needed.
- **For `ask.renders` with `anchor_field`**, the page must give each record an element whose `id` is that field's value (`<tr id="WM-067">`). Rendering the records from the data file after load is fine. A citation link then opens the page scrolled to the record, with no script of your own.

### React (TSX / JSX) runtime

Stele provides a fixed, centrally-managed runtime. You **cannot** add libraries or pin versions. Available imports:

| Library | Import | Version |
|---|---|---|
| React (with Hooks) | `react` | 19.x |
| ReactDOM | `react-dom`, `react-dom/client` | 19.x |
| Tailwind utility classes | _(global, no import)_ | — |
| lucide-react | `lucide-react` | 1.x |
| Recharts | `recharts` | 3.x — **currently broken**, see gotchas below |
| D3 | `d3` | 7.x |
| Lodash | `lodash` | 4.x |
| mathjs | `mathjs` | 15.x |
| Papa Parse | `papaparse` | 5.x |

Minimal component:

```tsx
export default function Dashboard() {
  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold">Project Dashboard</h1>
    </div>
  );
}
```

**Breaks rendering:** a `.tsx`/`.jsx` without a default export, a default export with required props, or imports from libraries outside the runtime list. There is no `package.json`, no bundler config, no way to add dependencies.

Components can `fetch()` sibling files (CSV, JSON) at relative paths — commit the data file alongside the component.

### Known TSX runtime gotchas

The runtime table tells you what's *importable*. It does not guarantee every listed library renders cleanly — a library can be present and still fail at module init if its published bundle expects a CommonJS loader the browser ESM runtime doesn't provide. **Type-checking does not catch these failures; only rendering the component does.** When building a TSX artifact, render it (locally with a Stele preview, or by pushing to a draft branch) and check the browser console before declaring the work done.

Specific things not to do:

- **Don't use `recharts`.** Importing anything from `recharts` triggers `Uncaught Error: Dynamic require of "react" is not supported` at module init — the published bundle calls `require("react")` synchronously and the runtime has no CommonJS shim. The entire component fails to mount, not just the chart. For charts, render plain SVG (a two-bar comparison is ~30 lines) or use `d3` directly. Both are reliable.
- **Don't write custom CSS that depends on Tailwind features beyond utility classes.** Tailwind is loaded as a runtime browser build that scans the rendered DOM for utility classes — there is no theme config, no `@apply` in stylesheets, no plugins. Inline `style={{...}}` is the escape hatch when a value isn't in the default palette.
- **Don't reach for libraries outside the runtime list, even popular ones.** No `framer-motion`, no `@radix-ui/*`, no `react-router`, no `next/*`, no other charting or animation packages — there is no install step that can add them. If a TSX needs motion, write CSS transitions; if it needs routing, render conditionally on state.
- **Don't pin versions or assume `package.json`.** There is none. Import bare specifiers (`from "react"`, `from "lucide-react"`) and accept whatever the runtime provides.
- **Don't fetch absolute repo paths.** Sibling-relative fetches (`fetch("./data.csv")`) work; an absolute URL to another part of the site does not.

### Markdown frontmatter

```markdown
---
title: Architecture Overview
description: High-level system design
stele:
  landing: true
---
```

`stele.landing: true` marks the file as the preferred landing page for its directory, and `title` names the page ahead of its first H1. `theme:` draws this one page in another theme than its folder's, `description` is the summary under the title in the guide theme, and `weight` (a number, lower first) orders the page in the guide theme's sidebar. In a collection folder (below), each type's standard fields (`status`, `date`, `severity`, `supersedes`, …) build the folder's generated list.

## Themes (guide-style pages)

Stele draws Markdown pages in the folder's theme. `default` is Stele's plain look. `guide` is the Axelerant codebase-guide design: numbered section cards, a fixed sidebar of every page in the guide, previous/next links. Use it for a set of pages read together — a codebase guide, onboarding notes, an analysis with several pages.

- **Turn it on with one line** in the folder's `.stele.yml`: `theme: guide`. It covers the folder and below.
- **Write plain Markdown.** One `#` title per page, with at most one `*emphasised*` word (drawn in the accent colour). Each `##` becomes a numbered card, and the first paragraph under it reads as the section's lead. Put the page's one-sentence point in frontmatter `description`. Use `> [!WARNING]` / `> [!TIP]` / `> [!NOTE]` for callouts, starting with a bold clause.
- **Don't write a nav, an index of pages, section numbers or prev/next links.** Stele derives the sidebar from the folders (subfolders become groups), frontmatter `weight` and titles, and a new page shows up without any edit. Only when folders don't express the grouping, add a `nav:` list to the same `.stele.yml`; pages it leaves out still appear after it. Format in [`references/manifest.md`](references/manifest.md).
- **Hand-written HTML is never restyled.** For a guide-style HTML page, link `/_stele/themes/guide/theme.css` and `<script src="/_stele/themes/guide/theme.js" defer>` (fixed URLs, no `../` counting) and leave an empty `<nav data-stele-nav></nav>`; Stele fills it with the sidebar. Use the theme's classes (`header .crumb/.thesis/.meta`, `section.card` with `h2 .no` and `p.lead`, `.callout.warn|info|good`, `.pill.*`, `.tablewrap`, `.cols`, `.stage`) and no inline styles. Do **not** copy `guide.css`, `guide.js` or a hand-written nav into the repo. The user guide's [Themes](https://stele.axelerant.tech/docs/themes) page has a full skeleton.

## Collections (ADRs, runbooks, audit findings)

Stele lists some folders for you. `docs/adr/` (ADRs), `docs/runbooks/` (runbooks) and `docs/audits/` (technical audit findings) are **collections** with no configuration, and any other folder becomes one with `collections: adr` (or `runbook`, `finding`) in its `.stele.yml`. Each Markdown file in the folder is an item; Stele reads its frontmatter at sync and adds a generated table of the items to the folder's landing, below the README, ordered by status, with relations shown both ways and computed counts.

So when you add an ADR, runbook or finding:

- **Write the item file with its type's standard frontmatter** (ADR: `title`, `status`, `date`, `decision-makers`; runbook: `title`, `owner`, `last_verified`; finding: `title`, `status`, `severity`). Use the known status values.
- **Do not add it to a hand-written list in the README**, and don't write counts there; the generated list and counts update themselves. If the README already has a hand list, ask the user whether to remove it or set `append: false`.
- **Link items with forward relations only**, by item id (the path inside the folder without `.md`): `supersedes: [0003-old-choice]` on the new ADR, `related:`, `duplicates:`. Stele derives "Superseded by" and the rest.
- For runbooks on call, the alert-to-runbook mapping is the file named by `alerts_file` in `.docs/repo.yml`, not the runbook's `alert:` field.

Nothing here is enforced: unknown values, broken references and a mistake in `collections:` are sync warnings, and every page still renders.

**Read [`references/collections.md`](references/collections.md) before writing an item or a `collections:` setting** — it has every type's fields and values, ids and relations, the README's collection fields (`audited_on`, `scope`, `must_do`), where the list appears, and the alerts file format.

## `.stele.yml` (configuration)

`.stele.yml` is **optional**. Stele works with zero configuration; add a manifest only when defaults aren't right. It can appear at the repo root and/or in any subdirectory; paths are always relative to the directory the config lives in.

The fields, briefly:

- `roots` — restrict indexing to these subdirectories (children narrow; cannot widen the parent).
- `exclude` — glob patterns to skip in addition to `.gitignore` (children add to the parent's set).
- `landing` — file path for this directory's landing page. **Wins over `index.*` and `README.md`** — use this to override conventional landings without renaming files.
- `access` — narrow who may open this directory to `restricted` (only the site's viewer list, staff included), `internal` (everyone at Axelerant), `invited` (Axelerant plus the viewer list) or `link` (also share-link holders). **Intersected with the site's setting and every parent's value, so it can only narrow.** A guessed path under the folder is refused whether or not the page exists, and the assistant never answers from pages the asker cannot open. Use it for a client folder in a shared repo, or an internal folder on a site shared outside Axelerant.
- `file_browser` — `enabled` / `path` for the `/_browse` browser. **Root manifest only.**
- `build` — run a shell command at sync time and serve the output. **Does not inherit.** See the build section below.
- `collections` — make this directory a collection of one built-in type (`adr`, `runbook`, `finding`) so Stele lists its items on the landing, or `none` to turn a conventional folder off. Nearest setting wins. A mistake inside it is a sync warning, not a failure.
- `ask` — an assistant that answers questions from these documents, with links back to the pages they came from. **Does not inherit its parent's file set**: each `ask:` is a corpus rooted at its own directory, and the nearest one wins for a page. See the Ask section below.

**Read [`references/manifest.md`](references/manifest.md) before authoring or editing a `.stele.yml`** — it has the full schema, every field's defaults and merge semantics, common patterns (publishing only certain trees, hiding drafts, pinning a TSX as the site landing), and validation gotchas.

## Ask (an assistant over your documents)

An `ask:` block in a `.stele.yml` gives that directory a chat panel that answers from the documents under it and links every claim to the page it came from.

```yaml
ask:
  name: Platform Docs
```

The manifest says what the corpus is; it never says which model answers it. Two things need doing outside the repository before it answers, and neither is something you can fix by editing YAML: the site must be **assigned a provider and a model** in the portal, and a Stele administrator must **opt the site in** — an acknowledgement that repository text and viewers' questions go to a third-party model. Until both are true, the manifest is parsed, validated, and inert. Mistakes here surface as warnings on the site's Ask settings page, not as sync failures: the site keeps rendering either way.

**It reads more than the site publishes.** All text under the corpus root is readable, including files the indexing rules exclude — which is the point, because a `build:` step hides its own sources from the published site. Four ceilings always hold: the corpus root, `.gitignore`, hidden directories, and a secret denylist. **So check the corpus file list on the site's Ask settings page before you consider it done** — it flags every file that is readable but unpublished, and `ask.exclude` is how you remove one.

`audience` names a set of people, the same sets as the site's access: it defaults to `internal` (everyone at Axelerant). `audience: invited` adds the people on the site's viewer list (signed in by emailed link) but still refuses share-link-only visitors; `audience: all` opens it to anyone who can read the site, share-link viewers included. It is intersected with the site's access and any folder `access:`, so it can only narrow, and the assistant never answers from pages the asker cannot open. Anything beyond `internal` needs the site's provider approved for customer data, and every audience needs the site opt-in.

**Every claim links to the page it came from, and the link is chosen at sync time, never by the model.** A page cites itself (sections included); a source under a `build:` folder, such as a `.likec4` model, cites the diagram page it becomes; a data file a page draws cites the raw file unless you say which page renders it:

```yaml
ask:
  name: Support
  renders:
    technical-audit/findings.json:
      page: technical-audit/index.html
      anchor_field: id   # only if the page gives each record an element id
```

**Read [`references/manifest.md`](references/manifest.md) for the full `ask:` schema**, the merge rules, and "Where citations point", which works through the page, LikeC4 and data-file cases.

## Build steps (LikeC4, D2, generated docs)

Stele can run a build command for a directory at sync time and serve the resulting output as that directory's content. Commit the *sources*, gitignore the output, push — Stele rebuilds on every sync. Diagram tools work this way: source files (`.c4`/`.likec4`/`.d2`) aren't rendered as pages; the `build` step turns them into HTML/SVG that is.

The build environment is a **fixed, small** set of tools — anything outside this list fails with "command not found":

- `node` / `npm` / `npx` (Node 24, full registry)
- `git`, `curl`
- `dot` (graphviz)
- `likec4` — pre-installed globally
- `d2` — pre-installed

If a build needs a tool that isn't here (PlantUML, mermaid-cli, language toolchains beyond Node, etc.), don't assume it works because it works on your laptop — ask the maintainers to add it to the worker image.

Minimal LikeC4 manifest:

```yaml
# architecture/c4/.stele.yml
exclude:
  - dist/404.html
build:
  command: likec4 build . --output-single-file
  output: dist/
```

When indexing, Stele only walks `output/` for this directory and rebases its contents up — `architecture/c4/dist/index.html` is served at `architecture/c4/index.html`. The build runs in the manifest's directory with a 2-minute timeout; non-zero exit fails the sync.

**Read [`references/build-steps.md`](references/build-steps.md) when setting up a build folder** — it has the full LikeC4, D2, Graphviz, and "no-build Mermaid" recipes, the exact constraints (timeout, no persistent state, no inheritance), and the rationale for each.

## Cheatsheet

- Renderable: `.md`, `.html`, `.htm`, `.tsx`, `.jsx`. Everything else is served as a static asset.
- Landing order: `.stele.yml` `landing:` → `index.html` → `index.htm` → `index.jsx` → `index.tsx` → `index.md` → `README.md` → frontmatter `stele.landing: true`.
- `.stele.yml` is optional. Fields: `roots`, `exclude`, `landing`, `access` (narrows who may open the folder; never widens), `build` (per-directory), `ask` (per-directory), `collections` (per-directory), `theme` and `nav` (per-directory), `file_browser` (root only).
- Collections: `docs/adr/`, `docs/runbooks/`, `docs/audits/` (or `collections:` elsewhere) are listed by Stele from item frontmatter. Don't hand-maintain an index; write forward relations only (`supersedes`, `related`, `duplicates`) as item ids (path in the folder without `.md`). See `references/collections.md`.
- Per-directory configs: `roots` narrows, `exclude` unions, `landing` is local, `build` does not inherit, `ask` roots a corpus at its own directory and the nearest one wins.
- `ask:` reads everything under its directory, published or not — check the corpus file list on the site's Ask settings page and use `ask.exclude`. `audience` defaults to `internal` (everyone at Axelerant) and only ever narrows the site's and folders' access. Needs a portal grant and a site opt-in before it answers.
- Citations: a page cites itself, a `build:` source cites its diagram page, a data file cites the raw file unless `ask.renders` names the page that renders it (`anchor_field` for per-record links). `ask.sources: ["**/*.likec4"]` makes model sources readable.
- Guide-style pages: `theme: guide` in the folder's `.stele.yml`; Stele builds the sidebar, numbering and prev/next. HTML opts in via `/_stele/themes/guide/theme.css` + `theme.js` and an empty `<nav data-stele-nav></nav>`.
- React: default-export only, no required props, no custom dependencies, runtime is fixed.
- Diagram tools available in the build env: `likec4`, `d2`, `dot` (graphviz). Anything else (PlantUML, mermaid-cli, etc.) will fail with "command not found".
- For build folders: declare `build:` in the folder's `.stele.yml`; commit sources, gitignore the output.
- File browser lives at `/_browse` by default and is linked from every page.
- Push to the tracked branch → site updates within 60 seconds. No other deploy step.
- Live link to what you pushed: `resolve_links` (Stele MCP server) if it is in your tools; otherwise say the expected path and point the user at https://stele.axelerant.tech/docs/mcp. New repository: `onboard_repo`.
