Skip to content

feat(review): add config-as-code settings surface for the issue-planning tool#7521

Merged
loopover-orb[bot] merged 1 commit into
mainfrom
claude/orb-github-issue-automation-080318
Jul 20, 2026
Merged

feat(review): add config-as-code settings surface for the issue-planning tool#7521
loopover-orb[bot] merged 1 commit into
mainfrom
claude/orb-github-issue-automation-080318

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Adds a config-as-code settings surface for loopover_plan_repo_issues (#7426): three new RepositorySettings fields, config-as-code only (no DB column — following the Batch A/B/C pattern, config-as-code: migrate comment/audience/public-surface settings off the DB #6442-config-as-code: migrate gate/quality/AI-review mode settings off the DB (settings: + gate: dedup) #6444), settable via .loopover.yml's settings: block:
    • issuePlanEnabled (default true) — per-repo opt-out. The tool is already gated behind MCP maintainer access and the fleet-wide AI_SUMMARIES_ENABLED/AI_PUBLIC_COMMENTS_ENABLED switches; this is an additional per-repo layer for a repo that wants those on generally but this specific capability off.
    • issuePlanExtraLabels (default []) — additional label names suggested to the model alongside the repo's real GitHub labels and (when gittensor-enrolled, #7428) its type-label taxonomy. Purely additive.
    • issuePlanMilestoneReuse (default true) — whether the milestone resolve-or-create step (#7427) attempts to reuse an existing open milestone by exact title match, or always creates fresh.
  • Wires all three into src/services/issue-plan-draft.ts: resolveRepositorySettings is now fetched once per call (previously only fetched when gittensor-enrolled, inside resolveGittensorLabelEnrichment) and reused for the new enable-check, the label merge, the milestone-reuse toggle, and the existing gittensor label-enrichment path — removing that function's own duplicate fetch.
  • Full end-to-end wiring for the new fields, since RepositorySettings fields are a strict two-layer allowlist (a TS Pick<> + the parser's explicit per-key code — an unrecognized key is silently dropped with zero signal): src/types.ts, packages/loopover-engine/src/focus-manifest.ts (parser + FocusManifestSettings type), packages/loopover-engine/src/types/manifest-deps-types.ts (the engine's own standalone mirror of RepositorySettings), src/db/repositories.ts (hardcoded defaults, all 3 occurrences), src/openapi/schemas.ts (RepositorySettingsSchema — checked by ui:openapi:settings-parity), .loopover.yml.example and config/examples/loopover.full.yml (kept byte-identical per config-templates.test.ts — these two files must match from a canonical marker onward), and a short new section in apps/loopover-ui/content/docs/self-hosting-configuration.mdx's existing "Config-as-code blocks with no dashboard equivalent" reference.
  • Sub-issue of #7424 (Epic: ORB self-hoster issue & milestone planning routine) — the last of its 5 sub-issues.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Validation

  • git diff --check
  • npm run typecheck (root + @loopover/engine rebuilt first)
  • npm run test --workspace @loopover/engine (592 tests) and npm run engine-parity:drift-check — both clean; focus-manifest.ts is not a hand-duplicated twin-paired file, so no parity check is even triggered by this edit.
  • npm run test:coverage locally — full unsharded suite: 1022 files / 19399 tests passed (2 skipped). Zero pre-existing/unrelated failures — the flake in 3 miner test files present earlier this session was independently fixed and merged as test(unit): isolate loopover-mcp/miner tests from real machine state #7515 while this PR was in flight. New/changed code in src/services/issue-plan-draft.ts is 100% branch-covered.
  • npm run docs:drift-check / npm run manifest:drift-check / npm run db:migrations:check / npm run db:schema-drift:check / npm run selfhost:env-reference:check / npm run ui:openapi:check / npm run ui:openapi:settings-parity / npm run release-manifest:sync:check — all clean.
  • npm run ui:lint / npm run ui:typecheck / npm run ui:build — run (unlike the prior 3 PRs in this series) since this one touches apps/loopover-ui/content/docs/self-hosting-configuration.mdx. Clean (only pre-existing, unrelated warnings).
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries — 6 new tests covering issuePlanEnabled: false, issuePlanExtraLabels merging, issuePlanMilestoneReuse: false skipping the reuse lookup, plus 2 new focus-manifest.ts parser test entries and existing milestone/gittensor tests updated for the new unconditional settings fetch.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. (N/A — no auth/session surface touched.)
  • API/OpenAPI/MCP behavior is updated and tested where needed — RepositorySettingsSchema updated and parity-checked; no MCP tool input/output shape changed (the 3 fields are read internally, not new tool parameters).
  • UI changes use live API data or real empty/error/loading states. (N/A — the only UI change is static docs prose.)
  • Visible UI changes include a UI Evidence section. (N/A — a documentation-text-only change, not a visual/interactive change.)
  • Public docs/changelogs are updated where needed — new section added to self-hosting-configuration.mdx; CHANGELOG.md itself untouched (never edited in a normal PR).

UI Evidence

N/A — the only apps/loopover-ui change is static reference-docs prose (a new subsection of text in an existing MDX page), not a visual or interactive change.

Notes

Closes #7429

…ing tool

Adds RepositorySettings.issuePlanEnabled/issuePlanExtraLabels/
issuePlanMilestoneReuse (config-as-code only, no DB column, matching
the Batch A/B/C pattern) so a selfhoster can opt loopover_plan_repo_issues
out per repo, suggest additional labels beyond the repo's real ones,
and control whether milestone creation reuses an existing open
milestone by title match or always creates fresh.

Wires the fields into src/services/issue-plan-draft.ts: settings are
now fetched once per call (previously only fetched when gittensor-
enrolled) and reused for both the enable-check and the existing
gittensor label-enrichment path, removing its own duplicate fetch.

Adds matching type/parser wiring in packages/loopover-engine's
FocusManifest, OpenAPI schema entries, .loopover.yml.example and
config/examples/loopover.full.yml documentation (kept byte-identical
per config-templates.test.ts), and a short selfhoster docs section.

Closes #7429
@JSONbored JSONbored self-assigned this Jul 20, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@github-actions
github-actions Bot had a problem deploying to preview/pr-7521 July 20, 2026 20:52 Failure
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui 44f59ca Commit Preview URL

Branch Preview URL
Jul 20 2026, 08:53 PM

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 4.04kB (0.05%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
loopover-ui 7.62MB 4.04kB (0.05%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: loopover-ui

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/add-scalar-classes-BbWbaQrE.js (New) 2.17MB 2.17MB 100.0% 🚀
assets/tanstack-vendor-g3Wpdn08.js (New) 820.36kB 820.36kB 100.0% 🚀
openapi.json 303 bytes 521.69kB 0.06%
assets/docs.fumadocs-spike-api-reference-CniLDn18.js (New) 442.94kB 442.94kB 100.0% 🚀
assets/AgentScalarChatInterface.vue-CdoR9wJw.js (New) 201.71kB 201.71kB 100.0% 🚀
assets/modal-CXTkUkDn.js (New) 184.28kB 184.28kB 100.0% 🚀
assets/client-BAe8i8ES.js (New) 146.06kB 146.06kB 100.0% 🚀
assets/self-hosting-configuration-1P26CpWd.js (New) 81.47kB 81.47kB 100.0% 🚀
assets/maintainer-panel-DEMwp2vI.js (New) 78.49kB 78.49kB 100.0% 🚀
assets/ui-vendor-CxnyUR1c.js (New) 57.04kB 57.04kB 100.0% 🚀
assets/routes-BcsAqJL_.js (New) 34.29kB 34.29kB 100.0% 🚀
assets/owner-panel-uL5_5icf.js (New) 26.96kB 26.96kB 100.0% 🚀
assets/app-CIosWSyd.js (New) 25.65kB 25.65kB 100.0% 🚀
assets/app.runs-e1AvyJfS.js (New) 23.56kB 23.56kB 100.0% 🚀
assets/miner-panel-dXJgH7tV.js (New) 20.25kB 20.25kB 100.0% 🚀
assets/docs-source-C70qE7Ek.js (New) 19.36kB 19.36kB 100.0% 🚀
assets/api._op-r_PoV05j.js (New) 17.55kB 17.55kB 100.0% 🚀
assets/self-hosting-docs-audit-Bj-bg26K.js (New) 16.73kB 16.73kB 100.0% 🚀
assets/app.index-gH4YQ2Cl.js (New) 15.62kB 15.62kB 100.0% 🚀
assets/playground-panel-DHi1BK1-.js (New) 14.35kB 14.35kB 100.0% 🚀
assets/app.audit-BoB8XAQ9.js (New) 10.11kB 10.11kB 100.0% 🚀
assets/extension-5e2FRwbR.js (New) 10.04kB 10.04kB 100.0% 🚀
assets/app.config-generator-C_tx5ldn.js (New) 9.88kB 9.88kB 100.0% 🚀
assets/maintainers-B2ElLrCu.js (New) 8.03kB 8.03kB 100.0% 🚀
assets/miners-uOk43sxm.js (New) 7.85kB 7.85kB 100.0% 🚀
assets/agents-BB1NoLWP.js (New) 7.76kB 7.76kB 100.0% 🚀
assets/commands-panel-DNP317dT.js (New) 6.63kB 6.63kB 100.0% 🚀
assets/roadmap-BzW0Fsrt.js (New) 6.33kB 6.33kB 100.0% 🚀
assets/digest-panel-BEMvTkZv.js (New) 6.14kB 6.14kB 100.0% 🚀
assets/repos._owner._repo.quality-BKsg1hyA.js (New) 6.14kB 6.14kB 100.0% 🚀
assets/docs.index-DheNNUCE.js (New) 5.47kB 5.47kB 100.0% 🚀
assets/api.index-CnxdImVc.js (New) 4.7kB 4.7kB 100.0% 🚀
assets/api-CpVRspNA.js (New) 2.69kB 2.69kB 100.0% 🚀
assets/docs-Bp5KzPmS.js (New) 2.67kB 2.67kB 100.0% 🚀
assets/app.workbench-KS_-p8YV.js (New) 1.58kB 1.58kB 100.0% 🚀
assets/tooltip-BxVcb81t.js (New) 1.45kB 1.45kB 100.0% 🚀
assets/session-D9ath1E3.js (New) 1.44kB 1.44kB 100.0% 🚀
assets/tabs-DHW75HxC.js (New) 1.39kB 1.39kB 100.0% 🚀
assets/app.repos-Del6CZF6.js (New) 1.07kB 1.07kB 100.0% 🚀
assets/input-UOh8-EG0.js (New) 796 bytes 796 bytes 100.0% 🚀
assets/file-cog-BfcPpek1.js (New) 758 bytes 758 bytes 100.0% 🚀
assets/docs.ai-summaries-YePNryvn.js (New) 506 bytes 506 bytes 100.0% 🚀
assets/app.maintainer-Dz_QredV.js (New) 502 bytes 502 bytes 100.0% 🚀
assets/docs.branch-analysis-cFGyRfX4.js (New) 499 bytes 499 bytes 100.0% 🚀
assets/docs.scoreability-ClcwYSTZ.js (New) 499 bytes 499 bytes 100.0% 🚀
assets/docs.upstream-drift-E5eOhByU.js (New) 499 bytes 499 bytes 100.0% 🚀
assets/docs.federated-fleet-intelligence-Bul9vJZ-.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.maintainer-install-trust-j8JbVC85.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-ai-providers-B-EHWdpw.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-backup-scaling-CPVd5-O_.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-configuration-DMeighlY.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-docs-audit-JPFwDWr0.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-github-app-BHwYy04a.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-quickstart-DK7_2YwA.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-rag-uUhyC7CO.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-rees-D_q_NV9B.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-rees-analyzers-BeZFKrFa.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-release-checklist-tfIPp7ux.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-releases-D24NaHgs.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-security-BTmEtVI0.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-troubleshooting-3_1B_QhX.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.self-hosting-unified-ams-orb-8t-hFGPu.js (New) 498 bytes 498 bytes 100.0% 🚀
assets/docs.ams-config-precedence-D3jcwe2z.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-deployment-BfpYfXGy.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-discovery-plane-CrCNXYbn.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-env-reference-HiSx5K24.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-fleet-manifest-BRXcL0Lf.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-goal-spec-DaKnQoHs.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-observability-DnKZ-UBw.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-operations-runbook-Cky0sxvk.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-sizing-BbLAY7rz.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.ams-unattended-scheduling-BzeXUQ5b.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.beta-onboarding-DDz7QGT7.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.capacity-MbySWFvt.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.maintainer-self-hosting-_-yEc1nT.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.mcp-clients-BUdrFt1s.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.owner-checklist-CuyQIO1-.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.quickstart-DqvOhM36.js (New) 497 bytes 497 bytes 100.0% 🚀
assets/docs.github-app-DYOufC3p.js (New) 495 bytes 495 bytes 100.0% 🚀
assets/docs.maintainer-workflow-sy-g0-Eh.js (New) 495 bytes 495 bytes 100.0% 🚀
assets/docs.privacy-security-C6FEky9T.js (New) 495 bytes 495 bytes 100.0% 🚀
assets/docs.troubleshooting-XoB6lqax.js (New) 495 bytes 495 bytes 100.0% 🚀
assets/docs.tuning-DTJFt_mM.js (New) 495 bytes 495 bytes 100.0% 🚀
assets/docs.loopover-commands-Cg7MSVaq.js (New) 494 bytes 494 bytes 100.0% 🚀
assets/sparkles-H7jnvVGb.js (New) 494 bytes 494 bytes 100.0% 🚀
assets/docs.how-reviews-work-Cexud35h.js (New) 493 bytes 493 bytes 100.0% 🚀
assets/app.owner-CR5WAcS6.js (New) 474 bytes 474 bytes 100.0% 🚀
assets/app.commands-DRC3qDxS.js (New) 455 bytes 455 bytes 100.0% 🚀
assets/app.playground-OEdp6hgj.js (New) 442 bytes 442 bytes 100.0% 🚀
assets/reveal-p1b0yhVc.js (New) 442 bytes 442 bytes 100.0% 🚀
assets/index-D2S7X0M5.js (New) 438 bytes 438 bytes 100.0% 🚀
assets/app.digest-B06WV9bR.js (New) 430 bytes 430 bytes 100.0% 🚀
assets/eye-off-6B-4w5xd.js (New) 430 bytes 430 bytes 100.0% 🚀
assets/app.miner-BXeyBwVy.js (New) 422 bytes 422 bytes 100.0% 🚀
assets/key-round-BWL3bz4b.js (New) 355 bytes 355 bytes 100.0% 🚀
assets/bot-B34flvY2.js (New) 328 bytes 328 bytes 100.0% 🚀
assets/trash-2-bin-0Inu.js (New) 328 bytes 328 bytes 100.0% 🚀
assets/save-UktLbDxe.js (New) 327 bytes 327 bytes 100.0% 🚀
assets/git-pull-request-arrow-DECGJtcf.js (New) 321 bytes 321 bytes 100.0% 🚀
assets/wrench-BjqzgqSZ.js (New) 303 bytes 303 bytes 100.0% 🚀
assets/list-checks-B9dOClwn.js (New) 279 bytes 279 bytes 100.0% 🚀
assets/shield-C8apIaY3.js (New) 272 bytes 272 bytes 100.0% 🚀
assets/workflow-BwH71Vn7.js (New) 265 bytes 265 bytes 100.0% 🚀
assets/compass-HBw4Fd3m.js (New) 251 bytes 251 bytes 100.0% 🚀
assets/history-D39Z-52I.js (New) 237 bytes 237 bytes 100.0% 🚀
assets/activity-D22hP1sm.js (New) 234 bytes 234 bytes 100.0% 🚀
assets/message-square-DVIOwL6g.js (New) 233 bytes 233 bytes 100.0% 🚀
assets/lock-DfFEYt3v.js (New) 206 bytes 206 bytes 100.0% 🚀
assets/rotate-cw-20pX8j-7.js (New) 201 bytes 201 bytes 100.0% 🚀
assets/play-ByH-02W5.js (New) 190 bytes 190 bytes 100.0% 🚀
assets/circle-check-BLVXwjlN.js (New) 178 bytes 178 bytes 100.0% 🚀
assets/search-8gbpvE9K.js (New) 174 bytes 174 bytes 100.0% 🚀
assets/self-hosting-configuration-H9TkMc-v.js (New) 144 bytes 144 bytes 100.0% 🚀
assets/self-hosting-docs-audit-BH8qNpuT.js (New) 141 bytes 141 bytes 100.0% 🚀
assets/circle-BWZcDAdB.js (New) 130 bytes 130 bytes 100.0% 🚀
assets/modal-BZTN4dfO.js (New) 115 bytes 115 bytes 100.0% 🚀
assets/add-scalar-classes-mFS3gn1Q.js (Deleted) -2.17MB 0 bytes -100.0% 🗑️
assets/tanstack-vendor-BXCEAuOr.js (Deleted) -820.21kB 0 bytes -100.0% 🗑️
assets/docs.fumadocs-spike-api-reference-B-B6hCR3.js (Deleted) -442.94kB 0 bytes -100.0% 🗑️
assets/AgentScalarChatInterface.vue-CX_5_fCw.js (Deleted) -201.71kB 0 bytes -100.0% 🗑️
assets/modal-DlMggBCT.js (Deleted) -184.28kB 0 bytes -100.0% 🗑️
assets/client-DWrQvosS.js (Deleted) -146.06kB 0 bytes -100.0% 🗑️
assets/maintainer-panel-DYfCuDzs.js (Deleted) -78.49kB 0 bytes -100.0% 🗑️
assets/self-hosting-configuration-D5ug8lJ2.js (Deleted) -77.88kB 0 bytes -100.0% 🗑️
assets/ui-vendor-DBuBmHhw.js (Deleted) -57.04kB 0 bytes -100.0% 🗑️
assets/routes-B-lyJJ8H.js (Deleted) -34.29kB 0 bytes -100.0% 🗑️
assets/owner-panel-BeTRVy80.js (Deleted) -26.96kB 0 bytes -100.0% 🗑️
assets/app-cSvEyf0f.js (Deleted) -25.65kB 0 bytes -100.0% 🗑️
assets/app.runs-mSxwf9Dv.js (Deleted) -23.56kB 0 bytes -100.0% 🗑️
assets/miner-panel-C7NHlj6N.js (Deleted) -20.25kB 0 bytes -100.0% 🗑️
assets/docs-source-xg-awnFZ.js (Deleted) -19.36kB 0 bytes -100.0% 🗑️
assets/api._op-BLOZqGXV.js (Deleted) -17.55kB 0 bytes -100.0% 🗑️
assets/self-hosting-docs-audit-DrMc7R3V.js (Deleted) -16.73kB 0 bytes -100.0% 🗑️
assets/app.index-CDqIwdsC.js (Deleted) -15.62kB 0 bytes -100.0% 🗑️
assets/playground-panel-CCHTMxws.js (Deleted) -14.35kB 0 bytes -100.0% 🗑️
assets/app.audit-Ceqsww3M.js (Deleted) -10.11kB 0 bytes -100.0% 🗑️
assets/extension-B5_t43tB.js (Deleted) -10.04kB 0 bytes -100.0% 🗑️
assets/app.config-generator-Cs42lRrs.js (Deleted) -9.88kB 0 bytes -100.0% 🗑️
assets/maintainers-DmLBkmzq.js (Deleted) -8.03kB 0 bytes -100.0% 🗑️
assets/miners-CaSIqCyU.js (Deleted) -7.85kB 0 bytes -100.0% 🗑️
assets/agents-Dw9NzNlY.js (Deleted) -7.76kB 0 bytes -100.0% 🗑️
assets/commands-panel-C_a6q8RJ.js (Deleted) -6.63kB 0 bytes -100.0% 🗑️
assets/roadmap-COkMwYa4.js (Deleted) -6.33kB 0 bytes -100.0% 🗑️
assets/digest-panel-j0PlTYP8.js (Deleted) -6.14kB 0 bytes -100.0% 🗑️
assets/repos._owner._repo.quality-BL6OMAR1.js (Deleted) -6.14kB 0 bytes -100.0% 🗑️
assets/docs.index-DOjysjzT.js (Deleted) -5.47kB 0 bytes -100.0% 🗑️
assets/api.index-CSXUP-SY.js (Deleted) -4.7kB 0 bytes -100.0% 🗑️
assets/api-DE1WgaTG.js (Deleted) -2.69kB 0 bytes -100.0% 🗑️
assets/docs-Dc7fhAvs.js (Deleted) -2.67kB 0 bytes -100.0% 🗑️
assets/app.workbench-bHcpjJnV.js (Deleted) -1.58kB 0 bytes -100.0% 🗑️
assets/tooltip-7awPtuIl.js (Deleted) -1.45kB 0 bytes -100.0% 🗑️
assets/session-C7gONPdB.js (Deleted) -1.44kB 0 bytes -100.0% 🗑️
assets/tabs-bhZyKEl-.js (Deleted) -1.39kB 0 bytes -100.0% 🗑️
assets/app.repos-CCiueEKv.js (Deleted) -1.07kB 0 bytes -100.0% 🗑️
assets/input-BFTREYLO.js (Deleted) -796 bytes 0 bytes -100.0% 🗑️
assets/file-cog-ComBPjCA.js (Deleted) -758 bytes 0 bytes -100.0% 🗑️
assets/docs.ai-summaries-Olqdkmih.js (Deleted) -506 bytes 0 bytes -100.0% 🗑️
assets/app.maintainer-CSZ7lACs.js (Deleted) -502 bytes 0 bytes -100.0% 🗑️
assets/docs.branch-analysis-DG8ylDyR.js (Deleted) -499 bytes 0 bytes -100.0% 🗑️
assets/docs.scoreability-BtyEri1H.js (Deleted) -499 bytes 0 bytes -100.0% 🗑️
assets/docs.upstream-drift-BPaRR1pA.js (Deleted) -499 bytes 0 bytes -100.0% 🗑️
assets/docs.federated-fleet-intelligence-BEwm25Zs.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.maintainer-install-trust-TDoeRBz7.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-ai-providers-Dcqw1L1I.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-backup-scaling-HT06IWN3.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-configuration-C_zD6yOZ.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-docs-audit-DDn6C6wM.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-github-app-ZWMNxh4h.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-quickstart-B0Y2zicr.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-rag-DS_P9wbw.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-rees-analyzers-B_ZTm7qP.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-rees-c8cblSQm.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-release-checklist-C7NBUGRT.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-releases-BLFc45Uo.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-security-DTKZ6uw3.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-troubleshooting-bn_bT_ca.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.self-hosting-unified-ams-orb-BWo6Crw7.js (Deleted) -498 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-config-precedence-Dx_9GTT7.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-deployment-DGrLhZRS.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-discovery-plane-vOBoxKEd.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-env-reference-CWsoVZQa.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-fleet-manifest-9v7SIuYt.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-goal-spec-DyGxKJGf.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-observability-BVGuqo3H.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-operations-runbook-DyNpLlXd.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-sizing-D3m2mze0.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.ams-unattended-scheduling-BS1hiQh5.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.beta-onboarding-6AOs5OWD.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.capacity-DD85ZYxf.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.maintainer-self-hosting-Jmvtf09b.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.mcp-clients-CIEww-O7.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.owner-checklist-CsExJ1Zd.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.quickstart-BzMJbB8b.js (Deleted) -497 bytes 0 bytes -100.0% 🗑️
assets/docs.github-app-C4CAZCZO.js (Deleted) -495 bytes 0 bytes -100.0% 🗑️
assets/docs.maintainer-workflow-oxIYHoZh.js (Deleted) -495 bytes 0 bytes -100.0% 🗑️
assets/docs.privacy-security-BO0Q1E4I.js (Deleted) -495 bytes 0 bytes -100.0% 🗑️
assets/docs.troubleshooting-CKiletXH.js (Deleted) -495 bytes 0 bytes -100.0% 🗑️
assets/docs.tuning-CUjaBSmE.js (Deleted) -495 bytes 0 bytes -100.0% 🗑️
assets/docs.loopover-commands-eVLhNrkA.js (Deleted) -494 bytes 0 bytes -100.0% 🗑️
assets/sparkles-DuLykQNE.js (Deleted) -494 bytes 0 bytes -100.0% 🗑️
assets/docs.how-reviews-work-BZFbvjuB.js (Deleted) -493 bytes 0 bytes -100.0% 🗑️
assets/app.owner-CosOQsCr.js (Deleted) -474 bytes 0 bytes -100.0% 🗑️
assets/app.commands-R9G038x8.js (Deleted) -455 bytes 0 bytes -100.0% 🗑️
assets/app.playground-B-QQ8vOS.js (Deleted) -442 bytes 0 bytes -100.0% 🗑️
assets/reveal-C4chkSku.js (Deleted) -442 bytes 0 bytes -100.0% 🗑️
assets/index-DFQHvDXg.js (Deleted) -438 bytes 0 bytes -100.0% 🗑️
assets/app.digest-DsTQaFs3.js (Deleted) -430 bytes 0 bytes -100.0% 🗑️
assets/eye-off-C7YCsXMN.js (Deleted) -430 bytes 0 bytes -100.0% 🗑️
assets/app.miner-CMETqoec.js (Deleted) -422 bytes 0 bytes -100.0% 🗑️
assets/key-round-DrgXAoQH.js (Deleted) -355 bytes 0 bytes -100.0% 🗑️
assets/bot-DpLBCs0h.js (Deleted) -328 bytes 0 bytes -100.0% 🗑️
assets/trash-2-Dg--HIxA.js (Deleted) -328 bytes 0 bytes -100.0% 🗑️
assets/save-BtXrJ2Lj.js (Deleted) -327 bytes 0 bytes -100.0% 🗑️
assets/git-pull-request-arrow-Bx8UAUkT.js (Deleted) -321 bytes 0 bytes -100.0% 🗑️
assets/wrench-iZyjc3hM.js (Deleted) -303 bytes 0 bytes -100.0% 🗑️
assets/list-checks--hWhA-3D.js (Deleted) -279 bytes 0 bytes -100.0% 🗑️
assets/shield-D_zoM3CY.js (Deleted) -272 bytes 0 bytes -100.0% 🗑️
assets/workflow-JlujskcG.js (Deleted) -265 bytes 0 bytes -100.0% 🗑️
assets/compass-DbFHX1z1.js (Deleted) -251 bytes 0 bytes -100.0% 🗑️
assets/history-BEPMg9W4.js (Deleted) -237 bytes 0 bytes -100.0% 🗑️
assets/activity-DAicroqc.js (Deleted) -234 bytes 0 bytes -100.0% 🗑️
assets/message-square-D4warcYW.js (Deleted) -233 bytes 0 bytes -100.0% 🗑️
assets/lock-DFpra0V4.js (Deleted) -206 bytes 0 bytes -100.0% 🗑️
assets/rotate-cw-D1BerVhY.js (Deleted) -201 bytes 0 bytes -100.0% 🗑️
assets/play-DNEZHslL.js (Deleted) -190 bytes 0 bytes -100.0% 🗑️
assets/circle-check-CpfR-Oad.js (Deleted) -178 bytes 0 bytes -100.0% 🗑️
assets/search-CF4OJJ7p.js (Deleted) -174 bytes 0 bytes -100.0% 🗑️
assets/self-hosting-configuration-DDDoiK5H.js (Deleted) -144 bytes 0 bytes -100.0% 🗑️
assets/self-hosting-docs-audit-CFkZrCjP.js (Deleted) -141 bytes 0 bytes -100.0% 🗑️
assets/circle-DMZJJSMl.js (Deleted) -130 bytes 0 bytes -100.0% 🗑️
assets/modal-DaMl_XLf.js (Deleted) -115 bytes 0 bytes -100.0% 🗑️

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 20, 2026
@loopover-orb

loopover-orb Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-20 20:59:52 UTC

12 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR adds three config-as-code fields (issuePlanEnabled, issuePlanExtraLabels, issuePlanMilestoneReuse) for the loopover_plan_repo_issues MCP tool, wired through the full allowlist chain: types.ts, engine mirror type, focus-manifest parser, DB repository defaults, OpenAPI schema, and .yml examples/docs. The refactor consolidating resolveRepositorySettings to a single fetch per call (removing the duplicate fetch inside resolveGittensorLabelEnrichment) is correct and well-reasoned, and the milestoneReuse skip-lookup logic and extraLabels merge are both traced correctly to their call sites. Tests cover all three new fields including the milestone-reuse-false path with a live fetch mock verifying the list endpoint is never called.

Nits — 5 non-blocking
  • src/services/issue-plan-draft.ts: `attemptReuse ? normalizeIssueTitleKey(target.title) : ""` piggybacks on the empty-string falsy check rather than an explicit early return, which is a little indirect to read.
  • The updated comment in resolveGittensorLabelEnrichment's docblock is good but the function still silently discards the passed-in settings.typeLabelsEnabled check if settings resolution behavior ever diverges from resolveRepositorySettings's caching semantics — worth double-checking there's no staleness risk between the two settings reads in future refactors, though not an issue here since it's a single resolved object now.
  • config/examples/loopover.full.yml and .loopover.yml.example duplicate the same 21-line doc block verbatim — consider a shared source-of-truth generation step if this pattern grows further (already implied by the existing dual-file convention).
  • Consider extracting the `Spec: selfhoster config surface + docs for the planning routine #7429` issue number references into a single doc comment anchor rather than repeating the literal across multiple functions, for easier future grep/cleanup once the issue closes.
  • The focus-manifest.test.ts field-exhaustiveness test is a nice guard against forgetting a field in .loopover.yml.example — good pattern to keep for any future settings additions.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #7429
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 28 registered-repo PR(s), 21 merged, 369 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 28 PR(s), 369 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The PR adds a scoped `issuePlanEnabled`/`issuePlanExtraLabels`/`issuePlanMilestoneReuse` settings surface to `.loopover.yml` (schema, parser, types, examples) and wires it into the planning tool, and it adds a documented section (`settings.issuePlan*`) in the existing self-hosting-configuration docs page covering usage and safety defaults, matching the issue's deliverables.

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, JavaScript, MDX, Shell, Solidity
  • Official Gittensor activity: 28 PR(s), 369 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

Scroll preview
Route Before (production) After (this PR's preview)
/ before / (scroll)
before / (scroll)

A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 37e7f86 into main Jul 20, 2026
18 checks passed
@loopover-orb
loopover-orb Bot deleted the claude/orb-github-issue-automation-080318 branch July 20, 2026 21:00
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.23077% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.47%. Comparing base (b24cec8) to head (44f59ca).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/loopover-engine/src/focus-manifest.ts 50.00% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7521      +/-   ##
==========================================
- Coverage   88.48%   88.47%   -0.01%     
==========================================
  Files         720      720              
  Lines       75725    75733       +8     
  Branches    22543    22548       +5     
==========================================
  Hits        67004    67004              
- Misses       7677     7679       +2     
- Partials     1044     1050       +6     
Flag Coverage Δ
shard-1 32.99% <7.69%> (-0.05%) ⬇️
shard-2 36.85% <7.69%> (-0.01%) ⬇️
shard-3 25.66% <69.23%> (+<0.01%) ⬆️
shard-4 38.88% <7.69%> (-0.01%) ⬇️
shard-5 34.21% <7.69%> (-0.01%) ⬇️
shard-6 36.22% <7.69%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/db/repositories.ts 96.72% <ø> (ø)
src/openapi/schemas.ts 100.00% <ø> (ø)
src/services/issue-plan-draft.ts 100.00% <100.00%> (ø)
src/types.ts 100.00% <ø> (ø)
packages/loopover-engine/src/focus-manifest.ts 98.78% <50.00%> (-0.30%) ⬇️

... and 1 file with indirect coverage changes

JSONbored added a commit that referenced this pull request Jul 20, 2026
The rebase conflict resolution took main's openapi.json wholesale for
one commit; regenerate from the final merged schemas so both this PR's
and #7521's additions are present.
JSONbored added a commit that referenced this pull request Jul 20, 2026
The rebase conflict resolution took main's openapi.json wholesale for
one commit; regenerate from the final merged schemas so both this PR's
and #7521's additions are present.
JSONbored added a commit that referenced this pull request Jul 21, 2026
The rebase conflict resolution took main's openapi.json wholesale for
one commit; regenerate from the final merged schemas so both this PR's
and #7521's additions are present.
JSONbored added a commit that referenced this pull request Jul 21, 2026
… report, contributor trust profiles (#7581)

* fix(review): repair the public decision-accuracy metric's reversal detection

The reversal query derived "mistake" status from a PR's own state after a
close/merge, which can never detect a merge undone by a separate revert PR
(a merged PR's state never returns to open on GitHub) and was scoped only
to a frozen own-ledger snapshot. Reuse the existing reversal_reopened/
reversal_reverted events already recorded elsewhere, and blend in live
fleet-wide accuracy across registered self-hosted instances so the public
number reflects the current fleet, not a historical snapshot. Also surfaces
the fleet's anti-gaming detection count (#2350) on the same payload.

Refs #7567

* feat(site): add a public fairness report page

Adds /fairness, linked from the homepage's Decision accuracy tile: the
full 8-week accuracy trend, per-repo breakdown, and anti-gaming-flags-
caught count, plus a short methodology note. Reuses the existing
/v1/public/stats payload rather than adding a new endpoint -- aggregate
counts only, no PR content or contributor identities.

Refs #7567

* feat(review): add internal contributor trust profiles

Per-login, per-repo gate-decision accuracy (mirrors computeGateEval,
keyed by contributor_gate_history instead of the actor-free review_audit)
and fairness-outlier detection that flags deviation from a project's
median in either direction, never asserting fault. Composes with per-repo
submission counts and moderation-violation history into one trust profile
per contributor, plus a backfill mechanism reconstructing historical gate
history from review_audit + pull_requests.author_login for PRs that
predate contributor_gate_history.

Internal, bearer-gated routes only -- never exposed publicly. Config-as-
code throughout: a global LOOPOVER_FAIRNESS_ANALYTICS flag overridable via
the self-repo's .loopover.yml (mirroring publicStats/ops), plus a
per-repo fairnessAnalyticsMode so any installed repo can opt its own gate
decisions and moderation history out of the aggregation via its own
private .loopover.yml.

Refs #7567

* fix(site): guard against a fleetAccuracy-less /v1/public/stats response

Discovered via manual verification: the homepage stats band and the new
fairness report page both read data.fleetAccuracy without a null guard,
which crashes (and is caught by the route error boundary) against any
currently-live API response, since that field doesn't exist until the
backend change ships. Add defensive optional chaining so both surfaces
degrade to the own-ledger accuracy number instead, matching the intended
fallback behavior once the fields genuinely diverge only during a
frontend-ahead-of-backend deployment window.

Refs #7567

* chore(openapi): regenerate spec after rebase onto main

The rebase conflict resolution took main's openapi.json wholesale for
one commit; regenerate from the final merged schemas so both this PR's
and #7521's additions are present.

* fix(review): sync fairnessAnalytics config docs into loopover.full.yml

The per-repo fairnessAnalyticsMode setting and fleet-wide fairnessAnalytics
block were only documented in .loopover.yml.example, drifting from
config/examples/loopover.full.yml which must stay byte-identical from the
canonical marker onward (test/unit/config-templates.test.ts).

* fix(review): remove stray null byte from contributor-gate-eval.ts

A literal NUL byte had been typed into the (login, project) map-key
template literal instead of a separator character, making git and other
tooling treat the whole file as binary (no diff, no line-level coverage
attribution). Replaced with ':', matching the composite-key separator
convention used elsewhere (rag.ts, inline-comments-select.ts).

* fix(ci): pin Node version in ui-preview-deploy.yml instead of reading .nvmrc

node-version-file: .nvmrc (introduced repo-wide by 8bd60f0 / #7408) broke
this one job: it deliberately has no actions/checkout step (see the file
header -- it never runs fork/PR code), so .nvmrc doesn't exist on the
runner and Setup Node has failed on every run since. That failure trips
the "Record FAILED deployment for Reviewbot" step, which writes a
permanent failure GitHub Deployment status -- so ORB's preview-URL
discovery (preview-url.ts's getLatestDeploymentStatus) short-circuits on
that failure and never even checks the separately-successful Cloudflare
Workers Builds deployment, breaking the "after" screenshot/scroll-preview
for every visual PR repo-wide, including this one on PR #7581.

Hardcodes node-version instead, matching the same already-established
exception in gittensor-impact.yml and visual-capture-fallback.yml.

* fix(review): fall back to a placeholder for a missing after-GIF

The scroll-preview "after" slot resolved to undefined (rendered as a bare
"—") whenever there was no live preview page to capture, unlike the
screenshot slot which already substitutes a loading/failed placeholder
(afterPlaceholder) in the same situation. That made "GIF capture still
building/failed" indistinguishable from "GIF capture isn't configured for
this repo at all". actions_fallback never produces a GIF (only static
PNGs), so there's no cached fallback artifact to look up here the way
resolveFallbackAfterShot does for the screenshot slot -- the placeholder
substitution is the whole fix.

* test(review): cover the missing-limit branch on the backfill route

Closes the last codecov/patch gap on PR #7581 (routes.ts's typeof
body?.limit === "number" ternary only had its truthy arm exercised).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spec: selfhoster config surface + docs for the planning routine

1 participant