@aikdna/kdna-core 0.18.0 → 0.19.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 (44) hide show
  1. package/CHANGELOG.md +128 -94
  2. package/README.md +109 -215
  3. package/package.json +7 -2
  4. package/schema/agent-host-capabilities.schema.json +62 -0
  5. package/schema/agent-host-receipt.schema.json +371 -0
  6. package/schema/agent-host-request.schema.json +223 -0
  7. package/schema/{bundle-profile-v1.schema.json → bundle-profile.schema.json} +9 -5
  8. package/schema/checksums.schema.json +8 -8
  9. package/schema/consumption-plan.schema.json +428 -0
  10. package/schema/digest-evidence.schema.json +115 -26
  11. package/schema/{kdna-envelope-external-grant-v1.schema.json → external-grant-envelope.schema.json} +17 -4
  12. package/schema/{kdna-key-grant-v1.schema.json → external-key-grant.schema.json} +39 -7
  13. package/schema/judgment-trace.schema.json +1251 -0
  14. package/schema/load-plan.schema.json +5 -3
  15. package/schema/manifest.schema.json +70 -10
  16. package/schema/{payload-profile-v1.schema.json → payload-profile.schema.json} +30 -6
  17. package/schema/{runtime-capsule-2.schema.json → runtime-capsule.schema.json} +7 -31
  18. package/src/asset-reader.js +8 -2
  19. package/src/{v1 → container}/index.js +385 -198
  20. package/src/container/index.mjs +20 -0
  21. package/src/container-dispatcher.js +6 -6
  22. package/src/crypto-profile.js +37 -107
  23. package/src/external-key-grant.js +41 -15
  24. package/src/index.js +11 -8
  25. package/src/index.mjs +49 -45
  26. package/src/loader-compatibility.js +59 -0
  27. package/src/loader.js +1 -1
  28. package/src/public-api.js +5 -5
  29. package/src/remote-runtime.d.ts +13 -0
  30. package/src/remote-runtime.js +27 -0
  31. package/src/remote-runtime.mjs +3 -0
  32. package/src/runtime-api.js +5 -5
  33. package/src/{capsule-v2.js → runtime-capsule.js} +96 -254
  34. package/src/{execution-contract-v1.js → runtime-contract.js} +184 -152
  35. package/src/types.d.ts +200 -277
  36. package/src/workpack-pure.js +1 -1
  37. package/schema/agent-host-2-receipt.schema.json +0 -206
  38. package/schema/agent-host-2-request.schema.json +0 -135
  39. package/schema/agent-host-capabilities-1.schema.json +0 -40
  40. package/schema/consumption-plan-1.schema.json +0 -280
  41. package/schema/judgment-trace-1.schema.json +0 -748
  42. package/schema/runtime-capsule-1.schema.json +0 -68
  43. package/src/lint-pure.js +0 -433
  44. package/src/v1/index.mjs +0 -21
@@ -2,24 +2,29 @@
2
2
 
3
3
  const crypto = require('node:crypto');
4
4
 
5
- const Ajv2020 = require('ajv/dist/2020');
5
+ const JsonSchema2020 = require('ajv/dist/2020');
6
6
  const addFormats = require('ajv-formats');
7
7
 
8
- const { canonicalizeJcs, computeCapsuleDeliveryDigest } = require('./capsule-v2');
8
+ const { canonicalizeJcs, computeCapsuleDeliveryDigest } = require('./runtime-capsule');
9
9
  const digestEvidenceSchema = require('../schema/digest-evidence.schema.json');
10
- const capsule2Schema = require('../schema/runtime-capsule-2.schema.json');
11
- const planSchema = require('../schema/consumption-plan-1.schema.json');
12
- const capabilitiesSchema = require('../schema/agent-host-capabilities-1.schema.json');
13
- const requestSchema = require('../schema/agent-host-2-request.schema.json');
14
- const receiptSchema = require('../schema/agent-host-2-receipt.schema.json');
15
- const traceSchema = require('../schema/judgment-trace-1.schema.json');
16
-
17
- const PLAN_DIGEST_PROFILE = 'kdna-consumption-plan-jcs-v1';
18
- const CAPSULE_DELIVERY_PROFILE = 'kdna-capsule-jcs-v1';
19
- const CAPSULE_DIGEST_PROFILE = 'kdna-capsule-digests-v1';
20
- const HOST_PROTOCOL = 'kdna.agent-host/2';
21
- const CAPSULE_VERSION = '2.0';
22
- const DEFAULT_CORE_CAPSULE_VERSIONS = Object.freeze(['2.0', '1.0']);
10
+ const runtimeCapsuleSchema = require('../schema/runtime-capsule.schema.json');
11
+ const planSchema = require('../schema/consumption-plan.schema.json');
12
+ const capabilitiesSchema = require('../schema/agent-host-capabilities.schema.json');
13
+ const requestSchema = require('../schema/agent-host-request.schema.json');
14
+ const receiptSchema = require('../schema/agent-host-receipt.schema.json');
15
+ const traceSchema = require('../schema/judgment-trace.schema.json');
16
+
17
+ const PLAN_DIGEST_PROFILE = 'kdna.canonicalization.consumption-plan-jcs';
18
+ const PLAN_DIGEST_PROFILE_VERSION = '0.1.0';
19
+ const CAPSULE_DELIVERY_PROFILE = 'kdna.canonicalization.runtime-capsule-jcs';
20
+ const CAPSULE_DELIVERY_PROFILE_VERSION = '0.1.0';
21
+ const CAPSULE_DIGEST_PROFILE = 'kdna.digest-evidence';
22
+ const HOST_PROTOCOL = 'kdna.agent-host';
23
+ const HOST_PROTOCOL_VERSION = '0.1.0';
24
+ const CAPSULE_CONTRACT_VERSION = '0.1.0';
25
+ const DEFAULT_CORE_CAPSULE_CONTRACT_VERSIONS = Object.freeze([
26
+ CAPSULE_CONTRACT_VERSION,
27
+ ]);
23
28
  const JSON_MAX_BYTES = 2 * 1024 * 1024;
24
29
  const JSON_MAX_DEPTH = 64;
25
30
  const PRE_HOST_INTERNAL_REQUEST_ID = 'host_000000000000000000000000';
@@ -31,10 +36,10 @@ const PRE_HOST_BUDGET_ERROR = Object.freeze({
31
36
 
32
37
  let validators;
33
38
 
34
- class KDNAExecutionContractError extends Error {
39
+ class KDNARuntimeContractError extends Error {
35
40
  constructor(code, message, details) {
36
41
  super(message);
37
- this.name = 'KDNAExecutionContractError';
42
+ this.name = 'KDNARuntimeContractError';
38
43
  this.code = code;
39
44
  if (details !== undefined) this.details = details;
40
45
  }
@@ -42,11 +47,11 @@ class KDNAExecutionContractError extends Error {
42
47
 
43
48
  function schemaValidators() {
44
49
  if (validators) return validators;
45
- const ajv = new Ajv2020({ allErrors: true, strict: false });
50
+ const ajv = new JsonSchema2020({ allErrors: true, strict: false });
46
51
  addFormats(ajv);
47
52
  for (const schema of [
48
53
  digestEvidenceSchema,
49
- capsule2Schema,
54
+ runtimeCapsuleSchema,
50
55
  planSchema,
51
56
  capabilitiesSchema,
52
57
  requestSchema,
@@ -80,7 +85,7 @@ function invalid(code, message, details) {
80
85
  function throwInvalid(result) {
81
86
  if (result.valid) return;
82
87
  const first = result.errors[0] || {};
83
- throw new KDNAExecutionContractError(
88
+ throw new KDNARuntimeContractError(
84
89
  result.code || 'KDNA_EXECUTION_CONTRACT_INVALID',
85
90
  first.message || 'KDNA execution contract is invalid.',
86
91
  first.details,
@@ -111,7 +116,7 @@ function jcsCharacterCount(value) {
111
116
  }
112
117
 
113
118
  function snapshotJsonValue(value) {
114
- return parseExecutionContractJsonV1(canonicalizeJcs(value));
119
+ return parseRuntimeContractJson(canonicalizeJcs(value));
115
120
  }
116
121
 
117
122
  function validateSchema(kind, value) {
@@ -130,7 +135,7 @@ function validateSchema(kind, value) {
130
135
  ) {
131
136
  return invalid(
132
137
  'KDNA_ASSET_FILE_REQUIRED',
133
- 'ConsumptionPlan 1 requires a packaged .kdna Runtime asset.',
138
+ 'ConsumptionPlan requires a packaged .kdna Runtime asset.',
134
139
  details,
135
140
  );
136
141
  }
@@ -252,14 +257,14 @@ function snapshotPublicInput(input, requiredKeys, optionalKeys = []) {
252
257
  * Duplicate member names are rejected after JSON escape decoding, so
253
258
  * {"a": 1, "\\u0061": 2} is also rejected.
254
259
  */
255
- function parseExecutionContractJsonV1(input, options = {}) {
260
+ function parseRuntimeContractJson(input, options = {}) {
256
261
  if (
257
262
  options === null ||
258
263
  typeof options !== 'object' ||
259
264
  Array.isArray(options) ||
260
265
  Object.getPrototypeOf(options) !== Object.prototype
261
266
  ) {
262
- throw new KDNAExecutionContractError(
267
+ throw new KDNARuntimeContractError(
263
268
  'KDNA_JSON_OPTIONS_INVALID',
264
269
  'Execution-contract JSON parser options must be a plain object.',
265
270
  );
@@ -274,7 +279,7 @@ function parseExecutionContractJsonV1(input, options = {}) {
274
279
  !Object.prototype.hasOwnProperty.call(descriptors[key], 'value'),
275
280
  )
276
281
  ) {
277
- throw new KDNAExecutionContractError(
282
+ throw new KDNARuntimeContractError(
278
283
  'KDNA_JSON_OPTIONS_INVALID',
279
284
  'Execution-contract JSON parser options contain an unknown or accessor property.',
280
285
  );
@@ -289,7 +294,7 @@ function parseExecutionContractJsonV1(input, options = {}) {
289
294
  maxDepth < 1 ||
290
295
  maxDepth > JSON_MAX_DEPTH
291
296
  ) {
292
- throw new KDNAExecutionContractError(
297
+ throw new KDNARuntimeContractError(
293
298
  'KDNA_JSON_OPTIONS_INVALID',
294
299
  `maxBytes and maxDepth must be positive safe integers no greater than ${JSON_MAX_BYTES} and ${JSON_MAX_DEPTH}.`,
295
300
  );
@@ -299,13 +304,13 @@ function parseExecutionContractJsonV1(input, options = {}) {
299
304
  text = input;
300
305
  } else if (Buffer.isBuffer(input) || input instanceof Uint8Array) {
301
306
  if (input.byteLength > maxBytes) {
302
- throw new KDNAExecutionContractError(
307
+ throw new KDNARuntimeContractError(
303
308
  'KDNA_JSON_LIMIT_EXCEEDED',
304
309
  'Execution-contract JSON exceeds the configured byte limit.',
305
310
  );
306
311
  }
307
312
  if (input.byteLength >= 3 && input[0] === 0xef && input[1] === 0xbb && input[2] === 0xbf) {
308
- throw new KDNAExecutionContractError(
313
+ throw new KDNARuntimeContractError(
309
314
  'KDNA_JSON_BOM_FORBIDDEN',
310
315
  'Execution-contract JSON must not begin with a UTF-8 BOM.',
311
316
  );
@@ -313,27 +318,27 @@ function parseExecutionContractJsonV1(input, options = {}) {
313
318
  try {
314
319
  text = new TextDecoder('utf-8', { fatal: true }).decode(input);
315
320
  } catch {
316
- throw new KDNAExecutionContractError(
321
+ throw new KDNARuntimeContractError(
317
322
  'KDNA_JSON_INVALID_UNICODE',
318
323
  'Execution-contract JSON is not valid UTF-8.',
319
324
  );
320
325
  }
321
326
  } else {
322
- throw new KDNAExecutionContractError(
327
+ throw new KDNARuntimeContractError(
323
328
  'KDNA_JSON_INPUT_INVALID',
324
329
  'Execution-contract JSON input must be a string, Buffer, or Uint8Array.',
325
330
  );
326
331
  }
327
332
 
328
333
  if (text.charCodeAt(0) === 0xfeff) {
329
- throw new KDNAExecutionContractError(
334
+ throw new KDNARuntimeContractError(
330
335
  'KDNA_JSON_BOM_FORBIDDEN',
331
336
  'Execution-contract JSON must not begin with a BOM.',
332
337
  );
333
338
  }
334
339
 
335
340
  if (Buffer.byteLength(text, 'utf8') > maxBytes) {
336
- throw new KDNAExecutionContractError(
341
+ throw new KDNARuntimeContractError(
337
342
  'KDNA_JSON_LIMIT_EXCEEDED',
338
343
  'Execution-contract JSON exceeds the configured byte limit.',
339
344
  );
@@ -359,7 +364,7 @@ class StrictJsonParser {
359
364
  }
360
365
 
361
366
  syntax(message) {
362
- throw new KDNAExecutionContractError('KDNA_JSON_SYNTAX_INVALID', message, {
367
+ throw new KDNARuntimeContractError('KDNA_JSON_SYNTAX_INVALID', message, {
363
368
  code_unit_offset: this.index,
364
369
  });
365
370
  }
@@ -381,7 +386,7 @@ class StrictJsonParser {
381
386
  const char = this.text[this.index];
382
387
  if (char === '{' || char === '[') {
383
388
  if (depth >= this.maxDepth) {
384
- throw new KDNAExecutionContractError(
389
+ throw new KDNARuntimeContractError(
385
390
  'KDNA_JSON_LIMIT_EXCEEDED',
386
391
  'Execution-contract JSON exceeds the configured nesting limit.',
387
392
  );
@@ -418,7 +423,7 @@ class StrictJsonParser {
418
423
  if (this.text[this.index] !== '"') this.syntax('Expected a quoted JSON member name.');
419
424
  const key = this.parseString();
420
425
  if (keys.has(key)) {
421
- throw new KDNAExecutionContractError(
426
+ throw new KDNARuntimeContractError(
422
427
  'KDNA_JSON_DUPLICATE_KEY',
423
428
  `Execution-contract JSON contains duplicate member name ${JSON.stringify(key)}.`,
424
429
  { key, code_unit_offset: this.index },
@@ -529,7 +534,7 @@ class StrictJsonParser {
529
534
  }
530
535
 
531
536
  invalidUnicode() {
532
- throw new KDNAExecutionContractError(
537
+ throw new KDNARuntimeContractError(
533
538
  'KDNA_JSON_INVALID_UNICODE',
534
539
  'Execution-contract JSON contains an unpaired UTF-16 surrogate.',
535
540
  { code_unit_offset: this.index },
@@ -544,7 +549,7 @@ class StrictJsonParser {
544
549
  this.index += token.length;
545
550
  const number = Number(token);
546
551
  if (!Number.isFinite(number)) {
547
- throw new KDNAExecutionContractError(
552
+ throw new KDNARuntimeContractError(
548
553
  'KDNA_JSON_NUMBER_INVALID',
549
554
  'Execution-contract JSON number is outside the finite IEEE-754 range.',
550
555
  );
@@ -553,7 +558,7 @@ class StrictJsonParser {
553
558
  }
554
559
  }
555
560
 
556
- function computeConsumptionPlanDigestV1(plan) {
561
+ function computeConsumptionPlanDigest(plan) {
557
562
  try {
558
563
  if (plan === null || typeof plan !== 'object' || Array.isArray(plan)) {
559
564
  throw new TypeError('plan must be an object');
@@ -562,8 +567,8 @@ function computeConsumptionPlanDigestV1(plan) {
562
567
  delete projection.integrity;
563
568
  return digestJcs(projection);
564
569
  } catch (error) {
565
- if (error instanceof KDNAExecutionContractError) throw error;
566
- throw new KDNAExecutionContractError(
570
+ if (error instanceof KDNARuntimeContractError) throw error;
571
+ throw new KDNARuntimeContractError(
567
572
  'KDNA_PLAN_INPUT_INVALID',
568
573
  'ConsumptionPlan digest input must be a finite, acyclic JSON object.',
569
574
  { cause: error && typeof error.message === 'string' ? error.message : String(error) },
@@ -574,7 +579,7 @@ function computeConsumptionPlanDigestV1(plan) {
574
579
  function validatePlanSemantics(plan, trustedPlanDigest) {
575
580
  let computed;
576
581
  try {
577
- computed = computeConsumptionPlanDigestV1(plan);
582
+ computed = computeConsumptionPlanDigest(plan);
578
583
  } catch {
579
584
  return 'KDNA_PLAN_INPUT_INVALID';
580
585
  }
@@ -585,7 +590,7 @@ function validatePlanSemantics(plan, trustedPlanDigest) {
585
590
  return null;
586
591
  }
587
592
 
588
- function validateConsumptionPlanV1(plan, context) {
593
+ function validateConsumptionPlan(plan, context) {
589
594
  const contextResult = snapshotContext(context, ['trustedPlanDigest']);
590
595
  if (!contextResult.valid) return contextResult;
591
596
  const safeContext = contextResult.value;
@@ -605,12 +610,12 @@ function validateConsumptionPlanV1(plan, context) {
605
610
  return code ? invalid(code, 'ConsumptionPlan integrity correlation failed.') : ok(safePlan);
606
611
  }
607
612
 
608
- function buildConsumptionPlanV1(input) {
613
+ function buildConsumptionPlan(input) {
609
614
  let plan;
610
615
  try {
611
616
  plan = {
612
- type: 'kdna.consumption.plan',
613
- plan_version: '1.0.0',
617
+ type: 'kdna.consumption-plan',
618
+ contract_version: '0.1.0',
614
619
  plan_id: input.plan_id,
615
620
  created_at: input.created_at,
616
621
  mode: 'single',
@@ -618,26 +623,31 @@ function buildConsumptionPlanV1(input) {
618
623
  asset_ref: clone(input.asset_ref),
619
624
  projection_request: {
620
625
  profile: input.projection_profile,
621
- accepted_capsule_versions: [CAPSULE_VERSION],
626
+ accepted_capsule_versions: [CAPSULE_CONTRACT_VERSION],
622
627
  required_digest_profile: CAPSULE_DIGEST_PROFILE,
628
+ required_digest_profile_version: '0.1.0',
623
629
  require_packaged_asset: true,
624
630
  },
625
631
  host_request: { accepted_protocols: [HOST_PROTOCOL] },
626
632
  result_request: { shape: 'structured_judgment' },
627
633
  budget: clone(input.budget),
628
634
  trace_policy: clone(input.trace_policy),
629
- integrity: { profile: PLAN_DIGEST_PROFILE, plan_digest: '' },
635
+ integrity: {
636
+ profile: PLAN_DIGEST_PROFILE,
637
+ profile_version: PLAN_DIGEST_PROFILE_VERSION,
638
+ plan_digest: '',
639
+ },
630
640
  constraints: clone(input.constraints),
631
641
  };
632
- plan.integrity.plan_digest = computeConsumptionPlanDigestV1(plan);
642
+ plan.integrity.plan_digest = computeConsumptionPlanDigest(plan);
633
643
  } catch (error) {
634
- if (error instanceof KDNAExecutionContractError) throw error;
635
- throw new KDNAExecutionContractError(
644
+ if (error instanceof KDNARuntimeContractError) throw error;
645
+ throw new KDNARuntimeContractError(
636
646
  'KDNA_PLAN_INPUT_INVALID',
637
- 'Cannot build ConsumptionPlan 1 from the supplied input.',
647
+ 'Cannot build ConsumptionPlan from the supplied input.',
638
648
  );
639
649
  }
640
- const result = validateConsumptionPlanV1(plan, {
650
+ const result = validateConsumptionPlan(plan, {
641
651
  trustedPlanDigest: plan.integrity.plan_digest,
642
652
  });
643
653
  throwInvalid(result);
@@ -653,7 +663,7 @@ function blocked(issueCode) {
653
663
  };
654
664
  }
655
665
 
656
- function negotiateExecutionPairV1(plan, context) {
666
+ function negotiateRuntimePair(plan, context) {
657
667
  const contextResult = snapshotContext(context, [
658
668
  'trustedPlanDigest',
659
669
  'capabilities',
@@ -661,7 +671,7 @@ function negotiateExecutionPairV1(plan, context) {
661
671
  ]);
662
672
  if (!contextResult.valid) return blocked(contextResult.code);
663
673
  const safeContext = contextResult.value;
664
- const planResult = validateConsumptionPlanV1(plan, {
674
+ const planResult = validateConsumptionPlan(plan, {
665
675
  trustedPlanDigest: safeContext.trustedPlanDigest,
666
676
  });
667
677
  if (!planResult.valid) return blocked(planResult.code);
@@ -677,10 +687,10 @@ function negotiateExecutionPairV1(plan, context) {
677
687
  }
678
688
 
679
689
  const hasCapsule =
680
- safePlan.projection_request.accepted_capsule_versions.includes(CAPSULE_VERSION) &&
681
- safeContext.coreCapsuleVersions.includes(CAPSULE_VERSION) &&
682
- safeCapabilities.capsule_versions.includes(CAPSULE_VERSION);
683
- if (!hasCapsule) return blocked('KDNA_CAPSULE_VERSION_UNSUPPORTED');
690
+ safePlan.projection_request.accepted_capsule_versions.includes(CAPSULE_CONTRACT_VERSION) &&
691
+ safeContext.coreCapsuleVersions.includes(CAPSULE_CONTRACT_VERSION) &&
692
+ safeCapabilities.capsule_versions.includes(CAPSULE_CONTRACT_VERSION);
693
+ if (!hasCapsule) return blocked('KDNA_CAPSULE_CONTRACT_VERSION_UNSUPPORTED');
684
694
 
685
695
  const hasProtocol =
686
696
  safePlan.host_request.accepted_protocols.includes(HOST_PROTOCOL) &&
@@ -694,7 +704,7 @@ function negotiateExecutionPairV1(plan, context) {
694
704
 
695
705
  return {
696
706
  state: 'selected',
697
- capsule_version: CAPSULE_VERSION,
707
+ capsule_version: CAPSULE_CONTRACT_VERSION,
698
708
  host_protocol: HOST_PROTOCOL,
699
709
  issue_code: null,
700
710
  };
@@ -702,7 +712,7 @@ function negotiateExecutionPairV1(plan, context) {
702
712
 
703
713
  function expectedAgainst(source) {
704
714
  if (source === 'kdna.json.content_digest') return 'manifest_declaration';
705
- if (source === 'checksums.json.entry_set_digest' || source === 'checksums.json.asset_digest') {
715
+ if (source === 'checksums.json.entry_set_digest') {
706
716
  return 'checksum_declaration';
707
717
  }
708
718
  return 'external_expected';
@@ -742,8 +752,9 @@ function validateRequestSemantics(request, plan, enforceBudget = true) {
742
752
  if (
743
753
  request.plan_ref.plan_id !== plan.plan_id ||
744
754
  request.plan_ref.plan_digest_profile !== plan.integrity.profile ||
755
+ request.plan_ref.plan_digest_profile_version !== plan.integrity.profile_version ||
745
756
  request.plan_ref.plan_digest !== plan.integrity.plan_digest ||
746
- computeConsumptionPlanDigestV1(plan) !== plan.integrity.plan_digest
757
+ computeConsumptionPlanDigest(plan) !== plan.integrity.plan_digest
747
758
  ) {
748
759
  return 'KDNA_HOST_PLAN_REF_MISMATCH';
749
760
  }
@@ -762,14 +773,18 @@ function validateRequestSemantics(request, plan, enforceBudget = true) {
762
773
  if (request.capsule.access !== plan.asset_ref.access) return 'KDNA_HOST_ASSET_REF_MISMATCH';
763
774
 
764
775
  if (
765
- request.runtime_contract.capsule_version !== request.capsule.version ||
766
- request.capsule.version !== CAPSULE_VERSION
776
+ request.runtime_contract.capsule_version !== request.capsule.contract_version ||
777
+ request.capsule.contract_version !== CAPSULE_CONTRACT_VERSION
767
778
  ) {
768
- return 'KDNA_HOST_CAPSULE_VERSION_MISMATCH';
779
+ return 'KDNA_HOST_CAPSULE_CONTRACT_VERSION_MISMATCH';
769
780
  }
770
781
  if (
771
782
  request.runtime_contract.capsule_digest_profile !== CAPSULE_DELIVERY_PROFILE ||
772
- request.capsule.digests.profile !== plan.projection_request.required_digest_profile
783
+ request.runtime_contract.capsule_digest_profile_version !==
784
+ CAPSULE_DELIVERY_PROFILE_VERSION ||
785
+ request.capsule.digests.profile !== plan.projection_request.required_digest_profile ||
786
+ request.capsule.digests.profile_version !==
787
+ plan.projection_request.required_digest_profile_version
773
788
  ) {
774
789
  return 'KDNA_HOST_PROJECTION_CONTRACT_MISMATCH';
775
790
  }
@@ -777,6 +792,8 @@ function validateRequestSemantics(request, plan, enforceBudget = true) {
777
792
  const expectedProjectionContract = {
778
793
  profile: plan.projection_request.profile,
779
794
  required_digest_profile: plan.projection_request.required_digest_profile,
795
+ required_digest_profile_version:
796
+ plan.projection_request.required_digest_profile_version,
780
797
  require_packaged_asset: plan.projection_request.require_packaged_asset,
781
798
  };
782
799
  if (
@@ -813,7 +830,7 @@ function validateRequestSemantics(request, plan, enforceBudget = true) {
813
830
  return null;
814
831
  }
815
832
 
816
- function validateAgentHost2RequestV1(request, context) {
833
+ function validateAgentHostRequest(request, context) {
817
834
  const contextResult = snapshotContext(context, [
818
835
  'plan',
819
836
  'trustedPlanDigest',
@@ -825,42 +842,47 @@ function validateAgentHost2RequestV1(request, context) {
825
842
  const schemaResult = validateSchema('request', request);
826
843
  if (!schemaResult.valid) return schemaResult;
827
844
  const safeRequest = schemaResult.value;
828
- const planResult = validateConsumptionPlanV1(safeContext.plan, {
845
+ const planResult = validateConsumptionPlan(safeContext.plan, {
829
846
  trustedPlanDigest: safeContext.trustedPlanDigest,
830
847
  });
831
848
  if (!planResult.valid) return planResult;
832
849
  const safePlan = planResult.value;
833
- const negotiation = negotiateExecutionPairV1(safePlan, safeContext);
850
+ const negotiation = negotiateRuntimePair(safePlan, safeContext);
834
851
  if (negotiation.state !== 'selected') {
835
- return invalid(negotiation.issue_code, 'No strict ConsumptionPlan 1 / Host 2 pair was selected.');
852
+ return invalid(negotiation.issue_code, 'No strict ConsumptionPlan / Agent Host pair was selected.');
836
853
  }
837
854
  try {
838
855
  const code = validateRequestSemantics(safeRequest, safePlan, true);
839
- return code ? invalid(code, 'Agent Host 2 request correlation failed.') : ok(safeRequest);
856
+ return code ? invalid(code, 'Agent Host request correlation failed.') : ok(safeRequest);
840
857
  } catch (error) {
841
- return invalid('KDNA_INPUT_INVALID', 'Agent Host 2 request is not a safe JSON value.', {
858
+ return invalid('KDNA_INPUT_INVALID', 'Agent Host request is not a safe JSON value.', {
842
859
  cause: error && typeof error.message === 'string' ? error.message : String(error),
843
860
  });
844
861
  }
845
862
  }
846
863
 
847
- function assembleAgentHost2RequestV1(input, plan) {
864
+ function assembleAgentHostRequest(input, plan) {
848
865
  return {
849
866
  protocol: HOST_PROTOCOL,
867
+ protocol_version: HOST_PROTOCOL_VERSION,
850
868
  request_id: input.request_id,
851
869
  plan_ref: {
852
870
  plan_id: plan.plan_id,
853
871
  plan_digest_profile: plan.integrity.profile,
872
+ plan_digest_profile_version: plan.integrity.profile_version,
854
873
  plan_digest: plan.integrity.plan_digest,
855
874
  },
856
875
  runtime_contract: {
857
- capsule_version: CAPSULE_VERSION,
876
+ capsule_version: CAPSULE_CONTRACT_VERSION,
858
877
  capsule_digest_profile: CAPSULE_DELIVERY_PROFILE,
878
+ capsule_digest_profile_version: CAPSULE_DELIVERY_PROFILE_VERSION,
859
879
  capsule_delivery_digest: computeCapsuleDeliveryDigest(input.capsule),
860
880
  },
861
881
  projection_contract: {
862
882
  profile: plan.projection_request.profile,
863
883
  required_digest_profile: plan.projection_request.required_digest_profile,
884
+ required_digest_profile_version:
885
+ plan.projection_request.required_digest_profile_version,
864
886
  require_packaged_asset: plan.projection_request.require_packaged_asset,
865
887
  },
866
888
  result_contract: clone(plan.result_request),
@@ -874,7 +896,7 @@ function assembleAgentHost2RequestV1(input, plan) {
874
896
  };
875
897
  }
876
898
 
877
- function buildAgentHost2RequestV1(input, context) {
899
+ function buildAgentHostRequest(input, context) {
878
900
  const contextResult = snapshotContext(context, [
879
901
  'plan',
880
902
  'trustedPlanDigest',
@@ -885,34 +907,38 @@ function buildAgentHost2RequestV1(input, context) {
885
907
  const inputResult = snapshotPublicInput(input, ['request_id', 'capsule']);
886
908
  throwInvalid(inputResult);
887
909
  const safeContext = contextResult.value;
888
- const planResult = validateConsumptionPlanV1(safeContext.plan, {
910
+ const planResult = validateConsumptionPlan(safeContext.plan, {
889
911
  trustedPlanDigest: safeContext.trustedPlanDigest,
890
912
  });
891
913
  throwInvalid(planResult);
892
914
  const plan = planResult.value;
893
- const negotiation = negotiateExecutionPairV1(plan, safeContext);
915
+ const negotiation = negotiateRuntimePair(plan, safeContext);
894
916
  if (negotiation.state !== 'selected') {
895
- throw new KDNAExecutionContractError(
917
+ throw new KDNARuntimeContractError(
896
918
  negotiation.issue_code,
897
- 'Cannot build Host 2 request without a selected strict execution pair.',
919
+ 'Cannot build Agent Host request without a selected strict execution pair.',
898
920
  );
899
921
  }
900
922
  let request;
901
923
  try {
902
- request = assembleAgentHost2RequestV1(inputResult.value, plan);
924
+ request = assembleAgentHostRequest(inputResult.value, plan);
903
925
  } catch {
904
- throw new KDNAExecutionContractError(
926
+ throw new KDNARuntimeContractError(
905
927
  'KDNA_HOST_REQUEST_INPUT_INVALID',
906
- 'Cannot build Agent Host 2 request from the supplied input.',
928
+ 'Cannot build Agent Host request from the supplied input.',
907
929
  );
908
930
  }
909
- const result = validateAgentHost2RequestV1(request, { ...safeContext, plan });
931
+ const result = validateAgentHostRequest(request, { ...safeContext, plan });
910
932
  throwInvalid(result);
911
933
  return request;
912
934
  }
913
935
 
914
936
  function validateReceiptSemantics(receipt, request) {
915
- if (receipt.protocol !== request.protocol || receipt.request_id !== request.request_id) {
937
+ if (
938
+ receipt.protocol !== request.protocol ||
939
+ receipt.protocol_version !== request.protocol_version ||
940
+ receipt.request_id !== request.request_id
941
+ ) {
916
942
  return 'KDNA_HOST_REQUEST_ID_MISMATCH';
917
943
  }
918
944
  const runtimeReceipt = receipt.runtime_receipt;
@@ -947,7 +973,7 @@ function validateReceiptSemantics(receipt, request) {
947
973
  runtimeReceipt.capsule_version !== request.runtime_contract.capsule_version ||
948
974
  runtimeReceipt.capsule_digest_profile !== request.runtime_contract.capsule_digest_profile
949
975
  ) {
950
- return 'KDNA_HOST_CAPSULE_VERSION_MISMATCH';
976
+ return 'KDNA_HOST_CAPSULE_CONTRACT_VERSION_MISMATCH';
951
977
  }
952
978
 
953
979
  const outcomeUsage = receipt.outcome?.usage ?? null;
@@ -971,7 +997,7 @@ function validateReceiptSemantics(receipt, request) {
971
997
  return null;
972
998
  }
973
999
 
974
- function validateAgentHost2ReceiptV1(receipt, context) {
1000
+ function validateAgentHostReceipt(receipt, context) {
975
1001
  const contextResult = snapshotContext(context, ['request']);
976
1002
  if (!contextResult.valid) return contextResult;
977
1003
  const safeContext = contextResult.value;
@@ -982,16 +1008,16 @@ function validateAgentHost2ReceiptV1(receipt, context) {
982
1008
  if (!requestSchemaResult.valid) {
983
1009
  return invalid(
984
1010
  'KDNA_VALIDATION_CONTEXT_INVALID',
985
- 'Receipt validation requires a schema-valid independent Host 2 request.',
1011
+ 'Receipt validation requires a schema-valid independent Agent Host request.',
986
1012
  requestSchemaResult.errors,
987
1013
  );
988
1014
  }
989
1015
  const safeRequest = requestSchemaResult.value;
990
1016
  try {
991
1017
  const code = validateReceiptSemantics(safeReceipt, safeRequest);
992
- return code ? invalid(code, 'Agent Host 2 receipt correlation failed.') : ok(safeReceipt);
1018
+ return code ? invalid(code, 'Agent Host receipt correlation failed.') : ok(safeReceipt);
993
1019
  } catch (error) {
994
- return invalid('KDNA_INPUT_INVALID', 'Agent Host 2 receipt is not a safe JSON value.', {
1020
+ return invalid('KDNA_INPUT_INVALID', 'Agent Host receipt is not a safe JSON value.', {
995
1021
  cause: error && typeof error.message === 'string' ? error.message : String(error),
996
1022
  });
997
1023
  }
@@ -1038,11 +1064,11 @@ function expectedBudgetEvidence(plan, request, receipt) {
1038
1064
  return { limits: clone(plan.budget), actual, comparison };
1039
1065
  }
1040
1066
 
1041
- function deriveBudgetEvidenceV1(plan, context) {
1067
+ function deriveBudgetEvidence(plan, context) {
1042
1068
  const contextResult = snapshotContext(context, ['trustedPlanDigest', 'request', 'receipt']);
1043
1069
  throwInvalid(contextResult);
1044
1070
  const safeContext = contextResult.value;
1045
- const planResult = validateConsumptionPlanV1(plan, {
1071
+ const planResult = validateConsumptionPlan(plan, {
1046
1072
  trustedPlanDigest: safeContext.trustedPlanDigest,
1047
1073
  });
1048
1074
  throwInvalid(planResult);
@@ -1050,29 +1076,29 @@ function deriveBudgetEvidenceV1(plan, context) {
1050
1076
  if (safeContext.request !== null) {
1051
1077
  const requestResult = validateSchema('request', safeContext.request);
1052
1078
  if (!requestResult.valid) {
1053
- throw new KDNAExecutionContractError(
1079
+ throw new KDNARuntimeContractError(
1054
1080
  'KDNA_VALIDATION_CONTEXT_INVALID',
1055
- 'Budget derivation requires a schema-valid independent Host 2 request.',
1081
+ 'Budget derivation requires a schema-valid independent Agent Host request.',
1056
1082
  requestResult.errors,
1057
1083
  );
1058
1084
  }
1059
1085
  safeContext.request = requestResult.value;
1060
1086
  const requestCode = validateRequestSemantics(safeContext.request, safePlan, false);
1061
1087
  if (requestCode !== null) {
1062
- throw new KDNAExecutionContractError(
1088
+ throw new KDNARuntimeContractError(
1063
1089
  requestCode,
1064
- 'Budget derivation requires an independently correlated Host 2 request.',
1090
+ 'Budget derivation requires an independently correlated Agent Host request.',
1065
1091
  );
1066
1092
  }
1067
1093
  }
1068
1094
  if (safeContext.receipt !== null) {
1069
1095
  if (safeContext.request === null) {
1070
- throw new KDNAExecutionContractError(
1096
+ throw new KDNARuntimeContractError(
1071
1097
  'KDNA_VALIDATION_CONTEXT_INVALID',
1072
1098
  'Budget derivation cannot use a receipt without its independent request.',
1073
1099
  );
1074
1100
  }
1075
- const receiptResult = validateAgentHost2ReceiptV1(safeContext.receipt, {
1101
+ const receiptResult = validateAgentHostReceipt(safeContext.receipt, {
1076
1102
  request: safeContext.request,
1077
1103
  });
1078
1104
  throwInvalid(receiptResult);
@@ -1081,13 +1107,13 @@ function deriveBudgetEvidenceV1(plan, context) {
1081
1107
  return expectedBudgetEvidence(safePlan, safeContext.request, safeContext.receipt);
1082
1108
  }
1083
1109
 
1084
- function preparePreHostBudgetBlockedV1(capsule, safeContext) {
1085
- const planResult = validateConsumptionPlanV1(safeContext.plan, {
1110
+ function preparePreHostBudgetBlocked(capsule, safeContext) {
1111
+ const planResult = validateConsumptionPlan(safeContext.plan, {
1086
1112
  trustedPlanDigest: safeContext.trustedPlanDigest,
1087
1113
  });
1088
1114
  if (!planResult.valid) return planResult;
1089
1115
  const plan = planResult.value;
1090
- const negotiation = negotiateExecutionPairV1(plan, safeContext);
1116
+ const negotiation = negotiateRuntimePair(plan, safeContext);
1091
1117
  if (negotiation.state !== 'selected') {
1092
1118
  return invalid(
1093
1119
  negotiation.issue_code,
@@ -1097,7 +1123,7 @@ function preparePreHostBudgetBlockedV1(capsule, safeContext) {
1097
1123
 
1098
1124
  let projectedCandidate;
1099
1125
  try {
1100
- projectedCandidate = assembleAgentHost2RequestV1(
1126
+ projectedCandidate = assembleAgentHostRequest(
1101
1127
  { request_id: PRE_HOST_INTERNAL_REQUEST_ID, capsule },
1102
1128
  plan,
1103
1129
  );
@@ -1130,12 +1156,12 @@ function preparePreHostBudgetBlockedV1(capsule, safeContext) {
1130
1156
  }
1131
1157
 
1132
1158
  /**
1133
- * Build the only supported Trace 1 path for a successfully projected Capsule
1159
+ * Build the sole supported pre-Host blocked Trace path for a successfully projected Capsule
1134
1160
  * that exceeds an enforce-before-Host projection or task limit. This function
1135
1161
  * never exposes the internal request-shaped correlation candidate and cannot
1136
- * produce a deliverable Agent Host 2 request.
1162
+ * produce a deliverable Agent Host request.
1137
1163
  */
1138
- function buildPreHostBudgetBlockedTraceV1(input, context) {
1164
+ function buildPreHostBudgetBlockedTrace(input, context) {
1139
1165
  const inputResult = snapshotPublicInput(
1140
1166
  input,
1141
1167
  ['trace_id', 'timestamp', 'capsule'],
@@ -1151,10 +1177,10 @@ function buildPreHostBudgetBlockedTraceV1(input, context) {
1151
1177
  throwInvalid(contextResult);
1152
1178
  const safeInput = inputResult.value;
1153
1179
  const safeContext = contextResult.value;
1154
- const prepared = preparePreHostBudgetBlockedV1(safeInput.capsule, safeContext);
1180
+ const prepared = preparePreHostBudgetBlocked(safeInput.capsule, safeContext);
1155
1181
  throwInvalid(prepared);
1156
1182
 
1157
- return buildJudgmentTraceV1(
1183
+ return buildJudgmentTrace(
1158
1184
  {
1159
1185
  trace_id: safeInput.trace_id,
1160
1186
  timestamp: safeInput.timestamp,
@@ -1178,7 +1204,7 @@ function buildPreHostBudgetBlockedTraceV1(input, context) {
1178
1204
  * independent Plan/Host capability facts without requiring callers to
1179
1205
  * construct or retain an over-budget request object.
1180
1206
  */
1181
- function validatePreHostBudgetBlockedTraceV1(trace, context) {
1207
+ function validatePreHostBudgetBlockedTrace(trace, context) {
1182
1208
  const contextResult = snapshotContext(context, [
1183
1209
  'plan',
1184
1210
  'trustedPlanDigest',
@@ -1188,9 +1214,9 @@ function validatePreHostBudgetBlockedTraceV1(trace, context) {
1188
1214
  ]);
1189
1215
  if (!contextResult.valid) return contextResult;
1190
1216
  const safeContext = contextResult.value;
1191
- const prepared = preparePreHostBudgetBlockedV1(safeContext.capsule, safeContext);
1217
+ const prepared = preparePreHostBudgetBlocked(safeContext.capsule, safeContext);
1192
1218
  if (!prepared.valid) return prepared;
1193
- const traceResult = validateJudgmentTraceV1(trace, {
1219
+ const traceResult = validateJudgmentTrace(trace, {
1194
1220
  ...safeContext,
1195
1221
  plan: prepared.value.plan,
1196
1222
  request: prepared.value.projectedCandidate,
@@ -1240,9 +1266,10 @@ function unavailableDigestEvidence() {
1240
1266
  });
1241
1267
  return {
1242
1268
  profile: CAPSULE_DIGEST_PROFILE,
1243
- asset: item('kdna-container-bytes-v1'),
1244
- content: item('kdna-content-tree-v1'),
1245
- runtime_entry_set: item('kdna-runtime-entry-set-v1'),
1269
+ profile_version: '0.1.0',
1270
+ asset: item('kdna.digest-basis.container-bytes'),
1271
+ content: item('kdna.digest-basis.content-tree'),
1272
+ runtime_entry_set: item('kdna.digest-basis.runtime-entry-set'),
1246
1273
  };
1247
1274
  }
1248
1275
 
@@ -1324,8 +1351,9 @@ function validateTraceSemantics(
1324
1351
  if (
1325
1352
  trace.plan_ref.plan_id !== plan.plan_id ||
1326
1353
  trace.plan_ref.plan_digest_profile !== plan.integrity.profile ||
1354
+ trace.plan_ref.plan_digest_profile_version !== plan.integrity.profile_version ||
1327
1355
  trace.plan_ref.plan_digest !== plan.integrity.plan_digest ||
1328
- trace.plan_ref.plan_digest !== computeConsumptionPlanDigestV1(plan)
1356
+ trace.plan_ref.plan_digest !== computeConsumptionPlanDigest(plan)
1329
1357
  ) {
1330
1358
  return 'KDNA_TRACE_PLAN_REF_MISMATCH';
1331
1359
  }
@@ -1350,7 +1378,7 @@ function validateTraceSemantics(
1350
1378
  if (validateRequestSemantics(request, plan, false) !== null) {
1351
1379
  return 'KDNA_TRACE_REQUEST_MISMATCH';
1352
1380
  }
1353
- const negotiation = negotiateExecutionPairV1(plan, {
1381
+ const negotiation = negotiateRuntimePair(plan, {
1354
1382
  trustedPlanDigest: plan.integrity.plan_digest,
1355
1383
  capabilities,
1356
1384
  coreCapsuleVersions,
@@ -1390,7 +1418,7 @@ function validateTraceSemantics(
1390
1418
  receipt.runtime_receipt.host_recomputed_capsule_delivery_digest ||
1391
1419
  delivery.host_echoed !== receipt.runtime_receipt.echoed_capsule_delivery_digest ||
1392
1420
  delivery.host_recomputed === p ||
1393
- delivery.delivered_capsule_version !== CAPSULE_VERSION ||
1421
+ delivery.delivered_capsule_version !== CAPSULE_CONTRACT_VERSION ||
1394
1422
  delivery.request_id !== request.request_id ||
1395
1423
  trace.execution.delivery_status !== 'rejected_before_execution'
1396
1424
  ) {
@@ -1402,7 +1430,7 @@ function validateTraceSemantics(
1402
1430
  receipt !== null ||
1403
1431
  delivery.host_recomputed !== null ||
1404
1432
  delivery.host_echoed !== null ||
1405
- delivery.delivered_capsule_version !== CAPSULE_VERSION ||
1433
+ delivery.delivered_capsule_version !== CAPSULE_CONTRACT_VERSION ||
1406
1434
  delivery.request_id !== request.request_id ||
1407
1435
  trace.execution.delivery_status !== 'rejected_before_execution'
1408
1436
  ) {
@@ -1456,7 +1484,7 @@ function validateTraceSemantics(
1456
1484
  return 'KDNA_TRACE_NEGOTIATION_EVIDENCE_MISMATCH';
1457
1485
  }
1458
1486
  if (runtime.negotiation_state === 'blocked') {
1459
- const negotiation = negotiateExecutionPairV1(plan, {
1487
+ const negotiation = negotiateRuntimePair(plan, {
1460
1488
  trustedPlanDigest: plan.integrity.plan_digest,
1461
1489
  capabilities,
1462
1490
  coreCapsuleVersions,
@@ -1490,7 +1518,7 @@ function validateTraceSemantics(
1490
1518
  return 'KDNA_TRACE_HOST_RECEIPT_MISMATCH';
1491
1519
  }
1492
1520
 
1493
- const negotiation = negotiateExecutionPairV1(plan, {
1521
+ const negotiation = negotiateRuntimePair(plan, {
1494
1522
  trustedPlanDigest: plan.integrity.plan_digest,
1495
1523
  capabilities,
1496
1524
  coreCapsuleVersions,
@@ -1563,7 +1591,7 @@ function validateTraceSemantics(
1563
1591
  return validateTerminalState(trace, receipt);
1564
1592
  }
1565
1593
 
1566
- function validateJudgmentTraceV1(trace, context) {
1594
+ function validateJudgmentTrace(trace, context) {
1567
1595
  const contextResult = snapshotContext(context, [
1568
1596
  'plan',
1569
1597
  'trustedPlanDigest',
@@ -1580,7 +1608,7 @@ function validateJudgmentTraceV1(trace, context) {
1580
1608
  const schemaResult = validateSchema('trace', trace);
1581
1609
  if (!schemaResult.valid) return schemaResult;
1582
1610
  const safeTrace = schemaResult.value;
1583
- const planResult = validateConsumptionPlanV1(safeContext.plan, {
1611
+ const planResult = validateConsumptionPlan(safeContext.plan, {
1584
1612
  trustedPlanDigest: safeContext.trustedPlanDigest,
1585
1613
  });
1586
1614
  if (!planResult.valid) return planResult;
@@ -1612,7 +1640,7 @@ function validateJudgmentTraceV1(trace, context) {
1612
1640
  'Trace validation cannot correlate a receipt without its independent request.',
1613
1641
  );
1614
1642
  }
1615
- const receiptResult = validateAgentHost2ReceiptV1(safeContext.receipt, {
1643
+ const receiptResult = validateAgentHostReceipt(safeContext.receipt, {
1616
1644
  request: safeContext.request,
1617
1645
  });
1618
1646
  if (!receiptResult.valid) {
@@ -1649,7 +1677,7 @@ function validateJudgmentTraceV1(trace, context) {
1649
1677
  }
1650
1678
  }
1651
1679
 
1652
- function buildJudgmentTraceV1(input, context) {
1680
+ function buildJudgmentTrace(input, context) {
1653
1681
  const contextResult = snapshotContext(context, [
1654
1682
  'plan',
1655
1683
  'trustedPlanDigest',
@@ -1662,7 +1690,7 @@ function buildJudgmentTraceV1(input, context) {
1662
1690
  throwInvalid(contextResult);
1663
1691
  const safeContext = contextResult.value;
1664
1692
  throwInvalid(validateTrustedDeliveryObservation(safeContext));
1665
- const planResult = validateConsumptionPlanV1(safeContext.plan, {
1693
+ const planResult = validateConsumptionPlan(safeContext.plan, {
1666
1694
  trustedPlanDigest: safeContext.trustedPlanDigest,
1667
1695
  });
1668
1696
  throwInvalid(planResult);
@@ -1670,7 +1698,7 @@ function buildJudgmentTraceV1(input, context) {
1670
1698
 
1671
1699
  const capabilitiesResult = validateSchema('capabilities', safeContext.capabilities);
1672
1700
  if (!capabilitiesResult.valid) {
1673
- throw new KDNAExecutionContractError(
1701
+ throw new KDNARuntimeContractError(
1674
1702
  'KDNA_VALIDATION_CONTEXT_INVALID',
1675
1703
  'Trace construction requires schema-valid independent Host capabilities.',
1676
1704
  capabilitiesResult.errors,
@@ -1680,7 +1708,7 @@ function buildJudgmentTraceV1(input, context) {
1680
1708
  if (safeContext.request !== null) {
1681
1709
  const requestResult = validateSchema('request', safeContext.request);
1682
1710
  if (!requestResult.valid) {
1683
- throw new KDNAExecutionContractError(
1711
+ throw new KDNARuntimeContractError(
1684
1712
  'KDNA_VALIDATION_CONTEXT_INVALID',
1685
1713
  'Trace construction requires a schema-valid independent Host request.',
1686
1714
  requestResult.errors,
@@ -1693,14 +1721,14 @@ function buildJudgmentTraceV1(input, context) {
1693
1721
  false,
1694
1722
  );
1695
1723
  if (requestCode !== null) {
1696
- throw new KDNAExecutionContractError(
1724
+ throw new KDNARuntimeContractError(
1697
1725
  requestCode,
1698
1726
  'Trace construction requires an independently correlated Host request.',
1699
1727
  );
1700
1728
  }
1701
- const negotiation = negotiateExecutionPairV1(safeContext.plan, safeContext);
1729
+ const negotiation = negotiateRuntimePair(safeContext.plan, safeContext);
1702
1730
  if (negotiation.state !== 'selected') {
1703
- throw new KDNAExecutionContractError(
1731
+ throw new KDNARuntimeContractError(
1704
1732
  negotiation.issue_code,
1705
1733
  'Trace construction requires a selected strict execution pair.',
1706
1734
  );
@@ -1708,12 +1736,12 @@ function buildJudgmentTraceV1(input, context) {
1708
1736
  }
1709
1737
  if (safeContext.receipt !== null) {
1710
1738
  if (safeContext.request === null) {
1711
- throw new KDNAExecutionContractError(
1739
+ throw new KDNARuntimeContractError(
1712
1740
  'KDNA_VALIDATION_CONTEXT_INVALID',
1713
1741
  'Trace construction cannot use a receipt without its independent request.',
1714
1742
  );
1715
1743
  }
1716
- const receiptResult = validateAgentHost2ReceiptV1(safeContext.receipt, {
1744
+ const receiptResult = validateAgentHostReceipt(safeContext.receipt, {
1717
1745
  request: safeContext.request,
1718
1746
  });
1719
1747
  throwInvalid(receiptResult);
@@ -1724,7 +1752,7 @@ function buildJudgmentTraceV1(input, context) {
1724
1752
  const request = safeContext.request;
1725
1753
  const receipt = safeContext.receipt;
1726
1754
  const observation = safeContext.trustedDeliveryObservation;
1727
- const negotiation = negotiateExecutionPairV1(plan, safeContext);
1755
+ const negotiation = negotiateRuntimePair(plan, safeContext);
1728
1756
  const hasRequest = request !== null;
1729
1757
  const hasReceipt = receipt !== null;
1730
1758
  const comparison = hasReceipt
@@ -1738,12 +1766,13 @@ function buildJudgmentTraceV1(input, context) {
1738
1766
  let trace;
1739
1767
  try {
1740
1768
  trace = {
1741
- type: 'kdna.judgment.trace',
1742
- trace_version: '1.0.0',
1769
+ type: 'kdna.judgment-trace',
1770
+ contract_version: '0.1.0',
1743
1771
  trace_id: input.trace_id,
1744
1772
  plan_ref: {
1745
1773
  plan_id: plan.plan_id,
1746
1774
  plan_digest_profile: plan.integrity.profile,
1775
+ plan_digest_profile_version: plan.integrity.profile_version,
1747
1776
  plan_digest: plan.integrity.plan_digest,
1748
1777
  comparison: 'matched',
1749
1778
  },
@@ -1768,6 +1797,7 @@ function buildJudgmentTraceV1(input, context) {
1768
1797
  digest_evidence: hasRequest ? clone(request.capsule.digests) : unavailableDigestEvidence(),
1769
1798
  capsule_delivery_evidence: {
1770
1799
  basis: CAPSULE_DELIVERY_PROFILE,
1800
+ basis_version: CAPSULE_DELIVERY_PROFILE_VERSION,
1771
1801
  observed: p,
1772
1802
  sender_computed: hasRequest,
1773
1803
  host_recomputed: hasReceipt
@@ -1777,7 +1807,7 @@ function buildJudgmentTraceV1(input, context) {
1777
1807
  ? receipt.runtime_receipt.echoed_capsule_delivery_digest
1778
1808
  : null,
1779
1809
  delivered_capsule_version:
1780
- hasReceipt || observation === 'not_observed' ? CAPSULE_VERSION : null,
1810
+ hasReceipt || observation === 'not_observed' ? CAPSULE_CONTRACT_VERSION : null,
1781
1811
  host_boundary_comparison: comparison,
1782
1812
  request_id: hasReceipt || observation === 'not_observed' ? request.request_id : null,
1783
1813
  },
@@ -1810,7 +1840,7 @@ function buildJudgmentTraceV1(input, context) {
1810
1840
  ? {
1811
1841
  shape: request.result_contract.shape,
1812
1842
  result_digest: digestJcs(receipt.outcome),
1813
- basis: 'kdna-result-jcs-v1',
1843
+ basis: 'kdna.canonicalization.result-jcs',
1814
1844
  stored: input.result_stored ?? true,
1815
1845
  }
1816
1846
  : null,
@@ -1818,33 +1848,35 @@ function buildJudgmentTraceV1(input, context) {
1818
1848
  warnings: clone(input.warnings || []),
1819
1849
  };
1820
1850
  } catch {
1821
- throw new KDNAExecutionContractError(
1851
+ throw new KDNARuntimeContractError(
1822
1852
  'KDNA_TRACE_INPUT_INVALID',
1823
- 'Cannot build JudgmentTrace 1 from the supplied input and independent context.',
1853
+ 'Cannot build JudgmentTrace from the supplied input and independent context.',
1824
1854
  );
1825
1855
  }
1826
1856
 
1827
- const result = validateJudgmentTraceV1(trace, safeContext);
1857
+ const result = validateJudgmentTrace(trace, safeContext);
1828
1858
  throwInvalid(result);
1829
1859
  return trace;
1830
1860
  }
1831
1861
 
1832
1862
  module.exports = {
1833
- KDNAExecutionContractError,
1863
+ KDNARuntimeContractError,
1834
1864
  PLAN_DIGEST_PROFILE,
1865
+ PLAN_DIGEST_PROFILE_VERSION,
1835
1866
  HOST_PROTOCOL,
1836
- DEFAULT_CORE_CAPSULE_VERSIONS,
1837
- parseExecutionContractJsonV1,
1838
- computeConsumptionPlanDigestV1,
1839
- buildConsumptionPlanV1,
1840
- validateConsumptionPlanV1,
1841
- negotiateExecutionPairV1,
1842
- buildAgentHost2RequestV1,
1843
- validateAgentHost2RequestV1,
1844
- validateAgentHost2ReceiptV1,
1845
- deriveBudgetEvidenceV1,
1846
- buildPreHostBudgetBlockedTraceV1,
1847
- validatePreHostBudgetBlockedTraceV1,
1848
- buildJudgmentTraceV1,
1849
- validateJudgmentTraceV1,
1867
+ HOST_PROTOCOL_VERSION,
1868
+ DEFAULT_CORE_CAPSULE_CONTRACT_VERSIONS,
1869
+ parseRuntimeContractJson,
1870
+ computeConsumptionPlanDigest,
1871
+ buildConsumptionPlan,
1872
+ validateConsumptionPlan,
1873
+ negotiateRuntimePair,
1874
+ buildAgentHostRequest,
1875
+ validateAgentHostRequest,
1876
+ validateAgentHostReceipt,
1877
+ deriveBudgetEvidence,
1878
+ buildPreHostBudgetBlockedTrace,
1879
+ validatePreHostBudgetBlockedTrace,
1880
+ buildJudgmentTrace,
1881
+ validateJudgmentTrace,
1850
1882
  };