@dzhechkov/harness-cli 0.3.260 → 0.3.262
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/.dz-manifest.json +7 -7
- package/README.md +13 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -8
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/sbom.json +6 -6
- package/src/cli.ts +19 -7
package/.dz-manifest.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "README.md",
|
|
12
|
-
"sha256": "
|
|
12
|
+
"sha256": "af18869081f5141177b6427e812d724e15995d49b10cf67f24803eb5e1d79cb5"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "coverage/coverage-final.json",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"path": "dist/cli.d.ts.map",
|
|
44
|
-
"sha256": "
|
|
44
|
+
"sha256": "02a2ba1def8a57e1d4dcde048d5a62af19ab4cd825c98bcfbe8ac0df7de2062c"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"path": "dist/cli.js",
|
|
48
|
-
"sha256": "
|
|
48
|
+
"sha256": "8d3674dc681dc2493886534c8a30e124664a158fd4f7f2da476f5ff2ec615edd"
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
"path": "dist/cli.js.map",
|
|
52
|
-
"sha256": "
|
|
52
|
+
"sha256": "3975feb3b9102aad34cdcc070315a7756ef9241aa2bb618759a1bbac25ec7951"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"path": "dist/index.d.ts",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"path": "package.json",
|
|
76
|
-
"sha256": "
|
|
76
|
+
"sha256": "3e9deb36cf53245aaae26a72de359a7f57e9691d52454266ffe32f61dc963a27"
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
"path": "src/bin.ts",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"path": "src/cli.ts",
|
|
84
|
-
"sha256": "
|
|
84
|
+
"sha256": "9549a9864fddc36eb99a172f3f0e7c7e72ae32d36aebadaf826b58af0bed16b4"
|
|
85
85
|
},
|
|
86
86
|
{
|
|
87
87
|
"path": "src/index.ts",
|
|
@@ -109,5 +109,5 @@
|
|
|
109
109
|
}
|
|
110
110
|
]
|
|
111
111
|
},
|
|
112
|
-
"signature": "
|
|
112
|
+
"signature": "3ghvnJARKOZq3JBJswFiPPiar56oO/qN6KDRN1kU2yunpTVyhNAqXdr49P/a5w/OHWPKD7hX5Vk72VLYNkTWDA=="
|
|
113
113
|
}
|
package/README.md
CHANGED
|
@@ -2359,13 +2359,20 @@ dz recall "signature" --limit 3 --domain security
|
|
|
2359
2359
|
# [0.90] (security) ⟨both⟩ Crypto anti-hallucination anti-pattern: verifying a signature …
|
|
2360
2360
|
# [0.85] (publishing) ⟨both⟩ ⚠q 'Re-sign LAST' applies to EVERY signed pack a sweep touches …
|
|
2361
2361
|
# [0.80] (testing) ⟨vector⟩ A structural registry-coverage test that only checks key-SET …
|
|
2362
|
-
# domain "security": 1 exact match(es)
|
|
2362
|
+
# domain "security": among 6 candidate(s) — 1 exact match(es), 3 changed position;
|
|
2363
2363
|
# foreign-domain lessons kept (a boost, not a filter)
|
|
2364
|
+
# 1 lower-ranked lesson fell past the --limit 3 cut to make room — raise --limit to see them
|
|
2364
2365
|
|
|
2365
2366
|
dz recall "signature" --limit 3 --domain health-research
|
|
2366
2367
|
# domain "health-research": no lesson in this result carries it — order unchanged, nothing was hidden
|
|
2367
2368
|
```
|
|
2368
2369
|
|
|
2370
|
+
**One line out per hit.** Every value that reaches a `dz recall` output line — the lesson, its
|
|
2371
|
+
domain, your query, the requested domain — is rendered on a single line, with embedded line breaks
|
|
2372
|
+
shown as `⏎`. That is not cosmetic: any tool parsing this output line-wise (the `health-advisor`
|
|
2373
|
+
research skill reads it to detect whether this `dz` supports `--domain`) would otherwise see lines
|
|
2374
|
+
forged by stored content or by a crafted query.
|
|
2375
|
+
|
|
2369
2376
|
**Why a boost and not a filter.** Cross-domain transfer is the reason one shared store beats two
|
|
2370
2377
|
separate ones: *"a reviewer's evidence needs the same execute-don't-describe discipline as your own
|
|
2371
2378
|
claims"* was learned reviewing code and applies verbatim to medical sources. A filter would cut
|
|
@@ -2374,8 +2381,11 @@ for a hierarchical relative (`health` ↔ `health-research`) — and nothing is
|
|
|
2374
2381
|
count with `--domain` equals the hit count without it.
|
|
2375
2382
|
|
|
2376
2383
|
The bound matters: a domain tag is a hint about relevance, not evidence of it, so it breaks near-ties
|
|
2377
|
-
instead of overruling lexical ranking. And the note is honest in
|
|
2378
|
-
nothing matched,
|
|
2384
|
+
instead of overruling lexical ranking. And the note is honest in three directions — it says when
|
|
2385
|
+
nothing matched, it distinguishes *matched* from *actually moved*, and it counts what the `--limit`
|
|
2386
|
+
cut hid. That last one is the subtle part: the boost never drops a hit, but promoting a match into
|
|
2387
|
+
the top N does push the last one out of the printed list, so "nothing was dropped" would be true of
|
|
2388
|
+
the ranked list and false of the one you are reading. The note names the difference instead.
|
|
2379
2389
|
|
|
2380
2390
|
### Semantic recall (vector tier)
|
|
2381
2391
|
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8XH,2EAA2E;AAC3E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED,yFAAyF;AACzF,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KACvD;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8XH,2EAA2E;AAC3E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED,yFAAyF;AACzF,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KACvD;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA83O9E,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA8J5E"}
|
package/dist/cli.js
CHANGED
|
@@ -1848,6 +1848,14 @@ async function cmdRecall(options, flags, cwd, write) {
|
|
|
1848
1848
|
// never receive its promised lift — the feature was weakest in exactly the case it
|
|
1849
1849
|
// exists for (foreign-domain dilution pushing a relevant lesson just past the cut).
|
|
1850
1850
|
// Fetch a bounded surplus, re-rank, then trim to the limit the caller asked for.
|
|
1851
|
+
// EVERY value that reaches an output line goes through this, not just stored fields.
|
|
1852
|
+
// Round 5: `pattern` and `domain` were sanitised but the QUERY and the requested
|
|
1853
|
+
// domain were not, so a caller-supplied newline could still forge a line that looks
|
|
1854
|
+
// like the tool's own — including the boost note a peer reads as a capability probe.
|
|
1855
|
+
// The rule is "one line out per line of output", and it has to hold for every field.
|
|
1856
|
+
const oneLine = (v) => String(v).replace(/[\r\n\u2028\u2029\u0085\v\f]+/g, ' ⏎ ');
|
|
1857
|
+
const shownQuery = oneLine(query);
|
|
1858
|
+
const shownDomain = wantedDomain === undefined ? undefined : oneLine(wantedDomain);
|
|
1851
1859
|
const fetchLimit = wantedDomain !== undefined ? Math.min(limit * 3, limit + 20) : limit;
|
|
1852
1860
|
const result = await recallHybrid(projectRoot, query, { limit: fetchLimit, mode });
|
|
1853
1861
|
if (mode === 'semantic' && result.vectorEngine === 'none') {
|
|
@@ -1873,19 +1881,19 @@ async function cmdRecall(options, flags, cwd, write) {
|
|
|
1873
1881
|
return 0;
|
|
1874
1882
|
}
|
|
1875
1883
|
if (hits.length === 0) {
|
|
1876
|
-
write(`dz recall "${
|
|
1884
|
+
write(`dz recall "${shownQuery}"`);
|
|
1877
1885
|
write(` No matching patterns (teach some with \`dz teach\`, or consolidate sessions).`);
|
|
1878
1886
|
// The domain note must print here too (Codex QE #10): a --domain run with zero hits
|
|
1879
1887
|
// silently said nothing about the domain, so the reader could not tell whether the
|
|
1880
1888
|
// boost had been applied and found nothing, or had not run at all.
|
|
1881
|
-
if (boost !== null &&
|
|
1882
|
-
write(renderDomainBoostNote(boost,
|
|
1889
|
+
if (boost !== null && shownDomain !== undefined)
|
|
1890
|
+
write(renderDomainBoostNote(boost, shownDomain));
|
|
1883
1891
|
return 0;
|
|
1884
1892
|
}
|
|
1885
1893
|
const vectorOn = result.vectorEngine !== 'none' && result.vectorError === undefined && mode !== 'lexical';
|
|
1886
1894
|
const lexLabel = result.lexicalBackend === 'sqlite' ? 'SQLite FTS5' : 'keyword (JSON)';
|
|
1887
1895
|
const ranking = vectorOn ? `${lexLabel} + vector (${result.vectorEngine}) ranking` : `${lexLabel} ranking (lexical)`;
|
|
1888
|
-
write(`dz recall "${
|
|
1896
|
+
write(`dz recall "${shownQuery}" — ${hits.length} hit(s), ${ranking}`);
|
|
1889
1897
|
let sawQuarantined = false;
|
|
1890
1898
|
for (const h of hits) {
|
|
1891
1899
|
const backendTag = vectorOn ? ` ⟨${h.backend}⟩` : '';
|
|
@@ -1897,17 +1905,21 @@ async function cmdRecall(options, flags, cwd, write) {
|
|
|
1897
1905
|
// the domain-boost note that learning_bridge.py reads as a capability probe. Any
|
|
1898
1906
|
// consumer that parses this output line-wise has the same exposure, so the fix
|
|
1899
1907
|
// belongs at the point of rendering rather than in each reader.
|
|
1900
|
-
|
|
1901
|
-
|
|
1908
|
+
// Sanitise EVERY stored field that reaches the line, and every character a reader
|
|
1909
|
+
// might treat as a break — not just CR/LF. Round 4 forged the domain-boost note
|
|
1910
|
+
// twice over: once through `domain`, which was rendered raw, and once through a
|
|
1911
|
+
// U+2028 that Python's splitlines() honours and this replace did not.
|
|
1912
|
+
const shown = oneLine(h.pattern.pattern).slice(0, 80);
|
|
1913
|
+
write(` [${h.pattern.reward.toFixed(2)}] (${oneLine(h.pattern.domain)})${backendTag}${qTag} ${shown}`);
|
|
1902
1914
|
}
|
|
1903
1915
|
if (sawQuarantined) {
|
|
1904
1916
|
// The loop stays VISIBLE (ADR D2): a quarantined hit is shown, marked, and explained.
|
|
1905
1917
|
write(' ⚠q = quarantined (unproven hypothesis, rank damped) — confirm with dz teach --reinforce, or dz recall --promote <dzId> --apply');
|
|
1906
1918
|
}
|
|
1907
|
-
if (boost !== null &&
|
|
1919
|
+
if (boost !== null && shownDomain !== undefined) {
|
|
1908
1920
|
// Say what the boost did — INCLUDING when it did nothing. A silent reorder would
|
|
1909
1921
|
// let the reader believe the ranking was domain-aware when it had no match to work with.
|
|
1910
|
-
write(renderDomainBoostNote(boost,
|
|
1922
|
+
write(renderDomainBoostNote(boost, shownDomain));
|
|
1911
1923
|
const cutNote = renderDomainCutNote(displaced, limit);
|
|
1912
1924
|
if (cutNote !== '')
|
|
1913
1925
|
write(cutNote);
|