refactor(review): extract shared secret-detection module (#4608) - #4678
Merged
Conversation
secrets-scan.ts (PR-diff hard-block) and content-lane/security-scan.ts (content-lane hard-block) hand-duplicated the same format-specific patterns and placeholder-value heuristics with no automated pairing between them, despite living under src/ in the same build and deploy. That already caused two independent, live drifts (#4587, #4604) even after a same-day commit edited both files for one change. Extract the shared primitives (SECRET_PATTERNS, GENERIC_SECRET_ASSIGNMENT_PATTERN, hasLongSequentialRun, isPlaceholderSecretValue, hasGenericSecretAssignment, HARD_SECRET_KINDS) into src/review/secret-patterns.ts, imported by secrets-scan.ts, content-lane/security-scan.ts, and safety.ts (which carried its own third copy of HARD_SECRET_KINDS). Pure extraction, no behavior change: the only functional edit is canonicalizing GENERIC_SECRET_ASSIGNMENT_PATTERN to one capture-group shape used consistently by both callers. review-enrichment/src/analyzers/secret-scan.ts (REES) stays untouched and genuinely separate (standalone Railway deploy, deliberately wider rule set). Add a named twin-pair entry to scripts/check-engine-parity.ts (mirroring the #4605 SAFE_URL_TWIN_PAIR/DIFF_FILE_PRIORITY_TWIN_PAIR precedent) that mechanically drift-checks only the subset REES shares with the new module: the isPlaceholderSecretValue algorithm and the hard-kind names that are exact string matches on both sides today (excluding private_key_block/aws_access_key, which REES already names differently, so the check doesn't false-fail on introduction).
Contributor
|
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 #4678 +/- ##
==========================================
- Coverage 94.14% 94.14% -0.01%
==========================================
Files 435 436 +1
Lines 38566 38541 -25
Branches 14060 14052 -8
==========================================
- Hits 36308 36283 -25
Misses 1599 1599
Partials 659 659
🚀 New features to boost your workflow:
|
2 tasks
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
* fix(review): tighten generic secret fixture allowlist * fix(review): apply the closed fixture allowlist to the shared secret-patterns module secrets-scan.ts and content-lane/security-scan.ts now import isPlaceholderSecretValue from secret-patterns.ts (#4608/#4678), so the fixture-allowlist fix needs to land there too, plus the engine-parity drift-check marker that mirrors this logic into review-enrichment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
src/review/secrets-scan.ts(PR-diff hard-block) andsrc/review/content-lane/security-scan.ts(content-lane hard-block) hand-duplicated the same secret-detection primitives with no automated pairing
between them, despite both living under
src/, same build, same deploy. That already caused twoindependent, currently-live drifts (fix(review): stop generic_secret_assignment false-flagging self-naming fixture/enum values #4587, Port missing secret-scan fixes to content-lane/security-scan.ts #4604) even after a same-day commit edited both files for one
change.
SECRET_PATTERNS,GENERIC_SECRET_ASSIGNMENT_PATTERN,hasLongSequentialRun,isPlaceholderSecretValue,hasGenericSecretAssignment, andHARD_SECRET_KINDSinto one newsrc/review/secret-patterns.ts, imported bysecrets-scan.ts,content-lane/security-scan.ts, andsrc/review/safety.ts(which carried its own third hand-copy ofHARD_SECRET_KINDS).canonicalizing
GENERIC_SECRET_ASSIGNMENT_PATTERNto one capture-group shape (both callers previouslyused slightly different, but behaviorally equivalent, regex forms).
review-enrichment/src/analyzers/secret-scan.ts(REES) stays untouched and genuinely separate (standaloneRailway deploy, deliberately wider rule set). Adds a
SECRET_DETECTION_TWIN_PAIRnamed-pair entry toscripts/check-engine-parity.ts(same mechanism as Fix engine-parity diffFilePriority typo; make drift-check recursive/function-aware #4605'sSAFE_URL_TWIN_PAIR/DIFF_FILE_PRIORITY_TWIN_PAIR) that mechanically drift-checks only the subset REES shares with the newmodule — the
isPlaceholderSecretValuealgorithm plus the hard-kind names that are exact string matcheson both sides today — so REES's much wider rule set doesn't false-fail a full-file comparison.
Fixes #4608.
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. (see note below)npm run test:workers(N/A — notest/workers/**code path touched)npm run build:mcp(N/A — nopackages/gittensory-mcpcode touched)npm run test:mcp-pack(N/A — same reason)npm run ui:openapi:check(N/A — no API/schema change)npm run ui:lint(N/A — noapps/gittensory-uifiles touched)npm run ui:typecheck(N/A — same reason)npm run ui:build(N/A — same reason)npm audit --audit-level=moderateIf any required check was skipped, explain why:
vitest runover the six affected test files (test/unit/secret-patterns.test.ts,secrets-scan.test.ts,content-lane-security-scan.test.ts,safety.test.ts,safety-wiring.test.ts,check-engine-parity-script.test.ts) with--coverage, instead of the full unshardednpm run test:coverage.coverage/lcov.infoconfirms all four changedsrc/**files are at 100% lines/branches:secret-patterns.ts25/25 lines, 20/20 branches;secrets-scan.ts34/34, 18/18;content-lane/security-scan.ts35/35, 20/20;
safety.ts19/19, 14/14. All 210 tests in that scope pass.test:workers/build:mcp/test:mcp-pack/ui:*were skipped because this PR touches onlysrc/review/**,scripts/check-engine-parity.ts, andtest/unit/**— no workers-pool tests, MCP package, or UI/apps code.Also ran the real
npm run engine-parity:drift-checkdirectly (not just its unit tests) against the liverepo — passes clean. CI's
validatejob runs the complete gate on every check above.Safety
UI Evidencesection below with screenshots. (N/A — no visible UI change)UI Evidence
N/A — backend-only refactor, no visible UI/frontend/docs/extension change.
Notes
src/review/safety.tsis included even though issue Extract shared secret-detection module across secrets-scan.ts and content-lane/security-scan.ts #4608 names onlysecrets-scan.tsandcontent-lane/security-scan.ts: it carried its own byte-identical third copy ofHARD_SECRET_KINDSaspart of the same PR-diff hard-block path the issue describes, so leaving it out would have left one of the
three existing duplicates unfixed.
private_key_block/aws_access_keyare deliberately excluded from the new drift-check's kind-namemarkers: REES already names those two concepts
private_key/aws_access_key_id, a pre-existing, harmless,out-of-scope naming divergence — including them would false-fail the check on this very PR.