Skip to content

feat(agent): model branch and linked-issue eligibility - #347

Merged
JSONbored merged 5 commits into
JSONbored:mainfrom
Lobster-0429:feat/eligibility-plan
Jun 3, 2026
Merged

feat(agent): model branch and linked-issue eligibility#347
JSONbored merged 5 commits into
JSONbored:mainfrom
Lobster-0429:feat/eligibility-plan

Conversation

@Lobster-0429

Copy link
Copy Markdown
Contributor

Summary

  • Closes feat(scoring): simulate linked-issue and branch eligibility scenarios #288: models whether a candidate branch or PR is eligible enough to pursue based on linked issue state and branch signals
  • Adds src/services/eligibility-plan.ts — a pure deriveEligibilityPlan(result) renderer over ScorePreviewResult that explains eligibility blockers and cleanup paths
  • Simulates linked-issue present/missing/closed/reopened cases plus branch eligibility (eligible/ineligible/unknown/not-required)
  • Public summaries avoid private scoreability, reward/risk, wallet, hotkey, and trust context; local source/path context is fail-closed and never echoed
  • Adds test/unit/eligibility-scenarios.test.ts (21 tests): fixtures for linked, unlinked, closed-link, reopened-link, branch-ineligible, branch-eligibility-missing + public/private sanitizer tests

Scope

  • 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 — clean
  • npm run test:coverage locally — 793 pass (1 skipped); pre-existing Windows failures confirmed on main before this branch; coverage stays above 97%
  • 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:

  • UI/MCP/worker checks not applicable — this PR adds one pure rendering service plus its unit test; no UI, MCP, or worker surface changed

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.
  • Local source-upload remains fail-closed — the plan never includes local path or source content; a test asserts no /Users, /home, /tmp, or C:\Users strings leak.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. (not applicable)
  • API/OpenAPI/MCP behavior is updated and tested where needed. (renderer is pure; wiring into surfaces is out of scope for this issue)
  • Visible UI changes include screenshots or a short recording. (not applicable)
  • Public docs/changelogs are updated where needed. (not applicable)

Notes

EligibilityPlan shape:

Field Meaning
eligible True only when the linked-issue multiplier is eligible AND branch is affirmatively confirmed
linkedIssueStatus not_required / raw / plausible / validated / invalid / unavailable
branchEligibilityStatus eligible / ineligible / unknown / not_required
blockers Public-safe, code-keyed eligibility blocker text
cleanupPaths Concrete sanitized steps to reach eligibility
linkedIssueProjection What validating the linked issue would unlock (null when not requested / no gain)
publicSummary One-sentence status, scrubbed of private context

Key design decision — conservative eligible: a "validated linked issue + unknown branch eligibility" combination is treated as not eligible. The scoring model only disables the multiplier on confirmed ineligibility, but for an eligibility plan we require positive branch confirmation so the plan never overpromises. Missing metadata surfaces a branch_eligibility_missing blocker and cleanup path instead.

Eligibility blocker subset (filtered from ScorePreviewResult.blockedBy): branch_ineligible, branch_eligibility_missing, linked_issue_invalid, linked_issue_unvalidated — each mapped to generic public-safe phrasing.

Test structure (21 tests): six scenario fixtures (linked/validated, unlinked, closed-link/invalid, reopened-link/raw, branch-ineligible, branch-eligibility-missing) asserting the eligible flag, status fields, underlying preview blocker codes, cleanup paths, and the linkedIssueFixed projection; plus two sanitizer tests confirming every public field passes sanitizePublicComment across all cases and that local path/source context is fail-closed.

Adds src/services/eligibility-plan.ts, a pure renderer that derives a
structured EligibilityPlan from a ScorePreviewResult. It explains whether
a candidate branch or PR is eligible enough to pursue based on linked
issue state and branch signals, with public-safe summaries and cleanup
paths. Advisory only — never files issues, opens PRs, comments, labels,
closes, or merges; never uploads or echoes local source/path context.

deriveEligibilityPlan(result) returns:
- eligible: only true when the linked-issue multiplier is eligible AND the
  branch is affirmatively confirmed (eligible or not_required). "unknown"
  or missing branch metadata is treated as not-yet-eligible so the plan
  never overpromises.
- linkedIssueStatus / branchEligibilityStatus: surfaced verbatim.
- blockers: public-safe, code-keyed descriptions for the eligibility
  subset of ScorePreviewResult.blockedBy (branch_ineligible,
  branch_eligibility_missing, linked_issue_invalid, linked_issue_unvalidated).
- cleanupPaths: concrete, sanitized steps to reach eligibility.
- linkedIssueProjection: public-safe note of what validating the linked
  issue would unlock (null when no linked issue is requested or no gain).
- publicSummary: one-sentence status, scrubbed of private context.

All public fields pass sanitizePublicComment, so reward/score/wallet/
hotkey/trust language cannot reach contributor-facing surfaces.

test/unit/eligibility-scenarios.test.ts (new, 21 tests):
- Fixtures for linked (validated), unlinked (mode none), closed-link
  (invalid), reopened-link (raw/unvalidated), branch-ineligible, and
  branch-eligibility-missing cases.
- Asserts eligible flag, status fields, blocker codes in the underlying
  preview, cleanup paths, and the linkedIssueFixed projection.
- Public/private sanitizer tests: every public field across all cases
  passes sanitizePublicComment; local path/source context is fail-closed
  and never leaks (no /Users, /home, /tmp, C:\Users).
JSONbored and others added 2 commits June 3, 2026 12:08
CI validate/coverage failed: global branch coverage was 96.98% (< 97%
threshold) with eligibility-plan.ts at 86.66% branches — it was pushed
without a local `--coverage` run.

- Add fixtures for the reachable "plausible" and "unavailable" linked-issue
  statuses so the status-key and blocker branches are exercised.
- Remove the dead "unlinked" status-key branch (unreachable: linkedIssueStatus
  is only "not_required" when branch status is also "not_required") and its
  unused summary entry.
- Mark the type-required-but-unreachable defensive fallbacks with
  `/* v8 ignore */` (noUncheckedIndexedAccess forces the `??` guards): the
  blocker public-text lookup, the status-summary lookup, and the
  always-present linkedIssueFixed/current scenario guards.

eligibility-plan.ts branches: 86.66% -> 97.14%; global branches back over
the 97% gate. All tests pass (24 in this file).
@Lobster-0429

Copy link
Copy Markdown
Contributor Author

Hi, @JSONbored,
Please review this again, Thank you!

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@web-dev0521 this is ready from my pass.

A few notes:

  • The conservative branch eligibility behavior is the right default; unknown branch eligibility should not overpromise readiness.
  • The public-facing text goes through the sanitizer and avoids private scoring/reward language.
  • The focused scenario coverage is enough for this pure service.

No code changes requested.

Validation expected:

  • Keep the current green CI.

@dosubot dosubot Bot added the lgtm label Jun 3, 2026
@JSONbored
JSONbored merged commit ea255ba into JSONbored:main Jun 3, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in gittensory - v1 roadmap Jun 3, 2026
Lobster-0429 added a commit to Lobster-0429/gittensory that referenced this pull request Jun 3, 2026
…st fallbacks

Merging main (JSONbored#347 eligibility-plan, JSONbored#355 analytics role) dropped global
branch coverage to 96.98%, below the 97% gate, failing the validate job.

- scenario-summary.ts was at 84.61% branch: the rankScenarios comparator's
  order/localeCompare tie-breakers never ran because every fixture used
  distinct scores. Add equal-score (different-name) and duplicate-name
  fixtures to exercise both fallbacks.
- repo-policy-readiness.ts owner-context '?? default' fallbacks only run
  when focusManifest is undefined; existing tests passed parsed (defined)
  manifests. Add an undefined-manifest fixture.

Global branch coverage now 97.07% (9508/9794).
@JSONbored JSONbored added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. and removed feature labels Jun 10, 2026
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

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

feat(scoring): simulate linked-issue and branch eligibility scenarios

2 participants