@aikdna/kdna-core 0.16.0 → 0.18.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/index.js CHANGED
@@ -13,6 +13,8 @@ const publicApi = require('./public-api');
13
13
  const workpackPure = require('./workpack-pure');
14
14
  const v1 = require('./v1');
15
15
  const runtimeApi = require('./runtime-api');
16
+ const capsuleV2 = require('./capsule-v2');
17
+ const executionContractV1 = require('./execution-contract-v1');
16
18
 
17
19
  module.exports = {
18
20
  ...publicApi,
@@ -27,4 +29,6 @@ module.exports = {
27
29
  ...workpackPure,
28
30
  ...v1,
29
31
  ...runtimeApi,
32
+ ...capsuleV2,
33
+ ...executionContractV1,
30
34
  };
package/src/index.mjs CHANGED
@@ -10,7 +10,7 @@ export {
10
10
  formatContext,
11
11
  } from './loader.js';
12
12
 
13
- export { lintDomain } from './lint-pure.js';
13
+ export { lintDomain, validateManifest } from './lint-pure.js';
14
14
 
15
15
  export {
16
16
  MIMETYPE,
@@ -40,30 +40,145 @@ export { validateDomainSchema, validateCrossFile } from './validate-pure.js';
40
40
 
41
41
  export { renderPreviewHTML, escHtml, renderCard } from './render.js';
42
42
 
43
- export { composeContext, composeContextWithAttribution, classifySignals, classifySignalsAcrossDomains, composeChecks, loadAndCompose, loadCluster, detectDomainConflicts, generateClusterTrace } from './compose.js';
43
+ export {
44
+ composeContext,
45
+ composeContextWithAttribution,
46
+ classifySignals,
47
+ classifySignalsAcrossDomains,
48
+ composeChecks,
49
+ loadAndCompose,
50
+ loadCluster,
51
+ detectDomainConflicts,
52
+ generateClusterTrace,
53
+ } from './compose.js';
44
54
 
45
55
  import assetReader from './asset-reader.js';
46
56
  import cryptoProfile from './crypto-profile.js';
47
57
  import externalKeyGrant from './external-key-grant.js';
58
+ import publicApi from './public-api.js';
59
+ import workpackPure from './workpack-pure.js';
60
+ import capsuleV2 from './capsule-v2.js';
61
+ import executionContractV1 from './execution-contract-v1.js';
62
+
63
+ export const openKDNA = publicApi.openKDNA;
64
+ export const openKDNASync = publicApi.openKDNASync;
65
+ export const inspectKDNA = publicApi.inspectKDNA;
66
+ export const inspectKDNASync = publicApi.inspectKDNASync;
67
+ export const loadKDNA = publicApi.loadKDNA;
68
+ export const loadKDNASync = publicApi.loadKDNASync;
69
+ export const validateKDNA = publicApi.validateKDNA;
70
+ export const validateKDNASync = publicApi.validateKDNASync;
71
+ export const renderForAgent = publicApi.renderForAgent;
72
+ export const renderForAgentSync = publicApi.renderForAgentSync;
73
+ export const verifyAsset = publicApi.verifyAsset;
74
+ export const verifyAssetSync = publicApi.verifyAssetSync;
75
+ export const verifyDigest = publicApi.verifyDigest;
76
+ export const verifyDigestSync = publicApi.verifyDigestSync;
77
+ export const verifySignature = publicApi.verifySignature;
78
+ export const verifySignatureSync = publicApi.verifySignatureSync;
79
+ export const matchDomain = publicApi.matchDomain;
80
+ export const matchDomainSync = publicApi.matchDomainSync;
81
+ export const composeKDNA = publicApi.composeKDNA;
82
+
83
+ export const DIGEST_PROFILE = capsuleV2.DIGEST_PROFILE;
84
+ export const CAPSULE_DIGEST_PROFILE = capsuleV2.CAPSULE_DIGEST_PROFILE;
85
+ export const BASIS = capsuleV2.BASIS;
86
+ export const computeAssetDigest = capsuleV2.computeAssetDigest;
87
+ export const computeRuntimeEntrySetDigest = capsuleV2.computeRuntimeEntrySetDigest;
88
+ export const computeDigestEvidence = capsuleV2.computeDigestEvidence;
89
+ export const canonicalizeJcs = capsuleV2.canonicalizeJcs;
90
+ export const computeCapsuleDeliveryDigest = capsuleV2.computeCapsuleDeliveryDigest;
91
+ export const buildCapsuleV2 = capsuleV2.buildCapsuleV2;
92
+ export const loadCapsuleV2 = capsuleV2.loadCapsuleV2;
93
+ export const adaptCapsuleV2ToV1 = capsuleV2.adaptCapsuleV2ToV1;
94
+
95
+ export const KDNAExecutionContractError = executionContractV1.KDNAExecutionContractError;
96
+ export const PLAN_DIGEST_PROFILE = executionContractV1.PLAN_DIGEST_PROFILE;
97
+ export const HOST_PROTOCOL = executionContractV1.HOST_PROTOCOL;
98
+ export const DEFAULT_CORE_CAPSULE_VERSIONS = executionContractV1.DEFAULT_CORE_CAPSULE_VERSIONS;
99
+ export const parseExecutionContractJsonV1 = executionContractV1.parseExecutionContractJsonV1;
100
+ export const computeConsumptionPlanDigestV1 = executionContractV1.computeConsumptionPlanDigestV1;
101
+ export const buildConsumptionPlanV1 = executionContractV1.buildConsumptionPlanV1;
102
+ export const validateConsumptionPlanV1 = executionContractV1.validateConsumptionPlanV1;
103
+ export const negotiateExecutionPairV1 = executionContractV1.negotiateExecutionPairV1;
104
+ export const buildAgentHost2RequestV1 = executionContractV1.buildAgentHost2RequestV1;
105
+ export const validateAgentHost2RequestV1 = executionContractV1.validateAgentHost2RequestV1;
106
+ export const validateAgentHost2ReceiptV1 = executionContractV1.validateAgentHost2ReceiptV1;
107
+ export const deriveBudgetEvidenceV1 = executionContractV1.deriveBudgetEvidenceV1;
108
+ export const buildPreHostBudgetBlockedTraceV1 =
109
+ executionContractV1.buildPreHostBudgetBlockedTraceV1;
110
+ export const validatePreHostBudgetBlockedTraceV1 =
111
+ executionContractV1.validatePreHostBudgetBlockedTraceV1;
112
+ export const buildJudgmentTraceV1 = executionContractV1.buildJudgmentTraceV1;
113
+ export const validateJudgmentTraceV1 = executionContractV1.validateJudgmentTraceV1;
48
114
 
49
115
  export const STANDARD_ENTRIES = assetReader.STANDARD_ENTRIES;
50
116
  export const createKdnaAssetReader = assetReader.createKdnaAssetReader;
51
- export const LICENSED_ENTRY_PROFILE = cryptoProfile.LICENSED_ENTRY_PROFILE;
52
- export const deriveLicensedEntryKey = cryptoProfile.deriveLicensedEntryKey;
53
- export const encryptLicensedEntry = cryptoProfile.encryptLicensedEntry;
54
- export const decryptLicensedEntry = cryptoProfile.decryptLicensedEntry;
55
- export const createLicensedDecryptEntry = cryptoProfile.createLicensedDecryptEntry;
56
- export const EXTERNAL_ENVELOPE_PROFILE = externalKeyGrant.EXTERNAL_ENVELOPE_PROFILE;
57
- export const EXTERNAL_GRANT_PROFILE = externalKeyGrant.EXTERNAL_GRANT_PROFILE;
58
- export const KDNAExternalGrantError = externalKeyGrant.KDNAExternalGrantError;
59
- export const canonicalJson = externalKeyGrant.canonicalJson;
60
- export const grantSigningPayload = externalKeyGrant.grantSigningPayload;
61
- export const validateExternalEnvelope = externalKeyGrant.validateExternalEnvelope;
62
- export const validateExternalKeyGrant = externalKeyGrant.validateExternalKeyGrant;
63
- export const deriveExternalAssetCek = externalKeyGrant.deriveExternalAssetCek;
64
- export const encodeExternalEnvelope = externalKeyGrant.encodeExternalEnvelope;
65
- export const decodeExternalEnvelope = externalKeyGrant.decodeExternalEnvelope;
66
- export const encryptExternalGrantEntry = externalKeyGrant.encryptExternalGrantEntry;
67
- export const generateDeviceKeyPairs = externalKeyGrant.generateDeviceKeyPairs;
68
- export const createExternalKeyGrant = externalKeyGrant.createExternalKeyGrant;
69
- export const authorizeExternalKeyGrant = externalKeyGrant.authorizeExternalKeyGrant;
117
+
118
+ export const {
119
+ LICENSED_ENTRY_PROFILE,
120
+ LICENSED_EXPERIMENTAL_PROFILE,
121
+ PASSWORD_PROTECTED_PROFILE,
122
+ PASSWORD_PROTECTED_SCRYPT_PROFILE,
123
+ ALG,
124
+ RFC_KDF,
125
+ RFC_KEY_WRAPPING,
126
+ LEGACY_KDF,
127
+ PASSWORD_KDF,
128
+ SCRYPT_KDF,
129
+ deriveWrappingKey,
130
+ generateCEK,
131
+ wrapCEK,
132
+ unwrapCEK,
133
+ encryptLicensedEntryV1,
134
+ decryptLicensedEntryV1,
135
+ derivePasswordKey,
136
+ generateRecoveryCode,
137
+ decodeRecoveryCode,
138
+ encryptProtectedEntry,
139
+ decryptProtectedEntry,
140
+ createPasswordDecryptEntry,
141
+ createRecoveryDecryptEntry,
142
+ derivePasswordKeyScrypt,
143
+ encryptProtectedEntryScrypt,
144
+ decryptProtectedEntryScrypt,
145
+ createPasswordDecryptEntryScrypt,
146
+ deriveLicensedEntryKey,
147
+ encryptLicensedEntryLegacy,
148
+ decryptLicensedEntryLegacy,
149
+ encryptLicensedEntry,
150
+ decryptLicensedEntry,
151
+ createLicensedDecryptEntry,
152
+ hkdfSha256,
153
+ aesWrap,
154
+ aesUnwrap,
155
+ } = cryptoProfile;
156
+
157
+ export const {
158
+ EXTERNAL_ENVELOPE_PROFILE,
159
+ EXTERNAL_GRANT_PROFILE,
160
+ EXTERNAL_AAD_PROFILE,
161
+ DEVICE_KEK_PROFILE,
162
+ KDNAExternalGrantError,
163
+ canonicalJson,
164
+ grantSigningPayload,
165
+ validateExternalEnvelope,
166
+ validateExternalKeyGrant,
167
+ externalEnvelopeAad,
168
+ deriveExternalAssetCek,
169
+ encodeExternalEnvelope,
170
+ decodeExternalEnvelope,
171
+ encryptExternalGrantEntry,
172
+ generateDeviceKeyPairs,
173
+ createExternalKeyGrant,
174
+ authorizeExternalKeyGrant,
175
+ isVerifiedExternalEntitlement,
176
+ } = externalKeyGrant;
177
+
178
+ export const {
179
+ WORK_PACK_SCHEMA,
180
+ validateWorkPackManifest,
181
+ checkWorkPackStructure,
182
+ inspectWorkPack,
183
+ loadWorkPack,
184
+ } = workpackPure;
package/src/lint-pure.js CHANGED
@@ -253,8 +253,8 @@ function lintDomain(dataMap) {
253
253
  }
254
254
 
255
255
  /**
256
- * Canonical enum tables for manifest validation.
257
- * Single source of truth — keep in sync with schema/kdna-manifest-v1rc.json and specs/enum-tables.md.
256
+ * Legacy authoring-source enum tables for migration validation.
257
+ * These do not define the current Runtime manifest contract.
258
258
  */
259
259
  const VALID_STATUS = new Set(['draft', 'experimental', 'stable', 'deprecated', 'staging']);
260
260
  const VALID_BADGE = new Set(['untested', 'tested', 'validated', 'expert_reviewed', 'production_ready']);
@@ -279,7 +279,10 @@ const MANIFEST_REQUIRED = [
279
279
  ];
280
280
 
281
281
  /**
282
- * Validate a kdna.json manifest against the canonical KDNA Asset format.
282
+ * Validate a legacy authoring-source kdna.json manifest.
283
+ *
284
+ * This function is retained for explicit source migration. Current Runtime
285
+ * containers are validated against schema/manifest.schema.json by v1.validate.
283
286
  *
284
287
  * @param {Object} manifest — parsed kdna.json
285
288
  * @returns {{ errors: string[], warnings: string[] }}
package/src/public-api.js CHANGED
@@ -1,22 +1,16 @@
1
1
  /**
2
- * Stable public API for third-party KDNA integrations.
2
+ * Compatibility names for the stable current KDNA Runtime API.
3
3
  *
4
- * Lower-level modules remain exported for advanced runtimes, but external
5
- * adapters should prefer these names. They encode the asset-first contract:
6
- * callers pass .kdna files or bytes, and no persistent directory extraction is
7
- * required.
4
+ * These names previously implemented a second legacy source-tree validator and
5
+ * loader. They now route to the same current inspect/validate/LoadPlan/Capsule
6
+ * implementation as the unversioned package API. No current payload is
7
+ * reverse-projected into KDNA_Core.json or KDNA_Patterns.json.
8
8
  */
9
9
 
10
+ const fs = require('fs');
10
11
  const { createKdnaAssetReader } = require('./asset-reader');
11
- const { lintDomain } = require('./lint-pure');
12
- const { validateCrossFile, validateDomainSchema } = require('./validate-pure');
13
- const { formatContext } = require('./loader');
14
- const {
15
- composeContextWithAttribution,
16
- detectDomainConflicts,
17
- classifySignalsAcrossDomains,
18
- generateClusterTrace,
19
- } = require('./compose');
12
+ const v1 = require('./v1');
13
+ const runtimeApi = require('./runtime-api');
20
14
 
21
15
  function readerFrom(options = {}) {
22
16
  return options.reader || createKdnaAssetReader();
@@ -26,6 +20,18 @@ function isAsset(value) {
26
20
  return value && typeof value === 'object' && value.entries instanceof Map && typeof value.readEntry === 'function';
27
21
  }
28
22
 
23
+ const ASSET_SOURCE_BYTES = Symbol.for('@aikdna/kdna-core.asset-source-bytes');
24
+
25
+ function canonicalBytes(input) {
26
+ if (Buffer.isBuffer(input)) return input;
27
+ if (input instanceof Uint8Array) return Buffer.from(input);
28
+ if (typeof input === 'string') return fs.readFileSync(input);
29
+ if (isAsset(input) && Buffer.isBuffer(input[ASSET_SOURCE_BYTES])) {
30
+ return input[ASSET_SOURCE_BYTES];
31
+ }
32
+ throw new Error('KDNA operation expects a .kdna path, Buffer, Uint8Array, or asset opened by openKDNA');
33
+ }
34
+
29
35
  async function asAsset(input, options = {}) {
30
36
  if (isAsset(input)) return input;
31
37
  return readerFrom(options).open(input);
@@ -47,156 +53,69 @@ function openKDNASync(input, options = {}) {
47
53
  async function inspectKDNA(input, options = {}) {
48
54
  const reader = readerFrom(options);
49
55
  const asset = await asAsset(input, { ...options, reader });
50
- const profile = await reader.loadProfile(asset, 'index', options);
56
+ const current = v1.inspect(canonicalBytes(asset), options);
57
+ const manifest = await reader.readManifest(asset);
58
+ const entries = await reader.listEntries(asset);
59
+ const contentDigest = await reader.contentDigest(asset);
51
60
  const verification = options.verify === false ? null : await reader.verify(asset, options);
52
61
  return {
53
- name: profile.name,
54
- version: profile.version,
55
- judgment_version: profile.judgment_version,
56
- access: profile.manifest.access || 'open',
57
- status: profile.manifest.status || null,
58
- quality_badge: profile.manifest.quality_badge || null,
59
- risk_level: profile.manifest.risk_level || null,
60
- keywords: profile.keywords,
61
- entries: profile.entries,
62
- asset_digest: profile.asset_digest,
63
- content_digest: profile.content_digest,
62
+ ...current,
63
+ entries,
64
+ asset_digest: asset.asset_digest,
65
+ content_digest: contentDigest,
64
66
  signature_valid: verification ? verification.signature_valid : null,
65
67
  ok: verification ? verification.ok : null,
66
68
  errors: verification ? verification.errors : [],
67
69
  warnings: verification ? verification.warnings : [],
68
- manifest: profile.manifest,
70
+ manifest,
69
71
  };
70
72
  }
71
73
 
72
74
  function inspectKDNASync(input, options = {}) {
73
75
  const reader = readerFrom(options);
74
76
  const asset = asAssetSync(input, { ...options, reader });
75
- const profile = reader.loadProfileSync(asset, 'index', options);
77
+ const current = v1.inspect(canonicalBytes(asset), options);
78
+ const manifest = reader.readManifestSync(asset);
79
+ const entries = reader.listEntriesSync(asset);
80
+ const contentDigest = reader.contentDigestSync(asset);
76
81
  const verification = options.verify === false ? null : reader.verifySync(asset, options);
77
82
  return {
78
- name: profile.name,
79
- version: profile.version,
80
- judgment_version: profile.judgment_version,
81
- access: profile.manifest.access || 'open',
82
- status: profile.manifest.status || null,
83
- quality_badge: profile.manifest.quality_badge || null,
84
- risk_level: profile.manifest.risk_level || null,
85
- keywords: profile.keywords,
86
- entries: profile.entries,
87
- asset_digest: profile.asset_digest,
88
- content_digest: profile.content_digest,
83
+ ...current,
84
+ entries,
85
+ asset_digest: asset.asset_digest,
86
+ content_digest: contentDigest,
89
87
  signature_valid: verification ? verification.signature_valid : null,
90
88
  ok: verification ? verification.ok : null,
91
89
  errors: verification ? verification.errors : [],
92
90
  warnings: verification ? verification.warnings : [],
93
- manifest: profile.manifest,
91
+ manifest,
94
92
  };
95
93
  }
96
94
 
97
95
  async function loadKDNA(input, options = {}) {
98
- const reader = readerFrom(options);
99
- const asset = await asAsset(input, { ...options, reader });
100
- return reader.loadProfile(asset, options.profile || 'compact', options);
96
+ return runtimeApi.loadAuthorized(isAsset(input) ? canonicalBytes(input) : input, options);
101
97
  }
102
98
 
103
99
  function loadKDNASync(input, options = {}) {
104
- const reader = readerFrom(options);
105
- const asset = asAssetSync(input, { ...options, reader });
106
- return reader.loadProfileSync(asset, options.profile || 'compact', options);
100
+ return runtimeApi.loadAuthorized(isAsset(input) ? canonicalBytes(input) : input, options);
107
101
  }
108
102
 
109
103
  async function validateKDNA(input, options = {}) {
110
- const reader = readerFrom(options);
111
- const asset = await asAsset(input, { ...options, reader });
112
- const assetResult = await reader.verify(asset, options);
113
- let dataMap;
114
- let lintResult = { errors: [], warnings: [] };
115
- let schemaResult = { errors: [], warnings: [] };
116
- let crossFileResult = { errors: [], warnings: [] };
117
-
118
- try {
119
- dataMap = await reader.readDataMap(asset, undefined, options);
120
- lintResult = lintDomain(dataMap);
121
- schemaResult = validateDomainSchema(dataMap, options.schemas || {});
122
- crossFileResult = validateCrossFile(dataMap);
123
- } catch (e) {
124
- lintResult.errors.push(e.message);
125
- }
126
-
127
- const errors = [
128
- ...assetResult.errors,
129
- ...lintResult.errors,
130
- ...schemaResult.errors,
131
- ...crossFileResult.errors,
132
- ];
133
- const warnings = [
134
- ...assetResult.warnings,
135
- ...lintResult.warnings,
136
- ...schemaResult.warnings,
137
- ...crossFileResult.warnings,
138
- ];
139
- return {
140
- ok: errors.length === 0,
141
- errors,
142
- warnings,
143
- asset: assetResult,
144
- lint: lintResult,
145
- schema: schemaResult,
146
- cross_file: crossFileResult,
147
- };
104
+ return v1.validate(isAsset(input) ? canonicalBytes(input) : input, options);
148
105
  }
149
106
 
150
107
  function validateKDNASync(input, options = {}) {
151
- const reader = readerFrom(options);
152
- const asset = asAssetSync(input, { ...options, reader });
153
- const assetResult = reader.verifySync(asset, options);
154
- let lintResult = { errors: [], warnings: [] };
155
- let schemaResult = { errors: [], warnings: [] };
156
- let crossFileResult = { errors: [], warnings: [] };
157
-
158
- try {
159
- const dataMap = reader.readDataMapSync(asset, undefined, options);
160
- lintResult = lintDomain(dataMap);
161
- schemaResult = validateDomainSchema(dataMap, options.schemas || {});
162
- crossFileResult = validateCrossFile(dataMap);
163
- } catch (e) {
164
- lintResult.errors.push(e.message);
165
- }
166
-
167
- const errors = [
168
- ...assetResult.errors,
169
- ...lintResult.errors,
170
- ...schemaResult.errors,
171
- ...crossFileResult.errors,
172
- ];
173
- const warnings = [
174
- ...assetResult.warnings,
175
- ...lintResult.warnings,
176
- ...schemaResult.warnings,
177
- ...crossFileResult.warnings,
178
- ];
179
- return {
180
- ok: errors.length === 0,
181
- errors,
182
- warnings,
183
- asset: assetResult,
184
- lint: lintResult,
185
- schema: schemaResult,
186
- cross_file: crossFileResult,
187
- };
108
+ return v1.validate(isAsset(input) ? canonicalBytes(input) : input, options);
188
109
  }
189
110
 
190
111
  async function renderForAgent(input, options = {}) {
191
- const loaded = await loadKDNA(input, options);
192
- if (loaded.context != null) return loaded.context;
193
- return loaded.domain ? formatContext(loaded.domain) : '';
112
+ const loaded = await loadKDNA(input, { ...options, as: 'prompt' });
113
+ return loaded && typeof loaded.text === 'string' ? loaded.text : '';
194
114
  }
195
115
 
196
116
  function renderForAgentSync(input, options = {}) {
197
- const loaded = loadKDNASync(input, options);
198
- if (loaded.context != null) return loaded.context;
199
- return loaded.domain ? formatContext(loaded.domain) : '';
117
+ const loaded = loadKDNASync(input, { ...options, as: 'prompt' });
118
+ return loaded && typeof loaded.text === 'string' ? loaded.text : '';
200
119
  }
201
120
 
202
121
  async function verifyAsset(input, options = {}) {
@@ -230,8 +149,10 @@ function verifySignatureSync(input, options = {}) {
230
149
  function scoreMatch(input, info) {
231
150
  const haystack = String(input || '').toLowerCase();
232
151
  const terms = [
233
- info.name,
234
- ...(info.keywords || []),
152
+ info.asset_id,
153
+ info.title,
154
+ ...(info.keywords || info.manifest?.keywords || []),
155
+ info.summary || info.manifest?.summary,
235
156
  info.manifest?.description,
236
157
  info.manifest?.core_insight,
237
158
  ]
@@ -250,7 +171,7 @@ async function matchDomain(input, candidates, options = {}) {
250
171
  const match = scoreMatch(input, info);
251
172
  if (match.score > 0) results.push({ ...info, score: match.score, matched: match.matched });
252
173
  }
253
- return results.sort((a, b) => b.score - a.score || String(a.name).localeCompare(String(b.name)));
174
+ return results.sort((a, b) => b.score - a.score || String(a.asset_id).localeCompare(String(b.asset_id)));
254
175
  }
255
176
 
256
177
  function matchDomainSync(input, candidates, options = {}) {
@@ -262,42 +183,17 @@ function matchDomainSync(input, candidates, options = {}) {
262
183
  const match = scoreMatch(input, info);
263
184
  if (match.score > 0) results.push({ ...info, score: match.score, matched: match.matched });
264
185
  }
265
- return results.sort((a, b) => b.score - a.score || String(a.name).localeCompare(String(b.name)));
186
+ return results.sort((a, b) => b.score - a.score || String(a.asset_id).localeCompare(String(b.asset_id)));
266
187
  }
267
188
 
268
189
  async function composeKDNA(inputs, options = {}) {
269
- const loaded = [];
270
- for (const input of inputs || []) {
271
- const profile = await loadKDNA(input, { ...options, profile: options.profile || 'compact', context: false });
272
- if (profile.domain) {
273
- loaded.push({
274
- id: profile.manifest.name || profile.domain.core?.meta?.domain,
275
- name: profile.manifest.name || profile.domain.core?.meta?.domain,
276
- manifest: profile.manifest,
277
- ...profile.domain,
278
- });
279
- }
280
- }
281
- const { selected, excluded } = classifySignalsAcrossDomains(options.input || '', loaded);
282
- const selectedIds = new Set(selected.map((d) => d.id));
283
- const activeDomains = options.input ? loaded.filter((d) => selectedIds.has(d.id)) : loaded;
284
- const conflicts = detectDomainConflicts(activeDomains);
285
- const { context, attributionMap } = composeContextWithAttribution(activeDomains, options);
286
- return {
287
- domains: loaded,
288
- activeDomains,
289
- selected,
290
- excluded,
291
- conflicts,
292
- context,
293
- attributionMap,
294
- trace: generateClusterTrace({
295
- input: options.input || '',
296
- loadedDomains: loaded,
297
- activeDomains,
298
- conflicts,
299
- }),
300
- };
190
+ void inputs;
191
+ void options;
192
+ const error = new Error(
193
+ 'composeKDNA is unavailable until the current Cluster/Capsule composition protocol is defined.',
194
+ );
195
+ error.code = 'KDNA_COMPOSE_PROTOCOL_UNAVAILABLE';
196
+ throw error;
301
197
  }
302
198
 
303
199
  module.exports = {
@@ -68,18 +68,17 @@ function planLoad(inputPath, options = {}) {
68
68
  }
69
69
 
70
70
  function loadAuthorized(inputPath, options = {}) {
71
- const plan = planLoad(inputPath, options);
72
- if (plan.can_load_now !== true) {
73
- const issueCodes = Array.isArray(plan.issues)
74
- ? plan.issues.map((issue) => issue.code).filter(Boolean)
75
- : [];
71
+ if (isDirectory(inputPath)) {
72
+ const plan = invalidDirectoryPlan(inputPath);
76
73
  const error = new Error(
77
74
  `LoadPlan denied loading: state=${plan.state || 'invalid'} required_action=${plan.required_action || 'block'}`,
78
75
  );
79
- error.code = issueCodes[0] || 'KDNA_LOAD_NOT_AUTHORIZED';
76
+ error.code = 'KDNA_ASSET_FILE_REQUIRED';
80
77
  error.plan = plan;
81
78
  throw error;
82
79
  }
80
+ // v1.loadAuthorized snapshots packaged paths once and uses that same Buffer
81
+ // for its LoadPlan, authorization decision, and Runtime Capsule projection.
83
82
  return v1.loadAuthorized(inputPath, guardResolver(options));
84
83
  }
85
84