Skip to content

Commit ae02cb8

Browse files
theCodeDriftclaude
andcommitted
feat(taskless): record measurements in comments, do not forecast
The most repeated finding in the merged-PR review threads: a comment that cites a version or a claim the code moved out from under it. On #161 alone, five threads — "we pin 3.17.1" left behind after VALE_VERSION went to 3.18.0, a comment naming .rmd as plaintext after the diff moved it to markup, a block still framing 3.18.0 as "the known incoming bump" after it shipped. Same shape on #155 and #157. The rule flags the construction rather than the stale number, which is the half a static check can see. Vale reads .ts in its comments-only tier, so it lints the comment text and never the code. Zero findings on packages/cli/src today, because #161 fixed them all. Reach verified separately by planting a forecast comment in a real source file: fixtures run under an isolating config, so a passing test does not prove the matcher glob reaches anything. Also ignores .taskless/ in eslint and prettier. A rule about source comments needs .ts fixtures, Vale decides its comments-only tier by extension, and those files belong to no tsconfig — so lint-staged failed the commit on "not found by the project service". Rule fixtures are inputs written to be flagged; verify and test are what keep them honest. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017cEN93Acyp4zBwP3oDnyy1
1 parent 9777918 commit ae02cb8

7 files changed

Lines changed: 57 additions & 5 deletions

File tree

‎.prettierignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ worktrees/
1313

1414
# The demo project: deliberately-wrong source and prose fixtures.
1515
example/
16+
17+
# Taskless rule fixtures: deliberately-wrong prose and source.
18+
.taskless/
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// The docs describe the current Vale, and 3.18.0 is the known incoming bump.
2+
export const VALE_VERSION = "3.17.1";
3+
4+
// None of these is reachable today, though once we upgrade the second tier
5+
// will start routing differently.
6+
export const TIERS = [];
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Measured on the pinned 3.18.0 binary: a bare non-comment line in bare.pyi
2+
// yields no finding, so the file is plaintext rather than markup.
3+
export const VALE_VERSION = "3.18.0";
4+
5+
// Re-probed after the bump rather than renumbered. The claim is the binary's,
6+
// not the release notes'.
7+
export const TIERS = [];
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Vale reads .ts in its comments-only tier: the comment text is linted and the
2+
# code body is invisible, so this rule can never fire on an identifier.
3+
[packages/cli/src/**/*.ts]
4+
tskl) rule = comments-record-not-forecast
5+
BasedOnStyles =
6+
comments-record-not-forecast.comments-record-not-forecast = YES
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
extends: existence
2+
message: "'%s' forecasts. Record what was measured, and date the claim."
3+
level: warning
4+
ignorecase: true
5+
tokens:
6+
- 'the known incoming'
7+
- 'the incoming bump'
8+
- 'the upcoming release'
9+
- 'in a future release'
10+
- 'when we bump'
11+
- 'once we upgrade'
12+
- 'once we bump'
13+
- 'we anticipate'
14+
- 'is expected to become'
15+
- 'will likely become'

‎.taskless/taskless.json‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,25 @@
33
"install": {
44
"targets": {
55
".taskless": {
6-
"skills": ["taskless"],
7-
"commands": ["tskl.md"],
6+
"skills": [
7+
"taskless"
8+
],
9+
"commands": [
10+
"tskl.md"
11+
],
812
"mode": "canonical"
913
},
1014
".claude": {
11-
"skills": ["taskless"],
12-
"commands": ["tskl.md"],
15+
"skills": [
16+
"taskless"
17+
],
18+
"commands": [
19+
"tskl.md"
20+
],
1321
"mode": "reference"
1422
}
1523
},
16-
"cliVersion": "0.11.0-20260824213902xf26a7b0"
24+
"cliVersion": "0.11.0-20260824213902xf26a7b0",
25+
"onboarded": true
1726
}
1827
}

‎eslint.config.js‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ export default tseslint.config(
2828
// Zero-dependency CommonJS workflow scripts (covered by their own
2929
// node:test suite); the app's TS/ESM-oriented rules don't apply.
3030
".github/scripts/",
31+
// Taskless rule fixtures. A rule's `.tests/` holds inputs written to be
32+
// flagged, and a rule about source comments needs `.ts` fixtures
33+
// specifically — Vale picks its comments-only tier by extension. They are
34+
// not part of any tsconfig, so the type-aware rules fail to parse them.
35+
// `taskless verify` and `taskless test` are what keep them honest.
36+
".taskless/",
3137
// The demo project. Its source is deliberately wrong — `example.cjs`
3238
// calls `eval` so a rule has something to find — and its fixtures are
3339
// prose written to be flagged. Linting it fails on content nobody wrote

0 commit comments

Comments
 (0)