Skip to content

feat(config): add review.labeling_rules deterministic label suggestions (#2045) - #3534

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
nickmopen:feat/labeling-rules
Jul 5, 2026
Merged

feat(config): add review.labeling_rules deterministic label suggestions (#2045)#3534
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
nickmopen:feat/labeling-rules

Conversation

@nickmopen

Copy link
Copy Markdown
Contributor

Closes #2045 (part of #1959).

Adds review.labeling_rules — deterministic {label, when} rules that suggest a non-scoring label when a PR's changed paths / title / description match. Suggestions are advisory; they're auto-applied only when the repo's autoLabelEnabled is set. Empty/unset ⇒ no suggestion (byte-identical to today).

What's here

  • focus-manifest.ts
    • LabelingRule type ({ label, whenPaths, titleContains, descriptionContains }) + labelingRules on FocusManifestReviewConfig.
    • parseReviewLabelingRules — mirrors parseReviewPreMergeChecks: public-safe labels, refuses the reserved gittensor: namespace (scoring/type labels), requires ≥1 when criterion, caps at MAX_PATH_INSTRUCTIONS, warn+drops invalid entries.
    • reviewConfigToJson round-trip (omitted when empty ⇒ byte-identical) + present + the EMPTY literals.
  • src/review/labeling-rules.ts — pure, deterministic resolveLabelingRules(rules, facts, autoLabelEnabled) → { suggest, apply }. A rule fires when all its set criteria match (path glob via matchesManifestPath, case-insensitive title/description contains). Mirrors the pure resolvePrTypeLabel decider — no IO.
  • .gittensory.yml.example — documented review.labeling_rules.

Scope note

This PR delivers the deterministic config + pure resolver + tests + doc. Wiring the resolver into the live label-apply path in queue/processors.ts is a natural follow-up — deliberately kept separate, mirroring how resolvePrTypeLabel is a pure decider distinct from its processor application, so this PR stays pure and side-effect-free.

Validation

Typecheck clean. Focused suites green (labeling-rules, focus-manifest, signals-coverage, and the example-file validation):

Test Files  5 passed (5)
     Tests  357 passed (357)

Tests cover every parse branch (reserved/invalid/missing-label/no-criterion/cap/non-list), round-trip (full / path-only / title-only / absent-omitted), and resolve (each when criterion, AND semantics, autoLabel on/off, dedup + order).

…ns (JSONbored#2045)

A maintainer can declare deterministic `{label, when}` rules that SUGGEST a
non-scoring label when a PR's changed paths / title / description match. Surfaced
as advisory suggestions; auto-applied only when the repo's autoLabelEnabled is set.
Empty (default) ⇒ no suggestion (byte-identical). Part of JSONbored#1959.

- focus-manifest.ts: LabelingRule type + labelingRules on FocusManifestReviewConfig;
  parseReviewLabelingRules (mirrors parseReviewPreMergeChecks) — public-safe labels,
  refuses the reserved `gittensor:` namespace, requires >=1 when-criterion, caps at
  MAX_PATH_INSTRUCTIONS, warn+drop invalid; reviewConfigToJson round-trip (omitted
  when empty ⇒ byte-identical) + present + EMPTY literals.
- src/review/labeling-rules.ts: pure, deterministic resolveLabelingRules(rules, facts,
  autoLabelEnabled) → { suggest, apply } — mirrors the pure resolvePrTypeLabel decider
  (no IO; the GitHub apply stays a separate processor concern).
- .gittensory.yml.example: documented review.labeling_rules.
- Tests: every parse branch (reserved/invalid/no-criterion/cap/non-list), round-trip
  (full / path-only / title-only / absent-omitted), and resolve (each when-criterion,
  AND semantics, autoLabel on/off, dedup+order).

Scope: the deterministic config + pure resolver + tests + doc. Wiring the resolver
into the live label-apply path in queue/processors.ts is a follow-up, mirroring how
resolvePrTypeLabel is a pure decider separate from its processor application.
@nickmopen
nickmopen requested a review from JSONbored as a code owner July 5, 2026 16:05
@superagent-security

Copy link
Copy Markdown
Contributor

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

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

loopover-orb Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Warning

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

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-05 16:12:32 UTC

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

⏸️ Suggested Action - Manual Review

Review summary
Adds `review.labeling_rules` — deterministic parse, pure resolver, round-trip serializer, and comprehensive tests — correctly mirroring the `parseReviewPreMergeChecks`/`resolvePrTypeLabel` patterns. AND-semantics in `ruleMatches`, the reserved-namespace guard, the 50-entry cap, dedup, and `autoLabelEnabled` flag all implement what the description promises. Every empty/default literal is consistently updated, and the round-trip serialization is byte-identical when rules are absent. The explicit deferral of processor wiring is the right scope call. No blockers.

Nits — 6 non-blocking
  • labeling-rules.ts: `LabelingRuleFacts.description` is typed `string` (not `string | null`) — whoever wires this into the processor must coerce a null/undefined PR body to `""` before calling `resolveLabelingRules`; a brief JSDoc note on the type enforces this contract before the follow-up wiring lands.
  • labeling-rules.ts:35: dedup with `suggest.includes(rule.label)` is O(n²) over the suggest list — fine at the 50-rule cap, but a `Set<string>` for seen labels is the conventional pattern and removes the implicit coupling to cap size.
  • focus-manifest.ts: if `title_contains` or `description_contains` is present but non-string (e.g. `123`), `parsePublicSafeText` warns and returns null, silently narrowing the rule's constraints rather than dropping the whole entry — a maintainer who writes `title_contains: 123` and has `when_paths` set will get a broader-firing rule than they intended; consider emitting a 'ignoring entry' warning and `continue`-ing when any present criterion fails to parse.
  • focus-manifest.ts: extract the repeated inline review-config empty literal into a named `EMPTY_REVIEW_CONFIG` constant (parallel to `EMPTY_GATE_CONFIG`/`EMPTY_AUTO_REVIEW_CONFIG`) — this PR required three identical edits to `EMPTY_MANIFEST`, `emptyManifest()`, and `parseReviewConfig`, which is exactly the fragility a constant eliminates.
  • labeling-rules.ts: add a `@​param` or inline note on `LabelingRuleFacts` documenting that `description` must be `""` (not null/undefined) when the PR body is absent — this is the one contract the follow-up processor wiring must get right and it's not obvious from the type alone.
  • Readiness score is below the configured threshold — Use the readiness panel as advisory maintainer context; the score does not block this PR.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #2045
Related work ⚠️ 3 scoped overlaps Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 121 registered-repo PR(s), 81 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor nickmopen; Gittensor profile; 121 PR(s), 0 issue(s).
Gate result ✅ Passing No configured blocker found.
Review context
  • Author: nickmopen
  • Role context: outside_contributor
  • 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: 121 PR(s), 0 issue(s).
  • Related work: Titles/paths share 5 meaningful terms. (issue #1680, issue #1681)
  • Related work: Titles/paths share 5 meaningful terms. (issue #1683, issue #1681)
  • Related work: Titles/paths share 7 meaningful terms. (issue #2044, issue #2045)
  • Additional title-only matches omitted; title-only overlap does not block.
Contributor next steps
  • Review top overlaps.
  • Add a concise scope and risk note.
  • Await review-lane availability.
  • Refresh registry data or choose a registered active repo.
  • Check active issues and PRs before submitting.
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

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.10%. Comparing base (fc021a5) to head (f43e384).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3534      +/-   ##
==========================================
+ Coverage   93.09%   93.10%   +0.01%     
==========================================
  Files         301      302       +1     
  Lines       31450    31496      +46     
  Branches    11483    11502      +19     
==========================================
+ Hits        29279    29325      +46     
  Misses       1517     1517              
  Partials      654      654              
Files with missing lines Coverage Δ
src/review/labeling-rules.ts 100.00% <100.00%> (ø)
src/signals/focus-manifest.ts 98.96% <100.00%> (+0.03%) ⬆️
🚀 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 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.

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

@loopover-orb
loopover-orb Bot merged commit f47f0b3 into JSONbored:main Jul 5, 2026
8 checks passed
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.

feat(config): add review.labeling_rules deterministic label suggestions

1 participant