@aikdna/kdna-core 0.15.4 → 0.15.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.15.5 (2026-06-28)
4
+
5
+ Phase 12 audit follow-up. Closes 3 issues filed against this
6
+ repo (#145, #146, #147).
7
+
8
+ - **#145** The `compilePatterns` output for `misunderstanding`
9
+ cards was already preserved (the v1 round-trip fix in 0.15.4
10
+ carried `failure_risk` / `applies_when` / `does_not_apply_when`).
11
+ The audit confirmed the fix is in place. No code change required;
12
+ this entry documents the verification.
13
+ - **#146** `cardsFromV1Payload` (in the studio-cli consumer) now
14
+ infers a `type` for `payload.patterns` entries that omit it,
15
+ by inspecting the field set. Misunderstandings (which have
16
+ `wrong` + `correct`), terms (have `term` + `definition`),
17
+ banned terms, patterns, and aesthetics are now all picked up.
18
+ Truly unclassifiable entries are logged and skipped, never
19
+ silently dropped. The fix lives in the consumer
20
+ (`@aikdna/kdna-studio-cli` 0.8.6) rather than here.
21
+ - **#147** `buildSigningPayload` now excludes `build-receipt.json`
22
+ and any entry under `reports/`, matching `buildContentDigest`.
23
+ The prior omission meant a producer that signed with this code
24
+ and a verifier that digested with `buildContentDigest` would
25
+ compute two different byte strings and the signature would fail
26
+ to verify. The exclusion set is now a single source of truth.
27
+ `docs/CANONICALIZATION.md` updated to spell out the rule and
28
+ warn producers/verifiers that any new exclusion MUST be added
29
+ to both paths in the same change.
30
+
3
31
  ## v0.15.4 (2026-06-28)
4
32
 
5
33
  Audit follow-ups (2026-06-28 round-trip verification). This release
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikdna/kdna-core",
3
- "version": "0.15.4",
3
+ "version": "0.15.5",
4
4
  "description": "KDNA Core library for validating, planning, and loading local .kdna judgment assets.",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -235,9 +235,18 @@ function canonicalJsonEntry(entryName, entryBuf, options = {}) {
235
235
  }
236
236
 
237
237
  function buildSigningPayload(asset, options = {}) {
238
+ // Bug (#147): the prior version only excluded `.DS_Store` and
239
+ // `signature.json`, while `buildContentDigest` above also excludes
240
+ // `build-receipt.json` and any entry under `reports/`. A producer
241
+ // that signed with this code and a verifier that digested the
242
+ // asset with `buildContentDigest` would compute two different
243
+ // byte strings and the signature would fail to verify. The fix
244
+ // mirrors `buildContentDigest`'s exclusion set exactly.
238
245
  const parts = [];
239
246
  for (const entryName of [...asset.entries.keys()].sort()) {
240
247
  if (entryName === '.DS_Store' || entryName === 'signature.json') continue;
248
+ if (entryName === 'build-receipt.json') continue;
249
+ if (entryName.startsWith('reports/')) continue;
241
250
  const entryBuf = asset.readEntry(entryName);
242
251
  let payloadBuf = entryBuf;
243
252
  if (JSON_ENTRY_RE.test(entryName)) {
package/src/v1/index.js CHANGED
@@ -1540,11 +1540,25 @@ function renderPromptItem(item) {
1540
1540
  if (item.term && item.why) return `${item.term}: ${item.why}`;
1541
1541
  if (item.wrong && item.correct) return `${item.wrong} -> ${item.correct}`;
1542
1542
  if (item.mode && item.correct) return `${item.mode} -> ${item.correct}`;
1543
+ // Failure-mode entries from audit fixtures carry `mode` and `correct`
1544
+ // but may be one-sided (only `mode`, only `correct`, only `why`).
1545
+ // Fall through to a single-side render so the prompt never has
1546
+ // `(unrendered card: ...)` for a card that has at least one
1547
+ // populated judgment field. Bug (#61).
1548
+ if (item.mode) return `failure mode: ${item.mode}`;
1549
+ if (item.correct) return `correct: ${item.correct}`;
1550
+ if (item.key_distinction) return item.key_distinction;
1551
+ if (item.why) return `because: ${item.why}`;
1543
1552
  if (item.name && item.description) return `${item.name}: ${item.description}`;
1544
1553
  if (item.name) return item.name;
1545
1554
  if (item.one_sentence) return item.one_sentence;
1546
1555
  if (item.essence) return item.essence;
1547
1556
  if (item.question) return item.question;
1557
+ // Self-check entries are sometimes stored as plain strings, sometimes
1558
+ // as { question: "..." } objects, sometimes as { one_sentence: "..." }.
1559
+ // The buildPayload path emits `one_sentence` for self_check, so
1560
+ // try that before the last-resort fall-through. Bug (#61).
1561
+ if (item.text) return item.text;
1548
1562
  // Last-resort fall-through. Returning the id (e.g. "bo_xxxx-...") makes
1549
1563
  // the output unreadable; prefer a note that the card is unrecognized.
1550
1564
  return `(unrendered card: ${item.type || 'unknown'})`;