@slicedearth/whoisleuth-cli 2.0.1 → 2.2.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 (97) hide show
  1. package/cli/arguments.mjs +21 -5
  2. package/cli/artifact-validation/case-response.mjs +771 -0
  3. package/cli/artifact-validation/investigation-capsule.mjs +426 -0
  4. package/cli/artifact-validation/lookup-evidence.mjs +718 -0
  5. package/cli/artifact-validation/signed-review.mjs +598 -0
  6. package/cli/artifact-validation/structure-primitives.mjs +105 -0
  7. package/cli/artifact-verify.mjs +1 -1
  8. package/cli/assurance-command-runner.mjs +324 -0
  9. package/cli/command-reference.mjs +1175 -843
  10. package/cli/completion.mjs +56 -9
  11. package/cli/discriminated-command-handlers.mjs +11 -0
  12. package/cli/doctor.mjs +2 -2
  13. package/cli/evidence-command-runner.mjs +41 -31
  14. package/cli/export-evidence.mjs +1 -1
  15. package/cli/fail-policy.mjs +33 -8
  16. package/cli/formatters/terminal-command-formats.mjs +437 -0
  17. package/cli/formatters/terminal-lookup.mjs +758 -0
  18. package/cli/formatters/terminal-metadata.mjs +58 -0
  19. package/cli/formatters/terminal-shared.mjs +83 -0
  20. package/cli/formatters/terminal.mjs +5 -1232
  21. package/cli/history-command-runner.mjs +132 -0
  22. package/cli/inline-command-families.mjs +45 -0
  23. package/cli/inline-command-runner.mjs +55 -0
  24. package/cli/investigation-plan.mjs +9 -2
  25. package/cli/investigation-run.mjs +114 -9
  26. package/cli/lookup-brief.mjs +141 -23
  27. package/cli/lookup-browser-view.mjs +289 -0
  28. package/cli/lookup-browser.mjs +3 -288
  29. package/cli/mail-review.mjs +2 -6
  30. package/cli/offline-artifact-validation.mjs +19 -0
  31. package/cli/review-command-runner.mjs +269 -0
  32. package/cli/runner.mjs +15 -972
  33. package/cli/saved-lookup.mjs +19 -2
  34. package/cli/support-command-runner.mjs +229 -0
  35. package/cli/workflow-command-runner.mjs +129 -0
  36. package/docs/cli-reference.md +16 -9
  37. package/docs/cli.md +16 -2
  38. package/lib/availability.mjs +12 -9
  39. package/lib/bounded-contract-normalizers.mjs +2 -9
  40. package/lib/browser-library-profile.mjs +1 -2
  41. package/lib/client-behavior-profile.mjs +1 -2
  42. package/lib/credential-surface-profile.mjs +1 -1
  43. package/lib/domain-posture-analysis.mjs +10 -1
  44. package/lib/domain-posture.mjs +51 -23
  45. package/lib/evidence-export.mjs +47 -5
  46. package/lib/evidence-report-markdown.mjs +4 -0
  47. package/lib/evidence-report.mjs +50 -0
  48. package/lib/generated/cisa-kev-catalog.mjs +34 -4
  49. package/lib/generated/registrar-standing-catalogue.mjs +367 -0
  50. package/lib/json-record.mjs +12 -0
  51. package/lib/lookup-child-profile-contract.mjs +858 -0
  52. package/lib/lookup-contract-primitives.mjs +98 -0
  53. package/lib/lookup-diagnostics.mjs +96 -0
  54. package/lib/lookup-network-evidence-bounds.mjs +1 -0
  55. package/lib/lookup-response.mjs +367 -0
  56. package/lib/lookup.mjs +28 -443
  57. package/lib/page-role-profile.mjs +1 -3
  58. package/lib/registrar-standing-catalogue-contract.mjs +70 -0
  59. package/lib/registrar-standing-contract.mjs +300 -0
  60. package/lib/registrar-standing.mjs +269 -0
  61. package/lib/registry-insights.mjs +2 -8
  62. package/lib/risk-scoring.mjs +26 -10
  63. package/lib/sslbl-certificates.generated.mjs +138 -136
  64. package/lib/structured-data-identity.mjs +1 -3
  65. package/lib/technology-evidence-role.mjs +51 -0
  66. package/lib/threat-intelligence-runtime.mjs +3 -3
  67. package/lib/threat-intelligence-types.mjs +13 -0
  68. package/lib/threatfox-intelligence.mjs +1 -3
  69. package/lib/tls-intelligence.mjs +1 -2
  70. package/lib/urlhaus-intelligence.mjs +1 -3
  71. package/lib/urlscan-intelligence.mjs +1 -3
  72. package/lib/website-security-posture.mjs +1 -2
  73. package/lib/website-technology.mjs +72 -23
  74. package/lib/whois-common-formats.mjs +276 -0
  75. package/lib/whois-dialects.mjs +534 -0
  76. package/lib/whois-parser-support.mjs +305 -0
  77. package/lib/whois-parser.mjs +135 -0
  78. package/lib/whois.mjs +6 -1187
  79. package/package.json +2 -2
  80. package/packages/cases/case-evidence-model.mjs +9 -0
  81. package/packages/cases/case-migration-model.mjs +17 -11
  82. package/packages/cases/case-record-operations.mjs +235 -0
  83. package/packages/cases/case-response-model.mjs +13 -9
  84. package/packages/cases/case-response-packet.mjs +297 -112
  85. package/packages/comparison/page-similarity.mjs +23 -0
  86. package/packages/contracts/case-portability.mjs +235 -61
  87. package/packages/contracts/cli-lookup.mjs +4 -3
  88. package/packages/contracts/domain-control-manifest.mjs +1 -1
  89. package/packages/contracts/investigation-portability.mjs +1 -1
  90. package/packages/contracts/risk-calibration.mjs +2 -2
  91. package/packages/contracts/workspace-portability.mjs +34 -6
  92. package/packages/interchange/external-findings-import.mjs +113 -45
  93. package/packages/investigation/evidence-coverage-ledger.mjs +21 -0
  94. package/packages/investigation/lookup-claim-readiness.mjs +2 -2
  95. package/packages/workspace/website-snapshot-model.mjs +79 -6
  96. package/third-party-notices.txt +1 -1
  97. package/cli/artifact-structure.mjs +0 -2507
@@ -2,7 +2,14 @@ import { MAX_DOMAIN_NAME_LENGTH } from "./domain-name.mjs";
2
2
  import { defineSchemaCompatibility } from "./schema-compatibility.mjs";
3
3
  import { defineSchemaLifecycleFamily } from "./schema-lifecycle.mjs";
4
4
  export const CASE_CONTRACT_OWNER = 'packages/contracts/case-portability.mts';
5
+ export const LATEST_PUBLIC_APPLICATION_VERSION = '2.1.0';
5
6
  export const CASE_PORTABILITY_IDENTITY_CONSTANTS = Object.freeze([
7
+ 'LATEST_PUBLIC_APPLICATION_VERSION',
8
+ 'LATEST_PUBLIC_CASE_SCHEMA_VERSION',
9
+ 'LATEST_PUBLIC_CASE_REPORT_SCHEMA_VERSION',
10
+ 'LATEST_PUBLIC_CASE_RESPONSE_PACKET_VERSION',
11
+ 'LATEST_PUBLIC_CASE_RESPONSE_REVIEW_INPUTS_VERSION',
12
+ 'LATEST_PUBLIC_WORKSPACE_ARCHIVE_VERSION',
6
13
  'CASE_BROWSER_STORE_LIFECYCLE_SCHEMA',
7
14
  'CASE_EXPORT_LIFECYCLE_SCHEMA',
8
15
  'CASE_SCHEMA_VERSION',
@@ -17,6 +24,7 @@ export const CASE_PORTABILITY_IDENTITY_CONSTANTS = Object.freeze([
17
24
  'SUPPORTED_CASE_RESPONSE_PACKET_VERSIONS',
18
25
  'CASE_RESPONSE_REVIEW_INPUTS_SCHEMA',
19
26
  'CASE_RESPONSE_REVIEW_INPUTS_VERSION',
27
+ 'SUPPORTED_CASE_RESPONSE_REVIEW_INPUTS_VERSIONS',
20
28
  'CLI_CASE_PACK_SCHEMA',
21
29
  'CLI_CASE_PACK_VERSION',
22
30
  'SUPPORTED_CLI_CASE_PACK_VERSIONS',
@@ -122,20 +130,43 @@ export const CASE_DOMAIN_RUNTIME_ADAPTERS = Object.freeze([
122
130
  export const CASE_BROWSER_STORE_LIFECYCLE_SCHEMA = 'whoisleuth.browser.case-store';
123
131
  export const CASE_EXPORT_LIFECYCLE_SCHEMA = 'whoisleuth.case-export';
124
132
  export const PUBLIC_CASE_SCHEMA_VERSION = 12;
125
- export const CASE_SCHEMA_VERSION = 13;
126
- export const CASE_BROWSER_SUPPORTED_VERSIONS = Object.freeze([PUBLIC_CASE_SCHEMA_VERSION, CASE_SCHEMA_VERSION]);
133
+ export const PUBLISHED_V2_CASE_SCHEMA_VERSION = 13;
134
+ export const CASE_SCHEMA_VERSION = 14;
135
+ export const LATEST_PUBLIC_CASE_SCHEMA_VERSION = 14;
136
+ export const CASE_BROWSER_SUPPORTED_VERSIONS = Object.freeze([
137
+ PUBLIC_CASE_SCHEMA_VERSION,
138
+ PUBLISHED_V2_CASE_SCHEMA_VERSION,
139
+ CASE_SCHEMA_VERSION,
140
+ ]);
127
141
  export const CASE_IMPORT_VERSIONS = CASE_BROWSER_SUPPORTED_VERSIONS;
128
142
  export const CASE_REPORT_SCHEMA = 'whoisleuth.case-report';
129
143
  export const PUBLIC_CASE_REPORT_SCHEMA_VERSION = 8;
130
- export const CASE_REPORT_SCHEMA_VERSION = 9;
131
- export const CASE_REPORT_OUTPUT_VERSIONS = Object.freeze([CASE_REPORT_SCHEMA_VERSION]);
144
+ export const PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION = 9;
145
+ export const CASE_REPORT_SCHEMA_VERSION = 10;
146
+ export const LATEST_PUBLIC_CASE_REPORT_SCHEMA_VERSION = 10;
147
+ export const CASE_REPORT_OUTPUT_VERSIONS = Object.freeze([
148
+ PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION,
149
+ CASE_REPORT_SCHEMA_VERSION,
150
+ ]);
132
151
  export const CASE_RESPONSE_PACKET_SCHEMA = 'whoisleuth.case-response-packet';
133
152
  export const PUBLIC_CASE_RESPONSE_PACKET_VERSION = 6;
134
- export const CASE_RESPONSE_PACKET_VERSION = 7;
135
- export const CASE_RESPONSE_PACKET_OUTPUT_VERSIONS = Object.freeze([PUBLIC_CASE_RESPONSE_PACKET_VERSION, CASE_RESPONSE_PACKET_VERSION]);
153
+ export const PUBLISHED_V2_CASE_RESPONSE_PACKET_VERSION = 7;
154
+ export const CASE_RESPONSE_PACKET_VERSION = 8;
155
+ export const LATEST_PUBLIC_CASE_RESPONSE_PACKET_VERSION = 8;
156
+ export const CASE_RESPONSE_PACKET_OUTPUT_VERSIONS = Object.freeze([
157
+ PUBLIC_CASE_RESPONSE_PACKET_VERSION,
158
+ PUBLISHED_V2_CASE_RESPONSE_PACKET_VERSION,
159
+ CASE_RESPONSE_PACKET_VERSION,
160
+ ]);
136
161
  export const SUPPORTED_CASE_RESPONSE_PACKET_VERSIONS = CASE_RESPONSE_PACKET_OUTPUT_VERSIONS;
137
162
  export const CASE_RESPONSE_REVIEW_INPUTS_SCHEMA = 'whoisleuth.case-response-review-inputs';
138
- export const CASE_RESPONSE_REVIEW_INPUTS_VERSION = 1;
163
+ export const PUBLISHED_V2_CASE_RESPONSE_REVIEW_INPUTS_VERSION = 1;
164
+ export const CASE_RESPONSE_REVIEW_INPUTS_VERSION = 2;
165
+ export const LATEST_PUBLIC_CASE_RESPONSE_REVIEW_INPUTS_VERSION = 2;
166
+ export const SUPPORTED_CASE_RESPONSE_REVIEW_INPUTS_VERSIONS = Object.freeze([
167
+ PUBLISHED_V2_CASE_RESPONSE_REVIEW_INPUTS_VERSION,
168
+ CASE_RESPONSE_REVIEW_INPUTS_VERSION,
169
+ ]);
139
170
  export const CLI_CASE_PACK_SCHEMA = 'whoisleuth.cli.case-pack';
140
171
  export const CLI_CASE_PACK_VERSION = 2;
141
172
  export const SUPPORTED_CLI_CASE_PACK_VERSIONS = Object.freeze([CLI_CASE_PACK_VERSION]);
@@ -152,6 +183,7 @@ export const CLI_CASE_PACK_LIMITATIONS = Object.freeze([
152
183
  ]);
153
184
  export const CLI_CASE_PACK_CASE_REPORT_EPOCHS = Object.freeze([
154
185
  Object.freeze({ caseVersions: Object.freeze([PUBLIC_CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([PUBLIC_CASE_REPORT_SCHEMA_VERSION]) }),
186
+ Object.freeze({ caseVersions: Object.freeze([PUBLISHED_V2_CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION]) }),
155
187
  Object.freeze({ caseVersions: Object.freeze([CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([CASE_REPORT_SCHEMA_VERSION]) }),
156
188
  ]);
157
189
  export function caseReportVersionMatchesCase(caseVersion, reportVersion) {
@@ -162,8 +194,14 @@ export function caseReportVersionMatchesCase(caseVersion, reportVersion) {
162
194
  }
163
195
  export const WORKSPACE_ARCHIVE_SCHEMA = 'whoisleuth.workspace-archive';
164
196
  export const PUBLIC_WORKSPACE_ARCHIVE_VERSION = 5;
165
- export const WORKSPACE_ARCHIVE_VERSION = 6;
166
- export const SUPPORTED_WORKSPACE_ARCHIVE_VERSIONS = Object.freeze([PUBLIC_WORKSPACE_ARCHIVE_VERSION, WORKSPACE_ARCHIVE_VERSION]);
197
+ export const PUBLISHED_V2_WORKSPACE_ARCHIVE_VERSION = 6;
198
+ export const WORKSPACE_ARCHIVE_VERSION = 7;
199
+ export const LATEST_PUBLIC_WORKSPACE_ARCHIVE_VERSION = 7;
200
+ export const SUPPORTED_WORKSPACE_ARCHIVE_VERSIONS = Object.freeze([
201
+ PUBLIC_WORKSPACE_ARCHIVE_VERSION,
202
+ PUBLISHED_V2_WORKSPACE_ARCHIVE_VERSION,
203
+ WORKSPACE_ARCHIVE_VERSION,
204
+ ]);
167
205
  export function isSupportedWorkspaceArchiveVersion(value) {
168
206
  return typeof value === 'number'
169
207
  && Number.isSafeInteger(value)
@@ -275,49 +313,49 @@ export const CASE_BROWSER_COMPATIBILITY = defineSchemaCompatibility({
275
313
  supportedVersions: CASE_BROWSER_SUPPORTED_VERSIONS, acceptsUnversionedLegacy: false,
276
314
  futureVersionBehavior: 'preserve_without_write', migration: 'normalize_to_current',
277
315
  writeSemantics: 'normalized_rewrite', byteBudget: MAX_CASE_STORE_BYTES, owner: CASE_CONTRACT_OWNER,
278
- note: 'The exact public version 12 writer migrates directly to version 13; other retired and all future stores remain untouched.',
316
+ note: 'Exact Case versions 12 and 13 migrate directly to current version 14; other retired stores are rejected and future stores remain untouched.',
279
317
  });
280
318
  export const CASE_EXPORT_COMPATIBILITY = defineSchemaCompatibility({
281
319
  id: 'export.cases', kind: 'export', schema: null, currentVersion: CASE_SCHEMA_VERSION,
282
320
  supportedVersions: CASE_IMPORT_VERSIONS, acceptsUnversionedLegacy: false,
283
321
  futureVersionBehavior: 'reject', migration: 'normalize_to_current',
284
322
  writeSemantics: 'non_destructive_merge', byteBudget: MAX_CASE_IMPORT_BYTES, owner: CASE_CONTRACT_OWNER,
285
- note: 'Exact public Case version 12 and current version 13 merge non-destructively through one bounded reader; other versions fail without mutation.',
323
+ note: 'Exact Case versions 12, 13 and 14 merge non-destructively through one bounded reader; other versions fail without mutation.',
286
324
  });
287
325
  export const CASE_REPORT_COMPATIBILITY = defineSchemaCompatibility({
288
326
  id: 'export.case-report', kind: 'export', schema: CASE_REPORT_SCHEMA, currentVersion: CASE_REPORT_SCHEMA_VERSION,
289
327
  supportedVersions: CASE_REPORT_OUTPUT_VERSIONS, acceptsUnversionedLegacy: false,
290
- futureVersionBehavior: 'not_applicable', migration: 'read_only', writeSemantics: 'read_only',
328
+ futureVersionBehavior: 'reject', migration: 'read_only', writeSemantics: 'read_only',
291
329
  byteBudget: null, owner: CASE_CONTRACT_OWNER,
292
- note: 'Case report version 9 is the durable output contract; retired and future report versions are unsupported.',
330
+ note: 'Published Case report version 9 and current version 10 are exact readable output contracts; retired and future report versions are unsupported.',
293
331
  });
294
332
  export const CASE_RESPONSE_PACKET_COMPATIBILITY = defineSchemaCompatibility({
295
333
  id: 'export.case-response-packet', kind: 'export', schema: CASE_RESPONSE_PACKET_SCHEMA,
296
334
  currentVersion: CASE_RESPONSE_PACKET_VERSION, supportedVersions: CASE_RESPONSE_PACKET_OUTPUT_VERSIONS,
297
335
  acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: 'read_only',
298
336
  writeSemantics: 'read_only', byteBudget: null, owner: CASE_CONTRACT_OWNER,
299
- note: 'Exact public packet version 6 and current version 7 are verified independently; other versions fail closed.',
337
+ note: 'Exact packet versions 6, 7 and 8 are verified independently; other versions fail closed.',
300
338
  });
301
339
  export const CASE_RESPONSE_REVIEW_INPUTS_COMPATIBILITY = defineSchemaCompatibility({
302
340
  id: 'derived.case-response-review-inputs', kind: 'derived', schema: CASE_RESPONSE_REVIEW_INPUTS_SCHEMA,
303
- currentVersion: CASE_RESPONSE_REVIEW_INPUTS_VERSION, supportedVersions: [CASE_RESPONSE_REVIEW_INPUTS_VERSION],
304
- acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: 'exact_current_only',
341
+ currentVersion: CASE_RESPONSE_REVIEW_INPUTS_VERSION, supportedVersions: SUPPORTED_CASE_RESPONSE_REVIEW_INPUTS_VERSIONS,
342
+ acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: 'read_only',
305
343
  writeSemantics: 'read_only', byteBudget: null, owner: CASE_CONTRACT_OWNER,
306
- note: 'Exact bounded review inputs are canonicalised with sorted-json-v2 for one response authorisation digest and reject extensions or future versions.',
344
+ note: 'Exact published review-input version 1 and current version 2 remain independently readable for response authorisation; extensions and future versions fail closed.',
307
345
  });
308
346
  export const CLI_CASE_PACK_COMPATIBILITY = defineSchemaCompatibility({
309
347
  id: 'export.cli-case-pack', kind: 'export', schema: CLI_CASE_PACK_SCHEMA, currentVersion: CLI_CASE_PACK_VERSION,
310
348
  supportedVersions: SUPPORTED_CLI_CASE_PACK_VERSIONS, acceptsUnversionedLegacy: false,
311
349
  futureVersionBehavior: 'reject', migration: 'read_only', writeSemantics: 'read_only',
312
350
  byteBudget: MAX_CASE_IMPORT_BYTES, owner: CASE_CONTRACT_OWNER,
313
- note: 'Case-pack version 2 verifies the exact public Case 12/report 8 epoch and the current Case 13/report 9 epoch with deterministic sorted-json-v2 integrity.',
351
+ note: 'Case-pack version 2 verifies exact Case/report epochs 12/8, 13/9 and 14/10 with deterministic sorted-json-v2 integrity.',
314
352
  });
315
353
  export const WORKSPACE_ARCHIVE_COMPATIBILITY = defineSchemaCompatibility({
316
354
  id: 'export.workspace-archive', kind: 'export', schema: WORKSPACE_ARCHIVE_SCHEMA,
317
355
  currentVersion: WORKSPACE_ARCHIVE_VERSION, supportedVersions: SUPPORTED_WORKSPACE_ARCHIVE_VERSIONS,
318
356
  acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: 'normalize_to_current',
319
357
  writeSemantics: 'non_destructive_merge', byteBudget: MAX_WORKSPACE_ARCHIVE_BYTES, owner: CASE_CONTRACT_OWNER,
320
- note: 'Workspace envelope version 6 adds the bounded analyst Review Item lifecycle section. Exact version 5 remains readable and migrates to an empty review-state section without inventing decisions; future envelopes fail without mutation.',
358
+ note: 'Workspace version 7 carries the current Case contract. Exact versions 5 and 6 remain readable; version 5 gains an empty Review Item section without inventing decisions, and future envelopes fail without mutation.',
321
359
  });
322
360
  export const WORKSPACE_SETTINGS_COMPATIBILITY = defineSchemaCompatibility({
323
361
  id: 'export.workspace-settings-section', kind: 'export', schema: WORKSPACE_SETTINGS_SCHEMA,
@@ -363,7 +401,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
363
401
  version: PUBLIC_CASE_SCHEMA_VERSION,
364
402
  role: 'historical',
365
403
  expectation: 'normalises_to_current_output',
366
- expectedOutputFixtureId: 'browser-case-v13',
404
+ expectedOutputFixtureId: 'browser-case-v14',
367
405
  shapeId: 'case.browser-store.public',
368
406
  scope: 'repository',
369
407
  }),
@@ -374,6 +412,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
374
412
  sha256: 'd679030e52340ecc7795ac88de15316d88c8c07b94b34da60fd52589a0375712',
375
413
  contentDigestSha256: null,
376
414
  schema: CASE_BROWSER_STORE_LIFECYCLE_SCHEMA,
415
+ version: PUBLISHED_V2_CASE_SCHEMA_VERSION,
416
+ role: 'historical',
417
+ expectation: 'normalises_to_current_output',
418
+ expectedOutputFixtureId: 'browser-case-v14',
419
+ shapeId: 'case.browser-store.v13',
420
+ scope: 'repository',
421
+ }),
422
+ Object.freeze({
423
+ id: 'browser-case-v14',
424
+ path: 'test/fixtures/case-lifecycle/browser-case-v14.json',
425
+ bytes: 3131,
426
+ sha256: 'ece46f5d27a52a20196678af8236674836f3979c0d45f0ad5751c00677ec8bae',
427
+ contentDigestSha256: null,
428
+ schema: CASE_BROWSER_STORE_LIFECYCLE_SCHEMA,
377
429
  version: CASE_SCHEMA_VERSION,
378
430
  role: 'current',
379
431
  expectation: 'accepted_exact',
@@ -391,7 +443,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
391
443
  version: PUBLIC_CASE_SCHEMA_VERSION,
392
444
  role: 'historical',
393
445
  expectation: 'normalises_to_current_output',
394
- expectedOutputFixtureId: 'case-export-v13',
446
+ expectedOutputFixtureId: 'case-export-v14',
395
447
  shapeId: 'case.export.public',
396
448
  scope: 'repository',
397
449
  }),
@@ -402,6 +454,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
402
454
  sha256: 'fd2aa7623c2aaea385b952727ad74cf5af0f1ee21dc478c0e5c820a332376a0d',
403
455
  contentDigestSha256: null,
404
456
  schema: CASE_EXPORT_LIFECYCLE_SCHEMA,
457
+ version: PUBLISHED_V2_CASE_SCHEMA_VERSION,
458
+ role: 'historical',
459
+ expectation: 'normalises_to_current_output',
460
+ expectedOutputFixtureId: 'case-export-v14',
461
+ shapeId: 'case.export.v13',
462
+ scope: 'repository',
463
+ }),
464
+ Object.freeze({
465
+ id: 'case-export-v14',
466
+ path: 'test/fixtures/case-lifecycle/case-export-v14.json',
467
+ bytes: 3175,
468
+ sha256: '50cf1df53c3558852b712844d588d9eb955af858e160969d9a6af613c257feaf',
469
+ contentDigestSha256: null,
470
+ schema: CASE_EXPORT_LIFECYCLE_SCHEMA,
405
471
  version: CASE_SCHEMA_VERSION,
406
472
  role: 'current',
407
473
  expectation: 'accepted_exact',
@@ -430,11 +496,25 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
430
496
  sha256: 'd9903318123c63ae7a385f153286a5596585a401771c8def8149792b9b7b9326',
431
497
  contentDigestSha256: null,
432
498
  schema: CASE_REPORT_SCHEMA,
499
+ version: PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION,
500
+ role: 'historical',
501
+ expectation: 'accepted_exact',
502
+ expectedOutputFixtureId: null,
503
+ shapeId: 'case.report.v9',
504
+ scope: 'repository',
505
+ }),
506
+ Object.freeze({
507
+ id: 'case-report-v10',
508
+ path: 'test/fixtures/case-lifecycle/case-report-v10.json',
509
+ bytes: 4606,
510
+ sha256: '36c8b89bb1b335d923bd5035020ff47f89c88775e14d08af2d2eb2ee2f5cc03a',
511
+ contentDigestSha256: null,
512
+ schema: CASE_REPORT_SCHEMA,
433
513
  version: CASE_REPORT_SCHEMA_VERSION,
434
514
  role: 'current',
435
515
  expectation: 'accepted_exact',
436
516
  expectedOutputFixtureId: null,
437
- shapeId: 'case.report.v9',
517
+ shapeId: 'case.report.v10',
438
518
  scope: 'repository',
439
519
  }),
440
520
  Object.freeze({
@@ -444,11 +524,25 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
444
524
  sha256: '0ea150d920710b331839be0a0f995d4597a133ecb930ef850de1eecfca4d94e3',
445
525
  contentDigestSha256: 'sha256:fa5b7f079882dd72b15365d844937ae99e47f81465e79b3911c25e70c157e562',
446
526
  schema: CASE_RESPONSE_PACKET_SCHEMA,
527
+ version: PUBLISHED_V2_CASE_RESPONSE_PACKET_VERSION,
528
+ role: 'historical',
529
+ expectation: 'accepted_exact',
530
+ expectedOutputFixtureId: null,
531
+ shapeId: 'case.response-packet.v7',
532
+ scope: 'repository',
533
+ }),
534
+ Object.freeze({
535
+ id: 'case-response-packet-v8',
536
+ path: 'test/fixtures/case-lifecycle/case-response-packet-v8.json',
537
+ bytes: 12191,
538
+ sha256: '7bd2237f208714b92c3669c0581dbf0bc2dc22369e53b3ef9da088e8af0f4a83',
539
+ contentDigestSha256: 'sha256:86d4d88d1d9fc969e6efa432061c64bf0725767d81c50b8655abd2d231dcc5b6',
540
+ schema: CASE_RESPONSE_PACKET_SCHEMA,
447
541
  version: CASE_RESPONSE_PACKET_VERSION,
448
542
  role: 'current',
449
543
  expectation: 'accepted_exact',
450
544
  expectedOutputFixtureId: null,
451
- shapeId: 'case.response-packet.v7',
545
+ shapeId: 'case.response-packet.v8',
452
546
  scope: 'repository',
453
547
  }),
454
548
  Object.freeze({
@@ -458,11 +552,25 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
458
552
  sha256: '67d3d36f316cf17898e04c39f2ba0ba7599abdc4b4e387baef5f5866a73c7b9c',
459
553
  contentDigestSha256: null,
460
554
  schema: CASE_RESPONSE_REVIEW_INPUTS_SCHEMA,
555
+ version: PUBLISHED_V2_CASE_RESPONSE_REVIEW_INPUTS_VERSION,
556
+ role: 'historical',
557
+ expectation: 'accepted_exact',
558
+ expectedOutputFixtureId: null,
559
+ shapeId: 'case.response-review-inputs.v1',
560
+ scope: 'repository',
561
+ }),
562
+ Object.freeze({
563
+ id: 'case-response-review-inputs-v2',
564
+ path: 'test/fixtures/case-lifecycle/case-response-review-inputs-v2.json',
565
+ bytes: 7520,
566
+ sha256: 'dcc9aaa7cdbd79a33559095f4c212e4eea5ad635c8c36290456d8b1946845aa6',
567
+ contentDigestSha256: null,
568
+ schema: CASE_RESPONSE_REVIEW_INPUTS_SCHEMA,
461
569
  version: CASE_RESPONSE_REVIEW_INPUTS_VERSION,
462
570
  role: 'current',
463
571
  expectation: 'accepted_exact',
464
572
  expectedOutputFixtureId: null,
465
- shapeId: 'case.response-review-inputs.v1',
573
+ shapeId: 'case.response-review-inputs.v2',
466
574
  scope: 'repository',
467
575
  }),
468
576
  Object.freeze({
@@ -493,6 +601,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
493
601
  shapeId: 'case.cli-pack.current',
494
602
  scope: 'repository',
495
603
  }),
604
+ Object.freeze({
605
+ id: 'cli-case-pack-v2-case-v14',
606
+ path: 'test/fixtures/case-lifecycle/cli-case-pack-v2-case-v14.json',
607
+ bytes: 9363,
608
+ sha256: 'e25e98602c92e696a50c9fd48924c6c13853a5c23ea6fe617abc0b89d8c9e8ee',
609
+ contentDigestSha256: 'sha256:50044835b0e7aa45137b2f75b9894aa35c71101c769062eb524078bfb55eecc0',
610
+ schema: CLI_CASE_PACK_SCHEMA,
611
+ version: CLI_CASE_PACK_VERSION,
612
+ role: 'current',
613
+ expectation: 'accepted_exact',
614
+ expectedOutputFixtureId: null,
615
+ shapeId: 'case.cli-pack.current',
616
+ scope: 'repository',
617
+ }),
496
618
  Object.freeze({
497
619
  id: 'workspace-archive-v5-public',
498
620
  path: 'test/fixtures/case-lifecycle/workspace-archive-v5-public.json',
@@ -503,7 +625,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
503
625
  version: PUBLIC_WORKSPACE_ARCHIVE_VERSION,
504
626
  role: 'historical',
505
627
  expectation: 'normalises_to_current_output',
506
- expectedOutputFixtureId: 'workspace-archive-v6-empty-current',
628
+ expectedOutputFixtureId: 'workspace-archive-v7-empty-current',
507
629
  shapeId: 'case.workspace-archive.v5',
508
630
  scope: 'repository',
509
631
  }),
@@ -511,14 +633,28 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
511
633
  id: 'workspace-archive-v6-empty-current',
512
634
  path: 'test/fixtures/case-lifecycle/workspace-archive-v6-empty-current.json',
513
635
  bytes: 5557,
514
- sha256: '7a0701c7b0401de76df132fe7b2332fd1e2f1fade007a8af0103c8cec5a1b2f9',
636
+ sha256: 'bca86a66043c88838f252358962ff5cdbc306373a2ad2d209ae90abdeff09aaa',
637
+ contentDigestSha256: null,
638
+ schema: WORKSPACE_ARCHIVE_SCHEMA,
639
+ version: PUBLISHED_V2_WORKSPACE_ARCHIVE_VERSION,
640
+ role: 'historical',
641
+ expectation: 'normalises_to_current_output',
642
+ expectedOutputFixtureId: 'workspace-archive-v7-empty-current',
643
+ shapeId: 'case.workspace-archive.v6',
644
+ scope: 'repository',
645
+ }),
646
+ Object.freeze({
647
+ id: 'workspace-archive-v7-empty-current',
648
+ path: 'test/fixtures/case-lifecycle/workspace-archive-v7-empty-current.json',
649
+ bytes: 7258,
650
+ sha256: '892b0d321f42bfb34501019388da682071024af452a8263f138cc08221947f0a',
515
651
  contentDigestSha256: null,
516
652
  schema: WORKSPACE_ARCHIVE_SCHEMA,
517
653
  version: WORKSPACE_ARCHIVE_VERSION,
518
654
  role: 'current',
519
655
  expectation: 'accepted_exact',
520
656
  expectedOutputFixtureId: null,
521
- shapeId: 'case.workspace-archive.v6',
657
+ shapeId: 'case.workspace-archive.v7',
522
658
  scope: 'repository',
523
659
  }),
524
660
  Object.freeze({
@@ -577,8 +713,10 @@ const exportContracts = CASE_IMPORT_VERSIONS.map((version) => lifecycleContract(
577
713
  }));
578
714
  const reportContracts = CASE_REPORT_OUTPUT_VERSIONS.map((version) => lifecycleContract({
579
715
  compatibilityId: CASE_REPORT_COMPATIBILITY.id, schema: CASE_REPORT_SCHEMA, version,
580
- lifecycle: 'current', readable: false, emitted: true, exactKeys: true, extensionPolicy: 'reject',
581
- futureVersionBehaviour: 'not_applicable', migrationTarget: null, canonicalisation: null, byteBudget: null,
716
+ lifecycle: version === CASE_REPORT_SCHEMA_VERSION ? 'current' : 'legacy', readable: true,
717
+ emitted: version === CASE_REPORT_SCHEMA_VERSION, exactKeys: true, extensionPolicy: 'reject',
718
+ futureVersionBehaviour: 'reject',
719
+ migrationTarget: null, canonicalisation: null, byteBudget: null,
582
720
  }));
583
721
  const packetContracts = CASE_RESPONSE_PACKET_OUTPUT_VERSIONS.map((version) => lifecycleContract({
584
722
  compatibilityId: CASE_RESPONSE_PACKET_COMPATIBILITY.id, schema: CASE_RESPONSE_PACKET_SCHEMA, version,
@@ -617,7 +755,9 @@ function shape(id, schema, versions, requiredKeys, normalisation, target = null)
617
755
  }
618
756
  const CASE_LIFECYCLE_SHAPES = Object.freeze([
619
757
  shape('case.browser-store.public', CASE_BROWSER_STORE_LIFECYCLE_SCHEMA, [PUBLIC_CASE_SCHEMA_VERSION], ['version', 'cases'], 'project_known_fields'),
758
+ shape('case.browser-store.v13', CASE_BROWSER_STORE_LIFECYCLE_SCHEMA, [PUBLISHED_V2_CASE_SCHEMA_VERSION], ['version', 'cases'], 'project_known_fields'),
620
759
  shape('case.browser-store.current', CASE_BROWSER_STORE_LIFECYCLE_SCHEMA, [CASE_SCHEMA_VERSION], ['version', 'cases'], 'project_known_fields'),
760
+ shape('case.export.v13', CASE_EXPORT_LIFECYCLE_SCHEMA, [PUBLISHED_V2_CASE_SCHEMA_VERSION], ['version', 'cases'], 'preserve_document'),
621
761
  shape('case.export.public', CASE_EXPORT_LIFECYCLE_SCHEMA, [PUBLIC_CASE_SCHEMA_VERSION], ['version', 'cases'], 'preserve_document'),
622
762
  shape('case.response-packet.v6', CASE_RESPONSE_PACKET_SCHEMA, [PUBLIC_CASE_RESPONSE_PACKET_VERSION], [
623
763
  'schema', 'schemaVersion', 'generatedAt', 'reviewRequired', 'submissionPerformed',
@@ -625,22 +765,37 @@ const CASE_LIFECYCLE_SHAPES = Object.freeze([
625
765
  'provenance', 'integrity',
626
766
  ], 'preserve_signed_document'),
627
767
  shape('case.export.current', CASE_EXPORT_LIFECYCLE_SCHEMA, [CASE_SCHEMA_VERSION], ['version', 'cases'], 'preserve_document'),
628
- shape('case.report.v9', CASE_REPORT_SCHEMA, [CASE_REPORT_SCHEMA_VERSION], ['schema', 'schemaVersion', 'generatedAt', 'application', 'case', 'currentAssessment', 'evidenceTimeline', 'analystResponse', 'responseLifecycle', 'limitations'], 'preserve_document'),
629
- shape('case.response-packet.v7', CASE_RESPONSE_PACKET_SCHEMA, [CASE_RESPONSE_PACKET_VERSION], [
768
+ shape('case.report.v9', CASE_REPORT_SCHEMA, [PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION], ['schema', 'schemaVersion', 'generatedAt', 'application', 'case', 'currentAssessment', 'evidenceTimeline', 'analystResponse', 'responseLifecycle', 'limitations'], 'preserve_document'),
769
+ shape('case.report.v10', CASE_REPORT_SCHEMA, [CASE_REPORT_SCHEMA_VERSION], ['schema', 'schemaVersion', 'generatedAt', 'application', 'case', 'currentAssessment', 'evidenceTimeline', 'analystResponse', 'responseLifecycle', 'limitations'], 'preserve_document'),
770
+ shape('case.response-packet.v7', CASE_RESPONSE_PACKET_SCHEMA, [PUBLISHED_V2_CASE_RESPONSE_PACKET_VERSION], [
630
771
  'schema', 'schemaVersion', 'generatedAt', 'reviewRequired', 'submissionPerformed',
631
772
  'profile', 'case', 'incident', 'contacts', 'provenance', 'selectedEvidence',
632
773
  'contradictions', 'readiness', 'artefactReferences', 'preflight', 'escalationHistory',
633
774
  'escalationHistoryOmitted', 'escalationHistoryLimitations', 'responseLifecycle',
634
775
  'authorisation', 'integrity',
635
776
  ], 'preserve_signed_document'),
636
- shape('case.response-review-inputs.v1', CASE_RESPONSE_REVIEW_INPUTS_SCHEMA, [CASE_RESPONSE_REVIEW_INPUTS_VERSION], [
777
+ shape('case.response-packet.v8', CASE_RESPONSE_PACKET_SCHEMA, [CASE_RESPONSE_PACKET_VERSION], [
778
+ 'schema', 'schemaVersion', 'generatedAt', 'reviewRequired', 'submissionPerformed',
779
+ 'profile', 'case', 'incident', 'contacts', 'recipientRoute', 'actionBinding',
780
+ 'provenance', 'selectedEvidence', 'contradictions', 'readiness', 'artefactReferences',
781
+ 'preflight', 'escalationHistory', 'escalationHistoryOmitted',
782
+ 'escalationHistoryLimitations', 'responseLifecycle', 'authorisation', 'integrity',
783
+ ], 'preserve_signed_document'),
784
+ shape('case.response-review-inputs.v1', CASE_RESPONSE_REVIEW_INPUTS_SCHEMA, [PUBLISHED_V2_CASE_RESPONSE_REVIEW_INPUTS_VERSION], [
637
785
  'contract', 'version', 'profile', 'case', 'incident', 'contacts', 'selectedEvidence',
638
786
  'contradictions', 'readiness', 'artefactReferences', 'escalationHistory',
639
787
  'escalationHistoryOmitted', 'escalationHistoryLimitations', 'responseLifecycle',
640
788
  ], 'preserve_signed_document'),
789
+ shape('case.response-review-inputs.v2', CASE_RESPONSE_REVIEW_INPUTS_SCHEMA, [CASE_RESPONSE_REVIEW_INPUTS_VERSION], [
790
+ 'contract', 'version', 'profile', 'case', 'incident', 'contacts',
791
+ 'recipientRoute', 'actionBinding', 'selectedEvidence', 'contradictions',
792
+ 'readiness', 'artefactReferences', 'escalationHistory',
793
+ 'escalationHistoryOmitted', 'escalationHistoryLimitations', 'responseLifecycle',
794
+ ], 'preserve_signed_document'),
641
795
  shape('case.cli-pack.current', CLI_CASE_PACK_SCHEMA, [CLI_CASE_PACK_VERSION], CLI_CASE_PACK_ROOT_KEYS, 'preserve_signed_document'),
642
796
  shape('case.workspace-archive.v5', WORKSPACE_ARCHIVE_SCHEMA, [5], ['schema', 'version', 'generatedAt', 'manifest', 'sections', 'limitations'], 'preserve_signed_document'),
643
- shape('case.workspace-archive.v6', WORKSPACE_ARCHIVE_SCHEMA, [WORKSPACE_ARCHIVE_VERSION], ['schema', 'version', 'generatedAt', 'manifest', 'sections', 'limitations'], 'preserve_signed_document'),
797
+ shape('case.workspace-archive.v6', WORKSPACE_ARCHIVE_SCHEMA, [PUBLISHED_V2_WORKSPACE_ARCHIVE_VERSION], ['schema', 'version', 'generatedAt', 'manifest', 'sections', 'limitations'], 'preserve_signed_document'),
798
+ shape('case.workspace-archive.v7', WORKSPACE_ARCHIVE_SCHEMA, [WORKSPACE_ARCHIVE_VERSION], ['schema', 'version', 'generatedAt', 'manifest', 'sections', 'limitations'], 'preserve_signed_document'),
644
799
  shape('case.workspace-settings.v1', WORKSPACE_SETTINGS_SCHEMA, [WORKSPACE_SETTINGS_VERSION], ['schema', 'version', 'activeProfileId', 'theme'], 'preserve_document'),
645
800
  shape('case.encrypted-workspace-archive.v1', ENCRYPTED_WORKSPACE_ARCHIVE_SCHEMA, [ENCRYPTED_WORKSPACE_ARCHIVE_VERSION], ['schema', 'version', 'createdAt', 'content', 'kdf', 'cipher', 'ciphertext'], 'preserve_signed_document'),
646
801
  ]);
@@ -705,7 +860,7 @@ const CASE_LIFECYCLE_HOOKS = Object.freeze([
705
860
  id: 'case.packet.structure',
706
861
  role: 'structure_validator',
707
862
  runtime: 'cli',
708
- module: 'cli/artifact-structure.mts',
863
+ module: 'cli/offline-artifact-validation.mts',
709
864
  exportName: 'validateOfflineArtifactStructure',
710
865
  },
711
866
  {
@@ -880,7 +1035,7 @@ const CASE_LIFECYCLE_EXPIRY = Object.freeze([{
880
1035
  }]);
881
1036
  const CASE_LIFECYCLE_SERIALISATION = Object.freeze([
882
1037
  {
883
- id: 'case.browser-store.json.v13',
1038
+ id: 'case.browser-store.json.v14',
884
1039
  schema: CASE_BROWSER_STORE_LIFECYCLE_SCHEMA,
885
1040
  versions: [CASE_SCHEMA_VERSION],
886
1041
  mediaType: 'application/json',
@@ -895,10 +1050,10 @@ const CASE_LIFECYCLE_SERIALISATION = Object.freeze([
895
1050
  verifierHookIds: [],
896
1051
  },
897
1052
  ...[
898
- ['case.export.json.v13', CASE_EXPORT_LIFECYCLE_SCHEMA, [CASE_SCHEMA_VERSION], 'none', []],
899
- ['case.report.json.v9', CASE_REPORT_SCHEMA, [CASE_REPORT_SCHEMA_VERSION], 'none', []],
900
- ['case.packet.json.v7', CASE_RESPONSE_PACKET_SCHEMA, [...SUPPORTED_CASE_RESPONSE_PACKET_VERSIONS], 'structural_only_requires_separate_verification', ['case.packet.verify']],
901
- ['case.workspace.json.v6', WORKSPACE_ARCHIVE_SCHEMA, [WORKSPACE_ARCHIVE_VERSION], 'structural_only_requires_separate_verification', ['case.workspace.verify']],
1053
+ ['case.export.json.v14', CASE_EXPORT_LIFECYCLE_SCHEMA, [CASE_SCHEMA_VERSION], 'none', []],
1054
+ ['case.report.json.v10', CASE_REPORT_SCHEMA, [...CASE_REPORT_OUTPUT_VERSIONS], 'none', []],
1055
+ ['case.packet.json.v8', CASE_RESPONSE_PACKET_SCHEMA, [...SUPPORTED_CASE_RESPONSE_PACKET_VERSIONS], 'structural_only_requires_separate_verification', ['case.packet.verify']],
1056
+ ['case.workspace.json.v7', WORKSPACE_ARCHIVE_SCHEMA, [WORKSPACE_ARCHIVE_VERSION], 'structural_only_requires_separate_verification', ['case.workspace.verify']],
902
1057
  ['case.encrypted-workspace.json.v1', ENCRYPTED_WORKSPACE_ARCHIVE_SCHEMA, [ENCRYPTED_WORKSPACE_ARCHIVE_VERSION], 'structural_only_requires_separate_verification', ['case.encrypted-workspace.verify']],
903
1058
  ].map(([id, schema, versions, integrity, verifierHookIds]) => ({
904
1059
  id,
@@ -949,10 +1104,10 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
949
1104
  discriminator: null,
950
1105
  }],
951
1106
  emittedContract: { schema: CASE_BROWSER_STORE_LIFECYCLE_SCHEMA, version: CASE_SCHEMA_VERSION, discriminator: null },
952
- shapeIds: ['case.browser-store.public', 'case.browser-store.current'],
1107
+ shapeIds: ['case.browser-store.public', 'case.browser-store.v13', 'case.browser-store.current'],
953
1108
  boundProfileIds: ['case.browser-store.bounds', 'case.domain.bounds'],
954
1109
  hookIds: ['case.browser.normalise', 'case.browser.serialise'],
955
- serialisationProfileId: 'case.browser-store.json.v13',
1110
+ serialisationProfileId: 'case.browser-store.json.v14',
956
1111
  privacyProfileId: 'case.privacy.browser-state',
957
1112
  retentionEffect: 'browser_indexeddb',
958
1113
  ...sharedEdge,
@@ -968,7 +1123,7 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
968
1123
  discriminator: null,
969
1124
  }],
970
1125
  emittedContract: null,
971
- shapeIds: ['case.export.public', 'case.export.current'],
1126
+ shapeIds: ['case.export.public', 'case.export.v13', 'case.export.current'],
972
1127
  boundProfileIds: ['case.portable.bounds', 'case.domain.bounds'],
973
1128
  hookIds: ['case.export.merge'],
974
1129
  serialisationProfileId: null,
@@ -985,21 +1140,40 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
985
1140
  shapeIds: ['case.export.current'],
986
1141
  boundProfileIds: ['case.portable.bounds', 'case.domain.bounds'],
987
1142
  hookIds: ['case.export.build', 'case.portable.serialise'],
988
- serialisationProfileId: 'case.export.json.v13',
1143
+ serialisationProfileId: 'case.export.json.v14',
989
1144
  privacyProfileId: 'case.privacy.portable-output',
990
1145
  retentionEffect: 'operator_controlled_output',
991
1146
  ...sharedEdge,
992
1147
  },
1148
+ {
1149
+ id: 'case.consumer.report-pack-verify',
1150
+ plane: 'cli',
1151
+ operation: 'validate-embedded-report',
1152
+ acceptedContracts: [{
1153
+ schema: CASE_REPORT_SCHEMA,
1154
+ versions: [...CASE_REPORT_OUTPUT_VERSIONS],
1155
+ mode: 'embedded',
1156
+ discriminator: null,
1157
+ }],
1158
+ emittedContract: null,
1159
+ shapeIds: ['case.report.v9', 'case.report.v10'],
1160
+ boundProfileIds: ['case.domain.bounds'],
1161
+ hookIds: ['case.cli-pack.verify'],
1162
+ serialisationProfileId: null,
1163
+ privacyProfileId: 'case.privacy.portable-input',
1164
+ retentionEffect: 'deliberate_local_file',
1165
+ ...sharedEdge,
1166
+ },
993
1167
  {
994
1168
  id: 'case.consumer.report-build',
995
1169
  plane: 'shared',
996
1170
  operation: 'build-report',
997
1171
  acceptedContracts: [],
998
1172
  emittedContract: { schema: CASE_REPORT_SCHEMA, version: CASE_REPORT_SCHEMA_VERSION, discriminator: null },
999
- shapeIds: ['case.report.v9'],
1173
+ shapeIds: ['case.report.v10'],
1000
1174
  boundProfileIds: ['case.domain.bounds'],
1001
1175
  hookIds: ['case.report.build', 'case.portable.serialise'],
1002
- serialisationProfileId: 'case.report.json.v9',
1176
+ serialisationProfileId: 'case.report.json.v10',
1003
1177
  privacyProfileId: 'case.privacy.portable-output',
1004
1178
  retentionEffect: 'operator_controlled_output',
1005
1179
  ...sharedEdge,
@@ -1015,7 +1189,7 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1015
1189
  discriminator: null,
1016
1190
  }],
1017
1191
  emittedContract: null,
1018
- shapeIds: ['case.response-packet.v6', 'case.response-packet.v7'],
1192
+ shapeIds: ['case.response-packet.v6', 'case.response-packet.v7', 'case.response-packet.v8'],
1019
1193
  boundProfileIds: ['case.packet.bounds'],
1020
1194
  hookIds: ['case.packet.verify'],
1021
1195
  serialisationProfileId: null,
@@ -1034,7 +1208,7 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1034
1208
  discriminator: null,
1035
1209
  }],
1036
1210
  emittedContract: null,
1037
- shapeIds: ['case.response-packet.v6', 'case.response-packet.v7'],
1211
+ shapeIds: ['case.response-packet.v6', 'case.response-packet.v7', 'case.response-packet.v8'],
1038
1212
  boundProfileIds: ['case.packet.bounds'],
1039
1213
  hookIds: ['case.packet.structure', 'case.packet.verify'],
1040
1214
  serialisationProfileId: null,
@@ -1048,10 +1222,10 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1048
1222
  operation: 'build-packet',
1049
1223
  acceptedContracts: [],
1050
1224
  emittedContract: { schema: CASE_RESPONSE_PACKET_SCHEMA, version: CASE_RESPONSE_PACKET_VERSION, discriminator: null },
1051
- shapeIds: ['case.response-packet.v7'],
1225
+ shapeIds: ['case.response-packet.v8'],
1052
1226
  boundProfileIds: ['case.packet.bounds'],
1053
1227
  hookIds: ['case.packet.build', 'case.portable.serialise'],
1054
- serialisationProfileId: 'case.packet.json.v7',
1228
+ serialisationProfileId: 'case.packet.json.v8',
1055
1229
  privacyProfileId: 'case.privacy.portable-output',
1056
1230
  retentionEffect: 'operator_controlled_output',
1057
1231
  ...sharedEdge,
@@ -1062,12 +1236,12 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1062
1236
  operation: 'validate-review-inputs',
1063
1237
  acceptedContracts: [{
1064
1238
  schema: CASE_RESPONSE_REVIEW_INPUTS_SCHEMA,
1065
- versions: [CASE_RESPONSE_REVIEW_INPUTS_VERSION],
1239
+ versions: [...SUPPORTED_CASE_RESPONSE_REVIEW_INPUTS_VERSIONS],
1066
1240
  mode: 'direct',
1067
1241
  discriminator: null,
1068
1242
  }],
1069
1243
  emittedContract: null,
1070
- shapeIds: ['case.response-review-inputs.v1'],
1244
+ shapeIds: ['case.response-review-inputs.v1', 'case.response-review-inputs.v2'],
1071
1245
  boundProfileIds: ['case.packet.bounds'],
1072
1246
  hookIds: ['case.review-inputs.validate'],
1073
1247
  serialisationProfileId: null,
@@ -1085,7 +1259,7 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1085
1259
  version: CASE_RESPONSE_REVIEW_INPUTS_VERSION,
1086
1260
  discriminator: null,
1087
1261
  },
1088
- shapeIds: ['case.response-review-inputs.v1'],
1262
+ shapeIds: ['case.response-review-inputs.v2'],
1089
1263
  boundProfileIds: ['case.packet.bounds'],
1090
1264
  hookIds: ['case.review-inputs.build'],
1091
1265
  serialisationProfileId: null,
@@ -1147,7 +1321,7 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1147
1321
  discriminator: null,
1148
1322
  }],
1149
1323
  emittedContract: null,
1150
- shapeIds: ['case.workspace-archive.v5', 'case.workspace-archive.v6', 'case.workspace-settings.v1'],
1324
+ shapeIds: ['case.workspace-archive.v5', 'case.workspace-archive.v6', 'case.workspace-archive.v7', 'case.workspace-settings.v1'],
1151
1325
  boundProfileIds: ['case.workspace.bounds'],
1152
1326
  hookIds: ['case.workspace.verify'],
1153
1327
  serialisationProfileId: null,
@@ -1161,10 +1335,10 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1161
1335
  operation: 'build-workspace',
1162
1336
  acceptedContracts: [],
1163
1337
  emittedContract: { schema: WORKSPACE_ARCHIVE_SCHEMA, version: WORKSPACE_ARCHIVE_VERSION, discriminator: null },
1164
- shapeIds: ['case.workspace-archive.v6'],
1338
+ shapeIds: ['case.workspace-archive.v7'],
1165
1339
  boundProfileIds: ['case.workspace.bounds'],
1166
1340
  hookIds: ['case.workspace.build', 'case.portable.serialise'],
1167
- serialisationProfileId: 'case.workspace.json.v6',
1341
+ serialisationProfileId: 'case.workspace.json.v7',
1168
1342
  privacyProfileId: 'case.privacy.portable-output',
1169
1343
  retentionEffect: 'operator_controlled_output',
1170
1344
  ...sharedEdge,
@@ -1217,7 +1391,7 @@ const CASE_LIFECYCLE_CONSUMERS = Object.freeze([
1217
1391
  version: ENCRYPTED_WORKSPACE_ARCHIVE_VERSION,
1218
1392
  discriminator: null,
1219
1393
  },
1220
- shapeIds: ['case.workspace-archive.v5', 'case.workspace-archive.v6', 'case.encrypted-workspace-archive.v1'],
1394
+ shapeIds: ['case.workspace-archive.v5', 'case.workspace-archive.v6', 'case.workspace-archive.v7', 'case.encrypted-workspace-archive.v1'],
1221
1395
  boundProfileIds: ['case.workspace.bounds', 'case.encrypted-workspace.bounds'],
1222
1396
  hookIds: ['case.encrypted-workspace.build', 'case.portable.serialise'],
1223
1397
  serialisationProfileId: 'case.encrypted-workspace.json.v1',
@@ -1236,20 +1410,20 @@ export const CASE_PORTABILITY_LIFECYCLE_FAMILY = defineSchemaLifecycleFamily({
1236
1410
  ...exportContracts,
1237
1411
  ...reportContracts,
1238
1412
  ...packetContracts,
1239
- lifecycleContract({
1413
+ ...SUPPORTED_CASE_RESPONSE_REVIEW_INPUTS_VERSIONS.map((version) => lifecycleContract({
1240
1414
  compatibilityId: CASE_RESPONSE_REVIEW_INPUTS_COMPATIBILITY.id,
1241
1415
  schema: CASE_RESPONSE_REVIEW_INPUTS_SCHEMA,
1242
- version: CASE_RESPONSE_REVIEW_INPUTS_VERSION,
1243
- lifecycle: 'current',
1416
+ version,
1417
+ lifecycle: version === CASE_RESPONSE_REVIEW_INPUTS_VERSION ? 'current' : 'legacy',
1244
1418
  readable: true,
1245
- emitted: true,
1419
+ emitted: version === CASE_RESPONSE_REVIEW_INPUTS_VERSION,
1246
1420
  exactKeys: true,
1247
1421
  extensionPolicy: 'reject',
1248
1422
  futureVersionBehaviour: 'reject',
1249
1423
  migrationTarget: null,
1250
1424
  canonicalisation: 'sorted-json-v2',
1251
1425
  byteBudget: null,
1252
- }),
1426
+ })),
1253
1427
  lifecycleContract({
1254
1428
  compatibilityId: CLI_CASE_PACK_COMPATIBILITY.id,
1255
1429
  schema: CLI_CASE_PACK_SCHEMA,