diff --git a/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx b/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx index 28aecaaf51..d58a7f0eab 100644 --- a/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx +++ b/apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx @@ -195,6 +195,74 @@ function MaintainerSelfHosting() { ))} +

Onboarding simplification proposal (#1574)

+

+ This section records today's accurate setup path and the gaps worth closing next — the + issue deliverable for making self-host onboarding as fast as CodeRabbit while keeping robust + per-repo policy in container-private config. +

+ +

Today's recommended path (verified)

+
    +
  1. + cp .env.selfhost.example .env — conservative defaults (dry-run, + small GITTENSORY_REVIEW_REPOS). +
  2. +
  3. + Pull or build the image (INSTALL_AI_CLIS=true by default;{" "} + --build-arg INSTALL_AI_CLIS=false for deterministic-only). +
  4. +
  5. + One-click GitHub App via /setup + SELFHOST_SETUP_TOKEN ( + Checks: write included — re-approve on existing Apps after permission bumps). +
  6. +
  7. + Mount ./gittensory-config and copy{" "} + config/examples/global.gittensory.yml →{" "} + gittensory-config/.gittensory.yml for a centralized private default (per-repo + files deep-merge on top). +
  8. +
  9. + Add each pilot repo to GITTENSORY_REVIEW_REPOS, watch a PR in{" "} + dry-run, then enable advisory gate mode from the control panel or{" "} + POST /v1/repos/:owner/:repo/activation. +
  10. +
  11. + Go live by unsetting SELFHOST_DEPLOYMENT_MODE; tune autonomy in private + config when ready. +
  12. +
+ +

Gaps and proposed improvements

+ + + None of the proposals above require code changes to adopt today's path — they describe + UX we can add without weakening the private-config model or env-level kill switches. + +

How self-hosting fits with hosted docs

The hosted maintainer workflow still applies: review modes, gate settings, safety rules, and diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx index 6f8302c993..324aff2cb7 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx @@ -302,11 +302,41 @@ GITHUB_METADATA_CACHE_TTL_SECONDS=600`}

+

Repo activation — three layers

+

+ Self-host docs and logs use "activation" for more than one mechanism. They stack + independently: +

+ +

+ Preview before flipping: GET /v1/repos/:owner/:repo/activation-preview runs the + deterministic advisory engine over recent cached PRs (no AI cost) and returns a{" "} + recommendedAction of enable_advisory when the gate is still off. +

+

Per-PR feature flags

Most review capabilities need both their own flag and the repo in{" "} - GITTENSORY_REVIEW_REPOS. This gives you a global kill switch and a per-repo - rollout switch. + GITTENSORY_REVIEW_REPOS (unless a per-repo features: override says + otherwise). This gives you a global kill switch and a per-repo rollout switch.

+

Re-gate sweeps (agent-regate-sweep)

+

+ Live PR review is webhook-driven, but open PRs still need periodic re-evaluation — the base + branch moves, duplicate clusters resolve, settings change, and approved PRs can sit unmerged + until CI re-runs. A scheduled sweep (agent-regate-sweep, every ~2 minutes on + the maintenance tick) fans out lightweight agent-regate-pr jobs for the stalest + open PRs per repo (cap SWEEP_MAX_PRS=3 by default, REST-budget sized). +

+ +

+ Log markers: regate_sweep_throttled (sweep temporarily paused),{" "} + regate_sweep_trigger_backlog_deferred (prior regate work still draining — + avoids piling duplicate fan-outs). In metrics, break down deferrals by{" "} + job_type=agent-regate-pr or agent-regate-sweep when GitHub + rate-limit pressure spikes. +

+

Routine checks

  • Queue pending count is not growing without processing.
  • diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx index de8a35485e..4d3a50ec30 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx @@ -182,6 +182,83 @@ review_context_fetch_failed # REES/RAG/grounding context failure`} or RAG deliberately.

    +

    6. Activate your first repo

    +

    + Three separate knobs are easy to conflate — each does something different, and all three + matter for a smooth first rollout: +

    + +

    + Recommended first-repo path today: add the repo to{" "} + GITTENSORY_REVIEW_REPOS, seed a private global default, then enable advisory + gate mode once webhook delivery works. +

    + +

    + Copy the shipped global private default into the compose-mounted config directory (edit your + copy — never commit real policy to a public repo): +

    + +

    + Sign in to the control panel (ADMIN_GITHUB_LOGINS must include your GitHub + login), open the repo workspace, preview what Gittensory would have flagged on recent PRs, + then enable advisory mode in one click — the same patch as: +

    + " \\ + -H "Content-Type: application/json" \\ + -d '{}'`} + /> + + That activation endpoint turns on the gate check plus deterministic rules in{" "} + advisory mode (non-blocking, no auto-merge) — a CodeRabbit-style ramp. AI + review stays off until you configure it separately. Full semantics in{" "} + Configuration. + + + If reviews compute but no Gittensory Orb Review Agent check-run appears, open + your App's permissions page and confirm Checks: write is granted — + checks: read alone 403s the write silently. New permissions also require a + one-time re-approval on each installation; see{" "} + GitHub App and Orb. + +

    + When output looks right, switch SELFHOST_DEPLOYMENT_MODE from{" "} + dry-run to unset (live writes). For a shorter future path, see the onboarding + proposal on Self-hosted reviews. +

    +

    Defaults at a glance

    Nothing below needs a flag to start; everything past the first row needs an explicit{" "} diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-rag.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-rag.tsx index d3e459a661..a6438bd128 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-rag.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-rag.tsx @@ -38,7 +38,7 @@ function SelfHostingRag() { { title: "Repo activation", description: - "GITTENSORY_REVIEW_RAG=true and the repo in GITTENSORY_REVIEW_REPOS, or a private per-repo feature toggle.", + "GITTENSORY_REVIEW_RAG=true, repo in GITTENSORY_REVIEW_REPOS (or features.rag: true in private config). Gittensor is_registered is not required for self-host RAG when the allowlist covers the repo.", }, { title: "Vector backend", diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-troubleshooting.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-troubleshooting.tsx index e777abb355..5c3f33b55d 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-troubleshooting.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-troubleshooting.tsx @@ -103,7 +103,12 @@ rees_analyzer_config_invalid`}

    RAG returns no context

    • - Confirm GITTENSORY_REVIEW_RAG=true and repo activation. + Confirm GITTENSORY_REVIEW_RAG=true, the repo is in{" "} + GITTENSORY_REVIEW_REPOS (or has features.rag: true in private + config), and RAG indexing has run — see{" "} + Configuration for the three activation + layers (is_registered is only required for Gittensor-scored paths, not RAG on + a self-host allowlist).
    • Confirm Qdrant or the vector backend is reachable from the app container.
    • Confirm the embedding endpoint and model are running.
    • diff --git a/test/unit/docs-selfhost-activation-paths.test.ts b/test/unit/docs-selfhost-activation-paths.test.ts new file mode 100644 index 0000000000..4c1bbf22f2 --- /dev/null +++ b/test/unit/docs-selfhost-activation-paths.test.ts @@ -0,0 +1,54 @@ +import { readFileSync } from "node:fs"; +import { describe, expect, it } from "vitest"; + +// Drift guard (#1574): self-host onboarding docs must keep naming the three activation layers, the +// one-click activation routes, Checks:write re-approval, INSTALL_AI_CLIS, and the re-gate sweep job +// types — otherwise operators follow stale instructions after the underlying paths change. + +const QUICKSTART = "apps/gittensory-ui/src/routes/docs.self-hosting-quickstart.tsx"; +const CONFIG = "apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx"; +const OPERATIONS = "apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsx"; +const GITHUB_APP = "apps/gittensory-ui/src/routes/docs.self-hosting-github-app.tsx"; +const MAINTAINER = "apps/gittensory-ui/src/routes/docs.maintainer-self-hosting.tsx"; + +const quickstart = readFileSync(QUICKSTART, "utf8"); +const configuration = readFileSync(CONFIG, "utf8"); +const operations = readFileSync(OPERATIONS, "utf8"); +const githubApp = readFileSync(GITHUB_APP, "utf8"); +const maintainer = readFileSync(MAINTAINER, "utf8"); + +describe("self-host activation + onboarding docs (#1574)", () => { + it("quickstart documents allowlist, private config seed, activation POST, and Checks: write", () => { + expect(quickstart).toContain("GITTENSORY_REVIEW_REPOS"); + expect(quickstart).toContain("config/examples/global.gittensory.yml"); + expect(quickstart).toContain("gittensory-config/.gittensory.yml"); + expect(quickstart).toContain("/v1/repos/owner/my-repo/activation"); + expect(quickstart).toContain("Checks: write"); + expect(quickstart).toContain("INSTALL_AI_CLIS"); + }); + + it("configuration separates feature allowlist, gate activation, and is_registered", () => { + expect(configuration).toContain("GITTENSORY_REVIEW_REPOS"); + expect(configuration).toContain("is_registered"); + expect(configuration).toContain("/v1/repos/:owner/:repo/activation-preview"); + expect(configuration).toContain("/v1/repos/:owner/:repo/activation"); + }); + + it("operations documents the periodic re-gate sweep job types", () => { + expect(operations).toContain("agent-regate-sweep"); + expect(operations).toContain("agent-regate-pr"); + expect(operations).toContain("backlog-convergence-sweep"); + expect(operations).toContain("regate_sweep_throttled"); + }); + + it("github-app doc still requires Checks: write at the manifest level", () => { + expect(githubApp).toMatch(/Checks:\s*write/i); + expect(githubApp).toContain("Re-approving a permission bump"); + }); + + it("maintainer index includes the onboarding simplification proposal", () => { + expect(maintainer).toContain("Onboarding simplification proposal"); + expect(maintainer).toContain("POST /v1/repos/:owner/:repo/activation"); + expect(maintainer).toContain("global.gittensory.yml"); + }); +});