GitNexus shipped a CatalogHome grid, DropZone local analyze, onboarding phases, and server-connect wizards. Beskid Nexus is a hosted public explorer for pre-indexed repos — visitors arrive to browse graphs, not to analyze local folders or configure LLM providers.
Design model
Platform spec article
Design model
Spec standingStandard
-
Nexus opens the first indexed repo graph on / instead of a catalog grid or onboarding flows.
Context
Decision
/must load the graph explorer, selecting the first enabled catalog entry withindexed: trueordered bysortOrder.- Deep link
?repo=<catalog-id>selects an explicit entry when present. - CatalogHome, DropZone, QueryFAB, Graph RAG chat, and hosted OnboardingGuide are removed from public UI.
- Repo switching happens via navbar
<Select>, not a separate home phase. - When no indexed repo exists, show empty state + sign-in CTA for repo owners — not a marketing catalog grid.
Admin actions (add repo, re-index) must be overlays (dialog/sheet), not full-page route phases.
Consequences
gitnexus-webApp phases reduce toboot | setup | server-down | explorer.- E2E tests target graph canvas visibility and repo selector — not onboarding wizards.
- Cached LadybugDB exports remain the only graph source for public visitors.
Status
Accepted — supersedes GitNexus CatalogHome as the default Nexus entry experience.
-
Per-repo CRUD and analyze triggers require GitHub-verified ownership via hub token — not env admin rosters.
Context
GitNexus used a static admin roster for catalog mutations. Beskid Nexus indexes public graphs for many repositories — administration should follow GitHub ownership, not a deployment-time username list that does not scale across contributors and org repos.
Instance operators still need bootstrap authority for auth hub pairing and secrets — distinct from day-to-day repo administration.
Decision
POST/PATCH/DELETE /api/admin/catalog*andPOST .../analyzeandPOST .../refresh-docsrequire the session user to be owner or admin of the entry'sgitUrlper GitHub API (GET /repos/{owner}/{repo}with hub user token).GET /api/auth/memust exposeownedRepoIds— catalog ids the user may administer — for UI gating.requireAdmin(env roster) is retained only forPOST /api/admin/auth/pairand first-run setup endpoints.- Ownership verification may be cached up to 15 minutes per
(login, gitUrl). - Non-owners receive
403on mutating routes.
Consequences
github-ownership.tscentralizes URL parsing and API checks.- Frontend admin sheet gates on
ownedRepoIds.includes(activeEntry.id). - Public catalog and graph routes remain unauthenticated.
Status
Accepted — reference implementation in
beskid_nexus/gitnexus/src/server/nexus/github-ownership.ts. -
AI-generated codeDoc describes repository code only; platform spec body text never inlined — specLinks are validated hrefs from a read-only index.
Context
Nexus runs a hidden doc-maintenance worker after analyze. Without a hard boundary, generated node text could duplicate or paraphrase normative platform-spec MDX — creating two sources of truth and stale copies when spec changes.
Platform spec on
site/websiteleads code per project policy. Nexus is a reader of spec URLs, not a publisher of spec prose.Decision
codeDocis repo-scoped AI documentation — generated from graph metadata and short file snippets only.- Platform spec MDX bodies are never fed into code-doc prompts as source material.
- A read-only spec link index (
spec-index.json) stores titles, slugs, and headings for link discovery only. resolve_spec_linkstool returns candidate{ title, href }from the index; unknown hrefs must be rejected at commit.specLinksare 0–3 validated pointers — not summaries of spec content.code-doc-validatoranti-copy guard rejects records containing ≥40 consecutive characters matching spec index excerpts.- Graph API and UI must expose
codeDocandspecLinksas separate fields/sections.
When a topic is fully covered by platform spec,
codeDocstays brief and defers viaspecLinks.Consequences
- Two-phase doc pipeline: Phase A writes
codeDocfrom graph context; Phase B attaches links via index search. - Public API and UI must not mention OpenRouter, prompts, or AI vendors.
- Spec deploys require Nexus restart or index rebuild to pick up new link targets.
Status
Accepted — normative contracts in design model and contracts.
-
Signed-in users connect MCP clients to same-origin /api/mcp using deployment Bearer token; UI documents endpoint without exposing secrets.
Context
Nexus exposes graph query tools over MCP Streamable HTTP for IDE and agent integrations. Operators deploy a shared
NEXUS_MCP_AUTH_TOKENsecret. Users need a discoverable, copy-friendly surface — without embedding secrets in client bundles or public pages.Decision
- MCP must be mounted at
/api/mcpon the Nexus deployment origin. - All MCP requests must require
Authorization: Bearer $NEXUS_MCP_AUTH_TOKEN. - Header button Connect MCP must appear for signed-in users (any authenticated session).
- ConnectMcpDialog shows:
- Endpoint URL (
{window.location.origin}/api/mcp) - Auth header template with placeholder token guidance
- Copy buttons for URL and header format
- Link to MCP contracts
- Endpoint URL (
- The live Bearer token must not be returned by public or session API routes — operators supply it via deployment env (Coolify, etc.).
Consequences
gitnexus-webshipsconnect-mcp-dialog.tsxwired intoNexusAppShell.- MCP shares the cached graph data plane with public
/api/graph— no parallel index. - Platform spec documents the contract; Nexus UI links here for operator and integrator reference.
Status
Accepted — complements GitNexus MCP engine retention under Beskid Nexus product shell.
- MCP must be mounted at
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
| Section id | Required | Found |
|---|---|---|
what-this-feature-specifies | yes | yes |
implementation-anchors | yes | yes |
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
UX shell
Section titled “UX shell”Nexus must align with tracker and site chrome:
| Element | Contract |
|---|---|
| Layout | Top navbar (not sidebar) |
| Kicker | Beskid / Nexus / {repo} |
| Repo switch | <Select> bound to public catalog |
| Search | Symbol search over active graph |
| Theme | Light/dark toggle |
| Hub | BeskidHub launcher from @beskid/beskid-ui |
Interactive UI must use @beskid/ui-react primitives via the #/components/ui alias. Styles must import @beskid/ui-react/styles/shadcn-entry.css and @beskid/beskid-ui/styles/hub.css.
Graph-first landing
Section titled “Graph-first landing”| Rule | Behavior |
|---|---|
| N-01 | / must load the first enabled, indexed catalog entry by ascending sortOrder |
| N-02 | When no indexed entry exists, show empty state with sign-in CTA for repo owners |
| N-03 | Deep link ?repo=<catalog-id> must select that entry and load its graph |
| N-04 | Default view must be the graph explorer — not a catalog home grid |
Admin flows (add repo, re-index, delete) must appear as dialog or sheet overlays, not separate full-page phases.
Global registry model
Section titled “Global registry model”The server maintains catalog.json — the authoritative list of public Nexus entries.
| Field | Role |
|---|---|
id | Stable catalog identifier; used in ?repo= and admin routes |
displayName, description, gitUrl, defaultBranch | Public metadata |
sortOrder | Landing and selector ordering |
indexed, registryName | Whether a LadybugDB export exists and its storage key |
lastIndexedCommit, indexedAt, stats | Index freshness and graph size |
docStatus | Coarse doc pipeline state (idle | running | failed | ready) — no AI vendor details |
Index pipeline: clone → analyze worker → .gitnexus/ index → optional code-doc maintenance worker.
Code documentation vs platform spec
Section titled “Code documentation vs platform spec”Two distinct layers. Implementations must never merge or paraphrase platform spec into code documentation.
| Layer | Source | Stored in | Public exposure |
|---|---|---|---|
| Code documentation | Graph + source snippets | code-docs/{registryName}.json | properties.codeDoc on graph nodes/clusters |
| Platform spec | site/website/.../platform-spec/ | Site only — not copied | Never inlined |
| Spec links | Read-only spec index search | Same JSON sidecar | properties.specLinks — { title, href }[] |
CodeDocRecord
Section titled “CodeDocRecord”interface CodeDocRecord { entityId: string; entityKind: 'node' | 'cluster'; /** Repo-scoped explanation. Must NOT contain platform-spec prose. */ codeDoc: string; /** 0–3 canonical platform-spec URLs. href must exist in spec index. */ specLinks: Array<{ title: string; href: string }>; contentHash: string; updatedAt: string;}Doc worker rules:
- Code doc text is generated solely from graph context and file snippets.
- Spec search is used only by
resolve_spec_linksto propose canonical URLs — models must not invent paths. - When a spec page fully covers a topic,
codeDocstays brief and points viaspecLinks. - Anti-copy validation rejects records where
codeDoccontains long n-grams matching spec index chunks.
Public graph API must merge codeDoc and specLinks as separate node properties. UI must render them in distinct sections.
Server architecture
Section titled “Server architecture”┌─────────────────────────────────────────────────────────────┐│ gitnexus serve (single process) │├─────────────────────────────────────────────────────────────┤│ /api/catalog public registry + graph metadata ││ /api/graph cached LadybugDB export (stream) ││ /api/admin/catalog/* repo-owner gated CRUD + analyze ││ /api/mcp StreamableHTTP (Bearer token) ││ /api/internal/code-docs/* server-only job status (no UI) │├─────────────────────────────────────────────────────────────┤│ catalog.json → clone → analyze → .gitnexus/ index ││ post-analyze → doc-maintenance (OpenRouter, hidden) ││ code-docs/{registryName}.json ││ spec-index.json (read-only link resolution) │└─────────────────────────────────────────────────────────────┘MCP connect surface
Section titled “MCP connect surface”| Rule | Contract |
|---|---|
| N-MCP-01 | MCP endpoint must be same-origin {origin}/api/mcp |
| N-MCP-02 | Transport must require Authorization: Bearer $NEXUS_MCP_AUTH_TOKEN |
| N-MCP-03 | Header button Connect MCP must be visible when user is signed in |
| N-MCP-04 | Dialog must show endpoint URL, auth header template, copy actions, and link to MCP contracts |
Token value is a deployment secret — UI shows placeholder guidance for operators, not the live secret.
Ownership verification
Section titled “Ownership verification”On mutating catalog operations the server must call GitHub GET /repos/{owner}/{repo} with the user’s hub token and require permissions.admin or owner login match. Env-based admin rosters must not gate per-repo CRUD (operator setup endpoints excepted).