Skip to content

feat(scripts): blast-radius query — dependents, owning gates, live-coverage owners (#1425) - #1470

Merged
thymikee merged 2 commits into
mainfrom
devin/1785251819-depgraph-affected
Jul 28, 2026
Merged

feat(scripts): blast-radius query — dependents, owning gates, live-coverage owners (#1425)#1470
thymikee merged 2 commits into
mainfrom
devin/1785251819-depgraph-affected

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Summary

Closes #1425 (Track C, #1412). "Who depends on this and which tests own it" was four lookups
(depgraph, check-affected, iOS coverage manifest, ADR 0011 matrix); it is now one, and every part
of the answer is read from the existing source of truth rather than a second copy of it.

pnpm depgraph affected src/utils/exec.ts            # bounded text, ~0.5s
pnpm depgraph affected src/daemon/ref-frame.ts --json --limit 25
blast radius: src/utils/exec.ts  [zone utils, fan-in 81, fan-out 3]
dependents: 67 direct, 197 transitive (value edges; 14 type-only and 0 dynamic direct importers not counted)
  by zone: platforms 103, daemon-server 98, cli 14, utils 7, daemon-client 6, (root) 5, … (+7 more)
  direct:  src/cli/auth-session.ts, … (+57 more)
  widest:  src/platforms/android/adb-executor.ts (fan-in 40), … (+254 more)
gates for this set: format, lint, typecheck, layering, fallow, build, vitest-related, coverage, provider-integration
  run: pnpm check:affected --run
public commands whose handler chain reaches it (52): alert (snapshot), … (+42 more)
live scenario owners: test/integration/ios-simulator-e2e/coverage-manifest.ts is not in this tree …
guarantee-matrix rows implemented here (0):

Wiring, and the judgement calls that are not obvious from the code:

  • dependents — reverse reachability over scripts/depgraph/model.ts's value edges.
    Type-only and dynamic dependents are excluded from the counts (a type-only edge is free at
    runtime) but reported separately as weakDirect, because a pure vocabulary module
    (src/contracts/*) otherwise prints "0 dependents", which is the opposite of true.
  • gatesselectChecks({ changedFiles: [file, ...dependents.all] }), i.e. check-affected's
    own model. The two cannot contradict each other by construction; the cross-check below confirms
    it on real diffs.
  • owning commands — the daemon route table is parsed out of
    src/daemon/request-handler-chain.ts (parseRouteEntries) and joined with
    DAEMON_COMMAND_DESCRIPTORS × PUBLIC_COMMANDS; the chain closure follows value and dynamic
    edges, because every handler is loaded through import(). A route the table stops declaring
    throws and names the file to fix — a silently empty command list would read as "nothing owns
    this".
  • live scenario ownerstest(ios): expand simulator e2e coverage #1408's IOS_SIMULATOR_E2E_COVERAGE is consumed through the narrowest
    shape this lane needs (command → level/owner/assertion), loaded only if the manifest exists. It
    is not in main yet, so the query says so instead of implying no live coverage; verified against
    the test(ios): expand simulator e2e coverage #1408 branch's manifest, where the same run reports 49 owners for ref-frame.ts.
  • guarantee rows — ADR 0011 cells whose via module path equals the file (prose delegated
    cells name no module by construction). src/selectors/resolve.ts → 5 rows across three paths.

Bounded by default (--limit, default 10, every list discloses +N more); --json is unbounded.
scripts/depgraph/load.ts is the now-shared graph read used by both the report and the query.

CI scope

No CI work added. The only gate change is that depgraph:test also runs
scripts/depgraph/affected.test.ts inside the existing Layering Guard job: +0.7s
(depgraph:test 0.24s → 0.95s locally, 20 tests). No new workflow, job, permission, or lane.

Validation

  • pnpm format:check && pnpm lint && pnpm typecheck — clean
  • pnpm test:unit (524 files / 4671 tests), pnpm check:layering, pnpm test:output-economy,
    pnpm check:fallow, pnpm depgraph:test — all green
  • Acceptance perf: src/utils/exec.ts 0.53s, src/daemon/ref-frame.ts 0.5s wall clock (budget
    10s); asserted in-test at <10s.

Cross-check against check:affected (no contradictions)

For each sample diff: selectChecks over that diff's production files vs. the union of the blast
radius gate plans for the same files. Blast radius may be wider (it also plans for dependents);
it must never be narrower.

diff prod files check:affected (prod files) depgraph affected union selected by check:affected but not by blast radius
b2b116f (#1450) 10 format, lint, typecheck, layering, fallow, build, vitest-related same (none)
4c02b6a (#1433) 5 format, lint, typecheck, layering, fallow, build, vitest-related same (none)
e8b779c (#1392) 4 format, lint, typecheck, layering, fallow, build, vitest-related same (none)
fcaa6c9 (#1435) 77 format, lint, typecheck, layering, fallow, build, vitest-related + coverage, provider-integration (none)

The fourth diff is the informative one: dependents of the moved contracts reach src/platforms/**,
so the blast radius correctly adds the two platform-owned gates that a file-local plan misses.

Scope

One issue per PR: nothing from #1423 (repo-health snapshot) or #1424 (delta comment) is
implemented here, and #1408's manifest is consumed, not vendored.

Link to Devin session: https://app.devin.ai/sessions/0d8e3e21666746dd828556a1c4646008
Requested by: @thymikee

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@thymikee thymikee self-assigned this Jul 28, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-28 16:21 UTC

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 1.87 MB 1.87 MB 0 B
JS gzip 598.9 kB 598.9 kB 0 B
npm tarball 714.6 kB 714.6 kB +5 B
npm unpacked 2.50 MB 2.50 MB +34 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 21.5 ms 22.0 ms +0.5 ms
CLI --help 45.1 ms 45.9 ms +0.9 ms

Top changed chunks: no changes in the largest emitted chunks.

@thymikee

Copy link
Copy Markdown
Member

P1 — the documented --limit 25 form is broken. parseInvocation splits args by whether they start with a dash, so the value 25 becomes a second positional while parseScriptArgs receives --limit with no value. The common invocation depgraph affected path --json --limit 25 therefore fails before it can render bounded output. Preserve flag/value association when parsing argv and add CLI coverage for --limit 25 in both supported orderings.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

P1 — the documented --limit 25 form is broken.

Correct, and broken exactly as described. Fixed in 61488f7: parseInvocation now uses parseArgs({ allowPositionals: true }) directly instead of pre-partitioning argv by a leading dash (the shared parseScriptArgs helper rejects positionals, which is what pushed me into the bad split). Added CLI coverage for --limit 25 in both orderings plus --limit=25, the default, --help, and the rejection cases (missing path, two paths, --limit 0, --limit lots). Verified pnpm depgraph affected src/daemon/ref-frame.ts --json --limit 25 and pnpm depgraph affected --limit 3 src/utils/exec.ts both render.

@thymikee

Copy link
Copy Markdown
Member

Re-reviewed at 61488f7. The --limit regression is fixed: option values stay attached whether flags come before or after , and --limit=25 is covered. The parser now also covers invalid limits and multiple/missing paths. I ran the targeted exact-head commands with bounded output in both flag orders; all lists remained bounded and disclosed hidden entries. GitHub checks are green. Ready for human review.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Jul 28, 2026
@thymikee
thymikee merged commit e0b8463 into main Jul 28, 2026
27 checks passed
@thymikee
thymikee deleted the devin/1785251819-depgraph-affected branch July 28, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

obs: blast-radius query — file/symbol to dependents, owning gates, and live-coverage owners

1 participant