Audit the library
npm test only checks inputs somebody already thought of. This audit throws
arguments nobody wrote a test for at all 55 mixins and all 24 functions, at
every argument position, and reports what the library does with them. Run it
before a release and after any change that touches more than a couple of
members.
Work through all five steps. Report findings; do not fix anything until the user has seen the list.
1. The suite
npm test
All of it must pass before an audit means anything. This covers: the sass-true
specs, the smoke test that includes every mixin, and the manifest suite that
compiles every documented example, asserts every recorded rejection fails, runs
all of it again under the gls- names demanding byte-identical CSS, and fails if
gerillass.json or SKILL.md is out of date.
2. The adversarial sweep
node tools/audit.js # every mixin and function
node tools/audit.js ratio-box # just one
It calls each member with a list, a boolean, a colour, a bare number and a couple of strings — once per argument position, using named arguments so the positions before the one under test keep their defaults — then sorts the results into four buckets:
SILENT — no CSS, no error. Always a defect. The caller is told the call
worked and ships a missing declaration. Fix by adding the @else the @if chain
is missing. This was 14 mixins before v1.6.0 and should stay at zero.
UNHELPFUL ERROR — failed, but with a Sass internal message. The mixin
rejected the input, but the caller sees $string: 42 is not a string instead of
a sentence naming what the argument accepts. Fix by checking the type before
reaching for str-slice, nth or unit. Sass's own Missing argument $name is
not in this bucket: it names the argument, which is enough.
Sass's arithmetic errors, Undefined operation and can't be used in a calculation, belong here too. The tool missed them until the groundwork for
2.1.1, and recognising them raised this bucket from 0 to 39: background-dots,
background-stripes and triangle doing maths on their sizes, and the utility
functions remify, fontSizer, clearUnit, convertToEm and
convertToNumber. F9 and F11 in todos/fix-plan.md fixed all 39, so the bucket
is back to zero and should stay there. test/manifest.spec.js recognises the
same two messages, so a recorded rejection that fails with one of them fails the
suite.
WARNED ONLY — the build succeeded with a warning. A warning most pipelines
never surface. What is left here is of two kinds, both on purpose. One is
validateLength called on its own with a value that is not a length: the
function is public, and making it strict is what used to reject var(--gap).
The other is the one-argument form of breakpoint, container-query and
remove, which matches one width and warns rather than raising, by the
maintainer's decision of 15 September 2026. position
used to reach it for six of these; since S7 of todos/silent-values-plan.md
it checks its offsets itself and raises.
PASSED THROUGH — emitted CSS from a questionable argument. Read these; do not
act on the count. Some are correct — after(nonsense) really should emit
content: "nonsense". Others are real, like a colour argument that lands in the
CSS as the literal word true. The question to ask is whether the emitted value
could ever be valid CSS.
The sweep then runs again with four values CSS does take, var(--x),
currentColor, null and calc(1rem + 2px), into two buckets of their own:
REFUSED VALID CSS — raised on a value CSS takes. A report, not a gate. A
keyword argument, a selector or a size in a media condition is right to refuse
var(). A colour, a length or a content value usually is not.
BROKEN OUTPUT — compiled, but the CSS cannot work. Always a defect: var()
inside url(), var() inside a quoted string, or a / division Sass left
unevaluated, such as var(--x)/2.
It listed 13 when it was added and is zero since F8 to F11; the manifest suite
fails a documented example with the same shapes.
False positives this probe has hit before
Every one of these was a flaw in the tool that read as a defect in the library. If a finding looks strange, suspect the probe first.
- A mixin that takes a
@contentblock emits nothing when called without one. The tool mirrors the block from the documented example; a mixin whose example omits its block will produce a spurious SILENT finding. - A mixin with required arguments reports
Missing argumentfor every probe. That is Sass working correctly, and it is excluded from the unhelpful bucket. - Filling a required argument with a generic value produced errors about the filler rather than the probe. Fillers now come from the documented example.
- A default that references another argument, such as
background-dots's$gutter: $size * 5, cannot be passed positionally. Hence named arguments. - A variadic argument cannot be named, so those stay positional.
When something looks broken, confirm it by hand before writing it down:
printf '@import "gerillass";\n.x { @include center(diagonal); }\n' | sass --stdin --load-path=scss
3. Generated files
npm run manifest && git diff --stat
A non-empty diff means gerillass.json or SKILL.md was committed stale. The
suite catches this too, but check it here so the audit report is complete.
The gls- half needs no regeneration since 2.0.0 — it comes from
@forward "library" as gls-* — but the suite still compares both names, so a
partial missing from scss/library/_index.scss shows up there.
4. What the tests do not assert
The suite works at four depths: the smoke test proves every mixin evaluates, the manifest snapshots every documented example, the recorded rejections prove bad input is refused, and a sass-true spec proves the CSS is right. Only the last one can tell you an output was wrong from the beginning, and it covers 11 of 73 members.
List which members have one:
ls test/library/*.spec.scss test/utilities/*.spec.scss
List which mixins have a real spec and which rely on "it compiled". A mixin
carrying only the compile check can still be quietly wrong — that is exactly how
ratio-box emitted a ratio box with no ratio through several releases. Use
/sass-test to add assertions for the ones that matter most.
Also report mixins that take arguments and still validate none of them:
for f in scss/library/_*.scss; do
grep -q '^@mixin [a-z-]*(' "$f" || continue # takes no arguments
grep -q '@error' "$f" && continue # validates inline
grep -qE 'validate[A-Z]|is[A-Z][a-z]' "$f" && continue # validates through a utility
basename "$f" .scss | sed 's/^_//'
done
The last filter matters: ratio-box and responsive-video carry no @error of
their own but reject bad input through validateRatio, so a plain grep for
@error reports them as unvalidated and is wrong.
5. The packed artifact
npm pack --dry-run
Expect 114 files. meta/ and tools/ must not appear; gerillass.json and
SKILL.md must. For a release-grade audit, install the tarball somewhere else
and compile against it — .npmignore and the exports map mean the working
tree and the published package are not the same thing.
Reporting
Give counts per bucket, then the specific members, then a recommendation on what is worth fixing now versus deferring.
Say plainly what the audit did not cover. It varies one argument at a time,
so a combination that is only wrong together is invisible to it. It does not
look at @content behaviour, at whether the CSS is correct rather than merely
present, or at anything visual.