From 7bc4c63d73387eca532d5c5131ab397732530f19 Mon Sep 17 00:00:00 2001
From: oktofeesh1 <287075021+oktofeesh1@users.noreply.github.com>
Date: Thu, 16 Jul 2026 08:48:35 +0200
Subject: [PATCH] docs(ams): port docs/fleet-run-manifest.md to a website docs
page (docs.ams-fleet-manifest.tsx)
Add content/docs/ams-fleet-manifest.mdx covering the top-level fleet-operator
config for running the miner across many repos -- the repos list, per-repo
and total worktree/concurrency budgets, and how it contrasts with the
per-repo .loopover-miner.yml goal spec -- rendered via the existing
DocsPage/Callout/CodeBlock/FeatureRow primitives. Add the page to
docs-nav.tsx's "AMS: deployment" subgroup and to docs.index.tsx's
Maintainers audience card.
packages/loopover-miner/docs/fleet-run-manifest.md stays as the canonical
source (ships inside the published @loopover/miner package) with a short
pointer added to the new website page.
---
.../content/docs/ams-fleet-manifest.mdx | 64 +++++++++++++++++++
.../src/components/site/docs-nav.tsx | 1 +
apps/loopover-ui/src/routeTree.gen.ts | 21 ++++++
.../src/routes/docs.ams-fleet-manifest.tsx | 49 ++++++++++++++
apps/loopover-ui/src/routes/docs.index.tsx | 1 +
.../loopover-miner/docs/fleet-run-manifest.md | 4 ++
6 files changed, 140 insertions(+)
create mode 100644 apps/loopover-ui/content/docs/ams-fleet-manifest.mdx
create mode 100644 apps/loopover-ui/src/routes/docs.ams-fleet-manifest.tsx
diff --git a/apps/loopover-ui/content/docs/ams-fleet-manifest.mdx b/apps/loopover-ui/content/docs/ams-fleet-manifest.mdx
new file mode 100644
index 0000000000..26993590ac
--- /dev/null
+++ b/apps/loopover-ui/content/docs/ams-fleet-manifest.mdx
@@ -0,0 +1,64 @@
+---
+title: Fleet run-manifest
+description: The top-level config a fleet operator authors to run the miner across many repos at once -- which repos are in scope and how the worktree/concurrency budget is split.
+---
+
+The **fleet run-manifest** is the top-level config a *fleet operator* authors to run the miner
+across many repos at once: it declares which repos are in scope for a fleet run and how a finite
+worktree/concurrency budget is split between them. It is parsed by
+`parseFleetRunManifestContent` / `parseFleetRunManifest` in `@loopover/engine`
+(`packages/loopover-engine/src/fleet-run-manifest.ts`).
+
+It is **not** the same file as `.loopover-miner.yml` (see the [MinerGoalSpec field
+reference](/docs/ams-goal-spec)) — the naming is easy to conflate. Same tolerant-parser
+convention (every field optional, unknown keys ignored, a malformed field degrades to a
+documented default with a warning rather than throwing), but the opposite author and the
+opposite direction of intent:
+
+
+
+## Schema
+
+
+ Every field is optional; unknown keys are ignored; a malformed field falls back to a documented
+ default with a warning rather than hard-failing the run.
+
+
+- **`repos`** — a list of target repos. Each entry is either a bare `"owner/repo"` string (uses
+ the default per-repo budget) or a `{ repoFullName, maxConcurrentWorktrees }` mapping. Invalid or
+ duplicate entries are skipped with a warning. `repoFullName` is a canonical `owner/repo`,
+ compatible with `opportunity-fanout.js`'s target list. Default: `[]`.
+- **`repos[].maxConcurrentWorktrees`** — max concurrent worktrees (in-flight attempts) for that
+ repo. A positive integer (floored; sub-1 falls back to the default). Default: `1`.
+- **`totalConcurrentWorktrees`** — total concurrent worktrees across the whole fleet, regardless
+ of per-repo budgets. A positive integer. Default: `1`.
+
+## Wiring
+
+This module produces only the parsed, typed manifest. Driving the fleet concurrency allocator
+from it is the allocator's own concern, and the cross-repo `portfolio-queue.js` backlog reads the
+same repo list — both *consume* this manifest; neither wiring lives here.
+
+## Example (`fleet-run.yml`)
+
+
diff --git a/apps/loopover-ui/src/components/site/docs-nav.tsx b/apps/loopover-ui/src/components/site/docs-nav.tsx
index 5138d1994a..ef54ae1f2f 100644
--- a/apps/loopover-ui/src/components/site/docs-nav.tsx
+++ b/apps/loopover-ui/src/components/site/docs-nav.tsx
@@ -84,6 +84,7 @@ export const docsNav: DocsGroup[] = [
{ to: "/docs/ams-env-reference", label: "Env var reference" },
{ to: "/docs/ams-discovery-plane", label: "Discovery plane (opt-in)" },
{ to: "/docs/ams-goal-spec", label: "Miner goal spec" },
+ { to: "/docs/ams-fleet-manifest", label: "Fleet run-manifest" },
],
},
],
diff --git a/apps/loopover-ui/src/routeTree.gen.ts b/apps/loopover-ui/src/routeTree.gen.ts
index 8c54eaf2e4..fabcff69f6 100644
--- a/apps/loopover-ui/src/routeTree.gen.ts
+++ b/apps/loopover-ui/src/routeTree.gen.ts
@@ -62,6 +62,7 @@ import { Route as DocsAmsSizingRouteImport } from './routes/docs.ams-sizing'
import { Route as DocsAmsOperationsRunbookRouteImport } from './routes/docs.ams-operations-runbook'
import { Route as DocsAmsObservabilityRouteImport } from './routes/docs.ams-observability'
import { Route as DocsAmsGoalSpecRouteImport } from './routes/docs.ams-goal-spec'
+import { Route as DocsAmsFleetManifestRouteImport } from './routes/docs.ams-fleet-manifest'
import { Route as DocsAmsEnvReferenceRouteImport } from './routes/docs.ams-env-reference'
import { Route as DocsAmsDiscoveryPlaneRouteImport } from './routes/docs.ams-discovery-plane'
import { Route as DocsAmsDeploymentRouteImport } from './routes/docs.ams-deployment'
@@ -364,6 +365,11 @@ const DocsAmsGoalSpecRoute = DocsAmsGoalSpecRouteImport.update({
path: '/ams-goal-spec',
getParentRoute: () => DocsRoute,
} as any)
+const DocsAmsFleetManifestRoute = DocsAmsFleetManifestRouteImport.update({
+ id: '/ams-fleet-manifest',
+ path: '/ams-fleet-manifest',
+ getParentRoute: () => DocsRoute,
+} as any)
const DocsAmsEnvReferenceRoute = DocsAmsEnvReferenceRouteImport.update({
id: '/ams-env-reference',
path: '/ams-env-reference',
@@ -495,6 +501,7 @@ export interface FileRoutesByFullPath {
'/docs/ams-deployment': typeof DocsAmsDeploymentRoute
'/docs/ams-discovery-plane': typeof DocsAmsDiscoveryPlaneRoute
'/docs/ams-env-reference': typeof DocsAmsEnvReferenceRoute
+ '/docs/ams-fleet-manifest': typeof DocsAmsFleetManifestRoute
'/docs/ams-goal-spec': typeof DocsAmsGoalSpecRoute
'/docs/ams-observability': typeof DocsAmsObservabilityRoute
'/docs/ams-operations-runbook': typeof DocsAmsOperationsRunbookRoute
@@ -567,6 +574,7 @@ export interface FileRoutesByTo {
'/docs/ams-deployment': typeof DocsAmsDeploymentRoute
'/docs/ams-discovery-plane': typeof DocsAmsDiscoveryPlaneRoute
'/docs/ams-env-reference': typeof DocsAmsEnvReferenceRoute
+ '/docs/ams-fleet-manifest': typeof DocsAmsFleetManifestRoute
'/docs/ams-goal-spec': typeof DocsAmsGoalSpecRoute
'/docs/ams-observability': typeof DocsAmsObservabilityRoute
'/docs/ams-operations-runbook': typeof DocsAmsOperationsRunbookRoute
@@ -643,6 +651,7 @@ export interface FileRoutesById {
'/docs/ams-deployment': typeof DocsAmsDeploymentRoute
'/docs/ams-discovery-plane': typeof DocsAmsDiscoveryPlaneRoute
'/docs/ams-env-reference': typeof DocsAmsEnvReferenceRoute
+ '/docs/ams-fleet-manifest': typeof DocsAmsFleetManifestRoute
'/docs/ams-goal-spec': typeof DocsAmsGoalSpecRoute
'/docs/ams-observability': typeof DocsAmsObservabilityRoute
'/docs/ams-operations-runbook': typeof DocsAmsOperationsRunbookRoute
@@ -720,6 +729,7 @@ export interface FileRouteTypes {
| '/docs/ams-deployment'
| '/docs/ams-discovery-plane'
| '/docs/ams-env-reference'
+ | '/docs/ams-fleet-manifest'
| '/docs/ams-goal-spec'
| '/docs/ams-observability'
| '/docs/ams-operations-runbook'
@@ -792,6 +802,7 @@ export interface FileRouteTypes {
| '/docs/ams-deployment'
| '/docs/ams-discovery-plane'
| '/docs/ams-env-reference'
+ | '/docs/ams-fleet-manifest'
| '/docs/ams-goal-spec'
| '/docs/ams-observability'
| '/docs/ams-operations-runbook'
@@ -867,6 +878,7 @@ export interface FileRouteTypes {
| '/docs/ams-deployment'
| '/docs/ams-discovery-plane'
| '/docs/ams-env-reference'
+ | '/docs/ams-fleet-manifest'
| '/docs/ams-goal-spec'
| '/docs/ams-observability'
| '/docs/ams-operations-runbook'
@@ -1300,6 +1312,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DocsAmsGoalSpecRouteImport
parentRoute: typeof DocsRoute
}
+ '/docs/ams-fleet-manifest': {
+ id: '/docs/ams-fleet-manifest'
+ path: '/ams-fleet-manifest'
+ fullPath: '/docs/ams-fleet-manifest'
+ preLoaderRoute: typeof DocsAmsFleetManifestRouteImport
+ parentRoute: typeof DocsRoute
+ }
'/docs/ams-env-reference': {
id: '/docs/ams-env-reference'
path: '/ams-env-reference'
@@ -1497,6 +1516,7 @@ interface DocsRouteChildren {
DocsAmsDeploymentRoute: typeof DocsAmsDeploymentRoute
DocsAmsDiscoveryPlaneRoute: typeof DocsAmsDiscoveryPlaneRoute
DocsAmsEnvReferenceRoute: typeof DocsAmsEnvReferenceRoute
+ DocsAmsFleetManifestRoute: typeof DocsAmsFleetManifestRoute
DocsAmsGoalSpecRoute: typeof DocsAmsGoalSpecRoute
DocsAmsObservabilityRoute: typeof DocsAmsObservabilityRoute
DocsAmsOperationsRunbookRoute: typeof DocsAmsOperationsRunbookRoute
@@ -1546,6 +1566,7 @@ const DocsRouteChildren: DocsRouteChildren = {
DocsAmsDeploymentRoute: DocsAmsDeploymentRoute,
DocsAmsDiscoveryPlaneRoute: DocsAmsDiscoveryPlaneRoute,
DocsAmsEnvReferenceRoute: DocsAmsEnvReferenceRoute,
+ DocsAmsFleetManifestRoute: DocsAmsFleetManifestRoute,
DocsAmsGoalSpecRoute: DocsAmsGoalSpecRoute,
DocsAmsObservabilityRoute: DocsAmsObservabilityRoute,
DocsAmsOperationsRunbookRoute: DocsAmsOperationsRunbookRoute,
diff --git a/apps/loopover-ui/src/routes/docs.ams-fleet-manifest.tsx b/apps/loopover-ui/src/routes/docs.ams-fleet-manifest.tsx
new file mode 100644
index 0000000000..6663f5bb12
--- /dev/null
+++ b/apps/loopover-ui/src/routes/docs.ams-fleet-manifest.tsx
@@ -0,0 +1,49 @@
+import { createFileRoute, notFound } from "@tanstack/react-router";
+import { Suspense } from "react";
+
+import { DocsPage } from "@/components/site/docs-page";
+import { docsClientLoader } from "@/lib/docs-client-loader";
+
+// Rendered from content/docs/ams-fleet-manifest.mdx via fumadocs-mdx's browser entry
+// (docsClientLoader), through the existing DocsPage/Callout/CodeBlock/FeatureRow
+// primitives -- not fumadocs-ui's bundled components. See docs-source.ts's comment
+// for why the loader below resolves only a plain, serializable path string.
+export const Route = createFileRoute("/docs/ams-fleet-manifest")({
+ loader: async () => {
+ const { docsSource } = await import("@/lib/docs-source");
+ const page = docsSource.getPage(["ams-fleet-manifest"]);
+ if (!page) throw notFound();
+ return { path: page.path, title: page.data.title, description: page.data.description };
+ },
+ head: () => ({
+ meta: [
+ { title: "Fleet run-manifest — LoopOver docs" },
+ {
+ name: "description",
+ content:
+ "The top-level config a fleet operator authors to run the miner across many repos at once -- which repos are in scope and how the worktree/concurrency budget is split.",
+ },
+ { property: "og:title", content: "Fleet run-manifest — LoopOver docs" },
+ {
+ property: "og:description",
+ content:
+ "The top-level config a fleet operator authors to run the miner across many repos at once -- which repos are in scope and how the worktree/concurrency budget is split.",
+ },
+ { property: "og:url", content: "/docs/ams-fleet-manifest" },
+ ],
+ links: [{ rel: "canonical", href: "/docs/ams-fleet-manifest" }],
+ }),
+ component: AmsFleetManifest,
+});
+
+function AmsFleetManifest() {
+ const { path, title, description } = Route.useLoaderData();
+ const Content = docsClientLoader.getComponent(path);
+ return (
+
+ Loading…
}>
+
+
+
+ );
+}
diff --git a/apps/loopover-ui/src/routes/docs.index.tsx b/apps/loopover-ui/src/routes/docs.index.tsx
index f99497e665..432818363c 100644
--- a/apps/loopover-ui/src/routes/docs.index.tsx
+++ b/apps/loopover-ui/src/routes/docs.index.tsx
@@ -82,6 +82,7 @@ const AUDIENCES: Audience[] = [
{ to: "/docs/ams-env-reference", label: "Env var reference" },
{ to: "/docs/ams-discovery-plane", label: "Discovery plane (opt-in)" },
{ to: "/docs/ams-goal-spec", label: "Miner goal spec" },
+ { to: "/docs/ams-fleet-manifest", label: "Fleet run-manifest" },
{ to: "/docs/self-hosting-docs-audit", label: "Self-host docs audit" },
{ to: "/docs/maintainer-install-trust", label: "Install & trust guide" },
{ to: "/docs/github-app", label: "GitHub App configuration" },
diff --git a/packages/loopover-miner/docs/fleet-run-manifest.md b/packages/loopover-miner/docs/fleet-run-manifest.md
index ae0ec15715..6aa420fa83 100644
--- a/packages/loopover-miner/docs/fleet-run-manifest.md
+++ b/packages/loopover-miner/docs/fleet-run-manifest.md
@@ -1,5 +1,9 @@
# Fleet run-manifest
+> Also published on the docs website: [Fleet run-manifest](https://loopover.ai/docs/ams-fleet-manifest)
+> (same content, rendered with search and the rest of the maintainer docs nav). This file remains
+> the canonical source and ships inside the published `@loopover/miner` package.
+
The **fleet run-manifest** is the top-level config a *fleet operator* authors to run the miner across many repos
at once: it declares which repos are in scope for a fleet run and how a finite worktree/concurrency budget is
split between them. It is parsed by `parseFleetRunManifestContent` / `parseFleetRunManifest` in