Skip to content

feat(gate): add selfAuthoredLinkedIssueGateMode with config-as-code parity#1198

Merged
JSONbored merged 1 commit into
mainfrom
fix/self-authored-linked-issue-gate-mode
Jun 24, 2026
Merged

feat(gate): add selfAuthoredLinkedIssueGateMode with config-as-code parity#1198
JSONbored merged 1 commit into
mainfrom
fix/self-authored-linked-issue-gate-mode

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Exposes the self_authored_linked_issue signal as an opt-in per-repo gate field. When set to block, a PR that links an issue the contributor themselves opened becomes a hard gate blocker. Defaults to advisory — the finding surfaces in the check panel without blocking unless the maintainer explicitly opts in.

The issue-authorship detection is fail-open: when the linked issue's author is unknown (not yet in the local DB, or DB hiccup), the finding is never raised — no false positives.

Changes:

  • migrations/0055: self_authored_linked_issue_gate_mode TEXT NOT NULL DEFAULT 'advisory' on repository_settings
  • src/db/schema.ts: Drizzle column added
  • src/types.ts: selfAuthoredLinkedIssueGateMode: GateRuleMode on RepositorySettings; linkedIssueAuthorLogins on buildPullRequestAdvisory context
  • src/rules/advisory.ts: addPullRequestFindings detects self-authored issues from linkedIssueAuthorLogins (case-insensitive, fail-open on null); isConfiguredGateBlocker routes self_authored_linked_issue through the new mode
  • src/queue/processors.ts: gateCheckPolicy passes selfAuthoredLinkedIssueGateMode into the policy; adds resolveLinkedIssueAuthorLogins helper that fetches issue author logins from the DB (fail-safe, errors → null); both buildPullRequestAdvisory call sites now pass linkedIssueAuthorLogins
  • src/rules/predicted-gate.ts: includes selfAuthoredLinkedIssueGateMode in gate prediction
  • src/signals/focus-manifest.ts: reads and resolves gate.selfAuthoredLinkedIssue from .gittensory.yml (6 spots: type, empty constant, parse, hasAny, serialize, resolveEffectiveSettings); settings.selfAuthoredLinkedIssueGateMode overlay
  • src/signals/settings-preview.ts: exposes the field in the settings preview
  • src/openapi/schemas.ts: schema updated; openapi.json regenerated
  • Tests: 14 in rules.test.ts (detection + all gate-mode branches); 4 in gate-check-policy.test.ts (resolveLinkedIssueAuthorLogins — happy path, missing issue, DB error, empty array)

Scope

  • This PR touches backend/API code (src/)
  • This PR touches frontend/UI code (apps/gittensory-ui/)
  • This PR adds or modifies DB schema (migration 0055)
  • This PR changes gate/advisory evaluation logic
  • This PR adds a new per-repo settings field (config-as-code parity in same PR)
  • This PR changes auth/session/CORS behavior

Validation

  • npm run test:ci — fully green (typecheck, coverage, workers, mcp, openapi:check, ui)
  • 14 unit tests covering detection logic, fail-open cases, and all three gate modes (off/advisory/block)
  • 4 unit tests for resolveLinkedIssueAuthorLogins covering happy path + null + DB error + empty
  • Both sides of every ??/ternary/&& in new code covered
  • npm run ui:openapi regenerated and committed
  • Migration 0055 contiguous (next free after 0054)
  • git diff --check clean

Safety

  • No secrets, wallets, hotkeys, trust scores, or reward values anywhere
  • No changes to site/, CNAME, or **/lovable/**
  • No CHANGELOG.md edits
  • No AI/Claude/agent attribution in commits or PR text
  • Default is advisory — no change to existing gate behavior until maintainer opts in
  • Detection is fail-open: missing/null issue author → no finding, no block

Advances #1198

…arity

Exposes the self_authored_linked_issue signal as an opt-in per-repo gate
field. When set to `block`, a PR that links an issue the contributor
themselves opened becomes a hard gate blocker rather than an advisory
warning. Defaults to `advisory` — the finding surfaces in the panel
without ever closing a PR unless the maintainer opts in.

Implementation:
- DB migration 0055: adds `self_authored_linked_issue_gate_mode TEXT`
  to `repository_settings` (DEFAULT 'advisory')
- Drizzle schema + RepositorySettings type updated
- `buildPullRequestAdvisory`: adds `linkedIssueAuthorLogins` context
  param; raises `self_authored_linked_issue` when the PR author matches
  any linked issue author (case-insensitive, fail-open on unknown)
- `isConfiguredGateBlocker`: routes `self_authored_linked_issue` through
  the new `selfAuthoredLinkedIssueGateMode` policy field
- `gateCheckPolicy`: threads `selfAuthoredLinkedIssueGateMode` from
  resolved settings into the gate policy
- `resolveLinkedIssueAuthorLogins`: fetches issue author logins from the
  local DB (fail-safe: errors return null, never block the advisory)
- Both `buildPullRequestAdvisory` call sites in processors.ts now pass
  `linkedIssueAuthorLogins` resolved from the DB
- config-as-code parity: `focus-manifest.ts` reads/writes/resolves the
  field from `.gittensory.yml` gate.selfAuthoredLinkedIssue
- `settings-preview.ts`: exposes the field in the settings preview
- `predicted-gate.ts`: includes the field in the gate prediction input
- OpenAPI regenerated; snapshot tests updated

Tests: 14 unit tests in rules.test.ts cover the detection logic and all
gate-mode branches; 4 tests in gate-check-policy.test.ts cover
resolveLinkedIssueAuthorLogins (happy path, missing issue, DB error).
@dosubot dosubot Bot added the size:M label Jun 24, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

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

@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
gittensory-ui 99a914e Commit Preview URL

Branch Preview URL
Jun 24 2026, 08:48 AM

@JSONbored
JSONbored merged commit ff38769 into main Jun 24, 2026
17 checks passed
@JSONbored
JSONbored deleted the fix/self-authored-linked-issue-gate-mode branch June 24, 2026 08:49
@codecov

codecov Bot commented Jun 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.33333% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.78%. Comparing base (ad1f2c9) to head (99a914e).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/signals/focus-manifest.ts 25.00% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1198      +/-   ##
==========================================
- Coverage   94.80%   94.78%   -0.02%     
==========================================
  Files         157      157              
  Lines       19100    19115      +15     
  Branches     6915     6924       +9     
==========================================
+ Hits        18107    18119      +12     
  Misses        399      399              
- Partials      594      597       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant