Repository navigation
feat(affected): narrow package script chains; check flags entry targets it cannot read - #227
Merged
Merged
Conversation
…ts it cannot read --related expands an npm or pnpm script whose body is an && chain, through the scripts it calls, and narrows each test runner in it (including node --test and tsx --test with files or globs). Runners that select nothing are dropped, other commands are kept, and a target left with no runner is skipped. aster check reports an entry target (--entry, [check] entries, a lane target) that runs a script file or a package script Aster cannot narrow, and a package script that contains a runner it cannot narrow, with the reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ust name existing files A package script called from a chain that cannot be read (a cd, a pre/post hook, a cycle) stays a call instead of making the whole chain unnarrowable. node --test with a file that does not exist yet (built by an earlier step) is left as written. aster check no longer calls python -m or node --test a script file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
calvin-archastro
marked this pull request as draft
October 30, 2026 04:30
Coverage thresholds measure a whole suite, so a run narrowed to a few files fails thresholds the full run passes. Narrowed Vitest drops --coverage/--coverage.* and gets --coverage.enabled=false, Jest gets --coverage=false, pytest drops --cov* and gets --no-cov (when it used --cov), mix test drops --cover, bun test and node --test drop their coverage flags. A package script that turns coverage on in its body is read as a chain so the flag can be removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
orphan-test-target now treats a target as reached when a reached target's package script calls its script (bare pnpm <script>, npm run, yarn, nested), through the same call reader the chain expansion uses, and when its script only aliases such scripts. [check] allow_unnarrowable accepts a command fixed on purpose; a stale entry is the error stale-allow-unnarrowable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem and author intent
aster affected <target> --relatedran many CI test targets in full even when a change reached only a few tests, andaster checksaid nothing about it.Observed on a sweep of 39 recent firstlanding PRs (
aster affected test-ci --related --dry-run): "not a test command Aster can narrow; running as written" on//infra:test-ci(14 PRs),//services/go/archdev/web:test-ci(8),//infra/services/platform,//deploy/controller,//src/ts/developer-platform-cli, and others.Mechanism:
Goal: narrow chains of package scripts (generic, any repo), and make
aster checkreport every entry target the planner cannot narrow, using the same classification.What changed (before -> after)
Narrowing (
src/plugins/related_tests.rs):pnpm test-ciwith a chained body -> run as written.npm/pnpmthe body is split on&&, nested script calls are expanded (depth 8, cycle guard), and each command is narrowed or kept:bun test,node --test,tsx --test,node --import tsx --test): narrowed to the selected files it covers; dropped if none.tsc --noEmit,node gen.mjs --check): kept as written.&&), started withpnpm exec <cmd>/npm exec -c '<cmd>'sonode_modules/.binis on the path as in a script.NAME=valuestays in front. One command per step (not onea && bstring) so configured wrappers andbash -cone-liners apply to each step.node --testwith a shell glob (test/*.test.ts) is now matched against the selection (globset,*stops at/). Anode --testfile that does not exist (built by an earlier step) leaves that command as written.--passWithNoTests(a selected file outside that config'sincludewould otherwise fail the run).pnpm test <files>;;,||, pipes,cd, interpreter scripts, andpre/posthooks still stop narrowing (a called script with those stays a call). yarn/bun chains are not expanded (no equivalent ofexecthat finds package binaries).Check (
src/check.rs,src/cli/affected_files.rs):--entry,[check] entries, a lanetarget) whose command is not inert and not narrowable is reported byunnarrowable-test-commandwith a specific reason (script file / package script with no runner / unsupported form). A package script that contains a runner Aster cannot narrow is reported for any target. Samenarrowablecomputation as the planner.Docs: README (narrowing section and rule table),
src/cli/skills.md.Scope
Backend/CLI only (Rust).
Risk
Medium. Changes what
--relatedruns for package-script chains, which previously ran in full.cd/operators leave the script alone.vitest run --coverageruns a subset, which can trip coverage thresholds.aster checkgains findings on repos that have entry targets running script files;--strictusers will see new failures (intended).User impact
CI with
--relatedruns fewer tests for chain targets. Newaster checkfindings for script-file and unreadable entry targets.Testing
package_script_chain_testsand updatednode_narrows_direct_runners_and_plain_scriptsinsrc/plugins/related_tests.rs(nested chain, segment dropping, all-dropped skip, non-runner kept, cycle,cd, hooks, yarn, npm form, globs, declined runner kept).tests/script_chains.rs::a_package_script_chain_narrows_and_what_aster_cannot_read_is_reportedruns the real binary on a git workspace with fivetest-civariants; asserts the narrowed commands and that the set of targets the planner reports as "not a test command Aster can narrow" equals the setaster check --entry test-cireports.a_chain_with_no_selected_test_is_skipped_with_its_other_commandscovers the skip.cargo fmt,cargo clippy --all-targets -- -D warnings,cargo test: pass locally. Automatic coverage: the existing Aster CIcargo testjob picks uptests/script_chains.rs.node --testnarrowed or dropped)ensure-node-ptykeptnode --test bin-test/*.jskept as writtenaster check --strict --entry test-cion firstlanding origin/main: 0 findings before, 21 after.Added after review
--coverage*and gets--coverage.enabled=false; Jest--coverage=false; pytest drops--cov*and gets--no-cov(only if it used--cov);mix testdrops--cover; bun andnode --testdrop their coverage flags. A package script with coverage in its body is read as a chain so the flag can be removed. Tests:coverage_tests,tests/script_chains.rs::a_coverage_gated_chain_runs_its_narrowed_tests_without_coverage.orphan-test-target: a target is reached when a reached target's package script calls its script (barepnpm <script>,npm run,yarn, nested), via the same call reader as the chain expansion; a script that only aliases reached scripts is reached too. Test:tests/check.rs::a_target_that_a_reached_package_script_calls_is_not_an_orphan.[check] allow_unnarrowable = ["//addr:target"]and error rulestale-allow-unnarrowable, mirroringallow_orphans. Test:tests/check.rs::allow_unnarrowable_accepts_a_fixed_command_and_stale_entries_are_errors.Follow-ups
--coverageruns, and a realpnpm execrun of an expanded chain in a node_modules checkout../test-ci.sh) is only reported; Aster does not read it.🤖 Generated with Claude Code