From ab939ed81cb7c9c56c3346f5f5d8fb26a68b3dec Mon Sep 17 00:00:00 2001 From: Clayton Date: Mon, 1 Jun 2026 15:40:47 -0500 Subject: [PATCH 1/3] docs(ui): add role-based beta onboarding journeys --- .../public/downloads/gittensory-extension.zip | Bin 0 -> 19522 bytes apps/gittensory-ui/public/sitemap.xml | 1 + .../src/components/site/command-palette.tsx | 1 + .../src/components/site/docs-nav.tsx | 1 + apps/gittensory-ui/src/routeTree.gen.ts | 21 ++ .../src/routes/docs.beta-onboarding.tsx | 248 ++++++++++++++++++ apps/gittensory-ui/src/routes/docs.index.tsx | 24 +- .../src/routes/docs.quickstart.tsx | 4 +- test/unit/docs-beta-onboarding.test.ts | 47 ++++ 9 files changed, 341 insertions(+), 6 deletions(-) create mode 100644 apps/gittensory-ui/public/downloads/gittensory-extension.zip create mode 100644 apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx create mode 100644 test/unit/docs-beta-onboarding.test.ts diff --git a/apps/gittensory-ui/public/downloads/gittensory-extension.zip b/apps/gittensory-ui/public/downloads/gittensory-extension.zip new file mode 100644 index 0000000000000000000000000000000000000000..cce677c3932eae182eda9ce9704ffb957c2be148 GIT binary patch literal 19522 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 AC;$Ke literal 0 HcmV?d00001 diff --git a/apps/gittensory-ui/public/sitemap.xml b/apps/gittensory-ui/public/sitemap.xml index 026d36b418..769cdd5267 100644 --- a/apps/gittensory-ui/public/sitemap.xml +++ b/apps/gittensory-ui/public/sitemap.xml @@ -7,6 +7,7 @@ https://gittensory.aethereal.dev/extension https://gittensory.aethereal.dev/roadmap https://gittensory.aethereal.dev/docs + https://gittensory.aethereal.dev/docs/beta-onboarding https://gittensory.aethereal.dev/docs/quickstart https://gittensory.aethereal.dev/docs/mcp-clients https://gittensory.aethereal.dev/docs/miner-workflow diff --git a/apps/gittensory-ui/src/components/site/command-palette.tsx b/apps/gittensory-ui/src/components/site/command-palette.tsx index f95a28ae09..4b428873f2 100644 --- a/apps/gittensory-ui/src/components/site/command-palette.tsx +++ b/apps/gittensory-ui/src/components/site/command-palette.tsx @@ -27,6 +27,7 @@ const DEFAULT_ITEMS: PaletteItem[] = [ { label: "Product analytics", to: "/app/analytics", group: "App" }, { label: "Maintainer digest", to: "/app/digest", group: "App" }, { label: "Operator dashboard", to: "/app/operator", group: "App" }, + { label: "Beta onboarding", to: "/docs/beta-onboarding", group: "Docs" }, { label: "Quickstart", to: "/docs/quickstart", group: "Docs" }, { label: "MCP clients", to: "/docs/mcp-clients", group: "Docs" }, { label: "Miner workflow", to: "/docs/miner-workflow", group: "Docs" }, diff --git a/apps/gittensory-ui/src/components/site/docs-nav.tsx b/apps/gittensory-ui/src/components/site/docs-nav.tsx index ea4fe31e29..3e011f10b9 100644 --- a/apps/gittensory-ui/src/components/site/docs-nav.tsx +++ b/apps/gittensory-ui/src/components/site/docs-nav.tsx @@ -10,6 +10,7 @@ export const docsNav: DocsGroup[] = [ title: "Get started", items: [ { to: "/docs", label: "Overview" }, + { to: "/docs/beta-onboarding", label: "Beta onboarding" }, { to: "/docs/quickstart", label: "Quickstart" }, { to: "/docs/mcp-clients", label: "MCP client setup" }, ], diff --git a/apps/gittensory-ui/src/routeTree.gen.ts b/apps/gittensory-ui/src/routeTree.gen.ts index 09d8351146..38b93e1b4f 100644 --- a/apps/gittensory-ui/src/routeTree.gen.ts +++ b/apps/gittensory-ui/src/routeTree.gen.ts @@ -32,6 +32,7 @@ import { Route as DocsMcpClientsRouteImport } from './routes/docs.mcp-clients' import { Route as DocsMaintainerWorkflowRouteImport } from './routes/docs.maintainer-workflow' import { Route as DocsGithubAppRouteImport } from './routes/docs.github-app' import { Route as DocsBranchAnalysisRouteImport } from './routes/docs.branch-analysis' +import { Route as DocsBetaOnboardingRouteImport } from './routes/docs.beta-onboarding' import { Route as DocsAiSummariesRouteImport } from './routes/docs.ai-summaries' import { Route as AppWorkbenchRouteImport } from './routes/app.workbench' import { Route as AppRunsRouteImport } from './routes/app.runs' @@ -161,6 +162,11 @@ const DocsBranchAnalysisRoute = DocsBranchAnalysisRouteImport.update({ path: '/branch-analysis', getParentRoute: () => DocsRoute, } as any) +const DocsBetaOnboardingRoute = DocsBetaOnboardingRouteImport.update({ + id: '/beta-onboarding', + path: '/beta-onboarding', + getParentRoute: () => DocsRoute, +} as any) const DocsAiSummariesRoute = DocsAiSummariesRouteImport.update({ id: '/ai-summaries', path: '/ai-summaries', @@ -251,6 +257,7 @@ export interface FileRoutesByFullPath { '/app/runs': typeof AppRunsRoute '/app/workbench': typeof AppWorkbenchRoute '/docs/ai-summaries': typeof DocsAiSummariesRoute + '/docs/beta-onboarding': typeof DocsBetaOnboardingRoute '/docs/branch-analysis': typeof DocsBranchAnalysisRoute '/docs/github-app': typeof DocsGithubAppRoute '/docs/maintainer-workflow': typeof DocsMaintainerWorkflowRoute @@ -286,6 +293,7 @@ export interface FileRoutesByTo { '/app/runs': typeof AppRunsRoute '/app/workbench': typeof AppWorkbenchRoute '/docs/ai-summaries': typeof DocsAiSummariesRoute + '/docs/beta-onboarding': typeof DocsBetaOnboardingRoute '/docs/branch-analysis': typeof DocsBranchAnalysisRoute '/docs/github-app': typeof DocsGithubAppRoute '/docs/maintainer-workflow': typeof DocsMaintainerWorkflowRoute @@ -325,6 +333,7 @@ export interface FileRoutesById { '/app/runs': typeof AppRunsRoute '/app/workbench': typeof AppWorkbenchRoute '/docs/ai-summaries': typeof DocsAiSummariesRoute + '/docs/beta-onboarding': typeof DocsBetaOnboardingRoute '/docs/branch-analysis': typeof DocsBranchAnalysisRoute '/docs/github-app': typeof DocsGithubAppRoute '/docs/maintainer-workflow': typeof DocsMaintainerWorkflowRoute @@ -365,6 +374,7 @@ export interface FileRouteTypes { | '/app/runs' | '/app/workbench' | '/docs/ai-summaries' + | '/docs/beta-onboarding' | '/docs/branch-analysis' | '/docs/github-app' | '/docs/maintainer-workflow' @@ -400,6 +410,7 @@ export interface FileRouteTypes { | '/app/runs' | '/app/workbench' | '/docs/ai-summaries' + | '/docs/beta-onboarding' | '/docs/branch-analysis' | '/docs/github-app' | '/docs/maintainer-workflow' @@ -438,6 +449,7 @@ export interface FileRouteTypes { | '/app/runs' | '/app/workbench' | '/docs/ai-summaries' + | '/docs/beta-onboarding' | '/docs/branch-analysis' | '/docs/github-app' | '/docs/maintainer-workflow' @@ -629,6 +641,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof DocsBranchAnalysisRouteImport parentRoute: typeof DocsRoute } + '/docs/beta-onboarding': { + id: '/docs/beta-onboarding' + path: '/beta-onboarding' + fullPath: '/docs/beta-onboarding' + preLoaderRoute: typeof DocsBetaOnboardingRouteImport + parentRoute: typeof DocsRoute + } '/docs/ai-summaries': { id: '/docs/ai-summaries' path: '/ai-summaries' @@ -769,6 +788,7 @@ const AppRouteWithChildren = AppRoute._addFileChildren(AppRouteChildren) interface DocsRouteChildren { DocsAiSummariesRoute: typeof DocsAiSummariesRoute + DocsBetaOnboardingRoute: typeof DocsBetaOnboardingRoute DocsBranchAnalysisRoute: typeof DocsBranchAnalysisRoute DocsGithubAppRoute: typeof DocsGithubAppRoute DocsMaintainerWorkflowRoute: typeof DocsMaintainerWorkflowRoute @@ -784,6 +804,7 @@ interface DocsRouteChildren { const DocsRouteChildren: DocsRouteChildren = { DocsAiSummariesRoute: DocsAiSummariesRoute, + DocsBetaOnboardingRoute: DocsBetaOnboardingRoute, DocsBranchAnalysisRoute: DocsBranchAnalysisRoute, DocsGithubAppRoute: DocsGithubAppRoute, DocsMaintainerWorkflowRoute: DocsMaintainerWorkflowRoute, diff --git a/apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx b/apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx new file mode 100644 index 0000000000..2f742ba559 --- /dev/null +++ b/apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx @@ -0,0 +1,248 @@ +import { createFileRoute, Link } from "@tanstack/react-router"; + +import { DocsPage } from "@/components/site/docs-page"; +import { CodeBlock, Callout } from "@/components/site/primitives"; + +export const Route = createFileRoute("/docs/beta-onboarding")({ + head: () => ({ + meta: [ + { title: "Beta onboarding — Gittensory docs" }, + { + name: "description", + content: + "Role-based beta paths for miners, maintainers, repo owners, and operators — first useful action, not just API reference.", + }, + { property: "og:title", content: "Beta onboarding — Gittensory docs" }, + { + property: "og:description", + content: + "Role-based beta paths for miners, maintainers, repo owners, and operators — first useful action, not just API reference.", + }, + { property: "og:url", content: "/docs/beta-onboarding" }, + ], + links: [{ rel: "canonical", href: "/docs/beta-onboarding" }], + }), + component: BetaOnboarding, +}); + +function BetaOnboarding() { + return ( + + + Product positioning. Gittensory is a deterministic base-agent and control-plane + layer for the Gittensor ecosystem. It is{" "} + + jsonbored/gittensory + + , independent of{" "} + + entrius/gittensor + + . Use it to plan work, preflight branches, and keep GitHub review surfaces quiet — not as an + official Gittensor frontend, wallet UI, or payout dashboard. + + +

Miner journey

+

+ Miners and contributors use the local MCP package. Metadata stays on your machine; private + scoreability and blockers appear only in authenticated MCP/API responses. +

+
    +
  1. + Install the MCP. Global install or npx — see{" "} + Quickstart. + +
  2. +
  3. + Sign in. GitHub Device Flow — no PAT storage. + +
  4. +
  5. + Run diagnostics. Confirms API reachability, auth, source-upload posture, and + optional local score-preview wiring. + +
  6. +
  7. + Plan next work. Ranked actions, lane context, and blockers — copilot-only; does + not open PRs or post comments. + +
  8. +
  9. + Preflight the branch. Branch blockers, queue pressure, and maintainer-fit notes + before you push. + +
  10. +
  11. + Prepare a public-safe packet. Maintainer-readable PR description with no + private scoring language. + +
  12. +
+

+ Wire the same tools into Codex, Claude Desktop, or Cursor via{" "} + MCP client setup. Signed-in miners can also use the{" "} + Workbench and Miner dashboard in + the control panel. +

+ +

Maintainer journey

+

+ Maintainers install the GitHub App, configure per-repo policy, preview what could appear on a + confirmed-miner PR, then pull context on demand. +

+
    +
  1. + Install the GitHub App. Choose repositories and approve permissions — default + posture is silence. See GitHub App setup. +
  2. +
  3. + Configure settings. Opt in to at most one configured label and one sticky + sanitized comment per confirmed-miner PR. Tune repo policy in installation settings or via the + API. +
  4. +
  5. + Preview the public surface. Dry-run what would be written to GitHub without + mutating state. + +

    + The signed-in Maintainer console and{" "} + Repos tab surface the same preview diff when live data is + available. +

    +
  6. +
  7. + Use maintainer commands. On-demand context in the PR thread — output stays + maintainer-scoped when appropriate. + +
  8. +
+

+ Deeper workflow: Maintainer workflow. Privacy rules:{" "} + Privacy & security. +

+ +

Repo owner journey

+

+ Repo owners care about registration readiness and sensible .gittensor.yml{" "} + configuration before promoting labels or maintainer-cut policy. +

+
    +
  1. + Run a readiness report. Blockers, warnings, recommended registration mode, + and issue policy — private API only. + +
  2. +
  3. + Review config guidance. Recommended config diff with reasons and tradeoffs — + apply via PR when ready. + +
  4. +
  5. + Use the control panel. Open Repository owner{" "} + (or the Owner tab under Repos) to inspect the same signals with a + live repo selector after you sign in with GitHub. +
  6. +
+

+ Readiness is separate from upstream drift: a repo can look ready while Gittensor rules are stale. + Check Upstream drift when you change scoring assumptions. +

+ +

Operator journey

+

+ Operators watch deployment health, product usage, value rollups, and upstream drift across + installations. These surfaces are private and authenticated — never mirrored to public GitHub + comments. +

+
    +
  1. + Open usage & value. Weekly rollups, activation status, and noise-reduction + metrics in the control panel. +

    + Operator dashboard — backed by{" "} + GET /v1/app/operator-dashboard. +

    +
  2. +
  3. + Read the weekly value report. Summary lines plus rollup freshness and warnings + when backfills lag or fidelity degrades. +
  4. +
  5. + Check drift status. Compare ruleset snapshots and signal fidelity before + trusting miner or maintainer guidance. + +
  6. +
+

+ When drift is not current, treat MCP and API responses as tied to the printed + ruleset version. See Upstream drift for semantics. +

+ +

Public vs private boundaries

+

+ Public GitHub output must never include wallets, hotkeys, payout or reward estimates, raw trust + scores, public score estimates, private reviewability details, or farming language. Private MCP, + API, and control-panel surfaces may show authenticated scoreability, blockers, projections, and + evidence — framed as guidance, not guaranteed outcomes. +

+ + If you are unsure whether copy belongs on a PR thread, start with a maintainer packet or MCP + preflight. Public comments stay advisory and sanitized; richer context stays in private channels. + + +

Next steps

+
    +
  • + Miners: Quickstart →{" "} + Miner workflow +
  • +
  • + Maintainers: GitHub App →{" "} + Maintainer workflow +
  • +
  • + Repo owners: Owner console +{" "} + Privacy & security +
  • +
  • + Operators: Operator dashboard +{" "} + Upstream drift +
  • +
+
+ ); +} diff --git a/apps/gittensory-ui/src/routes/docs.index.tsx b/apps/gittensory-ui/src/routes/docs.index.tsx index 93c65c7df6..d8f09e3db9 100644 --- a/apps/gittensory-ui/src/routes/docs.index.tsx +++ b/apps/gittensory-ui/src/routes/docs.index.tsx @@ -1,5 +1,5 @@ import { createFileRoute, Link } from "@tanstack/react-router"; -import { ArrowRight, Bot, Building2, Compass, Shield } from "lucide-react"; +import { ArrowRight, Bot, Building2, Compass, Gauge, Shield } from "lucide-react"; import type { ReactNode } from "react"; import { DocsPage } from "@/components/site/docs-page"; @@ -31,7 +31,7 @@ function DocsIndex() {
{AUDIENCES.map((a) => ( @@ -55,8 +55,9 @@ const AUDIENCES: Audience[] = [ icon: , title: "Miners", description: "Plan better work, preflight branches, prepare PR packets.", - primary: { to: "/docs/quickstart", label: "Quickstart" }, + primary: { to: "/docs/beta-onboarding", label: "Beta onboarding" }, links: [ + { to: "/docs/quickstart", label: "Quickstart" }, { to: "/docs/miner-workflow", label: "Miner workflow" }, { to: "/docs/branch-analysis", label: "Branch analysis" }, { to: "/docs/scoreability", label: "Scoreability" }, @@ -66,8 +67,9 @@ const AUDIENCES: Audience[] = [ icon: , title: "Maintainers", description: "Confirmed-miner context, sanitized comments, no noisy checks.", - primary: { to: "/docs/github-app", label: "Install the GitHub App" }, + primary: { to: "/docs/beta-onboarding", label: "Beta onboarding" }, links: [ + { to: "/docs/github-app", label: "Install the GitHub App" }, { to: "/docs/maintainer-workflow", label: "Maintainer workflow" }, { to: "/docs/upstream-drift", label: "Upstream drift" }, { to: "/docs/ai-summaries", label: "AI summaries policy" }, @@ -77,12 +79,24 @@ const AUDIENCES: Audience[] = [ icon: , title: "Repo owners", description: "Registration readiness, label policy, repo settings preview.", - primary: { to: "/docs/github-app", label: "App install + scopes" }, + primary: { to: "/docs/beta-onboarding", label: "Beta onboarding" }, links: [ + { to: "/app/owner", label: "Owner console" }, { to: "/docs/privacy-security", label: "Privacy & security" }, { to: "/docs/troubleshooting", label: "Troubleshooting" }, ], }, + { + icon: , + title: "Operators", + description: "Usage rollups, weekly value report, upstream drift across deployments.", + primary: { to: "/docs/beta-onboarding", label: "Beta onboarding" }, + links: [ + { to: "/app/operator", label: "Operator dashboard" }, + { to: "/docs/upstream-drift", label: "Upstream drift" }, + { to: "/docs/troubleshooting", label: "Troubleshooting" }, + ], + }, { icon: , title: "Agent authors", diff --git a/apps/gittensory-ui/src/routes/docs.quickstart.tsx b/apps/gittensory-ui/src/routes/docs.quickstart.tsx index 826cf97d2d..e2ed31669b 100644 --- a/apps/gittensory-ui/src/routes/docs.quickstart.tsx +++ b/apps/gittensory-ui/src/routes/docs.quickstart.tsx @@ -71,7 +71,9 @@ gittensory-mcp preflight --login your-login --json`}

4. Wire it into your coding agent

Print a config snippet for your editor of choice and paste it in. See{" "} - MCP client setup for the details. + MCP client setup for the details. For the full miner path + (plan → preflight → packet) and other roles, see{" "} + Beta onboarding.

{ + const source = readFileSync(BETA_ONBOARDING_PATH, "utf8"); + + it("documents miner MCP flow through packet", () => { + expect(source).toMatch(/gittensory-mcp login/); + expect(source).toMatch(/gittensory-mcp doctor/); + expect(source).toMatch(/agent plan/); + expect(source).toMatch(/preflight/); + expect(source).toMatch(/agent packet/); + }); + + it("documents maintainer GitHub App setup, preview, and commands", () => { + expect(source).toMatch(/GitHub App/); + expect(source).toMatch(/settings-preview/); + expect(source).toMatch(/@gittensory help/); + expect(source).toMatch(/@gittensory preflight/); + }); + + it("documents repo owner readiness and config guidance", () => { + expect(source).toMatch(/registration-readiness/); + expect(source).toMatch(/gittensor-config-recommendation/); + expect(source).toMatch(/\/app\/owner/); + }); + + it("documents operator usage, value, and drift reporting", () => { + expect(source).toMatch(/operator-dashboard/); + expect(source).toMatch(/weekly value report/i); + expect(source).toMatch(/upstream\/drift/); + }); + + it("positions Gittensory as independent control-plane, not official Gittensor frontend", () => { + expect(source).toMatch(/official Gittensor product surface/i); + expect(source).toMatch(/official Gittensor frontend/i); + expect(source).toMatch(/independent of/i); + expect(source).toMatch(/base-agent/i); + expect(source).not.toMatch(/the official Gittensor frontend/i); + }); +}); From 25da3b37429ca78a1243266f46c6c882fa306d0e Mon Sep 17 00:00:00 2001 From: Clayton Date: Mon, 1 Jun 2026 15:52:29 -0500 Subject: [PATCH 2/3] fix: update --- .../src/routes/docs.beta-onboarding.tsx | 107 +++++++++--------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx b/apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx index 2f742ba559..0c57f545d0 100644 --- a/apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx +++ b/apps/gittensory-ui/src/routes/docs.beta-onboarding.tsx @@ -33,8 +33,8 @@ function BetaOnboarding() { description="Pick the lane that matches you. Each path ends in a concrete first win — install, configure, or read a report — without treating Gittensory as an official Gittensor product surface." > - Product positioning. Gittensory is a deterministic base-agent and control-plane - layer for the Gittensor ecosystem. It is{" "} + Product positioning. Gittensory is a deterministic base-agent and + control-plane layer for the Gittensor ecosystem. It is{" "} jsonbored/gittensory @@ -62,25 +62,31 @@ gittensory-mcp --help`}
  • Sign in. GitHub Device Flow — no PAT storage. - +
  • - Run diagnostics. Confirms API reachability, auth, source-upload posture, and - optional local score-preview wiring. + Run diagnostics. Confirms API reachability, auth, source-upload posture, + and optional local score-preview wiring.
  • - Plan next work. Ranked actions, lane context, and blockers — copilot-only; does - not open PRs or post comments. - + Plan next work. Ranked actions, lane context, and blockers — + copilot-only; does not open PRs or post comments. +
  • - Preflight the branch. Branch blockers, queue pressure, and maintainer-fit notes - before you push. - + Preflight the branch. Branch blockers, queue pressure, and maintainer-fit + notes before you push. +
  • Prepare a public-safe packet. Maintainer-readable PR description with no @@ -93,28 +99,28 @@ gittensory-mcp preflight --login your-login --json`} />

    Wire the same tools into Codex, Claude Desktop, or Cursor via{" "} MCP client setup. Signed-in miners can also use the{" "} - Workbench and Miner dashboard in - the control panel. + Workbench and Miner dashboard{" "} + in the control panel.

    Maintainer journey

    - Maintainers install the GitHub App, configure per-repo policy, preview what could appear on a - confirmed-miner PR, then pull context on demand. + Maintainers install the GitHub App, configure per-repo policy, preview what could appear on + a confirmed-miner PR, then pull context on demand.

    1. - Install the GitHub App. Choose repositories and approve permissions — default - posture is silence. See GitHub App setup. + Install the GitHub App. Choose repositories and approve permissions — + default posture is silence. See GitHub App setup.
    2. Configure settings. Opt in to at most one configured label and one sticky - sanitized comment per confirmed-miner PR. Tune repo policy in installation settings or via the - API. + sanitized comment per confirmed-miner PR. Tune repo policy in installation settings or via + the API.
    3. - Preview the public surface. Dry-run what would be written to GitHub without - mutating state. + Preview the public surface. Dry-run what would be written to GitHub + without mutating state.

    4. - Use maintainer commands. On-demand context in the PR thread — output stays - maintainer-scoped when appropriate. + Use maintainer commands. On-demand context in the PR thread — output + stays maintainer-scoped when appropriate.

    - Deeper workflow: Maintainer workflow. Privacy rules:{" "} - Privacy & security. + Deeper workflow: Maintainer workflow. Privacy + rules: Privacy & security.

    Repo owner journey

    @@ -151,16 +157,13 @@ gittensory-mcp preflight --login your-login --json`} />

    1. - Run a readiness report. Blockers, warnings, recommended registration mode, - and issue policy — private API only. - + Run a readiness report. Blockers, warnings, recommended registration + mode, and issue policy — private API only. +
    2. - Review config guidance. Recommended config diff with reasons and tradeoffs — - apply via PR when ready. + Review config guidance. Recommended config diff with reasons and + tradeoffs — apply via PR when ready.
    3. Use the control panel. Open Repository owner{" "} - (or the Owner tab under Repos) to inspect the same signals with a - live repo selector after you sign in with GitHub. + (or the Owner tab under Repos) to inspect the same signals + with a live repo selector after you sign in with GitHub.

    - Readiness is separate from upstream drift: a repo can look ready while Gittensor rules are stale. - Check Upstream drift when you change scoring assumptions. + Readiness is separate from upstream drift: a repo can look ready while Gittensor rules are + stale. Check Upstream drift when you change scoring + assumptions.

    Operator journey

    Operators watch deployment health, product usage, value rollups, and upstream drift across - installations. These surfaces are private and authenticated — never mirrored to public GitHub - comments. + installations. These surfaces are private and authenticated — never mirrored to public + GitHub comments.

    1. - Open usage & value. Weekly rollups, activation status, and noise-reduction - metrics in the control panel. + Open usage & value. Weekly rollups, activation status, and + noise-reduction metrics in the control panel.

      Operator dashboard — backed by{" "} GET /v1/app/operator-dashboard.

    2. - Read the weekly value report. Summary lines plus rollup freshness and warnings - when backfills lag or fidelity degrades. + Read the weekly value report. Summary lines plus rollup freshness and + warnings when backfills lag or fidelity degrades.
    3. Check drift status. Compare ruleset snapshots and signal fidelity before @@ -214,14 +218,15 @@ GET /v1/readiness`}

      Public vs private boundaries

      - Public GitHub output must never include wallets, hotkeys, payout or reward estimates, raw trust - scores, public score estimates, private reviewability details, or farming language. Private MCP, - API, and control-panel surfaces may show authenticated scoreability, blockers, projections, and - evidence — framed as guidance, not guaranteed outcomes. + Public GitHub output must never include wallets, hotkeys, payout or reward estimates, raw + trust scores, public score estimates, private reviewability details, or farming language. + Private MCP, API, and control-panel surfaces may show authenticated scoreability, blockers, + projections, and evidence — framed as guidance, not guaranteed outcomes.

      If you are unsure whether copy belongs on a PR thread, start with a maintainer packet or MCP - preflight. Public comments stay advisory and sanitized; richer context stays in private channels. + preflight. Public comments stay advisory and sanitized; richer context stays in private + channels.

      Next steps

      From 5db61b083ec29a32febdddf0229d1d51e08f3fc1 Mon Sep 17 00:00:00 2001 From: Clayton Date: Mon, 1 Jun 2026 16:16:32 -0500 Subject: [PATCH 3/3] fix: update --- .../public/downloads/gittensory-extension.zip | Bin 19522 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/gittensory-ui/public/downloads/gittensory-extension.zip diff --git a/apps/gittensory-ui/public/downloads/gittensory-extension.zip b/apps/gittensory-ui/public/downloads/gittensory-extension.zip deleted file mode 100644 index cce677c3932eae182eda9ce9704ffb957c2be148..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19522 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 AC;$Ke