Configurable per-tool build/test commands + opt-in full-suite go-test runner
Branch: feat/test-runner-commands (fork: DatScreamer/interlinked-cli)
Design doc: docs/interlinked-test-runners-plan.md (in the branch)
Problem
Every tool runner hard-codes its argv (go build ./..., golangci-lint run ...), there is no
way to override a command via config, and there is no full-suite test tool. A project whose
dev server rebuilds with Go build tags (e.g. -tags 'dev devaccounts') cannot make Interlinked
run that exact command, so its checks compile into a separate Go build cache — measured
~30–84 s cold vs ~6–21 s warm on the motivating Go workspace.
Changes on the branch
- New two-tier config —
.interlinked/tool-commands.json (committed) +
.interlinked/tool-commands.local.json (gitignored), keyed by check/config names
(go_build, go_test, golangci_lint, …). A full command array wins; otherwise
base_args replace the runner's default scope (./...) so Go flag ordering stays correct.
Trust split mirrors merge.ts: the committed team tier may set base_args +
timeout_ms (flags for a fixed binary / a bounded cap); command/env stay
personal-tier (interlinked doctor reports violations). No shell interpolation.
- Runners honor the override —
go-build, golangci-lint, and the new go-test tool
spawn the configured argv, with sync + async variants (src/harness/check-engine/).
- New
go-test catalog tool — project-wide, opt-in (auto-runs only when the project
configures go_test, or on explicit --only go-test / --tools go-test /
verify --only go-test), with generic-fallback + Go test parsers emitting [proven]
per-test findings. Wired into check --only/--tools/--report, TOOL_IDS, and the
ALL_TOOL_IDS drift guard.
affected_tests carries the tags — PostToolUse on a .go edit runs
go test <tags> -count=1 ./<pkg>, replacing the full-suite ./... scope with the touched
package (src/harness/quality-checks/).
- Skills + docs updated (interlinked-verify, interlinked-setup, router; design doc).
Acceptance (isolated GOCACHE, 2026-09-03, re-confirmed after rebase)
| Measurement |
Command |
Cache state |
Wall |
| Before (stock install) |
check --only go-build |
untagged, no shared cache |
8.7 s |
| After (branch) |
check --only go-build |
tagged, dev-warmed reuse |
6.0–6.8 s (clean) |
| After (branch) |
check --only go-test |
tagged, dev-warmed reuse |
21–26 s (per-test findings) |
| Reference |
go build -tags 'dev devaccounts' ./... |
fresh (no reuse) |
29.3 s |
| Reference |
go test -tags 'dev devaccounts' ./... |
fresh (no reuse) |
84.4 s |
The after-runs hug the warmed-tagged-cache baseline (direct warm repeats 5.5 s build / 23 s
suite), proving the tagged command reuses the dev cache instead of recompiling per surface.
Known v1 gaps (deferred in the plan doc)
verify --json has no per-runner go-test section yet (fixed-shape schema).
- Coverage-gate resolver wiring (js/ts/python only).
- PostToolUse honors the config after
interlinked harness restart in existing repos.
Configurable per-tool build/test commands + opt-in full-suite
go-testrunnerBranch:
feat/test-runner-commands(fork:DatScreamer/interlinked-cli)Design doc:
docs/interlinked-test-runners-plan.md(in the branch)Problem
Every tool runner hard-codes its argv (
go build ./...,golangci-lint run ...), there is noway to override a command via config, and there is no full-suite test tool. A project whose
dev server rebuilds with Go build tags (e.g.
-tags 'dev devaccounts') cannot make Interlinkedrun that exact command, so its checks compile into a separate Go build cache — measured
~30–84 s cold vs ~6–21 s warm on the motivating Go workspace.
Changes on the branch
.interlinked/tool-commands.json(committed) +.interlinked/tool-commands.local.json(gitignored), keyed by check/config names(
go_build,go_test,golangci_lint, …). A fullcommandarray wins; otherwisebase_argsreplace the runner's default scope (./...) so Go flag ordering stays correct.Trust split mirrors
merge.ts: the committed team tier may setbase_args+timeout_ms(flags for a fixed binary / a bounded cap);command/envstaypersonal-tier (
interlinked doctorreports violations). No shell interpolation.go-build,golangci-lint, and the newgo-testtoolspawn the configured argv, with sync + async variants (
src/harness/check-engine/).go-testcatalog tool — project-wide, opt-in (auto-runs only when the projectconfigures
go_test, or on explicit--only go-test/--tools go-test/verify --only go-test), with generic-fallback + Go test parsers emitting[proven]per-test findings. Wired into
check --only/--tools/--report,TOOL_IDS, and theALL_TOOL_IDSdrift guard.affected_testscarries the tags — PostToolUse on a.goedit runsgo test <tags> -count=1 ./<pkg>, replacing the full-suite./...scope with the touchedpackage (
src/harness/quality-checks/).Acceptance (isolated
GOCACHE, 2026-09-03, re-confirmed after rebase)check --only go-buildcheck --only go-buildcheck --only go-testgo build -tags 'dev devaccounts' ./...go test -tags 'dev devaccounts' ./...The after-runs hug the warmed-tagged-cache baseline (direct warm repeats 5.5 s build / 23 s
suite), proving the tagged command reuses the dev cache instead of recompiling per surface.
Known v1 gaps (deferred in the plan doc)
verify --jsonhas no per-runnergo-testsection yet (fixed-shape schema).interlinked harness restartin existing repos.