@aikdna/kdna-core 0.4.0 → 0.6.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/src/types.d.ts CHANGED
@@ -203,15 +203,29 @@ export interface KDNAFileDataMap {
203
203
  }
204
204
 
205
205
  export interface KDNAManifest {
206
- kdna_spec: string;
206
+ format: 'kdna';
207
+ format_version: '1.0';
208
+ spec_version: string;
207
209
  name: string;
208
210
  version: string;
209
- status: 'experimental' | 'basic' | 'stable' | 'pro';
211
+ judgment_version: string;
212
+ status: 'draft' | 'experimental' | 'stable' | 'deprecated' | 'staging';
213
+ quality_badge: 'untested' | 'tested' | 'validated' | 'expert_reviewed' | 'production_ready';
210
214
  access: 'open' | 'licensed' | 'runtime';
211
- language: string;
212
- author: { name: string; id?: string };
215
+ language?: string;
216
+ default_language: string;
217
+ languages: string[];
218
+ author: { name: string; id?: string; pubkey?: string; public_key_pem?: string };
213
219
  license: { type: string; url?: string };
214
220
  description: string;
221
+ keywords?: string[];
222
+ encryption?: {
223
+ profile?: string;
224
+ encrypted_entries?: string[];
225
+ [key: string]: any;
226
+ };
227
+ content_digest?: string;
228
+ signature?: string;
215
229
  }
216
230
 
217
231
  export interface LintResult {
@@ -241,6 +255,235 @@ export function formatContext(domain: LoadedDomain): string;
241
255
 
242
256
  export const FILE_MAP: Record<string, string>;
243
257
 
258
+ // Asset reader — direct .kdna API
259
+ export const STANDARD_ENTRIES: string[];
260
+
261
+ export interface KdnaAsset {
262
+ path: string | null;
263
+ size: number;
264
+ asset_digest: string;
265
+ entries: Map<string, unknown>;
266
+ readEntry(name: string): Uint8Array;
267
+ }
268
+
269
+ export interface KdnaAssetVerifyResult {
270
+ ok: boolean;
271
+ errors: string[];
272
+ warnings: string[];
273
+ entries: string[];
274
+ manifest: KDNAManifest | null;
275
+ asset_digest: string;
276
+ content_digest: string;
277
+ signature_valid: boolean | null;
278
+ }
279
+
280
+ export interface KdnaAssetIndexProfile {
281
+ profile: 'index';
282
+ manifest: KDNAManifest;
283
+ asset_digest: string;
284
+ content_digest: string;
285
+ entries: string[];
286
+ name: string | null;
287
+ version: string | null;
288
+ judgment_version: string | null;
289
+ keywords: string[];
290
+ }
291
+
292
+ export interface KdnaAssetLoadProfile {
293
+ profile: string;
294
+ manifest: KDNAManifest;
295
+ domain: LoadedDomain | null;
296
+ context: string | null;
297
+ }
298
+
299
+ export interface KdnaAssetReader {
300
+ openSync(input: string | Uint8Array): KdnaAsset;
301
+ open(input: string | Uint8Array): Promise<KdnaAsset>;
302
+ listEntriesSync(asset: KdnaAsset): string[];
303
+ listEntries(asset: KdnaAsset): Promise<string[]>;
304
+ readEntrySync(asset: KdnaAsset, entryName: string): Uint8Array;
305
+ readEntrySync(asset: KdnaAsset, entryName: string, encoding: string): string;
306
+ readEntry(asset: KdnaAsset, entryName: string): Promise<Uint8Array>;
307
+ readEntry(asset: KdnaAsset, entryName: string, encoding: string): Promise<string>;
308
+ readJsonSync(asset: KdnaAsset, entryName: string, options?: KdnaDecryptOptions): any;
309
+ readJson(asset: KdnaAsset, entryName: string, options?: KdnaDecryptOptions): Promise<any>;
310
+ readManifestSync(asset: KdnaAsset): KDNAManifest;
311
+ readManifest(asset: KdnaAsset): Promise<KDNAManifest>;
312
+ readDataMapSync(
313
+ asset: KdnaAsset,
314
+ entries?: string[],
315
+ options?: KdnaDecryptOptions,
316
+ ): KDNAFileDataMap;
317
+ readDataMap(
318
+ asset: KdnaAsset,
319
+ entries?: string[],
320
+ options?: KdnaDecryptOptions,
321
+ ): Promise<KDNAFileDataMap>;
322
+ contentDigestSync(asset: KdnaAsset): string;
323
+ contentDigest(asset: KdnaAsset): Promise<string>;
324
+ verifySync(
325
+ asset: KdnaAsset,
326
+ options?: {
327
+ asset_digest?: string;
328
+ content_digest?: string;
329
+ requireSignature?: boolean;
330
+ requireDecryption?: boolean;
331
+ } & KdnaDecryptOptions,
332
+ ): KdnaAssetVerifyResult;
333
+ verify(
334
+ asset: KdnaAsset,
335
+ options?: {
336
+ asset_digest?: string;
337
+ content_digest?: string;
338
+ requireSignature?: boolean;
339
+ requireDecryption?: boolean;
340
+ } & KdnaDecryptOptions,
341
+ ): Promise<KdnaAssetVerifyResult>;
342
+ loadProfileSync(
343
+ asset: KdnaAsset,
344
+ profile: 'index',
345
+ options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
346
+ ): KdnaAssetIndexProfile;
347
+ loadProfileSync(
348
+ asset: KdnaAsset,
349
+ profile?: 'compact' | 'scenario' | 'full' | string,
350
+ options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
351
+ ): KdnaAssetLoadProfile;
352
+ loadProfile(
353
+ asset: KdnaAsset,
354
+ profile: 'index',
355
+ options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
356
+ ): Promise<KdnaAssetIndexProfile>;
357
+ loadProfile(
358
+ asset: KdnaAsset,
359
+ profile?: 'compact' | 'scenario' | 'full' | string,
360
+ options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
361
+ ): Promise<KdnaAssetLoadProfile>;
362
+ }
363
+
364
+ export interface KdnaDecryptOptions {
365
+ decryptEntry?: (args: {
366
+ asset: KdnaAsset;
367
+ manifest: KDNAManifest;
368
+ entryName: string;
369
+ ciphertext: Uint8Array;
370
+ }) => string | Uint8Array | Promise<string | Uint8Array>;
371
+ }
372
+
373
+ export function createKdnaAssetReader(): KdnaAssetReader;
374
+
375
+ export const LICENSED_ENTRY_PROFILE: string;
376
+
377
+ export interface LicensedEntryEnvelope {
378
+ profile: string;
379
+ alg: 'AES-256-GCM';
380
+ kdf: 'scrypt-sha256';
381
+ salt: string;
382
+ iv: string;
383
+ tag: string;
384
+ ciphertext: string;
385
+ }
386
+
387
+ export function deriveLicensedEntryKey(options: {
388
+ licenseKey: string;
389
+ machineFingerprint: string;
390
+ salt: string | Uint8Array;
391
+ keyLength?: number;
392
+ }): Uint8Array;
393
+
394
+ export function encryptLicensedEntry(
395
+ plaintext: string | Uint8Array,
396
+ options: {
397
+ entryName: string;
398
+ manifest?: KDNAManifest;
399
+ licenseKey: string;
400
+ machineFingerprint: string;
401
+ },
402
+ ): LicensedEntryEnvelope;
403
+
404
+ export function decryptLicensedEntry(
405
+ envelope: string | Uint8Array | LicensedEntryEnvelope,
406
+ options: {
407
+ entryName: string;
408
+ manifest?: KDNAManifest;
409
+ licenseKey: string;
410
+ machineFingerprint: string;
411
+ },
412
+ ): Uint8Array;
413
+
414
+ export function createLicensedDecryptEntry(options: {
415
+ licenseKey: string;
416
+ machineFingerprint: string;
417
+ }): NonNullable<KdnaDecryptOptions['decryptEntry']>;
418
+
419
+ // Stable public API — preferred entry points for third-party integrations.
420
+ export type KDNAAssetInput = string | Uint8Array | KdnaAsset;
421
+
422
+ export interface KDNAInspectResult {
423
+ name: string | null;
424
+ version: string | null;
425
+ judgment_version: string | null;
426
+ access: string;
427
+ status: string | null;
428
+ quality_badge: string | null;
429
+ risk_level: string | null;
430
+ keywords: string[];
431
+ entries: string[];
432
+ asset_digest: string;
433
+ content_digest: string;
434
+ signature_valid: boolean | null;
435
+ ok: boolean | null;
436
+ errors: string[];
437
+ warnings: string[];
438
+ manifest: KDNAManifest;
439
+ }
440
+
441
+ export interface KDNAValidationReport {
442
+ ok: boolean;
443
+ errors: string[];
444
+ warnings: string[];
445
+ asset: KdnaAssetVerifyResult;
446
+ lint: LintResult;
447
+ schema: ValidationResult;
448
+ cross_file: ValidationResult;
449
+ }
450
+
451
+ export interface KDNAMatchResult extends KDNAInspectResult {
452
+ score: number;
453
+ matched: string[];
454
+ }
455
+
456
+ export interface KDNAComposeResult {
457
+ domains: Array<LoadedDomain & { id?: string; name?: string; manifest?: KDNAManifest }>;
458
+ activeDomains: Array<LoadedDomain & { id?: string; name?: string; manifest?: KDNAManifest }>;
459
+ selected: Array<{ id: string; name?: string; role?: string; reason: string }>;
460
+ excluded: Array<{ id: string; name?: string; role?: string; reason: string }>;
461
+ conflicts: Array<{ type: string; domains: string[]; description: string }>;
462
+ context: string;
463
+ attributionMap: Record<string, any>;
464
+ trace: Record<string, any>;
465
+ }
466
+
467
+ export function openKDNA(input: KDNAAssetInput): Promise<KdnaAsset>;
468
+ export function openKDNASync(input: KDNAAssetInput): KdnaAsset;
469
+ export function inspectKDNA(input: KDNAAssetInput, options?: { verify?: boolean } & KdnaDecryptOptions): Promise<KDNAInspectResult>;
470
+ export function inspectKDNASync(input: KDNAAssetInput, options?: { verify?: boolean } & KdnaDecryptOptions): KDNAInspectResult;
471
+ export function loadKDNA(input: KDNAAssetInput, options?: { profile?: 'index' | 'compact' | 'scenario' | 'full' | string; input?: string; context?: boolean } & KdnaDecryptOptions): Promise<KdnaAssetIndexProfile | KdnaAssetLoadProfile>;
472
+ export function loadKDNASync(input: KDNAAssetInput, options?: { profile?: 'index' | 'compact' | 'scenario' | 'full' | string; input?: string; context?: boolean } & KdnaDecryptOptions): KdnaAssetIndexProfile | KdnaAssetLoadProfile;
473
+ export function validateKDNA(input: KDNAAssetInput, options?: { schemas?: Record<string, any>; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): Promise<KDNAValidationReport>;
474
+ export function validateKDNASync(input: KDNAAssetInput, options?: { schemas?: Record<string, any>; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): KDNAValidationReport;
475
+ export function renderForAgent(input: KDNAAssetInput, options?: { profile?: 'compact' | 'scenario' | 'full' | string; input?: string } & KdnaDecryptOptions): Promise<string>;
476
+ export function renderForAgentSync(input: KDNAAssetInput, options?: { profile?: 'compact' | 'scenario' | 'full' | string; input?: string } & KdnaDecryptOptions): string;
477
+ export function verifyAsset(input: KDNAAssetInput, options?: { asset_digest?: string; content_digest?: string; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): Promise<KdnaAssetVerifyResult>;
478
+ export function verifyAssetSync(input: KDNAAssetInput, options?: { asset_digest?: string; content_digest?: string; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): KdnaAssetVerifyResult;
479
+ export function verifyDigest(input: KDNAAssetInput, expectedDigest: string, options?: KdnaDecryptOptions): Promise<KdnaAssetVerifyResult>;
480
+ export function verifyDigestSync(input: KDNAAssetInput, expectedDigest: string, options?: KdnaDecryptOptions): KdnaAssetVerifyResult;
481
+ export function verifySignature(input: KDNAAssetInput, options?: KdnaDecryptOptions): Promise<KdnaAssetVerifyResult>;
482
+ export function verifySignatureSync(input: KDNAAssetInput, options?: KdnaDecryptOptions): KdnaAssetVerifyResult;
483
+ export function matchDomain(input: string, candidates: Array<KDNAAssetInput | KDNAInspectResult>, options?: KdnaDecryptOptions): Promise<KDNAMatchResult[]>;
484
+ export function matchDomainSync(input: string, candidates: Array<KDNAAssetInput | KDNAInspectResult>, options?: KdnaDecryptOptions): KDNAMatchResult[];
485
+ export function composeKDNA(inputs: KDNAAssetInput[], options?: { input?: string; profile?: 'compact' | 'scenario' | 'full' | string; separator?: string } & KdnaDecryptOptions): Promise<KDNAComposeResult>;
486
+
244
487
  // Lint
245
488
  export function lintDomain(dataMap: KDNAFileDataMap): LintResult;
246
489
 
@@ -45,9 +45,6 @@ function validateDomainSchema(dataMap, schemaMap) {
45
45
  return { valid: true, errors: [], warnings };
46
46
  }
47
47
 
48
- let validCount = 0;
49
- let failCount = 0;
50
-
51
48
  for (const [file, schemaFile] of Object.entries(FILE_TO_SCHEMA)) {
52
49
  if (!dataMap[file]) continue;
53
50
  if (!schemaMap[schemaFile]) {
@@ -69,10 +66,7 @@ function validateDomainSchema(dataMap, schemaMap) {
69
66
  const validate = ajvInstance.compile(schema);
70
67
  const valid = validate(dataMap[file]);
71
68
 
72
- if (valid) {
73
- validCount++;
74
- } else {
75
- failCount++;
69
+ if (!valid) {
76
70
  for (const err of validate.errors || []) {
77
71
  const instancePath = err.instancePath || '/';
78
72
  errors.push(`${file}${instancePath}: ${err.message} (${err.keyword})`);