@dzhechkov/harness-core 0.3.100 → 0.3.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/claim-check-hook-policy.d.ts +42 -0
- package/dist/claim-check-hook-policy.d.ts.map +1 -0
- package/dist/claim-check-hook-policy.js +154 -0
- package/dist/claim-check-hook-policy.js.map +1 -0
- package/dist/claim-check.d.ts +21 -0
- package/dist/claim-check.d.ts.map +1 -0
- package/dist/claim-check.js +184 -0
- package/dist/claim-check.js.map +1 -0
- package/dist/feature-adr-claim-gate.d.ts +20 -0
- package/dist/feature-adr-claim-gate.d.ts.map +1 -0
- package/dist/feature-adr-claim-gate.js +28 -0
- package/dist/feature-adr-claim-gate.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/publish.d.ts +17 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +38 -3
- package/dist/publish.js.map +1 -1
- package/package.json +4 -4
- package/src/claim-check-hook-policy.ts +173 -0
- package/src/claim-check.ts +211 -0
- package/src/feature-adr-claim-gate.ts +42 -0
- package/src/index.ts +6 -0
- package/src/publish.ts +53 -3
package/dist/publish.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { existsSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { execSync } from 'node:child_process';
|
|
10
|
+
import { claimCheck } from './claim-check.js';
|
|
10
11
|
/** Bump patch version: 0.3.11 → 0.3.12 */
|
|
11
12
|
export function bumpPatch(version) {
|
|
12
13
|
// Parse the core x.y.z, tolerating a 2-part "x.y" (treated as x.y.0) and a
|
|
@@ -206,8 +207,41 @@ export function publishPackages(monorepoRoot, opts = {}) {
|
|
|
206
207
|
});
|
|
207
208
|
continue;
|
|
208
209
|
}
|
|
210
|
+
// Pre-publish claim-check gate. Default `'warn'` per ADR-001: publishing SURFACES a
|
|
211
|
+
// README's untagged claims by default, but `'warn'` NEVER changes publish status, so the
|
|
212
|
+
// existing publish path is unaffected. `'error'` fails only THIS package when it carries a
|
|
213
|
+
// high-severity claim; `'off'` disables the gate entirely (no `claimCheck` field emitted).
|
|
214
|
+
// Runs BEFORE the dry-run short-circuit so `--dry-run` previews surface what a live publish
|
|
215
|
+
// would. Reading the README never blocks the gate itself — unreadable ⇒ "no findings".
|
|
216
|
+
const claimGate = opts.claimGate ?? 'warn';
|
|
217
|
+
let claimCheckSummary;
|
|
218
|
+
if (claimGate !== 'off') {
|
|
219
|
+
const readmePath = join(pkg.dir, 'README.md');
|
|
220
|
+
if (existsSync(readmePath)) {
|
|
221
|
+
try {
|
|
222
|
+
const text = readFileSync(readmePath, 'utf-8');
|
|
223
|
+
const result = claimCheck(text);
|
|
224
|
+
const high = result.findings.filter((f) => f.severity === 'high').length;
|
|
225
|
+
claimCheckSummary = { findings: result.findings.length, high };
|
|
226
|
+
if (claimGate === 'error' && high > 0) {
|
|
227
|
+
results.push({
|
|
228
|
+
name: pkg.name,
|
|
229
|
+
oldVersion,
|
|
230
|
+
newVersion,
|
|
231
|
+
status: 'error',
|
|
232
|
+
error: `claim-check: ${high} high-severity claim(s) in README.md — tag MEASURED with a reproducer or CLAIMED/SYNTHETIC before publishing.`,
|
|
233
|
+
claimCheck: claimCheckSummary,
|
|
234
|
+
});
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
/* unreadable README never blocks the gate itself */
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
209
243
|
if (opts.dryRun) {
|
|
210
|
-
results.push({ name: pkg.name, oldVersion, newVersion, status: 'skipped' });
|
|
244
|
+
results.push({ name: pkg.name, oldVersion, newVersion, status: 'skipped', claimCheck: claimCheckSummary });
|
|
211
245
|
continue;
|
|
212
246
|
}
|
|
213
247
|
const pkgJsonPath = join(pkg.dir, 'package.json');
|
|
@@ -220,7 +254,7 @@ export function publishPackages(monorepoRoot, opts = {}) {
|
|
|
220
254
|
// shown on npmjs.com always matches the published package (no more manual off-by-one).
|
|
221
255
|
originalReadme = syncReadmeVersion(pkg.dir, oldVersion, newVersion);
|
|
222
256
|
if (opts.bumpOnly) {
|
|
223
|
-
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published' });
|
|
257
|
+
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published', claimCheck: claimCheckSummary });
|
|
224
258
|
continue;
|
|
225
259
|
}
|
|
226
260
|
// Build if has build script
|
|
@@ -235,7 +269,7 @@ export function publishPackages(monorepoRoot, opts = {}) {
|
|
|
235
269
|
encoding: 'utf-8',
|
|
236
270
|
env: { ...process.env },
|
|
237
271
|
});
|
|
238
|
-
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published' });
|
|
272
|
+
results.push({ name: pkg.name, oldVersion, newVersion, status: 'published', claimCheck: claimCheckSummary });
|
|
239
273
|
}
|
|
240
274
|
catch (err) {
|
|
241
275
|
// The version was written BEFORE build+publish; on any failure restore the
|
|
@@ -258,6 +292,7 @@ export function publishPackages(monorepoRoot, opts = {}) {
|
|
|
258
292
|
newVersion,
|
|
259
293
|
status: 'error',
|
|
260
294
|
error: err instanceof Error ? err.message : String(err),
|
|
295
|
+
claimCheck: claimCheckSummary,
|
|
261
296
|
});
|
|
262
297
|
}
|
|
263
298
|
}
|
package/dist/publish.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dzhechkov/harness-core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.102",
|
|
4
4
|
"description": "Shared harness logic - skill loading, additive apply, and the init/sync/verify/doctor operations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"yaml": "^2.0.0",
|
|
33
33
|
"@dzhechkov/adapter-agents-md": "0.1.1",
|
|
34
34
|
"@dzhechkov/adapter-cursor": "0.1.1",
|
|
35
|
-
"@dzhechkov/adapter-gemini": "0.1.1",
|
|
36
|
-
"@dzhechkov/core": "0.2.14",
|
|
37
35
|
"@dzhechkov/adapter-windsurf": "0.1.1",
|
|
36
|
+
"@dzhechkov/adapter-copilot": "0.1.1",
|
|
37
|
+
"@dzhechkov/core": "0.2.14",
|
|
38
38
|
"@dzhechkov/memory": "0.2.9",
|
|
39
|
-
"@dzhechkov/adapter-
|
|
39
|
+
"@dzhechkov/adapter-gemini": "0.1.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependenciesMeta": {
|
|
42
42
|
"@ruvector/rvf": {
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// Authoring-time claim-check HOOK POLICY — the pure decision core behind the
|
|
4
|
+
// `.claude/helpers/claim-check-hook.cjs` PreToolUse hook (feature: claim-check-authoring-time).
|
|
5
|
+
//
|
|
6
|
+
// This module does NOT re-implement or fork detection. It is a thin severity-POLICY layer over the
|
|
7
|
+
// FROZEN engine in `./claim-check.ts` (`claimCheck`): it runs `claimCheck(text)` and turns the
|
|
8
|
+
// findings into a hook decision. Its whole job is to resolve the ADR's core tension — a `high`
|
|
9
|
+
// finding (the retracted `100%`/`perfect` framing) must be surfaced, yet an agent legitimately
|
|
10
|
+
// QUOTING that framing while documenting the checker must NEVER be blocked, and the escape (backtick
|
|
11
|
+
// the literal) must be DISCOVERABLE from the output.
|
|
12
|
+
//
|
|
13
|
+
// Resolution (ADR Option A1):
|
|
14
|
+
// • DEFAULT policy (`mode !== 'deny'`) NEVER returns `action:'deny'` — provable by construction, not
|
|
15
|
+
// just by test. This is the load-bearing property NFR-1 names: the hook never blocks the agent.
|
|
16
|
+
// • Every message ALWAYS teaches the backtick escape, so an agent that trips a `high` learns the
|
|
17
|
+
// one-keystroke fix in the same turn and does not thrash.
|
|
18
|
+
// • Opt-in strict mode (`mode:'deny'`) MAY deny a `high` finding, but only when it is (c) NOT inside
|
|
19
|
+
// a fenced code block AND (d) a genuinely NEW line (an excerpt not already present in the Edit's
|
|
20
|
+
// pre-image). Any ambiguity/parse difficulty in the guards falls back to `allow` — never a
|
|
21
|
+
// spurious deny.
|
|
22
|
+
//
|
|
23
|
+
// Pure, never-throw, no I/O — all reading of stdin / files lives in the `.cjs` adapter, mirroring how
|
|
24
|
+
// the `dz claim-check` CLI and `dz publish` gate are thin adapters over the pure engine.
|
|
25
|
+
|
|
26
|
+
import { claimCheck, type ClaimCheckResult, type ClaimFinding } from './claim-check.js';
|
|
27
|
+
|
|
28
|
+
/** Options for {@link hookDecision}. */
|
|
29
|
+
export interface HookDecisionOpts {
|
|
30
|
+
/** `'warn'` (DEFAULT — the never-block policy) or `'deny'` (opt-in strict, still doubly guarded). */
|
|
31
|
+
readonly mode?: 'warn' | 'deny';
|
|
32
|
+
/** An `Edit`'s pre-image (`old_string`), used by the new-line deny guard. Absent for a `Write`. */
|
|
33
|
+
readonly oldString?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The decision the `.cjs` adapter renders into hook JSON. */
|
|
37
|
+
export interface HookDecision {
|
|
38
|
+
/** `'allow'` on every default-policy path; `'deny'` only under opt-in strict mode + both guards. */
|
|
39
|
+
readonly action: 'allow' | 'deny';
|
|
40
|
+
/** Model-facing finding report (always ends with the backtick-escape teaching). `null` when clean. */
|
|
41
|
+
readonly additionalContext: string | null;
|
|
42
|
+
/** User-facing summary; populated only when there is a `high` finding. `null` when clean or medium-only. */
|
|
43
|
+
readonly systemMessage: string | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The backtick-escape teaching, appended to EVERY finding report. This is the "escape discoverable
|
|
48
|
+
* from the hook's own output" acceptance criterion — an agent that trips a finding while documenting
|
|
49
|
+
* honesty is told exactly how to comply.
|
|
50
|
+
*/
|
|
51
|
+
export const ESCAPE_TEACHING =
|
|
52
|
+
'If a flagged line is legitimately QUOTING a forbidden claim as an example, wrap the literal in ' +
|
|
53
|
+
'backticks (e.g. a backticked `100% coverage`) — a backticked span reads as a code literal, not an ' +
|
|
54
|
+
'assertion, and is not flagged. That is the fix; do NOT weaken the checker. Otherwise state a ' +
|
|
55
|
+
'measured number vs a baseline, tagged MEASURED and naming a reproducer (npx vitest run, coverage report).';
|
|
56
|
+
|
|
57
|
+
/** claimCheck is already never-throw; wrap defensively so hookDecision is never-throw even on abuse. */
|
|
58
|
+
function safeClaimCheck(text: string): ClaimCheckResult {
|
|
59
|
+
try {
|
|
60
|
+
return claimCheck(text);
|
|
61
|
+
} catch {
|
|
62
|
+
return { ok: true, findings: [] };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function safeBool(fn: () => boolean, fallback: boolean): boolean {
|
|
67
|
+
try {
|
|
68
|
+
return fn();
|
|
69
|
+
} catch {
|
|
70
|
+
return fallback;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function formatFinding(f: ClaimFinding): string {
|
|
75
|
+
return ' - L' + f.line + ': "' + f.excerpt + '" — ' + f.reason + ' -> ' + f.suggestion;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Is the 1-based `line` inside a fenced ``` ``` ``` code block within `text`?
|
|
80
|
+
* Counts fence toggles strictly BEFORE the line; an odd count ⇒ the line sits inside a fence.
|
|
81
|
+
* Never throws — a non-string / out-of-range line returns `false` (treated as not-fenced).
|
|
82
|
+
*/
|
|
83
|
+
export function isFenced(text: string, line: number): boolean {
|
|
84
|
+
if (typeof text !== 'string' || typeof line !== 'number' || !isFinite(line) || line < 1) return false;
|
|
85
|
+
const lines = text.split(/\r?\n/);
|
|
86
|
+
const upTo = Math.min(line - 1, lines.length);
|
|
87
|
+
// CommonMark allows BOTH ``` and ~~~ fences, and a fence is closed only by its OWN marker — a
|
|
88
|
+
// ``` inside a ~~~ block is literal content, not a toggle. A naive toggle counter that accepts
|
|
89
|
+
// either marker therefore mis-tracks nesting; track the open marker instead.
|
|
90
|
+
let open: '`' | '~' | null = null;
|
|
91
|
+
for (let i = 0; i < upTo; i++) {
|
|
92
|
+
const m = /^\s*(`{3,}|~{3,})/.exec(lines[i] || '');
|
|
93
|
+
if (!m) continue;
|
|
94
|
+
const marker = m[1]![0] as '`' | '~';
|
|
95
|
+
if (open === null) open = marker;
|
|
96
|
+
else if (open === marker) open = null;
|
|
97
|
+
}
|
|
98
|
+
return open !== null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Is `excerpt` a NEW claim line (guard d)? True when there is no pre-image (`oldString` absent/empty —
|
|
103
|
+
* e.g. a `Write`) or the pre-image does not already contain the excerpt. A trailing clip ellipsis
|
|
104
|
+
* (the engine clips excerpts to 120 chars) is stripped before the containment check so an edited-around
|
|
105
|
+
* long pre-existing line is still recognised. Never throws.
|
|
106
|
+
*/
|
|
107
|
+
export function isNewLine(excerpt: string, oldString?: string): boolean {
|
|
108
|
+
if (typeof oldString !== 'string' || oldString.length === 0) return true;
|
|
109
|
+
if (typeof excerpt !== 'string' || excerpt.length === 0) return true;
|
|
110
|
+
let probe = excerpt;
|
|
111
|
+
if (probe.charAt(probe.length - 1) === '…') probe = probe.slice(0, -1);
|
|
112
|
+
if (probe.length === 0) return true;
|
|
113
|
+
return oldString.indexOf(probe) === -1;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The pure hook decision. Runs the FROZEN `claimCheck` over the pending text and applies the severity
|
|
118
|
+
* policy. NEVER throws. Under the DEFAULT policy (`mode !== 'deny'`) it NEVER returns `action:'deny'`
|
|
119
|
+
* — there is no code path to a deny unless `mode === 'deny'` AND a `high` finding clears BOTH guards.
|
|
120
|
+
*/
|
|
121
|
+
export function hookDecision(text: string, opts?: HookDecisionOpts): HookDecision {
|
|
122
|
+
const result = safeClaimCheck(text);
|
|
123
|
+
if (!result || result.ok || !Array.isArray(result.findings) || result.findings.length === 0) {
|
|
124
|
+
return { action: 'allow', additionalContext: null, systemMessage: null };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const denyEnabled = !!(opts && opts.mode === 'deny');
|
|
128
|
+
const oldString = opts ? opts.oldString : undefined;
|
|
129
|
+
const highs = result.findings.filter((f) => f.severity === 'high');
|
|
130
|
+
const mediums = result.findings.filter((f) => f.severity === 'medium');
|
|
131
|
+
|
|
132
|
+
const lines: string[] = [];
|
|
133
|
+
if (highs.length > 0) {
|
|
134
|
+
lines.push(
|
|
135
|
+
'claim-check flagged ' +
|
|
136
|
+
highs.length +
|
|
137
|
+
' HIGH finding(s) — the retracted perfect/100% framing the Integrity Rule forbids:',
|
|
138
|
+
);
|
|
139
|
+
for (const f of highs) lines.push(formatFinding(f));
|
|
140
|
+
}
|
|
141
|
+
if (mediums.length > 0) {
|
|
142
|
+
lines.push('claim-check flagged ' + mediums.length + ' medium finding(s) — untagged accuracy/count claim(s):');
|
|
143
|
+
for (const f of mediums) lines.push(formatFinding(f));
|
|
144
|
+
}
|
|
145
|
+
lines.push('');
|
|
146
|
+
lines.push(ESCAPE_TEACHING);
|
|
147
|
+
const additionalContext = lines.join('\n');
|
|
148
|
+
|
|
149
|
+
// DEFAULT policy: never deny. A deny is reachable ONLY when denyEnabled AND a high finding clears
|
|
150
|
+
// BOTH guards (outside a fence AND a new line). Any guard exception falls back to allow.
|
|
151
|
+
let action: 'allow' | 'deny' = 'allow';
|
|
152
|
+
if (denyEnabled && highs.length > 0) {
|
|
153
|
+
const blockable = highs.filter((f) => {
|
|
154
|
+
if (safeBool(() => isFenced(text, f.line), false)) return false;
|
|
155
|
+
return safeBool(() => isNewLine(f.excerpt, oldString), true);
|
|
156
|
+
});
|
|
157
|
+
if (blockable.length > 0) action = 'deny';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
let systemMessage: string | null = null;
|
|
161
|
+
if (highs.length > 0) {
|
|
162
|
+
systemMessage =
|
|
163
|
+
'claim-check: ' +
|
|
164
|
+
highs.length +
|
|
165
|
+
' HIGH finding(s) (perfect/100% framing) — ' +
|
|
166
|
+
(action === 'deny'
|
|
167
|
+
? 'BLOCKED under DZ_CLAIM_CHECK_HOOK=deny. '
|
|
168
|
+
: 'warning, not a block (set DZ_CLAIM_CHECK_HOOK=deny to enforce). ') +
|
|
169
|
+
'Backtick the literal to quote it as an example, or state a MEASURED number vs a baseline.';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return { action, additionalContext, systemMessage };
|
|
173
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// Ported from rUv / ruview (`@ruvnet/ruview@0.2.0`, `src/guardrails.js`), (c) rUv / ruview,
|
|
4
|
+
// MIT. Adapted for the dz harness monorepo. The hard-won detection semantics (label-vs-metric
|
|
5
|
+
// disambiguation, short-token `.map`/`map-reduce` guards, the `\b`-free `PERFECT_PCT_RE`, the
|
|
6
|
+
// code-span-scrub asymmetry, and the four-branch check order) are ported VERBATIM with their
|
|
7
|
+
// explanatory comments intact; ONLY the domain vocabulary lists (metric terms, reproducer hints,
|
|
8
|
+
// honest tags) and the human-facing reason/suggestion strings are re-worded from WiFi-sensing
|
|
9
|
+
// (ruview) to a skills/harness monorepo (dz).
|
|
10
|
+
//
|
|
11
|
+
// The dz Integrity Rule (CLAUDE.md) declares "NO shortcuts, fake data, or false claims; ALWAYS
|
|
12
|
+
// verify before claiming success." Today that rule is prose. This module is the static enforcement
|
|
13
|
+
// of it: every quantitative accuracy/coverage/count claim must be tagged MEASURED (with a
|
|
14
|
+
// reproducer) or CLAIMED/SYNTHETIC/ESTIMATED, and the retracted "100% / perfect" framing must
|
|
15
|
+
// never reappear untagged. It is a pure, never-throw, no-I/O module — all file reading lives in the
|
|
16
|
+
// `dz claim-check` CLI adapter and the `dz publish` pre-publish gate, mirroring how `usage.ts`
|
|
17
|
+
// keeps computation pure while the CLI does the reading.
|
|
18
|
+
|
|
19
|
+
/** A single untagged/overstated-claim finding. The pure engine sees only text — no `file` field. */
|
|
20
|
+
export interface ClaimFinding {
|
|
21
|
+
readonly severity: 'high' | 'medium';
|
|
22
|
+
readonly line: number; // 1-based, within the scanned text
|
|
23
|
+
readonly excerpt: string; // clip()'d to 120 chars
|
|
24
|
+
readonly reason: string;
|
|
25
|
+
readonly suggestion: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Result of a claim-check pass over one block of text. */
|
|
29
|
+
export interface ClaimCheckResult {
|
|
30
|
+
readonly ok: boolean;
|
|
31
|
+
readonly findings: ClaimFinding[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Phrases that signal a quantitative accuracy claim (safe as substrings). */
|
|
35
|
+
const METRIC_TERMS = [
|
|
36
|
+
// Generic accuracy vocabulary kept from ruview.
|
|
37
|
+
'accuracy', 'precision', 'recall',
|
|
38
|
+
'error rate', 'detection rate', 'true positive',
|
|
39
|
+
// dz claim vocabulary — a harness monorepo claims coverage, test counts, catalogue sizes,
|
|
40
|
+
// and performance numbers, not WiFi-sensing PCK/MPJPE.
|
|
41
|
+
'coverage', 'tests passed', 'test count', 'skills', 'commands',
|
|
42
|
+
'packages', 'presets', 'downloads', 'benchmark', 'speedup', 'latency',
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// Short/ambiguous metric tokens (ADR-263 F11): 'map' is usually the English
|
|
46
|
+
// word or a file extension, 'f1'/'o1' collide with finding/option labels.
|
|
47
|
+
// They only count as metric mentions when word-bounded, not a `.map` file
|
|
48
|
+
// reference, and the line (after scrubbing) carries a number — "mAP 62.3" is
|
|
49
|
+
// a claim, "F-numbers map to findings" is not.
|
|
50
|
+
// 'map' additionally must not be a `.map` file suffix or a hyphenated
|
|
51
|
+
// compound ("map-free", "map-reduce") — mAP the metric never appears as either.
|
|
52
|
+
// `\d+ tests` is dz's single most-repeated headline claim ("2136 tests") and was slipping through:
|
|
53
|
+
// the substring term is 'tests passed', so a bare count never fired. Anchor it to a PRECEDING number
|
|
54
|
+
// rather than adding a bare 'test' term — otherwise every `usage.test.ts:42` path reference would
|
|
55
|
+
// register as a metric mention.
|
|
56
|
+
const METRIC_TERMS_SHORT = [
|
|
57
|
+
/(?<![.\w])map\b(?!-)/, /\bf1\b/, /\bauc\b/, /\biou\b/,
|
|
58
|
+
/\b\d[\d,._]*\s+tests?\b/,
|
|
59
|
+
];
|
|
60
|
+
// Finding/option labels (F1, O2, …) count as labels unless the token sits in a
|
|
61
|
+
// metric context: an immediately following score/=/%/digit or colon ("F1: 0.91"),
|
|
62
|
+
// or a number later in the same clause ("F1 reaches 0.91" — an F1-score claim).
|
|
63
|
+
// Bare option refs ("F7 fixes", "O1–O9", "ADR-263 O2") carry no clause number of
|
|
64
|
+
// their own and stay labels. (A surviving 'f1' still only fires as a metric when
|
|
65
|
+
// its scrubbed line actually carries a number — see mentionsMetricTerm.)
|
|
66
|
+
const LABEL_TOKEN_RE = /\b[fo]\d+\b(?!\s*(?:score|=|\d|%|:))(?![^\n.;]*\d)/g;
|
|
67
|
+
const CODE_SPAN_RE = /`[^`]*`/g; // backticked identifiers are code, not claims
|
|
68
|
+
|
|
69
|
+
// Markdown link/image TARGETS are machinery, not prose claims. A shields.io badge URL
|
|
70
|
+
// (``) embeds the very words and
|
|
71
|
+
// numbers this checker hunts for, so leaving URLs in produced ~600 findings on this repo — noise
|
|
72
|
+
// that buries the real ones. The link TEXT is kept, so a claim written in prose still fires; the
|
|
73
|
+
// same counts always appear in prose next to the badges. Consequence, accepted knowingly: a number
|
|
74
|
+
// that exists ONLY inside a URL is not checked.
|
|
75
|
+
const MD_URL_RE = /\]\([^)\s]*(?:\s[^)]*)?\)/g;
|
|
76
|
+
const AUTOLINK_RE = /<https?:\/\/[^>]*>|(?<![(<])\bhttps?:\/\/\S+/g;
|
|
77
|
+
|
|
78
|
+
/** Strip markdown link/image targets and bare URLs, keeping the surrounding prose. */
|
|
79
|
+
function stripUrls(s: string): string {
|
|
80
|
+
return s.replace(MD_URL_RE, '] ').replace(AUTOLINK_RE, ' ');
|
|
81
|
+
}
|
|
82
|
+
const HAS_NUMBER_RE = /\d/;
|
|
83
|
+
|
|
84
|
+
/** Line with code spans and finding/option labels removed. */
|
|
85
|
+
function scrubLine(lower: string): string {
|
|
86
|
+
return lower.replace(CODE_SPAN_RE, ' ').replace(LABEL_TOKEN_RE, ' ');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function mentionsMetricTerm(lower: string, scrubbed: string): boolean {
|
|
90
|
+
if (METRIC_TERMS.some((t) => lower.includes(t))) return true;
|
|
91
|
+
if (!HAS_NUMBER_RE.test(scrubbed)) return false;
|
|
92
|
+
return METRIC_TERMS_SHORT.some((re) => re.test(scrubbed));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Tags that make a claim honest (case-insensitive). */
|
|
96
|
+
// `estimated` agrees with the `estimated: true` honest-uncertainty marker `dz usage` already
|
|
97
|
+
// emits — the two honesty systems must not contradict each other.
|
|
98
|
+
const HONEST_TAGS = ['measured', 'claimed', 'synthetic', 'unvalidated', 'baseline', 'estimated'];
|
|
99
|
+
|
|
100
|
+
/** Reproducer references that count as evidence backing a MEASURED claim. */
|
|
101
|
+
const REPRODUCER_HINTS = [
|
|
102
|
+
// Generic evidence hints kept from ruview.
|
|
103
|
+
'baseline', 'reproduce', 'sha256', 'tarball', 'cargo test',
|
|
104
|
+
// Packaging-claim reproducers (npm reviews): the tarball itself.
|
|
105
|
+
'npm pack', 'npm view', 'npm i ', 'npm install',
|
|
106
|
+
// dz reproducers — the actual commands/artifacts that back a dz claim.
|
|
107
|
+
'npm test', 'vitest', 'npm run', 'git rev', 'commit',
|
|
108
|
+
'test output', 'coverage report', 'measured on',
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
const PERCENT_RE = /\b(\d{1,3}(?:\.\d+)?)\s?%/g;
|
|
112
|
+
// "perfect" / "100%" framing is the specific retracted claim — always high severity.
|
|
113
|
+
// NOTE: no trailing \b after "%": "%"→" " is non-word→non-word, so a trailing \b
|
|
114
|
+
// never matches and would silently miss "100%". Bare 100% is only damning next to a
|
|
115
|
+
// metric term (see claimCheck); the word phrases are inherently accuracy claims.
|
|
116
|
+
const PERFECT_PCT_RE = /\b100(?:\.0+)?\s?%/;
|
|
117
|
+
const PERFECT_WORD_RE = /perfect accuracy|flawless|never (?:wrong|fails)/i;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Lint a block of text for untagged or overstated accuracy claims.
|
|
121
|
+
* Pure and never-throws: a non-string or empty input returns `{ ok: true, findings: [] }`.
|
|
122
|
+
*/
|
|
123
|
+
export function claimCheck(text: string): ClaimCheckResult {
|
|
124
|
+
const findings: ClaimFinding[] = [];
|
|
125
|
+
if (typeof text !== 'string' || text.length === 0) {
|
|
126
|
+
return { ok: true, findings };
|
|
127
|
+
}
|
|
128
|
+
const lines = text.split(/\r?\n/);
|
|
129
|
+
|
|
130
|
+
lines.forEach((raw, i) => {
|
|
131
|
+
const original = raw.trim();
|
|
132
|
+
if (!original) return;
|
|
133
|
+
// Analyse the URL-stripped line, but report the ORIGINAL so the excerpt stays recognisable.
|
|
134
|
+
const line = stripUrls(original);
|
|
135
|
+
if (!line.trim()) return;
|
|
136
|
+
const lower = line.toLowerCase();
|
|
137
|
+
|
|
138
|
+
const hasPercent = PERCENT_RE.test(line);
|
|
139
|
+
PERCENT_RE.lastIndex = 0; // reset stateful global regex
|
|
140
|
+
const scrubbed = scrubLine(lower);
|
|
141
|
+
// DELIBERATE DIVERGENCE from ruview, which matched METRIC_TERMS against the UNSCRUBBED line.
|
|
142
|
+
// dz's vocabulary contains path-like words ('packages', 'commands', 'skills'), so a code span
|
|
143
|
+
// such as `packages/x/usage.test.ts:42` registered as a metric mention and produced a false
|
|
144
|
+
// positive on prose that merely cites a file. Matching the code-span-scrubbed line fixes it:
|
|
145
|
+
// "accuracy reached `0.95`" still fires because 'accuracy' sits OUTSIDE the span, while the
|
|
146
|
+
// number check below deliberately keeps reading the un-code-scrubbed line so `0.95` counts.
|
|
147
|
+
const mentionsMetric = mentionsMetricTerm(scrubbed, scrubbed);
|
|
148
|
+
if (!hasPercent && !mentionsMetric) return;
|
|
149
|
+
|
|
150
|
+
const tagged = HONEST_TAGS.some((t) => lower.includes(t));
|
|
151
|
+
const hasReproducer = REPRODUCER_HINTS.some((h) => lower.includes(h));
|
|
152
|
+
const perfect = PERFECT_WORD_RE.test(line) || (mentionsMetric && PERFECT_PCT_RE.test(line));
|
|
153
|
+
|
|
154
|
+
if (perfect && !lower.includes('retract')) {
|
|
155
|
+
findings.push({
|
|
156
|
+
severity: 'high',
|
|
157
|
+
line: i + 1,
|
|
158
|
+
excerpt: clip(original),
|
|
159
|
+
reason: 'States perfect/100% accuracy — this is the exact framing the Integrity Rule forbids.',
|
|
160
|
+
suggestion: 'Replace with a measured number vs a baseline, tagged MEASURED (name the reproducer: npm test, coverage report), or mark the old claim "retracted".',
|
|
161
|
+
});
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// A quantitative claim needs a number. Digits hidden in a code span still
|
|
166
|
+
// count — "accuracy reached `0.95`" is a claim — so test the line with only
|
|
167
|
+
// finding/option labels stripped, NOT the code-span-scrubbed copy: scrubbing
|
|
168
|
+
// dropped `0.95` and wrongly short-circuited both the untagged and the
|
|
169
|
+
// MEASURED-without-reproducer checks below. A bare metric word in prose
|
|
170
|
+
// ("precision matters here", "every accuracy number must be MEASURED") has no
|
|
171
|
+
// number and is not a taggable claim (ADR-263 F11).
|
|
172
|
+
if (!hasPercent && !HAS_NUMBER_RE.test(lower.replace(LABEL_TOKEN_RE, ' '))) return;
|
|
173
|
+
|
|
174
|
+
// A metric/percent with no honesty tag at all.
|
|
175
|
+
if (!tagged) {
|
|
176
|
+
findings.push({
|
|
177
|
+
severity: 'medium',
|
|
178
|
+
line: i + 1,
|
|
179
|
+
excerpt: clip(original),
|
|
180
|
+
reason: 'Accuracy claim is not tagged MEASURED / CLAIMED / SYNTHETIC / ESTIMATED.',
|
|
181
|
+
suggestion: 'Tag it. If MEASURED, name the reproducer (npm test, coverage report, git rev, npm view).',
|
|
182
|
+
});
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Tagged MEASURED but cites no reproducer — still a gap (reached now even
|
|
187
|
+
// when the only number is inside a code span, e.g. "accuracy `0.97` (MEASURED)").
|
|
188
|
+
if (lower.includes('measured') && !hasReproducer) {
|
|
189
|
+
findings.push({
|
|
190
|
+
severity: 'medium',
|
|
191
|
+
line: i + 1,
|
|
192
|
+
excerpt: clip(original),
|
|
193
|
+
reason: 'Tagged MEASURED but cites no reproducer/evidence.',
|
|
194
|
+
suggestion: 'Add the evidence path: npm test output, a coverage report, npm view, or a git rev/commit.',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return { ok: findings.length === 0, findings };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function clip(s: string, n = 120): string {
|
|
203
|
+
return s.length > n ? `${s.slice(0, n - 1)}…` : s;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Convenience: a one-line human summary for CLI output. */
|
|
207
|
+
export function summarize(result: ClaimCheckResult): string {
|
|
208
|
+
if (result.ok) return 'claim-check: PASS — no untagged or overstated accuracy claims.';
|
|
209
|
+
const high = result.findings.filter((f) => f.severity === 'high').length;
|
|
210
|
+
return `claim-check: ${result.findings.length} finding(s) (${high} high) — accuracy claims need MEASURED/CLAIMED tags + a reproducer.`;
|
|
211
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
//
|
|
3
|
+
// feature-adr Step-8 claim-gate — the pure decision core for Deliverable B (feature:
|
|
4
|
+
// claim-check-authoring-time). QE reports are where untagged quantitative claims are BORN ("1094
|
|
5
|
+
// tests pass" with no tag and no reproducer). Step 8 of the feature-adr workflow runs
|
|
6
|
+
// `dz claim-check <FDIR>/08_qe_report.md --json --fail-on none` (in the QE agent's Bash tool, NOT
|
|
7
|
+
// here — this module does NO I/O) and reports the counts. This function folds those counts into an
|
|
8
|
+
// ADDITIVE result field plus a one-line human summary.
|
|
9
|
+
//
|
|
10
|
+
// Advisory only: it never changes the QE grade and never blocks the pipeline (mirroring the publish
|
|
11
|
+
// gate's warn default and the reward-learning "memory/QE side-channels never block" rule).
|
|
12
|
+
//
|
|
13
|
+
// Per the pure-core convention (`feature-adr-routing.ts`), this named function's BODY is inlined
|
|
14
|
+
// byte-equivalently into `.claude/workflows/feature-adr.js` (and its byte-identical
|
|
15
|
+
// skills-feature-adr template mirror); `feature-adr-model-routing.test.ts` asserts the inline copy
|
|
16
|
+
// matches this module body (drift guard). The body is written parser-safe (string `+` concat,
|
|
17
|
+
// explicit `if`/return, object literals — NO template literals) so the same source inlines verbatim.
|
|
18
|
+
|
|
19
|
+
/** The finding counts the Step-8 QE agent reported from `dz claim-check`. */
|
|
20
|
+
export interface Step8ClaimCounts {
|
|
21
|
+
readonly findings: number;
|
|
22
|
+
readonly high: number;
|
|
23
|
+
readonly medium: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** The additive Step-8 result field: the counts (or `null` when not run) plus a human summary line. */
|
|
27
|
+
export interface Step8ClaimGate {
|
|
28
|
+
/** `null` ⇒ the QE agent did not / could not run claim-check — an HONEST gap, never a false zero. */
|
|
29
|
+
readonly claimCheck: Step8ClaimCounts | null;
|
|
30
|
+
/** One-line human summary folded into logs. */
|
|
31
|
+
readonly note: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Turn the claim-check counts the QE agent reported into the additive result field + a note.
|
|
36
|
+
* `null`/absent counts yield an honest "not run" note — never a fabricated "0 findings" that would
|
|
37
|
+
* read like a clean pass. Pure, never-throws. This body is inlined verbatim into the workflow.
|
|
38
|
+
*/
|
|
39
|
+
export function step8ClaimGate(counts: Step8ClaimCounts | null): Step8ClaimGate {
|
|
40
|
+
if (!counts) return { claimCheck: null, note: 'claim-check: not run (no counts reported)' }
|
|
41
|
+
return { claimCheck: counts, note: counts.findings + ' finding(s) (' + counts.high + ' high) in 08_qe_report.md' }
|
|
42
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -119,6 +119,12 @@ export type { PluginManifest } from './plugin.js';
|
|
|
119
119
|
export type { SetupOptions, SetupResult, SetupStep } from './setup.js';
|
|
120
120
|
export type { PretrainResult, DetectedTech } from './pretrain.js';
|
|
121
121
|
export type { RecommendationReport, SkillRecommendation } from './recommend.js';
|
|
122
|
+
export { claimCheck, summarize } from './claim-check.js';
|
|
123
|
+
export type { ClaimFinding, ClaimCheckResult } from './claim-check.js';
|
|
124
|
+
export { hookDecision, isFenced, isNewLine, ESCAPE_TEACHING } from './claim-check-hook-policy.js';
|
|
125
|
+
export type { HookDecision, HookDecisionOpts } from './claim-check-hook-policy.js';
|
|
126
|
+
export { step8ClaimGate } from './feature-adr-claim-gate.js';
|
|
127
|
+
export type { Step8ClaimCounts, Step8ClaimGate } from './feature-adr-claim-gate.js';
|
|
122
128
|
export { discoverPackages, publishPackages, bumpPatch, compareVersions, findUnpackagedSkills, orderByDependencies, syncReadmeVersion } from './publish.js';
|
|
123
129
|
export { fetchAllDownloads } from './downloads.js';
|
|
124
130
|
export type { PackageDownloads, DownloadsReport } from './downloads.js';
|