Skip to content

fix(selfhost): decouple taxonomy labels from outcome labels#2735

Merged
JSONbored merged 2 commits into
mainfrom
fix/selfhost-decouple-taxonomy-labels
Jul 3, 2026
Merged

fix(selfhost): decouple taxonomy labels from outcome labels#2735
JSONbored merged 2 commits into
mainfrom
fix/selfhost-decouple-taxonomy-labels

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

The per-PR TYPE/taxonomy label (gittensor:bug/gittensor:feature/gittensor:priority,
classified from the PR title + changed paths) was nested inside if (decision.willLabel), the
gate that governs the public-facing gittensorLabel context label. Since decision.willLabel
folds in miner-detection status, publicAudienceMode: oss_maintainer + an unconfirmed miner,
autoLabelEnabled, and the repo's publicSurface mode, any of those conditions silently also
suppressed the type label — even though it is internal triage metadata, not a contributor-facing
signal, and its own header comment already said it should be independent of the context label.

This is a follow-up to #2719 (fix(selfhost): scope label automation for one-shot reviews): that
PR separated the outcome/enforcement label families from the base context label's autonomy dial;
this PR does the analogous split for the last remaining coupled family — taxonomy labels.

Changes:

  • New independent per-repo setting typeLabelsEnabled (default true, matching the prior
    de-facto behavior), wired through the standard settings pipeline (migration, RepositorySettings,
    .gittensory.yml parser, OpenAPI schema, DB repository defaults/row-mapping).
  • src/queue/processors.ts: moved the type-label block out from under decision.willLabel into
    its own gate keyed on typeLabelsEnabled. It now applies regardless of author type (bot,
    maintainer-excluded, missing author) or the narrower reasons the context label can be off
    (oss_maintainer + unconfirmed miner, autoLabelEnabled, publicSurface mode) — the one thing
    still respected is publicAudienceMode: gittensor_only's stricter promise of total silence for a
    non-confirmed-miner author, and the agentPaused kill-switch. Added a type_label_decision
    structured log line (applied/label or the suppression reason) alongside the existing
    type_label_error convention for operator visibility.
  • .gittensory.yml.example: documented typeLabelsEnabled and added a short summary of the four
    now-fully-independent label families (context / taxonomy / autonomy-outcome / anti-abuse
    enforcement) and which setting governs each.

No linked issue: this is a direct follow-up to the maintainer's own investigation that produced
#2719, continuing the same label-decoupling work with no separate tracking issue filed.

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 an issue, or this is small enough that the summary explains why an issue is not needed.

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally (unsharded, full run) — 7144+ tests passed, pre-existing skips only; every changed file (src/types.ts, src/db/schema.ts, src/db/repositories.ts, src/signals/focus-manifest.ts, src/signals/settings-preview.ts, src/queue/processors.ts, src/openapi/schemas.ts) is 100% line- and branch-covered on the diff, verified directly against coverage/lcov.info for the exact changed line ranges (two intentionally-unreachable lines — a contentGlobs forward-compat hook never wired to any real setting, and a ?? true fallback that can't be undefined once resolved through the DB layer — are marked with v8 ignore and explained inline, matching this file's existing convention).
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • npm run selfhost:env-reference:check (part of the full test:ci chain but not in this
    template's list) fails on a clean origin/main checkout with no changes from this PR applied —
    confirmed by stashing this branch's diff and re-running. Pre-existing, unrelated drift; flagged
    separately rather than folded into this PR's diff.

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/cookie/CORS/session code touched.
  • API/OpenAPI/MCP behavior is updated and tested where needed. — typeLabelsEnabled added to RepositorySettingsSchema and RepoSettingsPreviewSchema; openapi.json regenerated; ui:openapi:settings-parity passes.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. — N/A, no UI changed.
  • Visible UI changes include a UI Evidence section below. — N/A, backend/config-as-code only, no visible UI change.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs. — .gittensory.yml.example updated; CHANGELOG.md untouched.

Notes

  • New migration migrations/0101_type_labels_enabled.sql adds type_labels_enabled (NOT NULL DEFAULT 1) — a plain hand-authored ALTER TABLE ADD COLUMN, matching this repo's established
    migration convention. Verified the number was still free against origin/main immediately before
    authoring and again right before pushing.
  • RepositorySettings.typeLabelsEnabled is declared boolean | undefined (optional), matching the
    existing precedent for fields like badgeEnabled — always populated by the DB layer, optional
    only so the ~15 existing test fixtures that construct a RepositorySettings-shaped object
    without every field don't need touching.
  • Confirmed via a new regression test that publicAudienceMode: gittensor_only's stricter
    "stay entirely quiet for a non-confirmed-miner author" promise still holds even with the gate
    enabled — the type label does not leak out from underneath that mode's total-silence guarantee,
    unlike the narrower oss_maintainer/author-type exclusions it is deliberately decoupled from.

The per-PR TYPE label (gittensor:bug/feature/priority) was nested inside
the public-surface label decision, so miner-detection status, oss_maintainer
mode, or a maintainer-authored PR could silently suppress it even though it
is internal triage metadata, not a contributor-facing signal. Add an
independent typeLabelsEnabled setting (default true) and apply the type
label regardless of author type or the narrower reasons the base context
label can be off, while still respecting publicAudienceMode: gittensor_only's
stricter promise of total silence for a non-confirmed-miner author and the
agentPaused kill-switch.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 3, 2026

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
gittensory-ui 56e08f4 Commit Preview URL

Branch Preview URL
Jul 03 2026, 09:16 AM

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.04%. Comparing base (86dde13) to head (56e08f4).
⚠️ Report is 7 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2735      +/-   ##
==========================================
+ Coverage   96.01%   96.04%   +0.03%     
==========================================
  Files         244      245       +1     
  Lines       27300    27344      +44     
  Branches     9919     9934      +15     
==========================================
+ Hits        26211    26263      +52     
+ Misses        462      458       -4     
+ Partials      627      623       -4     
Files with missing lines Coverage Δ
src/db/repositories.ts 96.33% <100.00%> (+<0.01%) ⬆️
src/db/schema.ts 69.46% <ø> (ø)
src/openapi/schemas.ts 100.00% <ø> (ø)
src/queue/processors.ts 92.64% <100.00%> (+0.18%) ⬆️
src/signals/focus-manifest.ts 99.34% <100.00%> (ø)
src/signals/settings-preview.ts 99.23% <100.00%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb

loopover-orb Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-03 09:35:55 UTC

12 files · 1 AI reviewer · 1 blocker · readiness 100/100 · CI green · blocked

⏸️ Suggested Action - Manual Review

  • Possible leaked secret in the diff (generic_secret_assignment) — Remove the secret from the diff, rotate the exposed credential, then re-run the gate.

Review summary
The change adds a DB-backed `typeLabelsEnabled` setting and moves taxonomy label writes out of the public context-label gate while still honoring `agentPaused` and the stricter non-confirmed-author mute. The migration, schema, repository defaults/row mapping, config parser, preview schema, and OpenAPI output are wired consistently, with a NOT NULL default preserving existing behavior. The queue tests exercise the important decoupling cases, including disabled taxonomy labels and independence from the base context label.

Nits — 4 non-blocking
  • nit: `test/unit/queue.test.ts:16199` uses a realistic `token` fixture shape; switch that stub value to an obviously fake placeholder to avoid secret-scanner noise in future diffs.
  • nit: `src/queue/processors.ts:6252` adds a large explanatory comment directly in the hot-path function; the operational rule is useful, but most of the fixture/back-compat detail would be easier to maintain beside the `RepositorySettings.typeLabelsEnabled` type comment.
  • In `test/unit/queue.test.ts:16199`, rename the mocked response field value from `installation-token` to something like `fake-installation-token-for-tests` while keeping the GitHub response shape unchanged.
  • In `src/queue/processors.ts:6252`, trim the inline comment to the runtime gating contract and leave the optional-fixture rationale in `src/types.ts:672`, where future settings changes are more likely to be reviewed.

Concerns raised — review before merging

  • Possible leaked secret in the diff (generic_secret_assignment) — Remove the secret from the diff, rotate the exposed credential, then re-run the gate.
Signal Result Evidence
Code review ❌ 1 blocker 1 reviewer
Linked issue ✅ No-issue rationale PR body explains why no issue is linked.
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 (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 61 registered-repo PR(s), 52 merged, 478 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 61 PR(s), 478 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 61 PR(s), 478 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • No action.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
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.

🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot added gittensor gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. labels Jul 3, 2026
@JSONbored
JSONbored force-pushed the fix/selfhost-decouple-taxonomy-labels branch from 5ad170b to 56e08f4 Compare July 3, 2026 09:15
@JSONbored
JSONbored merged commit 73c9de4 into main Jul 3, 2026
15 checks passed
@JSONbored
JSONbored deleted the fix/selfhost-decouple-taxonomy-labels branch July 3, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Development

Successfully merging this pull request may close these issues.

1 participant