circle-ir-ai 2.35.0 → 2.37.0

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +176 -0
  2. package/dist/cache/backend.d.ts +39 -7
  3. package/dist/cache/backend.d.ts.map +1 -1
  4. package/dist/cache/backend.js +18 -6
  5. package/dist/cache/backend.js.map +1 -1
  6. package/dist/cache/backends/index.d.ts +12 -7
  7. package/dist/cache/backends/index.d.ts.map +1 -1
  8. package/dist/cache/backends/index.js +12 -7
  9. package/dist/cache/backends/index.js.map +1 -1
  10. package/dist/cache/backends/layout.d.ts +13 -4
  11. package/dist/cache/backends/layout.d.ts.map +1 -1
  12. package/dist/cache/backends/layout.js +20 -5
  13. package/dist/cache/backends/layout.js.map +1 -1
  14. package/dist/cache/backends/local-fs.d.ts +9 -5
  15. package/dist/cache/backends/local-fs.d.ts.map +1 -1
  16. package/dist/cache/backends/local-fs.js +9 -5
  17. package/dist/cache/backends/local-fs.js.map +1 -1
  18. package/dist/cache/backends/r2.d.ts +14 -9
  19. package/dist/cache/backends/r2.d.ts.map +1 -1
  20. package/dist/cache/backends/r2.js +14 -9
  21. package/dist/cache/backends/r2.js.map +1 -1
  22. package/dist/cache/classification-cache.d.ts +22 -4
  23. package/dist/cache/classification-cache.d.ts.map +1 -1
  24. package/dist/cache/classification-cache.js +32 -4
  25. package/dist/cache/classification-cache.js.map +1 -1
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/llm/ax-client.d.ts +24 -0
  31. package/dist/llm/ax-client.d.ts.map +1 -1
  32. package/dist/llm/ax-client.js +25 -0
  33. package/dist/llm/ax-client.js.map +1 -1
  34. package/dist/llm/discovery.d.ts +25 -0
  35. package/dist/llm/discovery.d.ts.map +1 -1
  36. package/dist/llm/discovery.js +13 -1
  37. package/dist/llm/discovery.js.map +1 -1
  38. package/dist/llm/index.d.ts +1 -0
  39. package/dist/llm/index.d.ts.map +1 -1
  40. package/dist/llm/index.js +2 -0
  41. package/dist/llm/index.js.map +1 -1
  42. package/dist/llm/llm-error-counter.d.ts +71 -0
  43. package/dist/llm/llm-error-counter.d.ts.map +1 -0
  44. package/dist/llm/llm-error-counter.js +109 -0
  45. package/dist/llm/llm-error-counter.js.map +1 -0
  46. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,182 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.37.0] - 2026-07-03
9
+
10
+ Real fix for the identical-65 pathology (`cognium-ai#191`) — surface
11
+ silent LLM-error swallow so a broken model deployment stops publishing
12
+ a score indistinguishable from static-only.
13
+
14
+ ### Motivation
15
+
16
+ The 2026-07-03 `zai-org/glm-5.2` and `minimax/minimax-m3` CWE-Bench-Java
17
+ runs both produced byte-identical 65/120 results with **zero**
18
+ `llm-discovery:` attribution markers. Cache Round 3 in 2.36.0 was
19
+ defense-in-depth against a *possible* second failure mode; this release
20
+ addresses the actual root cause:
21
+
22
+ `DiscoveryEngine.analyzeMethod`'s outer `catch` at
23
+ `src/llm/discovery.ts:549-569` returned a `DiscoveryResult` shape
24
+ identical to a legitimate "LLM said no vulnerability" answer. When
25
+ every LLM call failed — because the model endpoint 404'd on the exact
26
+ model tag the sweep passed — the benchmark output was
27
+ indistinguishable from a pure-static baseline. No stderr, no counter,
28
+ no banner, no attribution row.
29
+
30
+ ### Added — `DiscoveryResult.llmError` field (schema, additive)
31
+
32
+ `interface DiscoveryResult` gains an optional
33
+ `llmError?: { kind: DiscoveryErrorKind; message: string }` field
34
+ populated only in the catch path. Callers can now distinguish:
35
+
36
+ - Present-and-`vulnerabilityFound: false` = the LLM call failed;
37
+ the negative answer is a fallback, not a judgement.
38
+ - Absent-and-`vulnerabilityFound: false` = the LLM successfully
39
+ reported "no vulnerability found".
40
+
41
+ `DiscoveryErrorKind = LLMErrorCategory | 'unknown'` reuses the
42
+ categorical taxonomy `AxLLMClient._chatJSONImpl` already populates:
43
+ `empty_response | parse_error | timeout | http_error | rate_limited |
44
+ connection_error | transient_server_error | unknown`.
45
+
46
+ ### Added — `src/llm/llm-error-counter.ts` singleton
47
+
48
+ New process-wide `llmErrorCounter` (mirrors the existing
49
+ `llmCallLogger` pattern) with `increment(kind, sampleMessage?)`,
50
+ `snapshot()`, `total()`, and `reset()`. First `increment()` mirrors a
51
+ single stderr warning line so operators running a plain
52
+ `cognium-ai scan --llm` notice a broken config without opening the
53
+ JSONL log; subsequent errors are silent to avoid stderr flooding on
54
+ persistent outage.
55
+
56
+ Re-exported from `src/index.ts` for benchmark runners that need the
57
+ snapshot at end-of-run.
58
+
59
+ ### Added — `AxLLMClient.getLastErrorCategory()` public accessor
60
+
61
+ The existing private `lastErrorCategory: LLMErrorCategory | undefined`
62
+ field (set by `_chatJSONImpl` on failure, reset on entry) is now
63
+ readable via a public method. `DiscoveryEngine`'s catch path calls
64
+ this to categorize the failure before falling back to `'unknown'`.
65
+
66
+ ### Changed — `benchmarks/runners/run-cwe-bench-java.ts` banner
67
+
68
+ After the existing "LLM Call Statistics" block, the runner now reads
69
+ `llmErrorCounter.snapshot()` and prints a "Discovery-stage LLM Errors"
70
+ block when any errors are counted. When the failure rate exceeds 10%,
71
+ the block is prefixed with `⚠ HIGH FAILURE RATE` and appended with
72
+ three operator-guidance lines pointing at `LLM_BASE_URL` / `LLM_API_KEY`
73
+ / model availability plus a `LLM_LOG_JSONL=<path>` re-run hint.
74
+
75
+ The `llmStats` local counter continues to track the runner's direct
76
+ `batchFileDiscovery` fetches; the new banner covers the
77
+ `DiscoveryEngine.discoverVulnerabilities` code path that flows through
78
+ `AxLLMClient.chatJSON` and was previously invisible.
79
+
80
+ ### Changed — `cognium-ai/scripts/analyze-llm-log.ts` errorCategory support
81
+
82
+ `LogEntry` gains `errorCategory?: string`, and the analyzer prints an
83
+ "Error categories (cognium-ai#191)" section before the existing
84
+ "Error types (top 10)" free-form breakdown. Categorical rows are
85
+ comparable across models/providers; the raw-message table stays for
86
+ the tail of long-form messages that don't fit a category yet.
87
+
88
+ ### Rollback
89
+
90
+ Setting `llmError` to `undefined` on every catch-path result restores
91
+ the pre-2.37 shape. The counter and banner are additive; leaving them
92
+ in place with no callers is harmless. No cache invalidation.
93
+
94
+ ### Testing
95
+
96
+ `tests/llm-error-counter.test.ts` covers snapshot zero-defaults,
97
+ increment counts, first-warning stderr latch, reset semantics,
98
+ `'unknown'` fallback, and sample-message trimming.
99
+
100
+ ## [2.36.0] - 2026-07-03
101
+
102
+ Cache Round 3 (`cognium-ai#189`) — model-in-path defense-in-depth.
103
+ Motivated by the 2026-07-03 `zai-org/glm-5.2` and `minimax/minimax-m3`
104
+ CWE-Bench-Java runs, which both produced byte-identical 65/120
105
+ results with **zero** `llm-discovery:` attribution markers in either
106
+ log. Investigation confirmed the real root cause is a silent LLM-
107
+ error swallow in `src/llm/discovery.ts:524-531` (returns
108
+ `{vulnerabilityFound: false}` for any exception → LLM failures show
109
+ up as "no vulnerability found"). The cache-key composition IS
110
+ correctly model-fingerprinted, so this patch does NOT fix the
111
+ identical-result bug — it makes future model-cross-contamination
112
+ visible in R2 dashboards and impossible under a targeted `s3 rm`.
113
+
114
+ ### Changed — R2/local-fs layout: `<model-slug>` path segment
115
+
116
+ `CacheKey` gains a new optional `modelSlug?: string` field
117
+ (`src/cache/backend.ts`). `renderObjectPath()` in
118
+ `src/cache/backends/layout.ts` injects the slug between the
119
+ namespace root and the sharded digest for the three model-dependent
120
+ namespaces:
121
+
122
+ ```
123
+ verify/<model-slug>/<4hex>/<sha>.json (was: verify/<4hex>/<sha>.json)
124
+ discovery/<model-slug>/<4hex>/<sha>.json (was: discovery/<4hex>/<sha>.json)
125
+ classifier/<model-slug>/<4hex>/<sha>.json (was: classifier/<4hex>/<sha>.json)
126
+ ```
127
+
128
+ `tree/` and `cluster/` layouts are unchanged (both are model-
129
+ independent). When `modelSlug` is empty (no LLM configured, e.g.
130
+ pure-static scans), the flat 2.28.x path shape is preserved for
131
+ back-compat.
132
+
133
+ `ClassificationCache.toCacheKey()` populates `modelSlug` from the
134
+ per-phase `modelFingerprint` (already threaded through since
135
+ 2.28.0/`cognium-ai#151`) sanitized via the new exported helper
136
+ `sanitizeModelSlug()` (replaces `=` with `-` so
137
+ `disc=zai-org_glm-5.2` renders as `disc-zai-org_glm-5.2`).
138
+
139
+ ### Changed — SCHEMA_VER bumped `cic:v2` → `cic:v3`
140
+
141
+ All warm entries under both local-fs and R2 backends are invalidated
142
+ so operators re-populate under the Round-3 layout. Rollback path:
143
+ downgrade to `2.35.x` and old entries still miss (their `cic:v2`
144
+ envelope fails the `isValid()` schema check under the new version;
145
+ new writes go under `cic:v2` again). No breaking API change.
146
+
147
+ ### Rationale
148
+
149
+ Even though the digest composition already folds
150
+ `modelFingerprint` into the SHA-256 (so `verify=opus` and
151
+ `verify=gpt-4o-mini` land in different files), the flat 2.28.x
152
+ layout made model-cross-contamination invisible in the R2 dashboard.
153
+ Round 3 surfaces the model dimension as a top-level segment so:
154
+
155
+ 1. Operators see per-model cache footprint at a glance.
156
+ 2. Per-model eviction is a single `s3 rm --recursive s3://cognium-cache/v2/discovery/disc-gemma3-12b/`.
157
+ 3. Future digest-composition regressions (e.g. a stray refactor that
158
+ drops `modelFingerprint` from `computeDigest`) become visible as
159
+ an entry hitting under the wrong model prefix.
160
+
161
+ ### Tests
162
+
163
+ - `tests/cache-model-in-path.test.ts` — 12 new tests covering the
164
+ layout renderer, `sanitizeModelSlug`, `ClassificationCache`
165
+ round-trip under two different discovery models, tree/cluster
166
+ slug-independence, and the empty-fingerprint back-compat path.
167
+ - `tests/cache-key-shape.test.ts` — SCHEMA_VER assertion updated to
168
+ `'cic:v3'`.
169
+
170
+ Full suite: 1340 pass + 3 skipped (was 1328 + 3), typecheck clean.
171
+
172
+ ### Follow-up (out of scope for this release)
173
+
174
+ The silent LLM-error swallow at `src/llm/discovery.ts:524-531` is
175
+ the actual root cause of the "identical 65/120" observation from
176
+ the glm-5.2 + minimax-m3 runs. A separate ticket should:
177
+
178
+ - Surface LLM errors on the runner side (bubble up rate rather than
179
+ return fake `{vulnerabilityFound: false}`)
180
+ - Add a `llm.failureCount` metric to the CWE-Bench-Java runner's
181
+ summary output so a run that lost 100% of LLM calls doesn't look
182
+ like a legitimate static-baseline number.
183
+
8
184
  ## [2.35.0] - 2026-07-03
9
185
 
10
186
  Sprint P2 Batch 4 — wide precision pass. Three shipping tickets
@@ -12,22 +12,34 @@
12
12
  * fingerprint composition stays in `ClassificationCache` so a backend
13
13
  * swap doesn't change observable cache semantics.
14
14
  *
15
- * # CacheKey shape (Round 2 — 2.28.0)
15
+ * # CacheKey shape (Round 3 — 2.36.0, cognium-ai#189)
16
16
  *
17
17
  * The Round-1 interface (`get(key: string)`) wasn't enough to express
18
18
  * the per-namespace package-coordinate layout the R2 backend needs to
19
19
  * surface in dashboards. We now pass a structured `{ namespace, digest,
20
- * coordinate? }` so backends can render the path however they want:
20
+ * coordinate?, modelSlug? }` so backends can render the path however
21
+ * they want:
21
22
  *
22
- * tree → `<prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord present)
23
- * → `<prefix>/tree/_unowned/<2hex>/<sha>.json` (no coord)
24
- * verify → `<prefix>/verify/<2hex>/<sha>.json` (always flat)
25
- * discovery → `<prefix>/discovery/<2hex>/<sha>.json` (always flat)
23
+ * tree → `<prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord)
24
+ * → `<prefix>/tree/_unowned/<4hex>/<sha>.json` (no coord)
25
+ * verify → `<prefix>/verify/<model-slug>/<4hex>/<sha>.json` (slug present)
26
+ * → `<prefix>/verify/<4hex>/<sha>.json` (no slug)
27
+ * discovery → `<prefix>/discovery/<model-slug>/<4hex>/<sha>.json` (slug present)
28
+ * → `<prefix>/discovery/<4hex>/<sha>.json` (no slug)
29
+ * classifier → analogous to verify/discovery
30
+ * cluster → `<prefix>/cluster/<4hex>/<sha>.json` (model-independent)
26
31
  *
27
32
  * Coordinate is intentionally tree-only: discovery and verify are
28
33
  * keyed on method/batch content + model fingerprint, which already
29
34
  * collide-correctly across packages without a coordinate prefix.
30
35
  *
36
+ * `modelSlug` is intentionally non-tree: the tree cache is pattern-
37
+ * match (SAST) output that doesn't depend on any LLM. Splitting it by
38
+ * model would just fragment the cache. verify/discovery/classifier
39
+ * results are model-dependent and MUST NOT be shared between different
40
+ * discovery/verify models — a defense-in-depth against the digest-
41
+ * composition regressions that motivated Round 3 (cognium-ai#189).
42
+ *
31
43
  * Selection: `LLM_CACHE_BACKEND` env (`local` | `memory` | `r2`).
32
44
  * Default = `local` (back-compat). See `./backends/index.ts` factory.
33
45
  */
@@ -66,9 +78,29 @@ export interface CacheKey {
66
78
  /**
67
79
  * Optional package coordinate. Only consulted by tree-namespace keys;
68
80
  * verify/discovery backends ignore it. When absent or `_unowned`,
69
- * tree falls back to `_unowned/<2hex>/<sha>` layout.
81
+ * tree falls back to `_unowned/<4hex>/<sha>` layout.
70
82
  */
71
83
  coordinate?: PackageCoordinate;
84
+ /**
85
+ * Optional filesystem/URL-safe model identity for the cache path
86
+ * (cognium-ai#189, Round 3). Only consulted by non-tree namespaces
87
+ * (verify / discovery / classifier). When present, injected between
88
+ * the namespace root and the sharded digest:
89
+ * `<namespace>/<modelSlug>/<4hex>/<sha>.json`
90
+ * When absent (unset in the caller or empty string), the layout is
91
+ * flat `<namespace>/<4hex>/<sha>.json` (2.28.x back-compat).
92
+ *
93
+ * Motivation: even though `digest` is already model-fingerprinted
94
+ * (see classification-cache.ts `computeDigest`), surfacing the model
95
+ * segment in the path makes model-cross-contamination visible in R2
96
+ * dashboards, protects against future digest-composition regressions,
97
+ * and makes per-model cache eviction a `s3 rm` on a single prefix.
98
+ *
99
+ * Populated by `ClassificationCache.toCacheKey()` from the per-phase
100
+ * `modelFingerprint` (which is the same value already folded into the
101
+ * digest). MUST be URL/path-safe: the caller sanitizes `=` → `-`.
102
+ */
103
+ modelSlug?: string;
72
104
  }
73
105
  export interface CacheBackend {
74
106
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/cache/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,SAAS,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE3C;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,4EAA4E;IAC5E,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC,6DAA6D;IAC7D,MAAM,CAAC,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;;OAIG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1B;;;OAGG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB"}
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/cache/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,SAAS,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE3C;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,4EAA4E;IAC5E,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC,6DAA6D;IAC7D,MAAM,CAAC,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;;OAIG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1B;;;OAGG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB"}
@@ -12,22 +12,34 @@
12
12
  * fingerprint composition stays in `ClassificationCache` so a backend
13
13
  * swap doesn't change observable cache semantics.
14
14
  *
15
- * # CacheKey shape (Round 2 — 2.28.0)
15
+ * # CacheKey shape (Round 3 — 2.36.0, cognium-ai#189)
16
16
  *
17
17
  * The Round-1 interface (`get(key: string)`) wasn't enough to express
18
18
  * the per-namespace package-coordinate layout the R2 backend needs to
19
19
  * surface in dashboards. We now pass a structured `{ namespace, digest,
20
- * coordinate? }` so backends can render the path however they want:
20
+ * coordinate?, modelSlug? }` so backends can render the path however
21
+ * they want:
21
22
  *
22
- * tree → `<prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord present)
23
- * → `<prefix>/tree/_unowned/<2hex>/<sha>.json` (no coord)
24
- * verify → `<prefix>/verify/<2hex>/<sha>.json` (always flat)
25
- * discovery → `<prefix>/discovery/<2hex>/<sha>.json` (always flat)
23
+ * tree → `<prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord)
24
+ * → `<prefix>/tree/_unowned/<4hex>/<sha>.json` (no coord)
25
+ * verify → `<prefix>/verify/<model-slug>/<4hex>/<sha>.json` (slug present)
26
+ * → `<prefix>/verify/<4hex>/<sha>.json` (no slug)
27
+ * discovery → `<prefix>/discovery/<model-slug>/<4hex>/<sha>.json` (slug present)
28
+ * → `<prefix>/discovery/<4hex>/<sha>.json` (no slug)
29
+ * classifier → analogous to verify/discovery
30
+ * cluster → `<prefix>/cluster/<4hex>/<sha>.json` (model-independent)
26
31
  *
27
32
  * Coordinate is intentionally tree-only: discovery and verify are
28
33
  * keyed on method/batch content + model fingerprint, which already
29
34
  * collide-correctly across packages without a coordinate prefix.
30
35
  *
36
+ * `modelSlug` is intentionally non-tree: the tree cache is pattern-
37
+ * match (SAST) output that doesn't depend on any LLM. Splitting it by
38
+ * model would just fragment the cache. verify/discovery/classifier
39
+ * results are model-dependent and MUST NOT be shared between different
40
+ * discovery/verify models — a defense-in-depth against the digest-
41
+ * composition regressions that motivated Round 3 (cognium-ai#189).
42
+ *
31
43
  * Selection: `LLM_CACHE_BACKEND` env (`local` | `memory` | `r2`).
32
44
  * Default = `local` (back-compat). See `./backends/index.ts` factory.
33
45
  */
@@ -1 +1 @@
1
- {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/cache/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG"}
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/cache/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG"}
@@ -11,14 +11,19 @@
11
11
  * the backend, the structured `CacheKey` is rendered to a path via
12
12
  * `renderObjectPath()`:
13
13
  *
14
- * tree+coord → `<eco>/<name>@<ver>/<4hex>/<sha>.json`
15
- * tree+nocoord → `_unowned/<2hex>/<sha>.json`
16
- * verify → `<2hex>/<sha>.json`
17
- * discovery → `<2hex>/<sha>.json`
14
+ * tree+coord → `<eco>/<name>@<ver>/<4hex>/<sha>.json`
15
+ * tree+nocoord → `_unowned/<4hex>/<sha>.json`
16
+ * verify+slug → `<model-slug>/<4hex>/<sha>.json`
17
+ * verify+no slug → `<4hex>/<sha>.json`
18
+ * discovery+slug → `<model-slug>/<4hex>/<sha>.json`
19
+ * discovery+no slug → `<4hex>/<sha>.json`
20
+ * classifier+slug → `<model-slug>/<4hex>/<sha>.json`
21
+ * cluster (flat) → `<4hex>/<sha>.json`
18
22
  *
19
- * `R2_PREFIX` default bumped `v1` `v2` for the Round 2 layout. Operators
20
- * who want the old keys back can pin `R2_PREFIX=v1` (the 2.27.0 layout is
21
- * read-only at that prefix; new writes use `v2`).
23
+ * `R2_PREFIX` default kept at `v2` for the Round 3 layout. The path-
24
+ * shape change is additive flat 2.28.x entries stay readable, they
25
+ * just miss against Round-3 writes because `SCHEMA_VER` bumped v2→v3.
26
+ * Operators who want the pre-2.28 keys back can pin `R2_PREFIX=v1`.
22
27
  */
23
28
  import type { CacheBackend, CacheNamespace } from '../backend.js';
24
29
  import { LocalFSBackend } from './local-fs.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpD,wBAAgB,cAAc,IAAI,OAAO,GAAG,QAAQ,GAAG,IAAI,CAK1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,GAAG,YAAY,CAoCrF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpD,wBAAgB,cAAc,IAAI,OAAO,GAAG,QAAQ,GAAG,IAAI,CAK1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,GAAG,YAAY,CAoCrF"}
@@ -11,14 +11,19 @@
11
11
  * the backend, the structured `CacheKey` is rendered to a path via
12
12
  * `renderObjectPath()`:
13
13
  *
14
- * tree+coord → `<eco>/<name>@<ver>/<4hex>/<sha>.json`
15
- * tree+nocoord → `_unowned/<2hex>/<sha>.json`
16
- * verify → `<2hex>/<sha>.json`
17
- * discovery → `<2hex>/<sha>.json`
14
+ * tree+coord → `<eco>/<name>@<ver>/<4hex>/<sha>.json`
15
+ * tree+nocoord → `_unowned/<4hex>/<sha>.json`
16
+ * verify+slug → `<model-slug>/<4hex>/<sha>.json`
17
+ * verify+no slug → `<4hex>/<sha>.json`
18
+ * discovery+slug → `<model-slug>/<4hex>/<sha>.json`
19
+ * discovery+no slug → `<4hex>/<sha>.json`
20
+ * classifier+slug → `<model-slug>/<4hex>/<sha>.json`
21
+ * cluster (flat) → `<4hex>/<sha>.json`
18
22
  *
19
- * `R2_PREFIX` default bumped `v1` `v2` for the Round 2 layout. Operators
20
- * who want the old keys back can pin `R2_PREFIX=v1` (the 2.27.0 layout is
21
- * read-only at that prefix; new writes use `v2`).
23
+ * `R2_PREFIX` default kept at `v2` for the Round 3 layout. The path-
24
+ * shape change is additive flat 2.28.x entries stay readable, they
25
+ * just miss against Round-3 writes because `SCHEMA_VER` bumped v2→v3.
26
+ * Operators who want the pre-2.28 keys back can pin `R2_PREFIX=v1`.
22
27
  */
23
28
  import * as path from 'path';
24
29
  import { LocalFSBackend } from './local-fs.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cache/backends/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpD,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACvE,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACtC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,SAAyB;IACrE,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,aAAa,EAAE,CAAC;IAElD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACzC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QACrC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACjD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;QACzD,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe,EAAE,CAAC;YAC7D,uDAAuD;YACvD,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,6DAA6D;gBAC7D,wDAAwD;gBACxD,yCAAyC,CAC1C,CAAC;YACF,OAAO,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC7E,OAAO,IAAI,SAAS,CAAC;YACnB,QAAQ;YACR,MAAM;YACN,WAAW;YACX,eAAe;YACf,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;YACvC,MAAM,EAAE,GAAG,UAAU,IAAI,SAAS,EAAE;SACrC,CAAC,CAAC;IACL,CAAC;IAED,oEAAoE;IACpE,+DAA+D;IAC/D,mCAAmC;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC9E,OAAO,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cache/backends/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpD,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACvE,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACtC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,SAAyB;IACrE,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,aAAa,EAAE,CAAC;IAElD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACzC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QACrC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACjD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;QACzD,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe,EAAE,CAAC;YAC7D,uDAAuD;YACvD,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,6DAA6D;gBAC7D,wDAAwD;gBACxD,yCAAyC,CAC1C,CAAC;YACF,OAAO,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC7E,OAAO,IAAI,SAAS,CAAC;YACnB,QAAQ;YACR,MAAM;YACN,WAAW;YACX,eAAe;YACf,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;YACvC,MAAM,EAAE,GAAG,UAAU,IAAI,SAAS,EAAE;SACrC,CAAC,CAAC;IACL,CAAC;IAED,oEAAoE;IACpE,+DAA+D;IAC/D,mCAAmC;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC9E,OAAO,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAClD,CAAC"}
@@ -6,10 +6,19 @@
6
6
  * backend at a `<prefix>/<namespace>/` path, so the resulting full key
7
7
  * is:
8
8
  *
9
- * tree → `<root>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord)
10
- * → `<root>/tree/_unowned/<4hex>/<sha>.json` (fallback)
11
- * verify → `<root>/verify/<4hex>/<sha>.json`
12
- * discovery → `<root>/discovery/<4hex>/<sha>.json`
9
+ * tree → `<root>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord)
10
+ * → `<root>/tree/_unowned/<4hex>/<sha>.json` (fallback)
11
+ * verify → `<root>/verify/<model-slug>/<4hex>/<sha>.json` (slug)
12
+ * → `<root>/verify/<4hex>/<sha>.json` (no slug)
13
+ * discovery → `<root>/discovery/<model-slug>/<4hex>/<sha>.json` (slug)
14
+ * → `<root>/discovery/<4hex>/<sha>.json` (no slug)
15
+ * classifier → analogous to verify/discovery
16
+ * cluster → `<root>/cluster/<4hex>/<sha>.json` (flat)
17
+ *
18
+ * Round 3 (2.36.0, cognium-ai#189) added the `<model-slug>` segment
19
+ * for the three model-dependent namespaces so per-model cache
20
+ * partitioning is visible in R2 dashboards. `tree` and `cluster` stay
21
+ * flat because their content is model-independent.
13
22
  *
14
23
  * All four namespaces use a 4-hex (65 536) shard prefix. Rationale:
15
24
  *
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CActD"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAoBtD"}
@@ -6,10 +6,19 @@
6
6
  * backend at a `<prefix>/<namespace>/` path, so the resulting full key
7
7
  * is:
8
8
  *
9
- * tree → `<root>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord)
10
- * → `<root>/tree/_unowned/<4hex>/<sha>.json` (fallback)
11
- * verify → `<root>/verify/<4hex>/<sha>.json`
12
- * discovery → `<root>/discovery/<4hex>/<sha>.json`
9
+ * tree → `<root>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json` (coord)
10
+ * → `<root>/tree/_unowned/<4hex>/<sha>.json` (fallback)
11
+ * verify → `<root>/verify/<model-slug>/<4hex>/<sha>.json` (slug)
12
+ * → `<root>/verify/<4hex>/<sha>.json` (no slug)
13
+ * discovery → `<root>/discovery/<model-slug>/<4hex>/<sha>.json` (slug)
14
+ * → `<root>/discovery/<4hex>/<sha>.json` (no slug)
15
+ * classifier → analogous to verify/discovery
16
+ * cluster → `<root>/cluster/<4hex>/<sha>.json` (flat)
17
+ *
18
+ * Round 3 (2.36.0, cognium-ai#189) added the `<model-slug>` segment
19
+ * for the three model-dependent namespaces so per-model cache
20
+ * partitioning is visible in R2 dashboards. `tree` and `cluster` stay
21
+ * flat because their content is model-independent.
13
22
  *
14
23
  * All four namespaces use a 4-hex (65 536) shard prefix. Rationale:
15
24
  *
@@ -40,7 +49,13 @@ export function renderObjectPath(key) {
40
49
  }
41
50
  return `_unowned/${shard}/${sha}.json`;
42
51
  }
43
- // verify / discovery / classifier / cluster flat with same 4-hex shard.
52
+ // verify / discovery / classifier — inject `<model-slug>/` when the
53
+ // caller populated it (Round 3, cognium-ai#189). Falls through to
54
+ // the 2.28.x flat layout when the slug is absent so callers with no
55
+ // model configured (or the cluster namespace) get unchanged paths.
56
+ if (key.modelSlug) {
57
+ return `${key.modelSlug}/${shard}/${sha}.json`;
58
+ }
44
59
  return `${shard}/${sha}.json`;
45
60
  }
46
61
  //# sourceMappingURL=layout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/cache/backends/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,gFAAgF;AAChF,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,MAAM,UAAU,gBAAgB,CAAC,GAAa;IAC5C,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACvB,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAC9C,IAAI,GAAG,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC;QAC7B,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;YAC5C,MAAM,EAAE,WAAW,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAClD,OAAO,GAAG,WAAW,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC;QAC/C,CAAC;QACD,OAAO,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC;IACzC,CAAC;IAED,0EAA0E;IAC1E,OAAO,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/cache/backends/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,gFAAgF;AAChF,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,MAAM,UAAU,gBAAgB,CAAC,GAAa;IAC5C,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACvB,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAC9C,IAAI,GAAG,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC;QAC7B,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;YAC5C,MAAM,EAAE,WAAW,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAClD,OAAO,GAAG,WAAW,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC;QAC/C,CAAC;QACD,OAAO,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC;IACzC,CAAC;IAED,oEAAoE;IACpE,kEAAkE;IAClE,oEAAoE;IACpE,mEAAmE;IACnE,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,GAAG,GAAG,CAAC,SAAS,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC;IACjD,CAAC;IACD,OAAO,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC;AAChC,CAAC"}
@@ -1,12 +1,16 @@
1
1
  /**
2
2
  * Local filesystem cache backend (cognium-ai#158).
3
3
  *
4
- * Round 2 (2.28.0) layout (translated to platform path-sep):
4
+ * Round 3 (2.36.0, cognium-ai#189) layout (translated to platform path-sep):
5
5
  *
6
- * <cacheDir>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord)
7
- * <cacheDir>/tree/_unowned/<2hex>/<sha>.json (fallback)
8
- * <cacheDir>/verify/<2hex>/<sha>.json
9
- * <cacheDir>/discovery/<2hex>/<sha>.json
6
+ * <cacheDir>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord)
7
+ * <cacheDir>/tree/_unowned/<4hex>/<sha>.json (fallback)
8
+ * <cacheDir>/verify/<model-slug>/<4hex>/<sha>.json (slug)
9
+ * <cacheDir>/verify/<4hex>/<sha>.json (no slug)
10
+ * <cacheDir>/discovery/<model-slug>/<4hex>/<sha>.json (slug)
11
+ * <cacheDir>/discovery/<4hex>/<sha>.json (no slug)
12
+ * <cacheDir>/classifier/<model-slug>/<4hex>/<sha>.json (slug)
13
+ * <cacheDir>/cluster/<4hex>/<sha>.json (flat)
10
14
  *
11
15
  * Atomic write via tmp + rename so concurrent `cognium-ai scan`
12
16
  * processes don't corrupt each other's entries.
@@ -1 +1 @@
1
- {"version":3,"file":"local-fs.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/local-fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG5D,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,YAAW,YAAY;IACjD,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,QAAQ,CAAS;gBAEb,IAAI,EAAE,qBAAqB;IAKvC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,SAAS;IAMX,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAU1C,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAehD,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpC,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASpC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAsBxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
1
+ {"version":3,"file":"local-fs.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/local-fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG5D,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,YAAW,YAAY;IACjD,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,QAAQ,CAAS;gBAEb,IAAI,EAAE,qBAAqB;IAKvC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,SAAS;IAMX,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAU1C,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAehD,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpC,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IASpC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAsBxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
@@ -1,12 +1,16 @@
1
1
  /**
2
2
  * Local filesystem cache backend (cognium-ai#158).
3
3
  *
4
- * Round 2 (2.28.0) layout (translated to platform path-sep):
4
+ * Round 3 (2.36.0, cognium-ai#189) layout (translated to platform path-sep):
5
5
  *
6
- * <cacheDir>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord)
7
- * <cacheDir>/tree/_unowned/<2hex>/<sha>.json (fallback)
8
- * <cacheDir>/verify/<2hex>/<sha>.json
9
- * <cacheDir>/discovery/<2hex>/<sha>.json
6
+ * <cacheDir>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord)
7
+ * <cacheDir>/tree/_unowned/<4hex>/<sha>.json (fallback)
8
+ * <cacheDir>/verify/<model-slug>/<4hex>/<sha>.json (slug)
9
+ * <cacheDir>/verify/<4hex>/<sha>.json (no slug)
10
+ * <cacheDir>/discovery/<model-slug>/<4hex>/<sha>.json (slug)
11
+ * <cacheDir>/discovery/<4hex>/<sha>.json (no slug)
12
+ * <cacheDir>/classifier/<model-slug>/<4hex>/<sha>.json (slug)
13
+ * <cacheDir>/cluster/<4hex>/<sha>.json (flat)
10
14
  *
11
15
  * Atomic write via tmp + rename so concurrent `cognium-ai scan`
12
16
  * processes don't corrupt each other's entries.
@@ -1 +1 @@
1
- {"version":3,"file":"local-fs.js","sourceRoot":"","sources":["../../../src/cache/backends/local-fs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-fs.js","sourceRoot":"","sources":["../../../src/cache/backends/local-fs.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,22 @@
1
1
  /**
2
2
  * Cloudflare R2 (S3-compatible) cache backend (cognium-ai#158).
3
3
  *
4
- * Round 2 (2.28.0) layout:
4
+ * Round 3 (2.36.0, cognium-ai#189) layout:
5
5
  *
6
- * <prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord present)
7
- * <prefix>/tree/_unowned/<2hex>/<sha>.json (no coord)
8
- * <prefix>/verify/<2hex>/<sha>.json (flat)
9
- * <prefix>/discovery/<2hex>/<sha>.json (flat)
6
+ * <prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord present)
7
+ * <prefix>/tree/_unowned/<4hex>/<sha>.json (no coord)
8
+ * <prefix>/verify/<model-slug>/<4hex>/<sha>.json (slug present)
9
+ * <prefix>/verify/<4hex>/<sha>.json (no slug)
10
+ * <prefix>/discovery/<model-slug>/<4hex>/<sha>.json (slug present)
11
+ * <prefix>/discovery/<4hex>/<sha>.json (no slug)
12
+ * <prefix>/classifier/<model-slug>/<4hex>/<sha>.json (slug present)
13
+ * <prefix>/cluster/<4hex>/<sha>.json (flat; model-indep.)
10
14
  *
11
- * The coordinate is only consulted for tree-namespace keys; verify and
12
- * discovery stay flat because their content already encodes the model
13
- * fingerprint + per-batch fingerprint, so a coordinate prefix would
14
- * just bloat the path.
15
+ * The coordinate is only consulted for tree-namespace keys; verify /
16
+ * discovery / classifier stay coordinate-free because their content
17
+ * already encodes the model fingerprint + per-batch fingerprint. The
18
+ * `<model-slug>` segment (Round 3) surfaces the per-phase model
19
+ * identity in the R2 dashboard so cross-model contamination is visible.
15
20
  *
16
21
  * Configuration (env vars):
17
22
  * LLM_CACHE_BACKEND=r2
@@ -1 +1 @@
1
- {"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/r2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,SAAU,YAAW,YAAY;IAC5C,QAAQ,CAAC,IAAI,QAAQ;IACrB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,gBAAgB;IAelC,OAAO,CAAC,SAAS;IAIX,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAwB1C,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhD,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBpC,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAmB3C"}
1
+ {"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../../../src/cache/backends/r2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,SAAU,YAAW,YAAY;IAC5C,QAAQ,CAAC,IAAI,QAAQ;IACrB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,IAAI,EAAE,gBAAgB;IAelC,OAAO,CAAC,SAAS;IAIX,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAwB1C,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhD,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBpC,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAmB3C"}
@@ -1,17 +1,22 @@
1
1
  /**
2
2
  * Cloudflare R2 (S3-compatible) cache backend (cognium-ai#158).
3
3
  *
4
- * Round 2 (2.28.0) layout:
4
+ * Round 3 (2.36.0, cognium-ai#189) layout:
5
5
  *
6
- * <prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord present)
7
- * <prefix>/tree/_unowned/<2hex>/<sha>.json (no coord)
8
- * <prefix>/verify/<2hex>/<sha>.json (flat)
9
- * <prefix>/discovery/<2hex>/<sha>.json (flat)
6
+ * <prefix>/tree/<eco>/<name>@<ver>/<4hex>/<sha>.json (coord present)
7
+ * <prefix>/tree/_unowned/<4hex>/<sha>.json (no coord)
8
+ * <prefix>/verify/<model-slug>/<4hex>/<sha>.json (slug present)
9
+ * <prefix>/verify/<4hex>/<sha>.json (no slug)
10
+ * <prefix>/discovery/<model-slug>/<4hex>/<sha>.json (slug present)
11
+ * <prefix>/discovery/<4hex>/<sha>.json (no slug)
12
+ * <prefix>/classifier/<model-slug>/<4hex>/<sha>.json (slug present)
13
+ * <prefix>/cluster/<4hex>/<sha>.json (flat; model-indep.)
10
14
  *
11
- * The coordinate is only consulted for tree-namespace keys; verify and
12
- * discovery stay flat because their content already encodes the model
13
- * fingerprint + per-batch fingerprint, so a coordinate prefix would
14
- * just bloat the path.
15
+ * The coordinate is only consulted for tree-namespace keys; verify /
16
+ * discovery / classifier stay coordinate-free because their content
17
+ * already encodes the model fingerprint + per-batch fingerprint. The
18
+ * `<model-slug>` segment (Round 3) surfaces the per-phase model
19
+ * identity in the R2 dashboard so cross-model contamination is visible.
15
20
  *
16
21
  * Configuration (env vars):
17
22
  * LLM_CACHE_BACKEND=r2