Skip to content

feat(review): deterministic impact map (#2182-#2186) - #3796

Merged
JSONbored merged 6 commits into
mainfrom
feat/impact-map-foundation
Jul 6, 2026
Merged

feat(review): deterministic impact map (#2182-#2186)#3796
JSONbored merged 6 commits into
mainfrom
feat/impact-map-foundation

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Scope

Validation

  • git diff --check
  • npm run actionlint (no workflow files changed)
  • npm run typecheck
  • npm run test:coverage locally (targeted to the changed files — new modules at 100% line/branch; unified-comment-bridge.ts/ai-review.ts/focus-manifest.ts diff lines fully covered, verified against git diff line ranges)
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack (unaffected — no MCP package changes)
  • npm run ui:openapi:check
  • npm run ui:lint (0 errors; only pre-existing warnings on the two docs files I touched)
  • npm run ui:typecheck (pre-existing environment gap in this sandbox: @lovable.dev/vite-tanstack-config is unresolvable even on a clean git stash'd tree — not introduced by this PR)
  • npm run ui:build (blocked by the same pre-existing ui:typecheck-adjacent environment gap)
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries (see test list below)

If any required check was skipped, explain why:

  • ui:typecheck / ui:build: this sandbox is missing the private @lovable.dev/vite-tanstack-config devDependency; reproduced on a clean main checkout via git stash, so it predates and is unrelated to this PR. ui:lint (which does run) found 0 errors on the two docs files I edited.
  • npm run test:mcp-pack / npm run actionlint: no MCP package or workflow files touched by this diff.

Also ran and green: npm run db:migrations:check, npm run db:schema-drift:check, npm run selfhost:env-reference:check, npm run cf-typegen:check, npm run docs:drift-check (caught + fixed two real doc gaps for the new GITTENSORY_REVIEW_IMPACT_MAP flag).

New tests added: test/unit/impact-symbols.test.ts, test/unit/impact-map.test.ts, test/unit/impact-map-wire.test.ts, test/unit/impact-map-collapsible.test.ts, test/unit/impact-map-grounding.test.ts, test/unit/impact-map-processor-wiring.test.ts, plus updates to test/unit/focus-manifest.test.ts / test/unit/signals-coverage.test.ts for the new config field.

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 — the rendered "Impact map" section only ever shows file paths and symbol names.
  • No auth/cookie/CORS/GitHub App/Cloudflare/session changes in this PR.
  • API/OpenAPI/MCP behavior — not applicable (no route/schema changes).
  • UI changes — not applicable beyond two doc-flag description edits (no components/routes changed).
  • Visible UI changes — none (backend review-engine + docs-text only).
  • Public docs are updated where needed (docs.tuning.tsx, docs.privacy-security.tsx, .gittensory.yml.example).

UI Evidence

Not applicable — no visible UI/frontend changes in this PR (two documentation route text edits only, verified via ui:lint).

Notes

  • Parent epic Deterministic architecture / impact map #1971 lists an optional follow-up ("An AI-generated diagram may be added later behind a separate default-OFF flag") that is explicitly out of scope here.
  • Filed a follow-up task (not part of this PR) to add impactMap to the AI-review cache's dynamicReviewFeatures dynamic-context bypass in processors.ts, with proper webhook-level test coverage — see rationale in the Summary above.

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.38%. Comparing base (924b8ea) to head (60a35e0).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3796      +/-   ##
==========================================
+ Coverage   93.37%   93.38%   +0.01%     
==========================================
  Files         320      323       +3     
  Lines       32647    32727      +80     
  Branches    11960    11982      +22     
==========================================
+ Hits        30483    30563      +80     
  Misses       1530     1530              
  Partials      634      634              
Files with missing lines Coverage Δ
src/queue/processors.ts 94.43% <100.00%> (+0.01%) ⬆️
src/review/impact-map-wire.ts 100.00% <100.00%> (ø)
src/review/impact-map.ts 100.00% <100.00%> (ø)
src/review/impact-symbols.ts 100.00% <100.00%> (ø)
src/review/unified-comment-bridge.ts 99.47% <100.00%> (+0.04%) ⬆️
src/services/ai-review.ts 97.00% <100.00%> (+0.01%) ⬆️
src/signals/focus-manifest.ts 99.12% <100.00%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 6, 2026

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 60a35e0 Commit Preview URL

Branch Preview URL
Jul 06 2026, 11:59 AM

@superagent-security superagent-security Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Superagent found 1 security concern(s).

Comment thread src/review/impact-map.ts
* INPUT file order; each entry's `affectedModules` follows RAG's own retrieval order (cosine + optional BM25
* rerank, both already deterministic). Fail-safe: no vector/inference adapter, a cold/empty index, or any
* retrieval error yields an EMPTY impact map, never a throw.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2

Unbounded RAG queries from attacker-controlled changed-file count in computeImpactMap

Unbounded loop over changed files issues one RAG query per file without a max-files cap.

Cap the number of changed files processed (e.g. 10–20) before the loop to bound vector-query cost.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name="src/review/impact-map.ts">
<violation number="1" location="src/review/impact-map.ts:55">
<priority>P2</priority>
<title>Unbounded RAG queries from attacker-controlled changed-file count in computeImpactMap</title>
<evidence>computeImpactMap iterates over every changed file with extracted symbols and issues a separate retrieveContextWithMetrics call per file. The symbols array length is determined by the number of changed files in the PR (attacker-controlled input), and there is no upper bound on iterations. A PR with hundreds or thousands of changed JS/TS files could exhaust vector-query quota, cause worker timeouts, or inflate inference cost.</evidence>
<recommendation>Cap the number of files processed by computeImpactMap (e.g., MAX_IMPACT_MAP_ENTRIES = 10 or 20) before the loop, matching the downstream prompt/comment caps, so the computation cost is bounded regardless of PR size.</recommendation>
</violation>
</file>

@superagent-security superagent-security Bot added the pr:flagged PR flagged for review by security analysis. label Jul 6, 2026
JSONbored added 5 commits July 6, 2026 04:56
…2184)

Adds a pure changed-symbol extractor (impact-symbols.ts, #2182), a
deterministic impact-map computation over the existing RAG index
(impact-map.ts, #2183), and the review.impact_map config toggle
(#2184) that gates both, ANDed with a new operator env kill-switch
(GITTENSORY_REVIEW_IMPACT_MAP). Default OFF and byte-identical when
unset; no wiring into rendering or AI grounding yet (follow-up PR).

Part of #1971.
…2185)

Adds buildImpactMapCollapsible (and its ImpactMapSummaryInput type) to
unified-comment-bridge.ts, following the same pattern as the existing
Changed-files/Finding-categories collapsibles: one row per changed
module with its changed symbols and a bounded, "+N more"-capped list
of plausibly-affected modules. Public-safe path escaping. Wired into
buildUnifiedCommentBody as an additive, flag-gated section (omitted
entirely when the impact map is absent/empty).

Part of #1971.
Adds GittensoryAiReviewInput.impactMapContext (mirroring ragContext)
and splices it into the reviewer's user prompt when present, plus
formatImpactMapPromptSection in impact-map-wire.ts to format
computeImpactMap's output into a bounded "IMPACT MAP" block. Wires
the computation into runAiReviewForAdvisory (processors.ts), reusing
the already-resolved changed files and gated by BOTH the operator's
GITTENSORY_REVIEW_IMPACT_MAP flag and the per-repo review.impact_map
manifest opt-in. Additive-only; byte-identical when the flag is off
or the computed map is empty.

Part of #1971. Completes the group (#2182-#2186).
…angler version

The rebased branch carried a worker-configuration.d.ts generated against an
older wrangler version; wrangler types --check flagged it as drifted.
Superagent (P2): computeImpactMap issued one retrieveContextWithMetrics
call per changed-symbol file with no upper bound -- a PR touching
hundreds of files (contributor-controlled) would issue hundreds of
vector queries. Add MAX_IMPACT_MAP_INPUT_FILES (20, matching
boundary-test-generation.ts's MAX_TOUCHES precedent for the same
per-changed-file-loop concern) and filter+slice before the query loop,
preserving deterministic input order.

Also fixes config-templates.test.ts drift: the review.impact_map
documentation block was only added to .gittensory.yml.example, not its
config/examples/gittensory.full.yml counterpart (both copies), which
the drift test requires to stay byte-identical from the canonical body
marker onward.
@JSONbored
JSONbored force-pushed the feat/impact-map-foundation branch from cb913aa to da8c4c9 Compare July 6, 2026 11:57
@JSONbored
JSONbored force-pushed the feat/impact-map-foundation branch from da8c4c9 to 60a35e0 Compare July 6, 2026 11:57
@JSONbored

Copy link
Copy Markdown
Owner Author

Fixed all three real issues:

  1. Superagent P2 — `computeImpactMap` issued one RAG query per changed-symbol file with no cap; a PR with hundreds of changed files (contributor-controlled) would issue hundreds of vector queries. Added `MAX_IMPACT_MAP_INPUT_FILES` (20, matching `boundary-test-generation.ts`'s `MAX_TOUCHES` precedent), filtering + slicing before the query loop.
  2. `codecov`/`validate` — `config-templates.test.ts` drift: the `review.impact_map` doc block had only been added to `.gittensory.yml.example`, not its `config/examples/gittensory.full.yml` counterpart (both copies required to stay byte-identical).
  3. Merge conflict — rebased onto current `main`, which picked up several other concurrently-merged PRs also touching `focus-manifest.ts`'s `review` config object (a `comment_verbosity` knob, the deduped `test_generation` plumbing from a sibling PR) — manually reconciled all 6 conflict sites to keep every field, verified no duplication.

Deliberately did not wire `impact_map` into `dynamicReviewFeatures`'s AI-review-cache bypass in this PR — #3802 (repo quality-culture profile) is concurrently touching that exact same fingerprint object, and doing both at once risks the same collision this rebase just untangled. Left as its own tracked follow-up.

595 tests pass across all touched files, typecheck/actionlint/audit clean.

@superagent-security

Copy link
Copy Markdown
Contributor

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

@superagent-security superagent-security Bot removed the pr:flagged PR flagged for review by security analysis. label Jul 6, 2026
@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 6, 2026
@JSONbored
JSONbored merged commit ee686e0 into main Jul 6, 2026
12 checks passed
@JSONbored
JSONbored deleted the feat/impact-map-foundation branch July 6, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment