Relationships
#3195 extension source add imports src/cli/mod.ts, so every change lists extension as an affected command
Opened by zack · 10/8/2026· Shipped 10/8/2026
Problem
src/cli/commands/extension_source_add.ts imports six directory resolvers from src/cli/mod.ts:
import {
resolveDatastoresDir,
resolveModelsDir,
resolveReportsDir,
resolveVaultsDir,
resolveWebhooksDir,
resolveWorkflowsDir,
} from "../mod.ts";src/cli/mod.ts imports every command, so this one import puts the whole CLI in the extension command's module closure. Measured on main at 3a59b162 with the functions in scripts/affected_commands.ts:
- The closure of
src/cli/commands/extension.tsis 1,217 of 1,220 modules. extension_source_add.tsis the only non-test importer ofsrc/cli/mod.tsother thanmain.ts.
The effect is that affectedCommands in the verification attestation names extension for almost any source change. agent-constraints/verification-conventions.md records this as a known property ("extension is listed for almost every source change, because its closure reaches the whole CLI through src/cli/mod.ts"). Of the last 100 merged PRs, 95 list extension.
This matters to swamp-uat, which is starting to use affectedCommands to work out which UAT tests a change needs. With extension in nearly every list, the roughly 40 UAT test files that run extension commands are kept for changes that cannot reach them.
Proposed solution
Import the six names from the files that define them. They already live in their own modules, and mod.ts only re-exports them (its comment: "the canonical definitions live in separate files to avoid circular imports through mod.ts"):
import { resolveDatastoresDir } from "../resolve_datastores_dir.ts";
import { resolveModelsDir } from "../resolve_models_dir.ts";
import { resolveReportsDir } from "../resolve_reports_dir.ts";
import { resolveVaultsDir } from "../resolve_vaults_dir.ts";
import { resolveWebhooksDir } from "../resolve_webhooks_dir.ts";
import { resolveWorkflowsDir } from "../resolve_workflows_dir.ts";This is the same kind of change as #2902 (swamp-club#3143, "import libswamp names from their defining files, not the barrel"), and scripts/unbarrel.ts can do the rewrite.
Also:
- Update the
extensionbullet in the "Affected Commands" section ofagent-constraints/verification-conventions.md, which will no longer be true. - Consider a guard so the edge does not come back, for example a rule in
integration/ddd_layer_rules_test.tsthat no file undersrc/cli/commands/importssrc/cli/mod.ts.
What was checked
In a scratch copy of the tree with only the import rewritten:
deno check main.ts,deno fmt --checkanddeno linton the file pass.- The
extensionclosure drops from 1,217 to 434 modules. scripts/affected_commands_test.ts,integration/affected_commands_rules_test.ts,integration/ddd_layer_rules_test.tsandsrc/cli/mod_test.tsgave 111 passed and 1 failed. The failure was "git ls-files failed" because the copy was not a git repository. The wider suite was not run.
Estimated effect on UAT test selection, modelled over the last 100 merged PRs against one recorded UAT run: the share of test-file runtime that could be skipped rises from 14% to 21%, and the number of PRs that would skip more than half of it rises from 4 to 17. No PR's command list grows.
Alternatives
- Leave the import and special-case
extensioninscripts/affected_commands.ts. That hides the edge from the report without removing a command file's dependency on the whole CLI.
Shipped
Click a lifecycle step above to view its details.
Sign in to post a ripple.