vercel-labs / vercel-labs/konsistent
Negation entry with a constrained placeholder silently disables the entire convention
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 176
- Forks
- 6
- Avg merge
- 20h 26m
- Merged PRs (30d)
- 11
Description
Bug: a paths negation with a constrained placeholder silently disables the entire convention
Versions: reproduced on konsistent@1.0.0-beta.3 and 1.0.0-beta.4 (Node 26, macOS).
Repro
repro/
package.json # {"name":"repro","private":true}
konsistent.json
packages/good/{package.json,tsconfig.json,src/index.ts,test/}
packages/temporal/{package.json,tsconfig.json,src/activities.ts,test/} # NOTE: no src/index.ts
packages/excluded-pkg/package.json
{
"version": "v1",
"conventions": [
{
"name": "shell",
"paths": ["packages/{packageName}", "!packages/{packageName:matches(^(excluded-pkg)$)}"],
"must": { "haveType": "directory", "haveFiles": ["src/index.ts"] }
}
]
}
konsistent check --format=json → [], exit 0. The convention matches nothing: packages/temporal (missing src/index.ts) is not flagged, and neither is packages/excluded-pkg.
Change only the negation to a literal:
"paths": ["packages/{packageName}", "!packages/excluded-pkg"]
→ correctly reports packages/temporal Missing required file: src/index.ts (and skips excluded-pkg), exit 1.
Control without any negation: both temporal and excluded-pkg are flagged, as expected.
Expected
A negation entry with an inline constraint (!packages/{p:matches(^(a|b)$)}) should exclude only the paths whose captured value satisfies the constraint — per docs/reference/path-patterns.md#negation + constraints.md, constraints "skip" non-matching captures, so the negation should apply to a/b only.
Actual
The presence of a constrained-placeholder negation entry appears to negate every path the positive pattern matched (or fails to match and swallows the set) — the convention becomes a silent no-op. konsistent validate reports the config as valid, so nothing surfaces the dead rule.
Why this is nasty
Our production config used exactly this shape ("!packages/{packageName:matches(^(blob|extract|monitor)$)}") and our main structural convention was a no-op for weeks while check printed green. Suggest: either fix constraint evaluation in negation entries, or reject constrained placeholders in negations at validate time.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the issue with the provided konsistent.json and run konsistent check --format=json, then compare constrained and literal negation behavior. Read docs/reference/path-patterns.md#negation and constraints.md for the intended semantics. Done means constrained negations exclude only matching captures, nonmatching paths are still checked, and validation does not accept a silently dead convention.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100