@aikdna/kdna-core 0.20.0 → 0.21.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ - Validate decrypted external-grant and password payload plaintext against the
6
+ same declared Payload schema used for ordinary assets. Correct credentials
7
+ can no longer load schema-invalid judgment bytes.
8
+ - Close `core_structure` relation objects to the existing public relation
9
+ fields and project only that allowlist in compact Runtime Capsules, blocking
10
+ private Creation state hidden in arbitrary relation properties.
11
+ - Make the external-grant conformance golden carry one deterministic, actual
12
+ encrypted `.kdna` byte snapshot. The regression now checks the exact package
13
+ digest, Core validation, signed authorization, LoadPlan and authorized load
14
+ against that same artifact instead of deriving grant identity from
15
+ zlib-dependent repacking.
16
+ - Warn with `KDNA_DISPATCHER_DEGRADED` when the container dispatcher fails to
17
+ load for any reason other than the dispatcher file itself being absent,
18
+ instead of silently degrading to the legacy reader. The absence check now
19
+ resolves the dispatcher path up front, so a present dispatcher with a
20
+ missing internal dependency, a syntax or initialization error, or a
21
+ permission error is reported instead of being mistaken for a missing
22
+ module.
23
+ - Fail closed on hostile Argon2id parameters in untrusted password envelopes:
24
+ `memory_kib`, `iterations`, and `parallelism` must be integers within
25
+ defensive bounds (256 MiB / 16 / 8), removing a remote denial-of-service
26
+ path when loading third-party protected assets.
27
+
28
+ ## 0.21.0 (2026-07-20)
29
+
30
+ ### Changed
31
+
32
+ - Keep `planLoad` fail-closed for password-protected assets until the supplied
33
+ credential is actually verified by `load`; a mere password-present signal
34
+ no longer reports `ready` or `can_load_now: true`.
35
+ - Require at least one non-empty, author-neutral judgment unit and explicit
36
+ scope or boundary semantics while keeping optional creator provenance
37
+ separate from format validity.
38
+ - Preserve every declared pattern in compact projection instead of silently
39
+ applying a prefix budget.
40
+ - Report every non-empty payload path intentionally omitted by compact
41
+ projection, including deterministic counts, in Runtime Capsule trace and
42
+ prompt output; preserve complete axiom applicability lists and stop trimming
43
+ a full-statement fallback.
44
+ - Make `checksums.json` optional under one container authority and verify it
45
+ whenever it is present.
46
+ - Withdraw asset-signature containers from the Development Preview contract;
47
+ malformed or legacy signature declarations now fail closed. External grants
48
+ and Human Lock provenance remain separate responsibilities.
49
+ - Close licensed entitlement validation around the declared `password`,
50
+ `local_receipt`, `account`, and `org` profiles.
51
+ - Load external-grant Schemas through static package imports so bundler-based
52
+ ecosystem adapters retain the exact Core validators instead of failing at
53
+ activation time.
54
+
3
55
  ## 0.20.0 (2026-07-17)
4
56
 
5
57
  ### Changed
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @aikdna/kdna-core
2
2
 
3
+ > **Status:** Pre-release. This source tree contains the unreleased `0.21.0`
4
+ > corrective candidate; the published incumbent is `0.20.0`. Candidate source,
5
+ > APIs, and evidence must not be described as already published.
6
+
3
7
  Core library for packaged `.kdna` judgment assets. It implements one current
4
8
  container contract, authorization planning, integrity evidence, Runtime Capsule
5
9
  projection, and the correlated Agent Host execution boundary.
@@ -7,9 +11,13 @@ projection, and the correlated Agent Host execution boundary.
7
11
  ## Install
8
12
 
9
13
  ```bash
10
- npm install @aikdna/kdna-core
14
+ npm install @aikdna/kdna-core@0.20.0
11
15
  ```
12
16
 
17
+ That command installs the published incumbent. Use its release notes for the
18
+ exact `0.20.0` contract. The examples below describe the current source
19
+ candidate and require its final release coordinate before registry use.
20
+
13
21
  ## Pack, validate, plan, and load
14
22
 
15
23
  Use the package root. Version-qualified entry points and parallel generation
@@ -58,7 +66,7 @@ separate from loadability: `planLoad` and every load path block a valid asset
58
66
  that requires a newer loader with `KDNA_LOADER_VERSION_UNSUPPORTED` before
59
67
  projection.
60
68
 
61
- ## Stable Runtime contracts
69
+ ## Current candidate Runtime contracts
62
70
 
63
71
  There is one current responsibility chain:
64
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikdna/kdna-core",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "KDNA Core library for validating, planning, and loading local .kdna judgment assets.",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -40,6 +40,14 @@
40
40
  }
41
41
  }
42
42
  }
43
+ },
44
+ {
45
+ "if": { "properties": { "access": { "const": "licensed" } }, "required": ["access"] },
46
+ "then": { "required": ["entitlement"] }
47
+ },
48
+ {
49
+ "if": { "required": ["entitlement"] },
50
+ "then": { "properties": { "access": { "const": "licensed" } }, "required": ["access"] }
43
51
  }
44
52
  ],
45
53
  "properties": {
@@ -139,6 +147,19 @@
139
147
  "enum": ["public", "licensed", "remote"],
140
148
  "description": "Stable delivery and authorization mode for the asset."
141
149
  },
150
+ "entitlement": {
151
+ "type": "object",
152
+ "required": ["profile"],
153
+ "additionalProperties": true,
154
+ "properties": {
155
+ "profile": {
156
+ "type": "string",
157
+ "enum": ["password", "local_receipt", "account", "org"]
158
+ },
159
+ "offline": { "type": "boolean" },
160
+ "revocable": { "type": "boolean" }
161
+ }
162
+ },
142
163
  "summary": { "type": "string" },
143
164
  "description": { "type": "string" },
144
165
  "language": { "type": "string" },
@@ -223,19 +244,8 @@
223
244
  }
224
245
  }
225
246
  },
226
- "signatures": {
227
- "type": "array",
228
- "items": {
229
- "type": "object",
230
- "required": ["role", "path", "algorithm"],
231
- "properties": {
232
- "role": { "type": "string" },
233
- "path": { "type": "string" },
234
- "algorithm": { "type": "string" },
235
- "key_id": { "type": "string" }
236
- }
237
- }
238
- },
247
+ "signature": false,
248
+ "signatures": false,
239
249
  "dependencies": {
240
250
  "type": "object",
241
251
  "additionalProperties": {
@@ -243,7 +253,7 @@
243
253
  }
244
254
  },
245
255
  "extends": {
246
- "description": "Asset inheritance declaration (Story 12). This asset inherits judgment content from the named base asset. Distinct from 'dependencies' (peer composition): 'extends' creates a single-inheritance hierarchy where the child specialises the parent. The child's cards override the parent's cards with the same ID; parent cards not overridden are inherited. Format: '@scope/name@semver-range' string, or an object with 'name' and optional 'version' fields.",
256
+ "description": "Asset inheritance declaration. This asset inherits judgment content from the named base asset. Distinct from 'dependencies' (peer composition): 'extends' creates a single-inheritance hierarchy where the child specialises the parent. The child's cards override the parent's cards with the same ID; parent cards not overridden are inherited. Format: '@scope/name@semver-range' string, or an object with 'name' and optional 'version' fields.",
247
257
  "oneOf": [
248
258
  {
249
259
  "type": "string",
@@ -18,11 +18,63 @@
18
18
  },
19
19
  "core": {
20
20
  "type": "object",
21
- "required": ["highest_question", "axioms"],
21
+ "required": ["axioms"],
22
22
  "additionalProperties": true,
23
+ "anyOf": [
24
+ { "required": ["highest_question"] },
25
+ {
26
+ "required": ["judgment_role"],
27
+ "properties": {
28
+ "judgment_role": {
29
+ "anyOf": [
30
+ { "required": ["acts_as"] },
31
+ { "required": ["does_not_act_as"] },
32
+ { "required": ["responsibility"] }
33
+ ]
34
+ }
35
+ }
36
+ },
37
+ {
38
+ "required": ["boundaries"],
39
+ "properties": { "boundaries": { "minItems": 1 } }
40
+ },
41
+ {
42
+ "properties": {
43
+ "axioms": {
44
+ "contains": {
45
+ "type": "object",
46
+ "anyOf": [
47
+ {
48
+ "required": ["applies_when"],
49
+ "properties": {
50
+ "applies_when": {
51
+ "type": "array",
52
+ "minItems": 1,
53
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
54
+ }
55
+ }
56
+ },
57
+ {
58
+ "required": ["does_not_apply_when"],
59
+ "properties": {
60
+ "does_not_apply_when": {
61
+ "type": "array",
62
+ "minItems": 1,
63
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
64
+ }
65
+ }
66
+ }
67
+ ]
68
+ }
69
+ }
70
+ }
71
+ }
72
+ ],
23
73
  "properties": {
24
74
  "highest_question": {
25
75
  "type": "string",
76
+ "minLength": 1,
77
+ "pattern": "\\S",
26
78
  "description": "The single most important question this judgment system answers."
27
79
  },
28
80
  "worldview": {
@@ -39,23 +91,121 @@
39
91
  "type": "object",
40
92
  "additionalProperties": true,
41
93
  "properties": {
42
- "acts_as": { "type": "string" },
94
+ "acts_as": { "type": "string", "minLength": 1, "pattern": "\\S" },
43
95
  "does_not_act_as": {
44
96
  "oneOf": [
45
- { "type": "string" },
46
- { "type": "array", "items": { "type": "string" } }
97
+ { "type": "string", "minLength": 1, "pattern": "\\S" },
98
+ {
99
+ "type": "array",
100
+ "minItems": 1,
101
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
102
+ }
47
103
  ]
48
104
  },
49
- "responsibility": { "type": "string" }
105
+ "responsibility": { "type": "string", "minLength": 1, "pattern": "\\S" }
50
106
  },
51
107
  "description": "The authority this asset exercises and the responsibilities explicitly outside it."
52
108
  },
109
+ "core_structure": {
110
+ "type": "array",
111
+ "items": {
112
+ "type": "object",
113
+ "additionalProperties": false,
114
+ "required": ["from", "to", "via"],
115
+ "properties": {
116
+ "from": { "type": "string", "minLength": 1, "pattern": "\\S" },
117
+ "to": { "type": "string", "minLength": 1, "pattern": "\\S" },
118
+ "via": { "type": "string", "enum": ["priority", "exception"] },
119
+ "applies_when": {
120
+ "type": "array",
121
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
122
+ },
123
+ "does_not_apply_when": {
124
+ "type": "array",
125
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
126
+ }
127
+ }
128
+ },
129
+ "description": "Ordered public judgment relations. Relation objects are closed so private authoring state cannot enter Runtime projection."
130
+ },
53
131
  "axioms": {
54
132
  "type": "array",
55
- "description": "The list of axioms. Phase 1 accepts an empty array."
133
+ "minItems": 1,
134
+ "items": {
135
+ "oneOf": [
136
+ { "type": "string", "minLength": 1, "pattern": "\\S" },
137
+ {
138
+ "type": "object",
139
+ "minProperties": 1,
140
+ "properties": {
141
+ "applies_when": {
142
+ "type": "array",
143
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
144
+ },
145
+ "does_not_apply_when": {
146
+ "type": "array",
147
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
148
+ }
149
+ },
150
+ "anyOf": [
151
+ {
152
+ "required": ["statement"],
153
+ "properties": { "statement": { "type": "string", "minLength": 1, "pattern": "\\S" } }
154
+ },
155
+ {
156
+ "required": ["one_sentence"],
157
+ "properties": { "one_sentence": { "type": "string", "minLength": 1, "pattern": "\\S" } }
158
+ },
159
+ {
160
+ "required": ["full_statement"],
161
+ "properties": { "full_statement": { "type": "string", "minLength": 1, "pattern": "\\S" } }
162
+ }
163
+ ]
164
+ }
165
+ ]
166
+ },
167
+ "description": "At least one non-empty judgment statement with an actual selection meaning."
56
168
  },
57
169
  "boundaries": {
58
170
  "type": "array",
171
+ "items": {
172
+ "oneOf": [
173
+ { "type": "string", "minLength": 1, "pattern": "\\S" },
174
+ {
175
+ "type": "object",
176
+ "minProperties": 1,
177
+ "anyOf": [
178
+ { "required": ["scope"], "properties": { "scope": { "type": "string", "minLength": 1, "pattern": "\\S" } } },
179
+ { "required": ["out_of_scope"], "properties": { "out_of_scope": { "type": "string", "minLength": 1, "pattern": "\\S" } } },
180
+ { "required": ["text"], "properties": { "text": { "type": "string", "minLength": 1, "pattern": "\\S" } } },
181
+ { "required": ["statement"], "properties": { "statement": { "type": "string", "minLength": 1, "pattern": "\\S" } } },
182
+ { "required": ["one_sentence"], "properties": { "one_sentence": { "type": "string", "minLength": 1, "pattern": "\\S" } } },
183
+ { "required": ["boundary"], "properties": { "boundary": { "type": "string", "minLength": 1, "pattern": "\\S" } } },
184
+ { "required": ["stance"], "properties": { "stance": { "type": "string", "minLength": 1, "pattern": "\\S" } } },
185
+ {
186
+ "required": ["applies_when"],
187
+ "properties": {
188
+ "applies_when": {
189
+ "type": "array",
190
+ "minItems": 1,
191
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
192
+ }
193
+ }
194
+ },
195
+ {
196
+ "required": ["does_not_apply_when"],
197
+ "properties": {
198
+ "does_not_apply_when": {
199
+ "type": "array",
200
+ "minItems": 1,
201
+ "items": { "type": "string", "minLength": 1, "pattern": "\\S" }
202
+ }
203
+ }
204
+ }
205
+ ]
206
+ }
207
+ ]
208
+ },
59
209
  "description": "Explicit out-of-scope statements."
60
210
  },
61
211
  "risk_model": {
@@ -82,8 +82,7 @@
82
82
  "required": ["state"],
83
83
  "additionalProperties": false,
84
84
  "properties": {
85
- "state": { "enum": ["verified", "not_checked", "absent"] },
86
- "issuer": { "type": "string", "minLength": 1 }
85
+ "state": { "const": "absent" }
87
86
  }
88
87
  },
89
88
  "trace": {
@@ -106,9 +105,51 @@
106
105
  "input_kind": { "enum": ["packaged_file", "packaged_bytes"] },
107
106
  "runtime_eligible": { "const": true },
108
107
  "schema_valid": { "const": true },
109
- "signature_state": { "enum": ["verified", "not_checked", "absent"] },
110
- "profile": { "enum": ["index", "compact", "scenario", "full"] }
108
+ "signature_state": { "const": "absent" },
109
+ "profile": { "enum": ["index", "compact", "scenario", "full"] },
110
+ "projection_report": { "$ref": "#/$defs/projectionReport" }
111
111
  }
112
+ },
113
+ "projectionReport": {
114
+ "type": "object",
115
+ "required": ["status", "omitted", "omitted_total"],
116
+ "additionalProperties": false,
117
+ "properties": {
118
+ "status": { "enum": ["complete", "partial"] },
119
+ "omitted": {
120
+ "type": "array",
121
+ "items": {
122
+ "type": "object",
123
+ "required": ["path", "count"],
124
+ "additionalProperties": false,
125
+ "properties": {
126
+ "path": { "type": "string", "pattern": "^/" },
127
+ "count": { "type": "integer", "minimum": 1 }
128
+ }
129
+ }
130
+ },
131
+ "omitted_total": { "type": "integer", "minimum": 0 }
132
+ },
133
+ "allOf": [
134
+ {
135
+ "if": { "properties": { "status": { "const": "complete" } } },
136
+ "then": {
137
+ "properties": {
138
+ "omitted": { "maxItems": 0 },
139
+ "omitted_total": { "const": 0 }
140
+ }
141
+ }
142
+ },
143
+ {
144
+ "if": { "properties": { "status": { "const": "partial" } } },
145
+ "then": {
146
+ "properties": {
147
+ "omitted": { "minItems": 1 },
148
+ "omitted_total": { "minimum": 1 }
149
+ }
150
+ }
151
+ }
152
+ ]
112
153
  }
113
154
  }
114
155
  }
@@ -190,7 +190,6 @@ function normalizeInput(input) {
190
190
 
191
191
  function manifestForDigest(manifest) {
192
192
  const copy = { ...(manifest || {}) };
193
- delete copy.signature;
194
193
  delete copy.asset_digest;
195
194
  delete copy.container_sha256;
196
195
  delete copy.content_digest;
@@ -205,7 +204,7 @@ function manifestForDigest(manifest) {
205
204
 
206
205
  function buildContentDigest(asset) {
207
206
  const parts = [];
208
- const excluded = new Set(['.DS_Store', 'signature.json', 'build-receipt.json']);
207
+ const excluded = new Set(['.DS_Store', 'build-receipt.json']);
209
208
  for (const entryName of sortedEntryNames(asset.entries)) {
210
209
  if (excluded.has(entryName)) continue;
211
210
  if (entryName.startsWith('reports/')) continue;
@@ -221,92 +220,6 @@ function buildContentDigest(asset) {
221
220
  return `sha256:${sha256Hex(Buffer.from(parts.join('\n')))}`;
222
221
  }
223
222
 
224
- function manifestForSignature(manifest, { stripDigestFields = true } = {}) {
225
- // Mirrors manifestForDigest above. The two must agree on every field
226
- // they strip, or the signing and digest paths will hash different
227
- // representations of the same manifest and verifiers will report a
228
- // mismatch on otherwise-valid assets.
229
- //
230
- // Bug: prior version omitted the `authoring.content_digest` strip
231
- // that manifestForDigest performs, so the signing payload included
232
- // a digest field that the digest payload did not.
233
- const copy = { ...(manifest || {}) };
234
- delete copy.signature;
235
- delete copy._source;
236
- if (stripDigestFields) {
237
- delete copy.asset_digest;
238
- delete copy.container_sha256;
239
- delete copy.content_digest;
240
- if (copy.authoring && typeof copy.authoring === 'object') {
241
- const auth = { ...copy.authoring };
242
- delete auth.content_digest;
243
- copy.authoring = auth;
244
- }
245
- }
246
- return copy;
247
- }
248
-
249
- function canonicalJsonEntry(entryName, entryBuf, options = {}) {
250
- const parsed = parseJson(entryBuf, entryName);
251
- const value = entryName === 'kdna.json' ? manifestForSignature(parsed, options) : parsed;
252
- return Buffer.from(stableStringify(value));
253
- }
254
-
255
- function buildSigningPayload(asset, options = {}) {
256
- // Bug (#147): the prior version only excluded `.DS_Store` and
257
- // `signature.json`, while `buildContentDigest` above also excludes
258
- // `build-receipt.json` and any entry under `reports/`. A producer
259
- // that signed with this code and a verifier that digested the
260
- // asset with `buildContentDigest` would compute two different
261
- // byte strings and the signature would fail to verify. The fix
262
- // mirrors `buildContentDigest`'s exclusion set exactly.
263
- const parts = [];
264
- for (const entryName of sortedEntryNames(asset.entries)) {
265
- if (entryName === '.DS_Store' || entryName === 'signature.json') continue;
266
- if (entryName === 'build-receipt.json') continue;
267
- if (entryName.startsWith('reports/')) continue;
268
- const entryBuf = asset.readEntry(entryName);
269
- let payloadBuf = entryBuf;
270
- if (JSON_ENTRY_RE.test(entryName)) {
271
- payloadBuf = canonicalJsonEntry(entryName, entryBuf, options);
272
- }
273
- parts.push(`${entryName}:${sha256Hex(payloadBuf)}`);
274
- }
275
- return parts.join('\n');
276
- }
277
-
278
- function verifySignature(asset, manifest, errors, warnings) {
279
- if (!manifest.signature) {
280
- warnings.push('kdna.json.signature missing');
281
- return null;
282
- }
283
- if (!manifest.author?.public_key_pem) {
284
- errors.push('kdna.json.author.public_key_pem missing');
285
- return false;
286
- }
287
- if (!manifest.author?.pubkey) {
288
- errors.push('kdna.json.author.pubkey missing');
289
- return false;
290
- }
291
-
292
- const fingerprint = `ed25519:${sha256Hex(Buffer.from(manifest.author.public_key_pem))}`;
293
- if (fingerprint !== manifest.author.pubkey) {
294
- errors.push('author.public_key_pem fingerprint does not match author.pubkey');
295
- return false;
296
- }
297
-
298
- try {
299
- const signature = Buffer.from(String(manifest.signature).replace(/^ed25519:/, ''), 'hex');
300
- const publicKey = crypto.createPublicKey(manifest.author.public_key_pem);
301
- const ok = crypto.verify(null, Buffer.from(buildSigningPayload(asset)), publicKey, signature);
302
- if (!ok) errors.push('Ed25519 signature invalid');
303
- return ok;
304
- } catch (e) {
305
- errors.push(`signature verification failed: ${e.message}`);
306
- return false;
307
- }
308
- }
309
-
310
223
  function verifyMediaType(asset, errors) {
311
224
  if (!asset.entries.has('mimetype')) {
312
225
  errors.push('required entry missing: mimetype');
@@ -464,9 +377,12 @@ function verifySync(asset, options = {}) {
464
377
 
465
378
  // The current implementation is the sole authority for container,
466
379
  // manifest, CBOR payload, checksum, and load-contract validity. The reader
467
- // adds transport identity and legacy signature hooks; it must not maintain a
468
- // second manifest or payload dialect.
380
+ // adds transport identity; it must not maintain a second manifest or payload
381
+ // dialect.
469
382
  appendCurrentValidationErrors(asset, errors);
383
+ if (options.requireSignature === true) {
384
+ errors.push('asset signatures are outside the current Preview contract');
385
+ }
470
386
 
471
387
  if (!asset.entries.has('kdna.json')) errors.push('required entry missing: kdna.json');
472
388
  verifyMediaType(asset, errors);
@@ -484,7 +400,6 @@ function verifySync(asset, options = {}) {
484
400
  }
485
401
 
486
402
  let manifest = null;
487
- let signature_valid = null;
488
403
  if (asset.entries.has('kdna.json')) {
489
404
  try {
490
405
  manifest = readManifest(asset);
@@ -515,9 +430,6 @@ function verifySync(asset, options = {}) {
515
430
  }
516
431
  }
517
432
  }
518
- if (options.requireSignature || manifest.signature) {
519
- signature_valid = verifySignature(asset, manifest, errors, warnings);
520
- }
521
433
  // ── Human Lock signature verification ──────────────────
522
434
  if (asset.entries.has('KDNA_Core.json')) {
523
435
  try {
@@ -540,7 +452,6 @@ function verifySync(asset, options = {}) {
540
452
  manifest,
541
453
  asset_digest,
542
454
  content_digest,
543
- signature_valid,
544
455
  };
545
456
  }
546
457
 
@@ -630,6 +541,9 @@ function createKdnaAssetReader() {
630
541
  const entries = [...asset.entries.keys()].sort();
631
542
 
632
543
  appendCurrentValidationErrors(asset, errors);
544
+ if (options.requireSignature === true) {
545
+ errors.push('asset signatures are outside the current Preview contract');
546
+ }
633
547
 
634
548
  if (!asset.entries.has('kdna.json')) errors.push('required entry missing: kdna.json');
635
549
  verifyMediaType(asset, errors);
@@ -647,7 +561,6 @@ function createKdnaAssetReader() {
647
561
  }
648
562
 
649
563
  let manifest = null;
650
- let signature_valid = null;
651
564
  if (asset.entries.has('kdna.json')) {
652
565
  try {
653
566
  manifest = parseJson(asset.readEntry('kdna.json'), 'kdna.json');
@@ -678,9 +591,6 @@ function createKdnaAssetReader() {
678
591
  }
679
592
  }
680
593
  }
681
- if (options.requireSignature || manifest.signature) {
682
- signature_valid = verifySignature(asset, manifest, errors, warnings);
683
- }
684
594
  } catch (e) {
685
595
  errors.push(e.message);
686
596
  }
@@ -694,7 +604,6 @@ function createKdnaAssetReader() {
694
604
  manifest,
695
605
  asset_digest,
696
606
  content_digest,
697
- signature_valid,
698
607
  };
699
608
  },
700
609