diff --git a/web/content/docs/file/review-bot-brief.mdx b/web/content/docs/file/review-bot-brief.mdx
index 4d5460f..ef66d55 100644
--- a/web/content/docs/file/review-bot-brief.mdx
+++ b/web/content/docs/file/review-bot-brief.mdx
@@ -4,7 +4,11 @@ description: 'A complete, copy-paste operating document for a Relayfile-backed P
---
- **This whole page is the brief.** Everything below is addressed to the agent, not to you. Take it with **Copy page as markdown** (top right) or `curl -o AGENTS.md https://agentrelay.com/docs/file/markdown/review-bot-brief.md`.
+ **This whole page is the brief.** Everything below is addressed to the agent, not to you — it is meant to be fetched as markdown and handed over, not browsed:
+
+ ```bash
+ curl -o AGENTS.md https://agentrelay.com/docs/file/markdown/review-bot-brief.md
+ ```
Before handing it over, replace every `` placeholder — `/` and the specialist name are the two you set once, and ``, ``, ``, ``, ``, ``, and `` are filled per run or per finding. Verified against `relayfile` 0.10.53; it pairs with [Build a PR review bot](/docs/file/review-bot).
diff --git a/web/content/docs/file/review-bot.mdx b/web/content/docs/file/review-bot.mdx
index 1514113..266c96d 100644
--- a/web/content/docs/file/review-bot.mdx
+++ b/web/content/docs/file/review-bot.mdx
@@ -50,7 +50,7 @@ The integration stack is hosted either way — what changes is where the bot's p
## 1. Connect GitHub
-One command logs you into Cloud, creates the workspace, runs the provider OAuth, waits for the first sync, and mounts the result:
+One command logs you into Cloud, creates the workspace, runs the provider OAuth, and waits for the first sync. This is **provisioning** — a human does it once, on a machine with a browser, because the provider OAuth needs one:
```bash
relayfile setup \
@@ -62,6 +62,8 @@ relayfile setup \
`--no-open` prints the login and connect URLs instead of launching a browser — always pass it when an agent (or CI) is driving the command, since a headless browser launch burns the OAuth state.
+The local mirror it leaves behind is for *you*: somewhere to `ls`, `cat` and `grep` the tree and see exactly what your agents will see. It is not how a deployed bot reads the workspace — cloud sandboxes mount per run in [step 5](#5-give-every-sandbox-the-same-workspace), and short-lived functions skip the mount entirely. `--local-dir` is required here only because `--skip-mount` still prompts for a directory ([relayfile#461](https://github.com/AgentWorkforce/relayfile/pull/461)).
+
Both URLs are short-lived. A Cloud device code expires in minutes and the Nango connect URL has its own TTL, so complete them while the command is still waiting. If it exits first, re-run the same line — a re-run reuses the workspace and only opens a new connect flow when the provider isn't connected yet.
@@ -413,6 +415,16 @@ Alternatives: subscribe in-process with the SDK (`connectWebSocket({ onEvent })`
Either way the reviewer wakes on provider state changing rather than on a request arriving — see [Events and webhooks](/docs/file/events). In the cloud, keep the subscriber in one long-lived orchestrator that spawns a sandbox per PR.
+## Give your agent a guide for this
+
+Everything above is written for you. The same contract written for the agent — its environment, the orient-before-acting rules, its ACL boundaries, the `/runs` run protocol, discovery-first writeback, and how to confirm a write actually landed — is one markdown file you can hand it directly:
+
+```bash
+curl -o AGENTS.md https://agentrelay.com/docs/file/markdown/review-bot-brief.md
+```
+
+Drop it in as `AGENTS.md`, `CLAUDE.md`, or a skill. Replace the `` placeholders before handing it over: `/` and the specialist name are set once, while ``, ``, ``, ``, `` and `` are filled per run.
+
## Tear down
```bash
@@ -426,9 +438,6 @@ rm -rf ./relayfile-mount
`relayfile workspace join --name ` **renames an existing local entry** for that workspace id rather than adding a second one. If you're scripting workspace setup, check `relayfile workspace list` before and after.
-
- Copy-paste agent brief — the same contract written for the agent itself, ready to drop in as `AGENTS.md`.
-
@@ -440,7 +449,7 @@ rm -rf ./relayfile-mount
Why the orchestrator sees a specialist's write on the next read.
-
- The copy-paste operating document to hand the agent.
+
+ Every flag used in this guide.
diff --git a/web/lib/product-docs-nav.ts b/web/lib/product-docs-nav.ts
index 79ad751..6758978 100644
--- a/web/lib/product-docs-nav.ts
+++ b/web/lib/product-docs-nav.ts
@@ -29,6 +29,12 @@ export interface ProductDocSection {
repo: string;
/** Current published version, shown as a badge in the sidebar header. */
version?: string;
+ /**
+ * Slugs that are built and indexed but deliberately kept out of the sidebar —
+ * pages whose real audience is an agent fetching the `.md` mirror, not a
+ * human browsing the nav.
+ */
+ unlistedSlugs?: string[];
nav: NavGroup[];
}
@@ -38,6 +44,8 @@ export const fileSection: ProductDocSection = {
tagline: 'The event layer for AI agents.',
repo: 'AgentWorkforce/relayfile',
version: '0.10.53',
+ // Handed to an agent as markdown from the review-bot guide, not browsed.
+ unlistedSlugs: ['review-bot-brief'],
nav: [
{
title: 'Start',
@@ -49,10 +57,7 @@ export const fileSection: ProductDocSection = {
},
{
title: 'Guides',
- items: [
- { title: 'Build a PR review bot', slug: 'review-bot' },
- { title: 'Review bot agent brief', slug: 'review-bot-brief' },
- ],
+ items: [{ title: 'Build a PR review bot', slug: 'review-bot' }],
},
{
title: 'Concepts',
@@ -221,7 +226,12 @@ export function getProductSectionForPath(pathname: string): ProductDocSection |
}
export function getProductDocSlugs(section: ProductDocSection): string[] {
- return [...new Set(section.nav.flatMap((group) => group.items.map((item) => item.slug)))];
+ return [
+ ...new Set([
+ ...section.nav.flatMap((group) => group.items.map((item) => item.slug)),
+ ...(section.unlistedSlugs ?? []),
+ ]),
+ ];
}
export const productBasePath = (section: ProductDocSection): string => `/docs/${section.id}`;
diff --git a/web/lib/test/product-docs.test.ts b/web/lib/test/product-docs.test.ts
index 5502b09..ccaa63f 100644
--- a/web/lib/test/product-docs.test.ts
+++ b/web/lib/test/product-docs.test.ts
@@ -1,6 +1,11 @@
import { describe, expect, it } from 'vitest';
-import { factorySection, fileSection, getProductSearchIndex } from '../product-docs';
+import {
+ factorySection,
+ fileSection,
+ getProductDocSlugs,
+ getProductSearchIndex,
+} from '../product-docs';
describe('Factory product docs', () => {
it('publishes issue routing in navigation and scoped search', () => {
@@ -24,13 +29,20 @@ describe('Factory product docs', () => {
});
describe('Relayfile product docs', () => {
- it('publishes both review-bot guides in a Guides group', () => {
+ it('lists only the human guide in the sidebar', () => {
const guides = fileSection.nav.find((group) => group.title === 'Guides');
- expect(guides?.items).toEqual([
- { title: 'Build a PR review bot', slug: 'review-bot' },
- { title: 'Review bot agent brief', slug: 'review-bot-brief' },
- ]);
+ expect(guides?.items).toEqual([{ title: 'Build a PR review bot', slug: 'review-bot' }]);
+ });
+
+ it('still builds and indexes the agent brief, unlisted', () => {
+ const navSlugs = fileSection.nav.flatMap((group) => group.items.map((item) => item.slug));
+
+ expect(navSlugs).not.toContain('review-bot-brief');
+ expect(fileSection.unlistedSlugs).toContain('review-bot-brief');
+ // getProductDocSlugs drives the page, og and markdown routes, so the .md
+ // endpoint the guide links to must stay in it.
+ expect(getProductDocSlugs(fileSection)).toContain('review-bot-brief');
});
it('indexes the review-bot guide, including the cloud path', () => {