chaffchaff

Limitations

What chaff deliberately does not attempt, and where its numbers are estimates rather than measurements. If a limitation below changes what you'd do with a result, read it before trusting the result.

Static analysis only

chaff cannot see how your harness actually assembles context unless you feed it --from-instructions-log (Claude Code’s InstructionsLoaded hook log, which names exactly which files loaded and why). Without it, residency is modeled from documented rules, not observed. The model is doc-derived and cited per rule for the claude-code harness; for generic, nothing is resident unless you declare it.

Measured deltas don't automatically transfer

When a rule graduates to tier enforced, evidence measured (see the admission pipeline), its evidence is scoped to the named models and named battery it was measured on. A rule admitted on claude-haiku-4-5 stays labeled with that model everywhere it appears in output, and never silently generalizes to a model it was not run against. A rule whose effect vanishes on a larger model stays enforced with the scope printed, because that divergence is itself a finding worth knowing.

Token counts are ref-tokenizer estimates, unbanded, today

Every number in this release is the o200k_base ref-tokenizer count: pure JS, deterministic, identical in Node and the browser. The design calls for a per-model calibration band and an opt-in --tokenizer anthropic:<model> exact mode using Anthropic’s free count_tokens endpoint. That lands at a later milestone and is not implemented in this release. No chars/4 mode ships either: fake precision is worse than an honest interval would be, and an honest interval is not built yet.

Load classification is doc-derived, and declaration-only past Claude Code

--harness generic never guesses what is resident. An undeclared entry prints a note and is treated as on-demand. Other harnesses (Cursor, Windsurf, Cline) are not modeled at all: their load semantics are not documented well enough to model honestly yet, and a profile would rather say nothing than guess wrong.

No LLM means no genuine semantic understanding

chaff matches structural shapes (a broken import, near-duplicate shingles, a description with no trigger word), not meaning. It cannot tell you that two sentences contradict each other in spirit if they share no structural signal. False negatives are expected, and deliberately preferred over false positives: a missed contradiction costs you nothing you did not already have; a false alarm on a well-written file costs a broken build and, worse, teaches you to ignore the tool the next time it is right.

What chaff will never do

Not a roadmap gap. A design boundary. No LLM anywhere in the product, not even an opt-in “explain this finding” tier (it would make output non-reproducible and put a key path in a $0 tool). No security or prompt-injection scanning. No rewriting your prose: --fix applies only mechanical, span-local edits. No score without a named tokenizer. No enforced behavioral rule without a committed eval behind it.

See SPEC.md §1 for the full non-goals list, and SECURITY.md for the browser-only privacy claim and how to verify it yourself.