test(review): close e2e gaps for review.tone and review.exclude_paths - #4145
Conversation
…#1681) review.tone and review.exclude_paths/path_filters were only exercised at the pure-function level (focus-manifest.test.ts) or with empty-array fingerprint assertions in queue.test.ts. Add two full webhook -> processJob e2e tests: one confirms the composed tone section actually reaches env.AI.run's system prompt, the other confirms a non-empty exclude_paths glob genuinely removes a matching file's path and patch content from the AI reviewer's diff in advisory mode (block mode intentionally reviews the full diff, so the test exercises the branch where filtering actually applies).
|
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 #4145 +/- ##
=======================================
Coverage 93.71% 93.71%
=======================================
Files 385 385
Lines 36212 36212
Branches 13266 13266
=======================================
Hits 33937 33937
Misses 1618 1618
Partials 657 657 🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-08 08:03:03 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 6 non-blocking
Linked issue satisfactionPartially addressed Review context
Contributor next steps
Signal definitions
🟩 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.
|
Closes #1681
Summary
review.toneandreview.exclude_paths/review.path_filterswere previously only proven at the pure-function level(
focus-manifest.test.ts'scomposeManifestReviewInstructions/filterReviewFilesForAiunit tests) orwith empty-array fingerprint assertions in
queue.test.ts— nothing drove the fullwebhook ->
processJob->runGittensoryAiReviewpipeline to prove the resolved config actuallyreaches the AI reviewer.
threads review.tone from .gittensory.yml into the AI reviewer's system prompt (#2044): setsreview.tonein a repo.gittensory.ymlfixture (mirroring thechanged_files_summary/effort_scoretests' exact fixture pattern) and asserts the composed
Review tone (maintainer voice brief — complements review.profile): ...section is present in theactual
env.AI.runsystem message, not just in a pure-function return value.genuinely removes a review.exclude_paths match from the AI reviewer's diff in advisory mode (#review-exclude-paths): sets a non-emptyreview.exclude_pathsglob (every existing e2eassertion of this field only ever passes empty arrays) with two changed files, one matching the glob,
and asserts the excluded file's path and patch content are genuinely absent from the AI reviewer's
user prompt while the other file's diff is present. This is deliberately run in advisory mode:
runAiReviewForAdvisory(src/queue/processors.ts) only callsfilterReviewFilesForAiin advisorymode — block mode intentionally reviews the full diff so a filtered path can never be used to dodge an
AI consensus blocker — so advisory mode is the only branch that actually exercises the filter.
non-matching pattern locally and confirmed the exclude-paths test then fails (the excluded filename
legitimately appears in the prompt), before reverting to the real assertion.
src/**/packages/**changes — this is atest/**-only PR (not Codecov-patch-measured), scopednarrowly to feat(review): test review controls end to end #1681's two named test gaps. No fixes for the docs-only fields below are included here —
see the filed follow-ups.
Review-controls wiring matrix (#1681 deliverable)
Every
review.*field parsed from.gittensory.yml, its resolution path, and whether it actuallyreaches a live code path (not just parsing/validation). "e2e" = covered by a full
processJob/webhook-level test; "unit" = covered only at the pure-function level before this PR.review.toneresolveReviewPromptOverrides(src/signals/focus-manifest.ts:250) +composeManifestReviewInstructions(:236)src/queue/processors.ts:9378-9388(reviewInstructions) ->buildSystemPrompt'srepoInstructionsappend (src/services/ai-review.ts:879-891)review.profileai-review.test.ts)resolveReviewPromptOverridesbuildSystemPrompt'sREVIEW_PROFILE_SUFFIX(src/services/ai-review.ts:830-837, 869-872)review.security_focusai-review.test.ts)resolveReviewPromptOverridesbuildSystemPrompt'sSECURITY_FOCUS_SUFFIX(src/services/ai-review.ts:843-844, 873)review.instructionsresolveReviewPromptOverridesreviewInstructionsalongside tone (src/queue/processors.ts:9378-9388)review.path_instructionsresolveReviewPromptOverridesresolveReviewPathInstructions(src/queue/processors.ts:7371-7374, 9459-9462) ->buildSystemPrompt'spathGuidancereview.exclude_pathsresolveReviewPromptOverridesfilterReviewFilesForAi(src/signals/focus-manifest.ts:379-385, 408-414), applied only whenaiReviewMode !== "block"(src/queue/processors.ts:7201-7207)review.path_filtersresolveReviewPromptOverridesapplyReviewPathFilters(src/signals/focus-manifest.ts:389-405), same gate asexclude_pathsabovereview.inline_commentsresolveReviewPromptOverridesshouldRequestInlineFindings(src/review/inline-comments.ts:43),src/queue/processors.ts:9358-9362review.suggestionsresolveReviewPromptOverridesshouldRenderSuggestions(src/review/inline-comments.ts:60), ANDed with inline commentsreview.finding_categoriesresolveReviewPromptOverridesshouldRenderFindingCategories(src/review/inline-comments.ts:70), ANDed with inline commentsreview.changed_files_summaryqueue.test.tstest)resolveReviewPromptOverridessrc/queue/processors.ts:9142, 10515-10522review.effort_scorequeue.test.tstest)resolveReviewPromptOverridessrc/queue/processors.ts:9143, 10530review.max_findingsqueue.test.tstest #2049)resolveReviewPromptOverridessrc/queue/processors.ts:10554review.comment_verbosityresolveReviewPromptOverridessrc/queue/processors.ts:10555review.min_finding_severityresolveReviewPromptOverridessrc/queue/processors.ts:9144, 10616review.impact_mapresolveReviewPromptOverridesshouldComputeImpactMap(src/review/impact-map-wire.ts:26),src/queue/processors.ts:7257, 9414review.culture_profileresolveReviewPromptOverridesGITTENSORY_REVIEW_CULTURE_PROFILE,src/queue/processors.ts:7278-7280, 9410review.ai_modelqueue.test.tstest)resolveReviewSelfHostAiModel(src/signals/focus-manifest.ts:306)src/queue/processors.ts:7357-7364review.memoryresolveReviewMemoryManifestToggle(src/signals/focus-manifest.ts:281)shouldApplyReviewMemory,src/queue/processors.ts:9150, 11043review.pre_merge_checksresolveReviewPreMergeChecks(src/signals/focus-manifest.ts:288)src/queue/processors.ts:6573, 9023review.auto_reviewresolveReviewAutoReviewConfig(src/signals/focus-manifest.ts:298)src/queue/processors.ts:8293review.enrichment(analyzer toggles)resolveRepoEnrichmentToggles(src/signals/focus-manifest.ts:326)src/queue/processors.ts:7315review.visualresolveReviewVisualConfig(src/signals/focus-manifest.ts:314)src/queue/processors.ts:6973Docs-only / phantom fields (parsed, never consumed) — follow-ups filed, not fixed in this PR:
review.labeling_rulespackages/gittensory-engine/src/focus-manifest.ts:2002, 2251), butgrep -rn "LabelingRule" src/outside the type re-export infocus-manifest.tsreturns nothing — zero real consumer anywhere. Follow-up: #4146review.auto_merge_summarysrc/. Its render primitivebuildAutoMergeSummaryCollapsible(src/review/unified-comment.ts:229, #2051) has its own pure-function unit test but is never called fromunified-comment-bridge.tsorprocessors.ts. Follow-up: #4147review.linked_issue_satisfactiongate.linkedIssueSatisfaction)src/types.ts:761-769explicitly documentslinkedIssueSatisfactionGateMode(the real, DB-backed field.gittensory.yml gate.linkedIssueSatisfactionoverrides) as distinct from thisreview.*manifest field. Every real consumer insrc/queue/processors.ts(e.g.:6638, 7949, 8978) readssettings.linkedIssueSatisfactionGateMode, nevermanifest.review.linkedIssueSatisfaction— confirmed still true after the recent #4069 merge, which deepened thegate.*field's wiring but never touched this one. Settingreview.linked_issue_satisfactionin.gittensory.ymltoday does nothing. Follow-up: #4149Scope
type(scope): short summaryConventional Commit format.test/unit/queue.test.ts.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlint(no workflow files changed)npm run typechecknpm run test:coveragelocally, unsharded — full suite green: 582 files / 11899 tests passed, 0 failed, 0 uncovered patch lines (this PR touches onlytest/**, which Codecov does not measure).npm run test:workers(notest/workers/**files touched by this change)npm run build:mcp(no MCP package changes)npm run test:mcp-pack(no MCP package changes)npm run ui:openapi:check(no API/schema changes)npm run ui:lint(noapps/gittensory-ui/**changes)npm run ui:typecheck(noapps/gittensory-ui/**changes)npm run ui:build(noapps/gittensory-ui/**changes)npm audit --audit-level=moderate— 0 vulnerabilitiesIf any required check was skipped, explain why:
test/unit/queue.test.ts; it does not touch.github/workflows/**,test/workers/**, any MCP package, any API/schema/OpenAPI surface, orapps/gittensory-ui/**, so the corresponding checks above are not applicable.npm run typecheckand the full unshardednpm run test:coverageboth ran clean against the actual change.Safety
UI Evidencesection. (N/A — no UI changes; see below.)CHANGELOG.mdis not touched.)UI Evidence
N/A — this PR only adds backend test coverage (
test/unit/queue.test.ts); there is no visible UI, frontend, or docs change.Notes
wire-or-deprecate choice, per feat(review): test review controls end to end #1681's request): feat(review): wire labelingRules to a real label-suggestion evaluator, or remove the dead config field #4146 (
review.labeling_rules), feat(review): wire review.auto_merge_summary to the unified comment, or remove the dead render primitive #4147(
review.auto_merge_summary), docs(review): resolve the review.linked_issue_satisfaction / gate.linkedIssueSatisfaction phantom-field confusion #4149 (review.linked_issue_satisfaction).