Problem
lint:bats-test-task currently conflates the public mise task contract with the runner implementation.
During review of KnickKnackLabs/template#8, a readability fix moved the nontrivial BATS workflow from .mise/tasks/test into a repo-local libexec/test, leaving the public task as a thin Usage/argument adapter. The real task path and BATS behavior remain covered by integration tests, but codebase 0.3.0 fails with:
no 'bats' invocation found
The rule currently checks several distinct concerns together:
#USAGE argument and example metadata;
- literal direct BATS invocation inside
.mise/tasks/test;
- invocation count;
- implementation anti-patterns such as an outer
if $# wrapper.
That makes a direct invocation an architectural requirement even when a checked repo deliberately uses a thin task adapter and explicit internal runner.
Direction
Separate the contracts, or otherwise make delegation first-class.
A likely split is:
bats-test-task: validate the public test-task interface and Usage metadata;
bats-test-runner: validate the direct or explicitly delegated runner implementation.
For delegated runners, keep the boundary narrow and safe:
- delegation must use a literal repo-local path;
- the target must exist, be executable, remain inside the repo, and not be a symlink;
- exactly one BATS execution should exist across the adapter and runner;
- existing runner anti-pattern checks should still apply;
- dynamic or outside-repo delegation should not pass accidentally.
Current consumer boundary
Template will temporarily remove bats-test-task from its configured lint set rather than add an ignore directive or retain dense task implementation solely to satisfy the current rule.
This issue does not require Template#8 to wait for a codebase release. It tracks restoring an accurate generic lint contract afterward.
Acceptance
- Direct canonical BATS tasks continue to pass.
- Thin task adapters with safe explicit delegated runners can be checked.
- Missing Usage metadata still fails at the task boundary.
- Missing, dynamic, symlinked, outside-repo, or multiply-invoked runners fail clearly.
- Existing fixtures and diagnostics are reorganized around the separated concerns.
- Fold's BATS/code-structure guidance is updated if the public rule names or contract change.
Problem
lint:bats-test-taskcurrently conflates the public mise task contract with the runner implementation.During review of
KnickKnackLabs/template#8, a readability fix moved the nontrivial BATS workflow from.mise/tasks/testinto a repo-locallibexec/test, leaving the public task as a thin Usage/argument adapter. The real task path and BATS behavior remain covered by integration tests, butcodebase 0.3.0fails with:The rule currently checks several distinct concerns together:
#USAGEargument and example metadata;.mise/tasks/test;if $#wrapper.That makes a direct invocation an architectural requirement even when a checked repo deliberately uses a thin task adapter and explicit internal runner.
Direction
Separate the contracts, or otherwise make delegation first-class.
A likely split is:
bats-test-task: validate the public test-task interface and Usage metadata;bats-test-runner: validate the direct or explicitly delegated runner implementation.For delegated runners, keep the boundary narrow and safe:
Current consumer boundary
Template will temporarily remove
bats-test-taskfrom its configured lint set rather than add an ignore directive or retain dense task implementation solely to satisfy the current rule.This issue does not require Template#8 to wait for a
codebaserelease. It tracks restoring an accurate generic lint contract afterward.Acceptance