refactor(engine): extract the stranded linked-reference parsers out of the D1 repository layer - #5771
Conversation
…f the D1 repository layer (JSONbored#4882) `src/db/repositories.ts` is a ~386KB, D1-query-heavy repository-access file, and JSONbored#4882 calls out the exact candidate stranded inside it: "a pure regex-based parser living inside the very large D1-query-heavy repository-access file". That parser is the linked-issue/PR reference extractor -- pure regex logic with no D1 or `Env` dependency, yet four core modules reach into the database layer purely to get at it. Move it to `@loopover/engine` as `github/linked-references.ts` (regexes byte-for-byte identical, so the live gate's behavior is provably unchanged), and re-export it from `src/db/repositories.ts` as a thin shim so every existing importer keeps working. This also converges a real divergence. Because the engine cannot import from `src/`, `signals/predicted-gate-engine.ts` carried a hand-written second copy that had drifted: it was missing the inline-code-span guard. This repo's own PR template contains "(e.g. `Closes JSONbored#123`)" on the line contributors are told to fill out, not replace -- so the predicted gate read a linked issue where the live gate correctly sees none, telling contributors their PR was safe right before the linked-issue hard rule closed it. The engine copy also lacked the MAX_LINKED_ISSUE_NUMBERS overflow cap that linked-issue-hard-rules.ts relies on. Both gates now resolve one shared module. Tests cover the moved module at 100% statements/branches/functions/lines, including both sides of the code-span overlap predicate, the cross-repo qualified form, overflow at default/explicit/fractional/ negative limits, and regression tests pinning that the predicted gate and the live gate now agree on the unedited PR template.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5771 +/- ##
==========================================
- Coverage 95.07% 95.07% -0.01%
==========================================
Files 582 583 +1
Lines 46216 46211 -5
Branches 14820 14820
==========================================
- Hits 43940 43935 -5
Misses 1516 1516
Partials 760 760
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Caution 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥 🛑 LoopOver review result - reject/close recommendedReview updated: 2026-07-14 13:44:24 UTC
🛑 Suggested Action - Reject/Close Review summary Nits — 4 non-blocking
Why this is blocked
📋 Copy for AI agents — paste into your coding agent
Linked issue satisfactionPartially addressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 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.
|
|
Gittensory is closing this pull request on the maintainer's behalf (No linked issue detected). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed. |
Summary
Closes #4882.
This is the sweep that issue asks for, aimed at the file it names —
src/db/repositories.ts, the ~386KB, D1-query-heavy repository-access layer — and it moves the candidate that issue names: "a pure regex-based parser living inside the very large D1-query-heavy repository-access file."That parser is the linked-issue / linked-PR reference extractor:
extractLinkedIssueNumbersWithOverflow,extractLinkedIssueNumbers,extractLinkedPrNumbersandMAX_LINKED_ISSUE_NUMBERS. It is pure regex logic with no D1 orEnvdependency, yet four core modules (src/github/backfill.ts,src/review/enrichment-wire.ts,src/review/linked-issue-hard-rules.ts,src/signals/engine.ts) reach into the database layer purely to get at it.Moving it into
@loopover/enginealso fixes a real, live divergence, which is why this one was worth moving first.The divergence this closes
Because the engine cannot import from
src/,packages/loopover-engine/src/signals/predicted-gate-engine.tscarried a hand-written second copy of the parser — and that copy had drifted. It was missing the inline-code-span guard the live gate's copy has:src/db/repositories.ts)- [ ] I linked a currently open issue this PR resolves (e.g. `Closes #123`) …That string is line 10 of this repo's own
.github/pull_request_template.md. The template says to fill it out, not replace it — so the overwhelmingly common contributor PR body still contains it verbatim. The result:gittensory_predict_gateand the miner's local preflight told a contributor "you have a linked issue", while the live gate saw none and auto-closed the PR under the linked-issue hard rule. The pre-submit oracle was wrong in exactly the failure mode it exists to prevent.The engine copy also silently lacked the
MAX_LINKED_ISSUE_NUMBERS(50) overflow cap thatlinked-issue-hard-rules.tsrelies on.What changed
packages/loopover-engine/src/github/linked-references.ts— the parsers, moved verbatim (regexes byte-for-byte identical to the originals, so the live gate's behavior is provably unchanged). Placed in the engine's existinggithub/directory, alongsideconstants.tsandsanitize-public-comment.ts.packages/loopover-engine/src/signals/predicted-gate-engine.ts— its hand-written duplicate is deleted; it now imports the shared parser. The predicted gate and the live gate can no longer disagree.src/db/repositories.ts— the stranded implementation is gone; the file re-exports from the engine via a thin shim, so all four existing importers keep working unchanged. Imported by relative source path, matching this repo's established engine-consumption convention (src/signals/check-summary.ts).No public API changed, and no gate-decision behavior changed on the host side.
Other stranded-pure-logic candidates found in the same sweep
Recorded here so the next slice of #4882 doesn't have to re-derive them; all are pure, top-level, and D1-free inside
src/db/repositories.ts::6900-7290) —buildProductUsageDailyRollupRecord,buildProductUsageActivationFunnel,buildProductUsageRetentionRollups,productUsageRetentionRate,intersectionCount,addProductUsageUtcDays. The largest pure cluster in the file; a natural standalone engine module.sanitizeProductUsageMetadata/sanitizeProductUsageJson/sanitizeProductUsageString.parseAutonomyPolicy,parseGatePack,parseTypeLabelSet,normalizeReviewNagPolicy, …) — deliberately left alone here: they belong to thesettings/slice tracked by Finish thesettings/slice extraction #4879, and moving them in this PR would collide with it.loginMatchesis not a candidate despite looking pure — it builds a Drizzlesqlfragment and belongs with the query layer.Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderatenpm run test:ciwas run in full and is green. New suitetest/unit/linked-references.test.tscovers the moved module at 100% statements / branches / functions / lines (29/29, 19/19, 7/7, 21/21), including:owner/repo#N-qualified, and the cross-repo form that must not count;closes `nothing` #5must not become a match);#0, and a 400-digit number that overflows toInfinity;If any required check was skipped, explain why:
Safety
UI Evidencesection below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.UI Evidence
Not applicable — no UI, frontend, docs, or extension surface is touched. The diff is three backend/engine TypeScript files plus one new unit-test file.
Notes
packages/loopover-engine/src/index.ts: nothing in this PR consumes it through the published package entry point (both consumers import it by relative source path, per the existing convention), and adding an unused export there would widen the public surface for no caller.