@slicedearth/whoisleuth-cli 1.47.4 → 2.0.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 (235) hide show
  1. package/README.md +74 -177
  2. package/SECURITY.md +6 -3
  3. package/bin/whoisleuth.mjs +2 -1
  4. package/cli/archive-inspect.mjs +28 -10
  5. package/cli/arguments.mjs +204 -174
  6. package/cli/artifact-structure.mjs +837 -163
  7. package/cli/artifact-verify.mjs +90 -61
  8. package/cli/bounded-json.mjs +1 -1
  9. package/cli/bulk-checkpoint.mjs +33 -20
  10. package/cli/bulk.mjs +9 -2
  11. package/cli/case-pack.mjs +180 -576
  12. package/cli/ci-report.mjs +6 -1
  13. package/cli/collection-preflight.mjs +2 -2
  14. package/cli/command-catalogue.mjs +12 -3
  15. package/cli/command-reference.mjs +910 -92
  16. package/cli/completion.mjs +504 -226
  17. package/cli/config-profile.mjs +13 -3
  18. package/cli/discover.mjs +7 -1
  19. package/cli/discovery-observation-snapshot.mjs +24 -28
  20. package/cli/discovery-scan-command-runner.mjs +9 -9
  21. package/cli/discovery-scan.mjs +17 -3
  22. package/cli/discovery-snapshot.mjs +15 -7
  23. package/cli/domain-control-monitor.mjs +203 -30
  24. package/cli/domain-control-observations.mjs +15 -21
  25. package/cli/errors.mjs +8 -3
  26. package/cli/evidence-signing.mjs +10 -20
  27. package/cli/external-observation-mapping.mjs +3 -3
  28. package/cli/formatters/json.mjs +20 -32
  29. package/cli/formatters/terminal.mjs +583 -22
  30. package/cli/input.mjs +7 -2
  31. package/cli/interactive-launcher.mjs +226 -0
  32. package/cli/interchange-report.mjs +19 -19
  33. package/cli/investigation-manifest.mjs +1 -1
  34. package/cli/investigation-plan.mjs +167 -16
  35. package/cli/investigation-run.mjs +9 -1
  36. package/cli/lookalike-calibration.mjs +3 -1
  37. package/cli/lookup-brief.mjs +13 -8
  38. package/cli/lookup-browser.mjs +844 -0
  39. package/cli/lookup-command-runner.mjs +94 -31
  40. package/cli/lookup-diff.mjs +2 -2
  41. package/cli/lookup-plan.mjs +1 -0
  42. package/cli/mail-review.mjs +206 -94
  43. package/cli/manual.mjs +5 -5
  44. package/cli/offline-evidence-review.mjs +18 -7
  45. package/cli/open-asset-model-bridge.mjs +1 -1
  46. package/cli/output-file.mjs +70 -14
  47. package/cli/page-compare.mjs +11 -6
  48. package/cli/progress-events.mjs +2 -1
  49. package/cli/progress.mjs +3 -3
  50. package/cli/registry-cohort.mjs +9 -51
  51. package/cli/registry-doctor.mjs +67 -28
  52. package/cli/retained-artifact-diff.mjs +7 -8
  53. package/cli/risk-calibration.mjs +85 -38
  54. package/cli/runner.mjs +189 -75
  55. package/cli/saved-lookup.mjs +424 -57
  56. package/cli/sharing-review.mjs +6 -1
  57. package/cli/source-reliability.mjs +75 -36
  58. package/cli/terminal-presentation.mjs +43 -18
  59. package/docs/cli-reference.md +125 -1708
  60. package/docs/cli.md +86 -254
  61. package/frontend/src/lib/analysis/domain-control-manifest-core.js +3 -145
  62. package/frontend/src/lib/analysis/domain-control-records.js +3 -88
  63. package/lib/availability.mjs +58 -40
  64. package/lib/bounded-contract-normalizers.mjs +2 -4
  65. package/lib/bounded-file.mjs +78 -4
  66. package/lib/bounded-json.mjs +51 -13
  67. package/lib/browser-library-profile.mjs +1 -1
  68. package/lib/classify.mjs +56 -5
  69. package/lib/client-behavior-profile.mjs +1 -1
  70. package/lib/credential-surface-profile.mjs +1 -1
  71. package/lib/cryptographic-assurance.mjs +35 -17
  72. package/lib/ct-query.mjs +3 -3
  73. package/lib/ct-search.mjs +37 -21
  74. package/lib/distributed-operation-budget.mjs +4 -2
  75. package/lib/dns-delegation-health.mjs +9 -6
  76. package/lib/dns-intelligence.mjs +1 -1
  77. package/lib/dnssec-chain-validation.mjs +2 -3
  78. package/lib/dnssec-evidence-validation.mjs +13 -7
  79. package/lib/domain-assurance.mjs +12 -12
  80. package/lib/domain-change-packet.mjs +1 -1
  81. package/lib/domain-control-flight-recorder.mjs +442 -78
  82. package/lib/domain-control-manifest.mjs +314 -59
  83. package/lib/domain-posture-analysis.mjs +5 -2
  84. package/lib/encrypted-dns-contract.mjs +2 -3
  85. package/lib/evidence-export.mjs +518 -36
  86. package/lib/external-intelligence-risk.mjs +26 -10
  87. package/lib/feature-policy.mjs +1 -1
  88. package/lib/homepage-metadata-contract.mjs +290 -0
  89. package/lib/hostname.mjs +1 -1
  90. package/lib/html-signals.mjs +89 -5
  91. package/lib/http-intelligence.mjs +331 -2
  92. package/lib/interchange-fidelity-registry.mjs +28 -26
  93. package/lib/lookup-cache.mjs +6 -4
  94. package/lib/lookup.mjs +25 -2
  95. package/lib/observed-network-context.mjs +1 -1
  96. package/lib/page-fingerprints.mjs +2 -2
  97. package/lib/page-role-profile.mjs +1 -1
  98. package/lib/portable-generator.mjs +8 -0
  99. package/lib/provider-policy-admission.mjs +3 -1
  100. package/lib/rdap-bootstrap.mjs +76 -16
  101. package/lib/rdap-client.mjs +20 -12
  102. package/lib/rdap-normalization.mjs +306 -75
  103. package/lib/rdap-transport.mjs +2 -2
  104. package/lib/rdap-validation.mjs +65 -14
  105. package/lib/rdap.mjs +2 -2
  106. package/lib/registrable-domain.mjs +36 -0
  107. package/lib/registry-insights.mjs +7 -0
  108. package/lib/response-policy.mjs +27 -4
  109. package/lib/risk-calibration-summary.mjs +35 -33
  110. package/lib/risk-scoring.mjs +4 -3
  111. package/lib/safe-fetch.mjs +62 -40
  112. package/lib/security-txt.mjs +1 -1
  113. package/lib/smtp-transport-review.mjs +8 -5
  114. package/lib/sslbl-intelligence.mjs +6 -8
  115. package/lib/static-html-analysis.mjs +301 -4
  116. package/lib/structured-data-identity.mjs +51 -19
  117. package/lib/threat-intelligence-fixtures.mjs +2 -4
  118. package/lib/threat-intelligence-manifests.mjs +2 -7
  119. package/lib/threat-intelligence-runtime.mjs +3 -5
  120. package/lib/threat-intelligence-types.mjs +3 -0
  121. package/lib/threatfox-intelligence.mjs +7 -3
  122. package/lib/tls-intelligence.mjs +4 -4
  123. package/lib/urlhaus-intelligence.mjs +4 -2
  124. package/lib/urlscan-intelligence.mjs +6 -5
  125. package/lib/website-security-posture.mjs +1 -1
  126. package/lib/website-technology.mjs +1 -1
  127. package/lib/whois-authority.mjs +43 -8
  128. package/lib/whois-chain.mjs +25 -3
  129. package/lib/whois-normalization.mjs +3 -1
  130. package/lib/whois-transport.mjs +12 -3
  131. package/lib/zone-intent-review.mjs +1 -1
  132. package/package.json +12 -4
  133. package/{frontend/src/lib/analysis/case-brand-profile-references.js → packages/cases/case-brand-profile-references.mjs} +2 -2
  134. package/{frontend/src/lib/analysis/case-evidence-model.js → packages/cases/case-evidence-model.mjs} +35 -14
  135. package/{frontend/src/lib/analysis/case-investigation-branch-model.js → packages/cases/case-investigation-branch-model.mjs} +10 -12
  136. package/packages/cases/case-migration-model.mjs +476 -0
  137. package/{frontend/src/lib/analysis/case-model.js → packages/cases/case-model.mjs} +3 -3
  138. package/{frontend/src/lib/analysis/case-record-contracts.js → packages/cases/case-record-contracts.mjs} +3 -21
  139. package/{frontend/src/lib/analysis/case-record-core.js → packages/cases/case-record-core.mjs} +58 -31
  140. package/packages/cases/case-record-model.mjs +9 -0
  141. package/{frontend/src/lib/analysis/case-record-operations.js → packages/cases/case-record-operations.mjs} +72 -29
  142. package/{frontend/src/lib/analysis/case-report.js → packages/cases/case-report.mjs} +108 -14
  143. package/packages/cases/case-response-model.mjs +1604 -0
  144. package/packages/cases/case-response-packet.mjs +1312 -0
  145. package/{frontend/src/lib/analysis/case-storage-model.js → packages/cases/case-storage-model.mjs} +2 -2
  146. package/{frontend/src/lib/analysis/http-summary.js → packages/cases/http-summary.mjs} +1 -1
  147. package/{frontend/src/lib/analysis/comparison-ledger-bulk.js → packages/comparison/comparison-ledger-bulk.mjs} +2 -2
  148. package/{frontend/src/lib/analysis/comparison-ledger-contract.js → packages/comparison/comparison-ledger-contract.mjs} +4 -4
  149. package/{frontend/src/lib/analysis/comparison-ledger-json.js → packages/comparison/comparison-ledger-json.mjs} +1 -0
  150. package/{frontend/src/lib/analysis/comparison-ledger-serialization.js → packages/comparison/comparison-ledger-serialization.mjs} +1 -0
  151. package/packages/comparison/favicon-similarity.mjs +78 -0
  152. package/{frontend/src/lib/analysis/page-similarity.js → packages/comparison/page-similarity.mjs} +4 -3
  153. package/{frontend/src/lib/analysis/relationship-evidence.js → packages/comparison/relationship-evidence.mjs} +6 -7
  154. package/packages/contracts/analyst-review-state-contract.mjs +61 -0
  155. package/packages/contracts/analyst-review-state.mjs +50 -0
  156. package/packages/contracts/case-portability.mjs +1310 -0
  157. package/packages/contracts/cli-command-catalogue.mjs +2 -0
  158. package/packages/contracts/cli-lookup.mjs +394 -0
  159. package/packages/contracts/domain-control-flight-recorder.mjs +461 -0
  160. package/packages/contracts/domain-control-manifest.mjs +1027 -0
  161. package/packages/contracts/domain-control-monitor.mjs +310 -0
  162. package/packages/contracts/domain-control-review.mjs +828 -0
  163. package/packages/contracts/domain-name.mjs +4 -0
  164. package/packages/contracts/external-observation-interchange.mjs +224 -0
  165. package/packages/contracts/extracted-domain-lifecycle.mjs +218 -0
  166. package/packages/contracts/investigation-portability.mjs +331 -0
  167. package/packages/contracts/offline-comparison.mjs +160 -0
  168. package/packages/contracts/risk-calibration.mjs +1288 -0
  169. package/packages/contracts/schema-compatibility.mjs +71 -0
  170. package/packages/contracts/schema-lifecycle.mjs +1702 -0
  171. package/packages/contracts/sslbl-snapshot.mjs +17 -0
  172. package/packages/contracts/workspace-portability.mjs +1347 -0
  173. package/{frontend/src/lib/analysis/artifact-integrity.js → packages/evidence/artifact-integrity.mjs} +13 -11
  174. package/packages/evidence/decision-fact.mjs +735 -0
  175. package/packages/evidence/domain-control-runtime.mjs +547 -0
  176. package/packages/evidence/domain-name.mjs +41 -0
  177. package/packages/evidence/observation.mjs +384 -0
  178. package/{frontend/src/lib/analysis/external-findings-import.js → packages/interchange/external-findings-import.mjs} +24 -22
  179. package/packages/interchange/retained-text.mjs +8 -0
  180. package/{frontend/src/lib/analysis/acquisition-decision-packet.js → packages/investigation/acquisition-decision-packet.mjs} +9 -6
  181. package/{frontend/src/lib/analysis/bulk-domain-comparison.js → packages/investigation/bulk-domain-comparison.mjs} +5 -6
  182. package/{frontend/src/lib/analysis/bulk-mail-exposure.js → packages/investigation/bulk-mail-exposure.mjs} +4 -6
  183. package/{frontend/src/lib/analysis/bulk-review-export.js → packages/investigation/bulk-review-export.mjs} +5 -5
  184. package/packages/investigation/bulk-review-policy.mjs +1 -0
  185. package/{frontend/src/lib/analysis/investigation-capsule.js → packages/investigation/investigation-capsule.mjs} +30 -32
  186. package/packages/investigation/lookup-artefact-inputs.mjs +1 -0
  187. package/{frontend/src/lib/analysis/lookup-asset-graph.js → packages/investigation/lookup-asset-graph.mjs} +4 -2
  188. package/{frontend/src/lib/analysis/lookup-claim-passport.js → packages/investigation/lookup-claim-passport.mjs} +6 -10
  189. package/{frontend/src/lib/analysis/lookup-claim-readiness.js → packages/investigation/lookup-claim-readiness.mjs} +9 -2
  190. package/packages/investigation/lookup-investigation-brief.mjs +172 -0
  191. package/packages/monitoring/analyst-review-state.mjs +680 -0
  192. package/{frontend/src/lib/analysis/brand-profile-model.js → packages/workspace/brand-profile-model.mjs} +70 -47
  193. package/{frontend/src/lib/analysis/bulk-review-model.js → packages/workspace/bulk-review-model.mjs} +13 -14
  194. package/{frontend/src/lib/analysis/bulk-session-model.js → packages/workspace/bulk-session-model.mjs} +33 -59
  195. package/{frontend/src/lib/analysis/bulk-sort.js → packages/workspace/bulk-sort.mjs} +8 -5
  196. package/{frontend/src/lib/analysis/campaign-model.js → packages/workspace/campaign-model.mjs} +20 -22
  197. package/{frontend/src/lib/analysis/detection-rule-model.js → packages/workspace/detection-rule-model.mjs} +15 -17
  198. package/packages/workspace/hostile-input.mjs +172 -0
  199. package/{frontend/src/lib/analysis/investigation-guide.js → packages/workspace/investigation-guide.mjs} +8 -45
  200. package/{frontend/src/lib/analysis/investigation-template-model.js → packages/workspace/investigation-template-model.mjs} +18 -21
  201. package/{frontend/src/lib/analysis/page-baseline.js → packages/workspace/page-baseline.mjs} +6 -13
  202. package/{frontend/src/lib/analysis/relationship-observation-model.js → packages/workspace/relationship-observation-model.mjs} +13 -17
  203. package/{frontend/src/lib/analysis/shortlist-model.js → packages/workspace/shortlist-model.mjs} +20 -18
  204. package/{frontend/src/lib/analysis/watchlist-history.js → packages/workspace/watchlist-history.mjs} +9 -16
  205. package/{frontend/src/lib/analysis/watchlist-store.js → packages/workspace/watchlist-store.mjs} +24 -17
  206. package/{frontend/src/lib/analysis/website-snapshot-model.js → packages/workspace/website-snapshot-model.mjs} +13 -13
  207. package/{frontend/src/lib/analysis/workspace-archive-crypto.js → packages/workspace/workspace-archive-crypto.mjs} +49 -19
  208. package/{frontend/src/lib/analysis/workspace-archive.js → packages/workspace/workspace-archive.mjs} +110 -89
  209. package/third-party-notices.txt +14 -14
  210. package/frontend/src/lib/analysis/bulk-retry-plan.js +0 -79
  211. package/frontend/src/lib/analysis/bulk-source-coverage.js +0 -76
  212. package/frontend/src/lib/analysis/case-migration-model.js +0 -305
  213. package/frontend/src/lib/analysis/case-record-model.js +0 -9
  214. package/frontend/src/lib/analysis/case-response-model.js +0 -728
  215. package/frontend/src/lib/analysis/case-response-packet.js +0 -583
  216. package/frontend/src/lib/analysis/lookup-decision-support.js +0 -542
  217. package/frontend/src/lib/analysis/lookup-investigation-brief.js +0 -153
  218. package/frontend/src/lib/analysis/lookup-presentation.js +0 -120
  219. package/frontend/src/lib/analysis/lookup-response.js +0 -2
  220. package/frontend/src/lib/analysis/lookup-source-refresh.js +0 -277
  221. package/frontend/src/lib/analysis/lookup-summary-model.js +0 -398
  222. package/frontend/src/lib/analysis/scoring.js +0 -55
  223. package/frontend/src/lib/analysis/utils.js +0 -255
  224. package/frontend/src/lib/analysis/visualization-bounds.js +0 -26
  225. package/frontend/src/lib/analysis/visualization-force-graph.js +0 -352
  226. package/frontend/src/lib/analysis/visualization-matrix.js +0 -131
  227. package/frontend/src/lib/analysis/visualization-models.js +0 -338
  228. package/frontend/src/lib/analysis/visualization-time-series.js +0 -185
  229. package/lib/bounded-json-response.mjs +0 -170
  230. package/lib/lookup-response-contract.mjs +0 -1034
  231. package/lib/observation.mjs +0 -115
  232. /package/{frontend/src/lib/analysis/opaque-reference-id.js → packages/cases/opaque-reference-id.mjs} +0 -0
  233. /package/{frontend/src/lib/analysis/acquisition-due-diligence.js → packages/investigation/acquisition-due-diligence.mjs} +0 -0
  234. /package/{frontend/src/lib/analysis/evidence-coverage-ledger.js → packages/investigation/evidence-coverage-ledger.mjs} +0 -0
  235. /package/{frontend/src/lib/analysis/dns-record-normalization.js → packages/workspace/dns-record-normalization.mjs} +0 -0
@@ -0,0 +1,1027 @@
1
+ import { defineSchemaCompatibility } from "./schema-compatibility.mjs";
2
+ import { defineSchemaLifecycleFamily } from "./schema-lifecycle.mjs";
3
+ import { MAX_DOMAIN_NAME_LENGTH } from "./domain-name.mjs";
4
+ import { MAX_DOMAIN_CONTROL_MONITOR_CONCURRENCY, MAX_DOMAIN_CONTROL_MONITOR_DOMAINS, MIN_DOMAIN_CONTROL_MONITOR_CONCURRENCY, MIN_DOMAIN_CONTROL_MONITOR_DOMAINS, } from "./domain-control-monitor.mjs";
5
+ export { MAX_DOMAIN_CONTROL_MONITOR_CONCURRENCY, MAX_DOMAIN_CONTROL_MONITOR_DOMAINS, MIN_DOMAIN_CONTROL_MONITOR_CONCURRENCY, MIN_DOMAIN_CONTROL_MONITOR_DOMAINS, } from "./domain-control-monitor.mjs";
6
+ export const DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA = 'whoisleuth.domain-control-manifest-input';
7
+ export const DOMAIN_CONTROL_MANIFEST_SCHEMA = 'whoisleuth.domain-control-manifest';
8
+ export const DOMAIN_CONTROL_MANIFEST_INPUT_VERSION = 1;
9
+ export const DOMAIN_CONTROL_MANIFEST_VERSION = 2;
10
+ export const MAX_DOMAIN_CONTROL_MANIFEST_BYTES = 16 * 1024 * 1024;
11
+ export const MIN_DOMAIN_CONTROL_MANIFEST_ENTRIES = 1;
12
+ export const MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES = 100;
13
+ export const MIN_DOMAIN_CONTROL_RECORDS = 0;
14
+ export const MAX_CANONICAL_DOMAIN_CONTROL_RECORDS = 32;
15
+ export const DOMAIN_CONTROL_RECORD_INPUT_BOUND_FACTOR = 4;
16
+ export const MAX_DOMAIN_CONTROL_INPUT_RECORDS = MAX_CANONICAL_DOMAIN_CONTROL_RECORDS
17
+ * DOMAIN_CONTROL_RECORD_INPUT_BOUND_FACTOR;
18
+ export const MAX_DOMAIN_CONTROL_JSON_DEPTH = 16;
19
+ export const MAX_DOMAIN_CONTROL_JSON_VALUES = 400_000;
20
+ export const MAX_DOMAIN_CONTROL_NAME_INPUT_LENGTH = 1_024;
21
+ export const MAX_DOMAIN_CONTROL_DOMAIN_LENGTH = MAX_DOMAIN_NAME_LENGTH;
22
+ export const MAX_DOMAIN_CONTROL_TEXT_LENGTH = 300;
23
+ export const MAX_DOMAIN_CONTROL_NOTE_LENGTH = 500;
24
+ export const MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH = 64;
25
+ export const MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH = 32;
26
+ export const MAX_DOMAIN_CONTROL_MX_TEXT_LENGTH = 500;
27
+ export const MAX_DOMAIN_CONTROL_CAA_TAG_LENGTH = 32;
28
+ export const MAX_DOMAIN_CONTROL_CAA_VALUE_LENGTH = 500;
29
+ export const MAX_DOMAIN_CONTROL_CAA_PRESENTATION_LENGTH = 600;
30
+ export const MIN_DOMAIN_CONTROL_DS_DIGEST_LENGTH = 2;
31
+ export const MAX_DOMAIN_CONTROL_DS_DIGEST_LENGTH = 1_024;
32
+ export const MAX_DOMAIN_CONTROL_DS_PRESENTATION_LENGTH = 1_200;
33
+ export const DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR = 4;
34
+ export const MAX_DOMAIN_CONTROL_MX_PRIORITY = 65_535;
35
+ export const MAX_DOMAIN_CONTROL_CAA_FLAGS = 255;
36
+ export const MAX_DOMAIN_CONTROL_DS_KEY_TAG = 65_535;
37
+ export const MAX_DOMAIN_CONTROL_DS_ALGORITHM = 255;
38
+ export const MAX_DOMAIN_CONTROL_DS_DIGEST_TYPE = 255;
39
+ export const DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH = 64;
40
+ export const DOMAIN_CONTROL_DIGEST_SHA256_HEX_LENGTH = 64;
41
+ export const DOMAIN_CONTROL_DIGEST_SHA256_LENGTH = 'sha256:'.length
42
+ + DOMAIN_CONTROL_DIGEST_SHA256_HEX_LENGTH;
43
+ export const MAX_DOMAIN_CONTROL_GENERIC_JSON_DEPTH = 48;
44
+ export const MAX_DOMAIN_CONTROL_GENERIC_JSON_KEYS = 50_000;
45
+ export const MAX_DOMAIN_CONTROL_GENERIC_JSON_VALUES = 100_000;
46
+ export const MAX_DOMAIN_CONTROL_JSON_CONTAINER_ITEMS = 10_000;
47
+ export const MAX_DOMAIN_CONTROL_BROWSER_PROFILE_ENTRIES = 20;
48
+ export const MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_DEPTH = 50;
49
+ export const MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_KEYS = 5_050_000;
50
+ export const MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_VALUES = 10_100_000;
51
+ export const MAX_DOMAIN_CONTROL_PORTABLE_BYTES = 15 * 1024 * 1024;
52
+ export const DOMAIN_CONTROL_MANIFEST_INPUT_KEYS = Object.freeze([
53
+ 'schema',
54
+ 'version',
55
+ 'expiresAt',
56
+ 'entries',
57
+ ]);
58
+ export const DOMAIN_CONTROL_MANIFEST_ROOT_KEYS = Object.freeze([
59
+ 'schema',
60
+ 'version',
61
+ 'generatedAt',
62
+ 'expiresAt',
63
+ 'entries',
64
+ 'limitations',
65
+ 'integrity',
66
+ ]);
67
+ export const DOMAIN_CONTROL_MANIFEST_ENTRY_KEYS = Object.freeze([
68
+ 'domain',
69
+ 'nameservers',
70
+ 'ds',
71
+ 'mx',
72
+ 'caa',
73
+ 'tlsIssuer',
74
+ 'tlsSpkiSha256',
75
+ 'registrarLock',
76
+ 'renewalReviewAt',
77
+ 'note',
78
+ ]);
79
+ export const DOMAIN_CONTROL_MANIFEST_INTEGRITY_KEYS = Object.freeze([
80
+ 'algorithm',
81
+ 'canonicalization',
82
+ 'digestSha256',
83
+ ]);
84
+ export const DOMAIN_CONTROL_RECORD_LIST_FIELDS = Object.freeze([
85
+ 'nameservers',
86
+ 'ds',
87
+ 'mx',
88
+ 'caa',
89
+ ]);
90
+ export const DOMAIN_CONTROL_MX_RECORD_KEYS = Object.freeze([
91
+ 'exchange',
92
+ 'host',
93
+ 'value',
94
+ 'priority',
95
+ 'preference',
96
+ ]);
97
+ export const DOMAIN_CONTROL_CAA_RECORD_KEYS = Object.freeze([
98
+ 'critical',
99
+ 'flags',
100
+ 'tag',
101
+ 'value',
102
+ ]);
103
+ export const DOMAIN_CONTROL_DS_RECORD_KEYS = Object.freeze([
104
+ 'keyTag',
105
+ 'key_tag',
106
+ 'algorithm',
107
+ 'digestType',
108
+ 'digest_type',
109
+ 'digest',
110
+ ]);
111
+ export const DOMAIN_CONTROL_MANIFEST_LIMITATIONS = Object.freeze([
112
+ 'This analyst-authored manifest records intended domain-control state. It does not collect evidence or change registrar, DNS, mail, or certificate configuration.',
113
+ 'Empty desired fields are unconfigured rather than claims that a record should be absent.',
114
+ ]);
115
+ export const SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS = Object.freeze([
116
+ DOMAIN_CONTROL_MANIFEST_VERSION,
117
+ ]);
118
+ export const DOMAIN_CONTROL_MANIFEST_INPUT_COMPATIBILITY = defineSchemaCompatibility({
119
+ id: 'export.domain-control-manifest-input',
120
+ kind: 'export',
121
+ schema: DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA,
122
+ currentVersion: DOMAIN_CONTROL_MANIFEST_INPUT_VERSION,
123
+ supportedVersions: [DOMAIN_CONTROL_MANIFEST_INPUT_VERSION],
124
+ acceptsUnversionedLegacy: false,
125
+ futureVersionBehavior: 'reject',
126
+ migration: 'exact_current_only',
127
+ writeSemantics: 'read_only',
128
+ byteBudget: MAX_DOMAIN_CONTROL_MANIFEST_BYTES,
129
+ owner: 'packages/contracts/domain-control-manifest.mts',
130
+ note: 'Exact-current bounded ordinary JSON desired-state input. Malformed list shapes, ambiguous structured aliases, unknown structured fields, and over-limit collections fail closed outside the supported envelope.',
131
+ });
132
+ export const DOMAIN_CONTROL_MANIFEST_COMPATIBILITY = defineSchemaCompatibility({
133
+ id: 'export.domain-control-manifest',
134
+ kind: 'export',
135
+ schema: DOMAIN_CONTROL_MANIFEST_SCHEMA,
136
+ currentVersion: DOMAIN_CONTROL_MANIFEST_VERSION,
137
+ supportedVersions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS,
138
+ acceptsUnversionedLegacy: false,
139
+ futureVersionBehavior: 'reject',
140
+ migration: 'read_only',
141
+ writeSemantics: 'non_destructive_merge',
142
+ byteBudget: MAX_DOMAIN_CONTROL_MANIFEST_BYTES,
143
+ owner: 'packages/contracts/domain-control-manifest.mts',
144
+ note: 'The v1.47.4 current writer and v2 use version 2 with deterministic sorted-json-v2 integrity for bounded analyst-authored desired state; browser import is an explicit non-destructive field selection.',
145
+ });
146
+ export const DOMAIN_CONTROL_SCHEMA_LIFECYCLE = defineSchemaLifecycleFamily({
147
+ id: 'domain-control-manifest',
148
+ owner: 'packages/contracts/domain-control-manifest.mts',
149
+ privacy: 'analyst_authored_sensitive',
150
+ compatibility: [
151
+ DOMAIN_CONTROL_MANIFEST_INPUT_COMPATIBILITY,
152
+ DOMAIN_CONTROL_MANIFEST_COMPATIBILITY,
153
+ ],
154
+ contracts: [
155
+ {
156
+ compatibilityId: DOMAIN_CONTROL_MANIFEST_INPUT_COMPATIBILITY.id,
157
+ schema: DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA,
158
+ version: DOMAIN_CONTROL_MANIFEST_INPUT_VERSION,
159
+ role: 'input',
160
+ lifecycle: 'current',
161
+ readable: true,
162
+ emitted: true,
163
+ exactKeys: true,
164
+ extensionPolicy: 'reject',
165
+ futureVersionBehaviour: 'reject',
166
+ migrationTarget: null,
167
+ canonicalisation: null,
168
+ byteBudget: MAX_DOMAIN_CONTROL_MANIFEST_BYTES,
169
+ fixtureIds: ['domain-control-manifest-input-v1'],
170
+ },
171
+ {
172
+ compatibilityId: DOMAIN_CONTROL_MANIFEST_COMPATIBILITY.id,
173
+ schema: DOMAIN_CONTROL_MANIFEST_SCHEMA,
174
+ version: DOMAIN_CONTROL_MANIFEST_VERSION,
175
+ role: 'document',
176
+ lifecycle: 'current',
177
+ readable: true,
178
+ emitted: true,
179
+ exactKeys: true,
180
+ extensionPolicy: 'reject',
181
+ futureVersionBehaviour: 'reject',
182
+ migrationTarget: null,
183
+ canonicalisation: 'sorted-json-v2',
184
+ byteBudget: MAX_DOMAIN_CONTROL_MANIFEST_BYTES,
185
+ fixtureIds: ['domain-control-manifest-v2'],
186
+ },
187
+ ],
188
+ fixtures: [
189
+ {
190
+ id: 'domain-control-manifest-input-v1',
191
+ path: 'test/fixtures/domain-control-manifest-input-v1.json',
192
+ bytes: 658,
193
+ sha256: '2b8a10dec2d78ae0804a469d99b3dfbacbf380c8af0a01ec903106861cd73b09',
194
+ contentDigestSha256: null,
195
+ schema: DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA,
196
+ version: DOMAIN_CONTROL_MANIFEST_INPUT_VERSION,
197
+ role: 'input',
198
+ expectation: 'normalises_to_current_output',
199
+ expectedOutputFixtureId: 'domain-control-manifest-v2',
200
+ scope: 'repository',
201
+ },
202
+ {
203
+ id: 'domain-control-manifest-v2',
204
+ path: 'test/fixtures/domain-control-manifest-v2.json',
205
+ bytes: 1189,
206
+ sha256: '799211e5eba37e733c7f22aac92e073950ffb69c2da64cc11af7ade303deb17a',
207
+ contentDigestSha256: 'sha256:6d2015c111fe05e44babfd42f9adefbfb3bee3caf9fad33c60b9ca640b0f0c8a',
208
+ schema: DOMAIN_CONTROL_MANIFEST_SCHEMA,
209
+ version: DOMAIN_CONTROL_MANIFEST_VERSION,
210
+ role: 'current',
211
+ expectation: 'accepted_exact',
212
+ expectedOutputFixtureId: null,
213
+ scope: 'repository',
214
+ },
215
+ ],
216
+ metadata: {
217
+ metadataVersion: 2,
218
+ enforcement: 'declarative_only',
219
+ shapes: [
220
+ {
221
+ id: 'domain-control.input.v1',
222
+ schema: DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA,
223
+ versions: [DOMAIN_CONTROL_MANIFEST_INPUT_VERSION],
224
+ objects: [
225
+ {
226
+ path: '$',
227
+ requiredKeys: DOMAIN_CONTROL_MANIFEST_INPUT_KEYS,
228
+ optionalKeys: [],
229
+ unknownKeys: 'reject',
230
+ },
231
+ {
232
+ path: '$.entries[]',
233
+ requiredKeys: ['domain'],
234
+ optionalKeys: DOMAIN_CONTROL_MANIFEST_ENTRY_KEYS.filter((key) => key !== 'domain'),
235
+ unknownKeys: 'reject',
236
+ },
237
+ {
238
+ path: '$.entries[].mx[]',
239
+ requiredKeys: [],
240
+ optionalKeys: DOMAIN_CONTROL_MX_RECORD_KEYS,
241
+ unknownKeys: 'reject',
242
+ },
243
+ {
244
+ path: '$.entries[].caa[]',
245
+ requiredKeys: [],
246
+ optionalKeys: DOMAIN_CONTROL_CAA_RECORD_KEYS,
247
+ unknownKeys: 'reject',
248
+ },
249
+ {
250
+ path: '$.entries[].ds[]',
251
+ requiredKeys: [],
252
+ optionalKeys: DOMAIN_CONTROL_DS_RECORD_KEYS,
253
+ unknownKeys: 'reject',
254
+ },
255
+ ],
256
+ fixedArrays: [],
257
+ normalisation: 'input_to_current',
258
+ target: {
259
+ schema: DOMAIN_CONTROL_MANIFEST_SCHEMA,
260
+ version: DOMAIN_CONTROL_MANIFEST_VERSION,
261
+ },
262
+ },
263
+ {
264
+ id: 'domain-control.manifest.v1-v2',
265
+ schema: DOMAIN_CONTROL_MANIFEST_SCHEMA,
266
+ versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS,
267
+ objects: [
268
+ {
269
+ path: '$',
270
+ requiredKeys: DOMAIN_CONTROL_MANIFEST_ROOT_KEYS,
271
+ optionalKeys: [],
272
+ unknownKeys: 'reject',
273
+ },
274
+ {
275
+ path: '$.entries[]',
276
+ requiredKeys: DOMAIN_CONTROL_MANIFEST_ENTRY_KEYS,
277
+ optionalKeys: [],
278
+ unknownKeys: 'reject',
279
+ },
280
+ {
281
+ path: '$.integrity',
282
+ requiredKeys: DOMAIN_CONTROL_MANIFEST_INTEGRITY_KEYS,
283
+ optionalKeys: [],
284
+ unknownKeys: 'reject',
285
+ },
286
+ ],
287
+ fixedArrays: [
288
+ {
289
+ path: '$.limitations',
290
+ values: DOMAIN_CONTROL_MANIFEST_LIMITATIONS,
291
+ },
292
+ ],
293
+ normalisation: 'preserve_signed_document',
294
+ target: null,
295
+ },
296
+ ],
297
+ boundProfiles: [
298
+ {
299
+ id: 'domain-control.core-wire.v1',
300
+ bounds: [
301
+ { id: 'serialised-bytes', path: '$', phase: 'serialised', unit: 'bytes', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MANIFEST_BYTES, handling: 'reject' },
302
+ { id: 'manifest-entries', path: '$.entries', phase: 'pre_accumulation', unit: 'entries', minimum: MIN_DOMAIN_CONTROL_MANIFEST_ENTRIES, maximum: MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES, handling: 'reject' },
303
+ { id: 'input-nameservers', path: '$.entries[].nameservers', phase: 'pre_accumulation', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_DOMAIN_CONTROL_INPUT_RECORDS, handling: 'reject' },
304
+ { id: 'input-ds', path: '$.entries[].ds', phase: 'pre_accumulation', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_DOMAIN_CONTROL_INPUT_RECORDS, handling: 'reject' },
305
+ { id: 'input-mx', path: '$.entries[].mx', phase: 'pre_accumulation', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_DOMAIN_CONTROL_INPUT_RECORDS, handling: 'reject' },
306
+ { id: 'input-caa', path: '$.entries[].caa', phase: 'pre_accumulation', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_DOMAIN_CONTROL_INPUT_RECORDS, handling: 'reject' },
307
+ { id: 'canonical-nameservers', path: '$.entries[].nameservers', phase: 'normalised', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_CANONICAL_DOMAIN_CONTROL_RECORDS, handling: 'truncate' },
308
+ { id: 'canonical-ds', path: '$.entries[].ds', phase: 'normalised', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_CANONICAL_DOMAIN_CONTROL_RECORDS, handling: 'truncate' },
309
+ { id: 'canonical-mx', path: '$.entries[].mx', phase: 'normalised', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_CANONICAL_DOMAIN_CONTROL_RECORDS, handling: 'truncate' },
310
+ { id: 'canonical-caa', path: '$.entries[].caa', phase: 'normalised', unit: 'items', minimum: MIN_DOMAIN_CONTROL_RECORDS, maximum: MAX_CANONICAL_DOMAIN_CONTROL_RECORDS, handling: 'truncate' },
311
+ { id: 'json-depth', path: '$', phase: 'pre_accumulation', unit: 'depth', minimum: 0, maximum: MAX_DOMAIN_CONTROL_JSON_DEPTH, handling: 'reject' },
312
+ { id: 'json-values', path: '$', phase: 'pre_accumulation', unit: 'values', minimum: 1, maximum: MAX_DOMAIN_CONTROL_JSON_VALUES, handling: 'reject' },
313
+ { id: 'raw-domain', path: '$.entries[].domain', phase: 'pre_accumulation', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_NAME_INPUT_LENGTH, handling: 'reject' },
314
+ { id: 'canonical-domain', path: '$.entries[].domain', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_DOMAIN_LENGTH, handling: 'reject' },
315
+ { id: 'raw-nameserver', path: '$.entries[].nameservers[]', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_NAME_INPUT_LENGTH, handling: 'drop_value' },
316
+ { id: 'raw-tls-issuer', path: '$.entries[].tlsIssuer', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_TEXT_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
317
+ { id: 'tls-issuer', path: '$.entries[].tlsIssuer', phase: 'normalised', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_TEXT_LENGTH, handling: 'truncate' },
318
+ { id: 'raw-note', path: '$.entries[].note', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_NOTE_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
319
+ { id: 'note', path: '$.entries[].note', phase: 'normalised', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_NOTE_LENGTH, handling: 'truncate' },
320
+ { id: 'raw-generated-at', path: '$.generatedAt', phase: 'pre_accumulation', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'reject' },
321
+ { id: 'generated-at', path: '$.generatedAt', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH, handling: 'reject' },
322
+ { id: 'raw-expires-at', path: '$.expiresAt', phase: 'pre_accumulation', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'reject' },
323
+ { id: 'expires-at', path: '$.expiresAt', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH, handling: 'reject' },
324
+ { id: 'raw-renewal-review-at', path: '$.entries[].renewalReviewAt', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
325
+ { id: 'renewal-review-at', path: '$.entries[].renewalReviewAt', phase: 'normalised', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH, handling: 'drop_value' },
326
+ { id: 'mx-priority-text', path: '$.entries[].mx[].priority', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
327
+ { id: 'mx-preference-text', path: '$.entries[].mx[].preference', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
328
+ { id: 'caa-critical-text', path: '$.entries[].caa[].critical', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
329
+ { id: 'caa-flags-text', path: '$.entries[].caa[].flags', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
330
+ { id: 'ds-key-tag-text', path: '$.entries[].ds[].keyTag', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
331
+ { id: 'ds-key-tag-snake-text', path: '$.entries[].ds[].key_tag', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
332
+ { id: 'ds-algorithm-text', path: '$.entries[].ds[].algorithm', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
333
+ { id: 'ds-digest-type-text', path: '$.entries[].ds[].digestType', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
334
+ { id: 'ds-digest-type-snake-text', path: '$.entries[].ds[].digest_type', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_RECORD_INTEGER_TEXT_LENGTH, handling: 'drop_value' },
335
+ { id: 'raw-mx-text', path: '$.entries[].mx[]', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_MX_TEXT_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
336
+ { id: 'mx-text', path: '$.entries[].mx[]', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MX_TEXT_LENGTH, handling: 'drop_value' },
337
+ { id: 'mx-priority', path: '$.entries[].mx[].priority', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_MX_PRIORITY, handling: 'drop_value' },
338
+ { id: 'mx-preference', path: '$.entries[].mx[].preference', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_MX_PRIORITY, handling: 'drop_value' },
339
+ { id: 'raw-caa-tag', path: '$.entries[].caa[].tag', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_CAA_TAG_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
340
+ { id: 'caa-tag', path: '$.entries[].caa[].tag', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_CAA_TAG_LENGTH, handling: 'drop_value' },
341
+ { id: 'raw-caa-value', path: '$.entries[].caa[].value', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_CAA_VALUE_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
342
+ { id: 'caa-value', path: '$.entries[].caa[].value', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_CAA_VALUE_LENGTH, handling: 'drop_value' },
343
+ { id: 'raw-caa-presentation', path: '$.entries[].caa[]', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_CAA_PRESENTATION_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
344
+ { id: 'caa-presentation', path: '$.entries[].caa[]', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_CAA_PRESENTATION_LENGTH, handling: 'drop_value' },
345
+ { id: 'caa-critical', path: '$.entries[].caa[].critical', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_CAA_FLAGS, handling: 'drop_value' },
346
+ { id: 'caa-flags', path: '$.entries[].caa[].flags', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_CAA_FLAGS, handling: 'drop_value' },
347
+ { id: 'raw-ds-digest', path: '$.entries[].ds[].digest', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_DS_DIGEST_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
348
+ { id: 'ds-digest', path: '$.entries[].ds[].digest', phase: 'normalised', unit: 'characters', minimum: MIN_DOMAIN_CONTROL_DS_DIGEST_LENGTH, maximum: MAX_DOMAIN_CONTROL_DS_DIGEST_LENGTH, handling: 'drop_value' },
349
+ { id: 'raw-ds-presentation', path: '$.entries[].ds[]', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_DS_PRESENTATION_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
350
+ { id: 'ds-presentation', path: '$.entries[].ds[]', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_DS_PRESENTATION_LENGTH, handling: 'drop_value' },
351
+ { id: 'ds-key-tag', path: '$.entries[].ds[].keyTag', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_DS_KEY_TAG, handling: 'drop_value' },
352
+ { id: 'ds-key-tag-snake', path: '$.entries[].ds[].key_tag', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_DS_KEY_TAG, handling: 'drop_value' },
353
+ { id: 'ds-algorithm', path: '$.entries[].ds[].algorithm', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_DS_ALGORITHM, handling: 'drop_value' },
354
+ { id: 'ds-digest-type', path: '$.entries[].ds[].digestType', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_DS_DIGEST_TYPE, handling: 'drop_value' },
355
+ { id: 'ds-digest-type-snake', path: '$.entries[].ds[].digest_type', phase: 'normalised', unit: 'integer', minimum: 0, maximum: MAX_DOMAIN_CONTROL_DS_DIGEST_TYPE, handling: 'drop_value' },
356
+ { id: 'raw-spki-digest', path: '$.entries[].tlsSpkiSha256', phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'drop_value' },
357
+ { id: 'spki-digest', path: '$.entries[].tlsSpkiSha256', phase: 'normalised', unit: 'characters', minimum: DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH, maximum: DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH, handling: 'drop_value' },
358
+ { id: 'manifest-digest', path: '$.integrity.digestSha256', phase: 'normalised', unit: 'characters', minimum: DOMAIN_CONTROL_DIGEST_SHA256_LENGTH, maximum: DOMAIN_CONTROL_DIGEST_SHA256_LENGTH, handling: 'reject' },
359
+ ],
360
+ },
361
+ {
362
+ id: 'domain-control.browser-file.v1',
363
+ bounds: [
364
+ { id: 'raw-bytes', path: '$', phase: 'raw_intake', unit: 'bytes', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MANIFEST_BYTES, handling: 'reject' },
365
+ { id: 'json-depth', path: '$', phase: 'pre_accumulation', unit: 'depth', minimum: 0, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_DEPTH, handling: 'reject' },
366
+ { id: 'json-keys', path: '$', phase: 'pre_accumulation', unit: 'keys', minimum: 0, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_KEYS, handling: 'reject' },
367
+ { id: 'json-values', path: '$', phase: 'pre_accumulation', unit: 'values', minimum: 1, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_VALUES, handling: 'reject' },
368
+ { id: 'container-items', path: '$', phase: 'pre_accumulation', unit: 'items', minimum: 0, maximum: MAX_DOMAIN_CONTROL_JSON_CONTAINER_ITEMS, handling: 'reject' },
369
+ ],
370
+ },
371
+ {
372
+ id: 'domain-control.browser-profile.v1',
373
+ bounds: [
374
+ { id: 'exported-entries', path: '$.selectedDomains', phase: 'action', unit: 'entries', minimum: 1, maximum: MAX_DOMAIN_CONTROL_BROWSER_PROFILE_ENTRIES, handling: 'cap_operation' },
375
+ { id: 'previewed-entries', path: '$.verifiedManifest.entries', phase: 'action', unit: 'entries', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES, handling: 'reject' },
376
+ { id: 'applied-baselines', path: '$.choices', phase: 'action', unit: 'entries', minimum: 0, maximum: MAX_DOMAIN_CONTROL_BROWSER_PROFILE_ENTRIES, handling: 'cap_operation' },
377
+ ],
378
+ },
379
+ {
380
+ id: 'domain-control.cli-domain-control-file.v1',
381
+ bounds: [
382
+ { id: 'raw-bytes', path: '$', phase: 'raw_intake', unit: 'bytes', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MANIFEST_BYTES, handling: 'reject' },
383
+ { id: 'json-depth', path: '$', phase: 'pre_accumulation', unit: 'depth', minimum: 0, maximum: MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_DEPTH, handling: 'reject' },
384
+ { id: 'json-keys', path: '$', phase: 'pre_accumulation', unit: 'keys', minimum: 0, maximum: MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_KEYS, handling: 'reject' },
385
+ { id: 'json-values', path: '$', phase: 'pre_accumulation', unit: 'values', minimum: 1, maximum: MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_VALUES, handling: 'reject' },
386
+ { id: 'container-items', path: '$', phase: 'pre_accumulation', unit: 'items', minimum: 0, maximum: MAX_DOMAIN_CONTROL_JSON_CONTAINER_ITEMS, handling: 'reject' },
387
+ ],
388
+ },
389
+ {
390
+ id: 'domain-control.cli-monitor-file.v1',
391
+ bounds: [
392
+ { id: 'raw-bytes', path: '$', phase: 'raw_intake', unit: 'bytes', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MANIFEST_BYTES, handling: 'reject' },
393
+ { id: 'json-depth', path: '$', phase: 'pre_accumulation', unit: 'depth', minimum: 0, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_DEPTH, handling: 'reject' },
394
+ { id: 'json-keys', path: '$', phase: 'pre_accumulation', unit: 'keys', minimum: 0, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_KEYS, handling: 'reject' },
395
+ { id: 'json-values', path: '$', phase: 'pre_accumulation', unit: 'values', minimum: 1, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_VALUES, handling: 'reject' },
396
+ { id: 'container-items', path: '$', phase: 'pre_accumulation', unit: 'items', minimum: 0, maximum: MAX_DOMAIN_CONTROL_JSON_CONTAINER_ITEMS, handling: 'reject' },
397
+ ],
398
+ },
399
+ {
400
+ id: 'domain-control.cli-portable-file.v1',
401
+ bounds: [
402
+ { id: 'raw-bytes', path: '$', phase: 'raw_intake', unit: 'bytes', minimum: 1, maximum: MAX_DOMAIN_CONTROL_PORTABLE_BYTES, handling: 'reject' },
403
+ { id: 'json-depth', path: '$', phase: 'pre_accumulation', unit: 'depth', minimum: 0, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_DEPTH, handling: 'reject' },
404
+ { id: 'json-keys', path: '$', phase: 'pre_accumulation', unit: 'keys', minimum: 0, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_KEYS, handling: 'reject' },
405
+ { id: 'json-values', path: '$', phase: 'pre_accumulation', unit: 'values', minimum: 1, maximum: MAX_DOMAIN_CONTROL_GENERIC_JSON_VALUES, handling: 'reject' },
406
+ { id: 'container-items', path: '$', phase: 'pre_accumulation', unit: 'items', minimum: 0, maximum: MAX_DOMAIN_CONTROL_JSON_CONTAINER_ITEMS, handling: 'reject' },
407
+ ],
408
+ },
409
+ {
410
+ id: 'domain-control.cli-monitor-action.v1',
411
+ bounds: [
412
+ { id: 'selected-domains', path: '$.manifest.entries', phase: 'action', unit: 'entries', minimum: MIN_DOMAIN_CONTROL_MONITOR_DOMAINS, maximum: MAX_DOMAIN_CONTROL_MONITOR_DOMAINS, handling: 'cap_operation' },
413
+ { id: 'limit', path: '$.options.limit', phase: 'action', unit: 'entries', minimum: MIN_DOMAIN_CONTROL_MONITOR_DOMAINS, maximum: MAX_DOMAIN_CONTROL_MONITOR_DOMAINS, handling: 'reject' },
414
+ { id: 'concurrency', path: '$.options.concurrency', phase: 'action', unit: 'concurrency', minimum: MIN_DOMAIN_CONTROL_MONITOR_CONCURRENCY, maximum: MAX_DOMAIN_CONTROL_MONITOR_CONCURRENCY, handling: 'reject' },
415
+ ],
416
+ },
417
+ ],
418
+ hooks: [
419
+ { id: 'domain-control.shared.build-unsigned', role: 'builder', runtime: 'shared', module: 'packages/evidence/domain-control-runtime.mts', exportName: 'buildUnsignedDomainControlManifest' },
420
+ { id: 'domain-control.shared.normalise-document', role: 'normaliser', runtime: 'shared', module: 'packages/evidence/domain-control-runtime.mts', exportName: 'normalizeDomainControlManifestDocument' },
421
+ { id: 'domain-control.shared.measure-serialised-bytes', role: 'serialised_byte_counter', runtime: 'shared', module: 'packages/evidence/domain-control-runtime.mts', exportName: 'domainControlManifestSerialisedBytes' },
422
+ { id: 'domain-control.shared.assert-byte-budget', role: 'budget_guard', runtime: 'shared', module: 'packages/evidence/domain-control-runtime.mts', exportName: 'assertDomainControlManifestByteBudget' },
423
+ { id: 'domain-control.shared.serialise-document', role: 'serialiser', runtime: 'shared', module: 'packages/evidence/domain-control-runtime.mts', exportName: 'serializeDomainControlManifest' },
424
+ { id: 'domain-control.browser.build-input', role: 'builder', runtime: 'browser', module: 'packages/workspace/domain-control-passport.mts', exportName: 'buildBrandProfilePassportInput' },
425
+ { id: 'domain-control.browser.build-document', role: 'builder', runtime: 'browser', module: 'packages/workspace/domain-control-passport.mts', exportName: 'buildDomainControlPassport' },
426
+ { id: 'domain-control.browser.verify-unexpired', role: 'integrity_verifier', runtime: 'browser', module: 'packages/workspace/domain-control-passport.mts', exportName: 'verifyDomainControlPassport' },
427
+ { id: 'domain-control.browser.apply', role: 'merger', runtime: 'browser', module: 'packages/workspace/domain-control-passport.mts', exportName: 'applyVerifiedDomainControlPassport' },
428
+ { id: 'domain-control.node.build-document', role: 'builder', runtime: 'node', module: 'lib/domain-control-manifest.mts', exportName: 'buildDomainControlManifest' },
429
+ { id: 'domain-control.node.verify-integrity', role: 'integrity_verifier', runtime: 'node', module: 'lib/domain-control-manifest.mts', exportName: 'verifyDomainControlManifest' },
430
+ { id: 'domain-control.node.review', role: 'reviewer', runtime: 'node', module: 'lib/domain-control-manifest.mts', exportName: 'reviewDomainControlManifest' },
431
+ { id: 'domain-control.cli.offline-structure', role: 'structure_validator', runtime: 'cli', module: 'cli/artifact-structure.mts', exportName: 'validateSignedDigestArtifactStructure' },
432
+ { id: 'domain-control.cli.offline-verify', role: 'integrity_verifier', runtime: 'cli', module: 'cli/artifact-verify.mts', exportName: 'verifyOfflineArtifact' },
433
+ { id: 'domain-control.cli.interchange-report', role: 'interchange_reporter', runtime: 'cli', module: 'cli/interchange-report.mts', exportName: 'buildInterchangeFidelityReport' },
434
+ { id: 'domain-control.cli.sign-package', role: 'signer', runtime: 'cli', module: 'cli/evidence-signing.mts', exportName: 'signEvidencePackage' },
435
+ { id: 'domain-control.cli.verify-signature', role: 'signature_verifier', runtime: 'cli', module: 'cli/evidence-signing.mts', exportName: 'verifyEvidencePackageSignature' },
436
+ { id: 'domain-control.cli.sharing-review', role: 'sharing_reviewer', runtime: 'cli', module: 'cli/sharing-review.mts', exportName: 'buildSharingReview' },
437
+ { id: 'domain-control.cli.saved-lookup-review', role: 'reviewer', runtime: 'cli', module: 'cli/domain-control-observations.mts', exportName: 'buildCliDomainControlReview' },
438
+ { id: 'domain-control.cli.monitor-once', role: 'monitor', runtime: 'cli', module: 'cli/domain-control-monitor.mts', exportName: 'runDomainControlMonitor' },
439
+ ],
440
+ serialisationProfiles: [
441
+ {
442
+ id: 'domain-control.manifest-json.v1',
443
+ schema: DOMAIN_CONTROL_MANIFEST_SCHEMA,
444
+ versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS,
445
+ mediaType: 'application/json',
446
+ encoding: 'utf-8',
447
+ bom: false,
448
+ indentSpaces: 2,
449
+ terminalLf: true,
450
+ propertyOrder: 'normalised_fixed',
451
+ canonicalisation: null,
452
+ integrity: 'structural_only_requires_separate_verification',
453
+ serializerHookId: 'domain-control.shared.serialise-document',
454
+ verifierHookIds: [
455
+ 'domain-control.node.verify-integrity',
456
+ 'domain-control.browser.verify-unexpired',
457
+ ],
458
+ },
459
+ ],
460
+ privacyProfiles: [
461
+ {
462
+ id: 'domain-control.manifest-sensitive.v1',
463
+ classification: 'analyst_authored_sensitive',
464
+ projection: 'full_manifest',
465
+ includedCategories: [
466
+ 'domain-identifiers',
467
+ 'desired-dns',
468
+ 'desired-mail-routing',
469
+ 'desired-certificate',
470
+ 'desired-registrar',
471
+ 'renewal-timing',
472
+ 'analyst-notes',
473
+ 'document-times',
474
+ 'integrity-linkage',
475
+ ],
476
+ excludedCategories: ['raw-upstream-payloads', 'contacts', 'credentials', 'cookies', 'sessions'],
477
+ notePolicy: 'allowed_bounded',
478
+ retention: 'none',
479
+ network: 'none',
480
+ sharingReview: 'not_applicable',
481
+ },
482
+ {
483
+ id: 'domain-control.cli-manifest.v1',
484
+ classification: 'analyst_authored_sensitive',
485
+ projection: 'full_manifest',
486
+ includedCategories: [
487
+ 'domain-identifiers',
488
+ 'desired-dns',
489
+ 'desired-mail-routing',
490
+ 'desired-certificate',
491
+ 'desired-registrar',
492
+ 'renewal-timing',
493
+ 'analyst-notes',
494
+ 'document-times',
495
+ 'integrity-linkage',
496
+ ],
497
+ excludedCategories: ['raw-upstream-payloads', 'contacts', 'credentials', 'cookies', 'sessions'],
498
+ notePolicy: 'allowed_bounded',
499
+ retention: 'operator_controlled_output',
500
+ network: 'none',
501
+ sharingReview: 'required',
502
+ },
503
+ {
504
+ id: 'domain-control.browser-export.v1',
505
+ classification: 'analyst_authored_sensitive',
506
+ projection: 'browser_export',
507
+ includedCategories: [
508
+ 'domain-identifiers',
509
+ 'desired-dns',
510
+ 'desired-mail-routing',
511
+ 'desired-certificate',
512
+ 'desired-registrar',
513
+ 'renewal-timing',
514
+ 'document-times',
515
+ 'integrity-linkage',
516
+ ],
517
+ excludedCategories: [
518
+ 'analyst-notes',
519
+ 'profile-identity',
520
+ 'brand-context',
521
+ 'contacts',
522
+ 'observations',
523
+ 'change-windows',
524
+ 'planning',
525
+ 'suppressions',
526
+ ],
527
+ notePolicy: 'forced_null',
528
+ retention: 'deliberate_local_file',
529
+ network: 'none',
530
+ sharingReview: 'required',
531
+ },
532
+ {
533
+ id: 'domain-control.browser-import.v1',
534
+ classification: 'analyst_authored_sensitive',
535
+ projection: 'browser_import',
536
+ includedCategories: [
537
+ 'domain-identifiers',
538
+ 'desired-dns',
539
+ 'desired-mail-routing',
540
+ 'desired-certificate',
541
+ 'desired-registrar',
542
+ 'renewal-timing',
543
+ ],
544
+ excludedCategories: [
545
+ 'analyst-notes',
546
+ 'profile-identity',
547
+ 'brand-context',
548
+ 'contacts',
549
+ 'observations',
550
+ 'change-windows',
551
+ 'planning',
552
+ 'suppressions',
553
+ ],
554
+ notePolicy: 'discarded',
555
+ retention: 'browser_indexeddb',
556
+ network: 'none',
557
+ sharingReview: 'not_applicable',
558
+ },
559
+ {
560
+ id: 'domain-control.review-sensitive.v1',
561
+ classification: 'analyst_authored_sensitive',
562
+ projection: 'review_output',
563
+ includedCategories: [
564
+ 'domain-identifiers',
565
+ 'desired-dns',
566
+ 'desired-mail-routing',
567
+ 'desired-certificate',
568
+ 'desired-registrar',
569
+ 'renewal-timing',
570
+ 'observed-control-values',
571
+ 'observation-provenance',
572
+ 'observation-times',
573
+ 'document-times',
574
+ 'integrity-linkage',
575
+ ],
576
+ excludedCategories: [
577
+ 'analyst-notes',
578
+ 'raw-upstream-payloads',
579
+ 'contacts',
580
+ 'credentials',
581
+ 'cookies',
582
+ 'sessions',
583
+ ],
584
+ notePolicy: 'discarded',
585
+ retention: 'transient_report',
586
+ network: 'none',
587
+ sharingReview: 'not_applicable',
588
+ },
589
+ {
590
+ id: 'domain-control.metadata-only.v1',
591
+ classification: 'metadata_only',
592
+ projection: 'metadata_only',
593
+ includedCategories: ['schema-version', 'counts', 'integrity-digest', 'currentness'],
594
+ excludedCategories: [
595
+ 'domain-identifiers',
596
+ 'desired-dns',
597
+ 'desired-mail-routing',
598
+ 'desired-certificate',
599
+ 'desired-registrar',
600
+ 'renewal-timing',
601
+ 'analyst-notes',
602
+ 'raw-upstream-payloads',
603
+ ],
604
+ notePolicy: 'not_applicable',
605
+ retention: 'transient_report',
606
+ network: 'none',
607
+ sharingReview: 'not_applicable',
608
+ },
609
+ {
610
+ id: 'domain-control.signed-wrapper.v1',
611
+ classification: 'analyst_authored_sensitive',
612
+ projection: 'signed_wrapper',
613
+ includedCategories: [
614
+ 'complete-manifest',
615
+ 'signing-time',
616
+ 'public-key',
617
+ 'key-identifier',
618
+ ],
619
+ excludedCategories: ['private-key', 'credentials', 'raw-upstream-payloads'],
620
+ notePolicy: 'allowed_bounded',
621
+ retention: 'operator_controlled_output',
622
+ network: 'none',
623
+ sharingReview: 'required',
624
+ },
625
+ {
626
+ id: 'domain-control.bounded-passive-monitor.v1',
627
+ classification: 'analyst_authored_sensitive',
628
+ projection: 'bounded_passive_monitor',
629
+ includedCategories: [
630
+ 'domain-identifiers',
631
+ 'request-metadata',
632
+ 'normalised-observations',
633
+ 'bounded-errors',
634
+ ],
635
+ excludedCategories: ['raw-upstream-payloads', 'contacts', 'credentials', 'cookies', 'sessions'],
636
+ notePolicy: 'not_applicable',
637
+ retention: 'operator_controlled_output',
638
+ network: 'explicit_bounded_passive_deep',
639
+ sharingReview: 'required',
640
+ },
641
+ ],
642
+ expiryProfiles: [
643
+ {
644
+ id: 'domain-control.expiry.build-future.v1',
645
+ field: 'expiresAt',
646
+ anchor: 'generatedAt',
647
+ handling: 'require_after_anchor',
648
+ phase: 'build',
649
+ maximumLifetimeDays: null,
650
+ },
651
+ {
652
+ id: 'domain-control.expiry.require-current.v1',
653
+ field: 'expiresAt',
654
+ anchor: 'checkedAt',
655
+ handling: 'reject_expired',
656
+ phase: 'pre_action',
657
+ maximumLifetimeDays: null,
658
+ },
659
+ {
660
+ id: 'domain-control.expiry.report-currentness.v1',
661
+ field: 'expiresAt',
662
+ anchor: 'checkedAt',
663
+ handling: 'report_expired',
664
+ phase: 'review',
665
+ maximumLifetimeDays: null,
666
+ },
667
+ {
668
+ id: 'domain-control.expiry.integrity-only.v1',
669
+ field: 'expiresAt',
670
+ anchor: null,
671
+ handling: 'integrity_only',
672
+ phase: 'verification',
673
+ maximumLifetimeDays: null,
674
+ },
675
+ ],
676
+ consumerEdges: [
677
+ {
678
+ id: 'domain-control.browser-export',
679
+ plane: 'browser',
680
+ operation: 'export',
681
+ acceptedContracts: [
682
+ { schema: DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_MANIFEST_INPUT_VERSION], mode: 'direct' },
683
+ ],
684
+ emittedContract: { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, version: DOMAIN_CONTROL_MANIFEST_VERSION },
685
+ shapeIds: ['domain-control.input.v1', 'domain-control.manifest.v1-v2'],
686
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.browser-profile.v1'],
687
+ hookIds: [
688
+ 'domain-control.shared.build-unsigned',
689
+ 'domain-control.shared.measure-serialised-bytes',
690
+ 'domain-control.shared.assert-byte-budget',
691
+ 'domain-control.shared.serialise-document',
692
+ 'domain-control.browser.build-input',
693
+ 'domain-control.browser.build-document',
694
+ ],
695
+ serialisationProfileId: 'domain-control.manifest-json.v1',
696
+ privacyProfileId: 'domain-control.browser-export.v1',
697
+ expiryPolicyId: 'domain-control.expiry.build-future.v1',
698
+ requestMode: 'none',
699
+ retentionEffect: 'deliberate_local_file',
700
+ bindingState: 'declared_unenforced',
701
+ policyState: 'current',
702
+ },
703
+ {
704
+ id: 'domain-control.browser-import',
705
+ plane: 'browser',
706
+ operation: 'import',
707
+ acceptedContracts: [
708
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'direct' },
709
+ ],
710
+ emittedContract: null,
711
+ shapeIds: ['domain-control.manifest.v1-v2'],
712
+ boundProfileIds: [
713
+ 'domain-control.core-wire.v1',
714
+ 'domain-control.browser-file.v1',
715
+ 'domain-control.browser-profile.v1',
716
+ ],
717
+ hookIds: [
718
+ 'domain-control.shared.normalise-document',
719
+ 'domain-control.browser.verify-unexpired',
720
+ 'domain-control.browser.apply',
721
+ ],
722
+ serialisationProfileId: null,
723
+ privacyProfileId: 'domain-control.browser-import.v1',
724
+ expiryPolicyId: 'domain-control.expiry.require-current.v1',
725
+ requestMode: 'none',
726
+ retentionEffect: 'browser_indexeddb',
727
+ bindingState: 'declared_unenforced',
728
+ policyState: 'current',
729
+ },
730
+ {
731
+ id: 'domain-control.node-build',
732
+ plane: 'node',
733
+ operation: 'build',
734
+ acceptedContracts: [
735
+ { schema: DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_MANIFEST_INPUT_VERSION], mode: 'direct' },
736
+ ],
737
+ emittedContract: { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, version: DOMAIN_CONTROL_MANIFEST_VERSION },
738
+ shapeIds: ['domain-control.input.v1', 'domain-control.manifest.v1-v2'],
739
+ boundProfileIds: ['domain-control.core-wire.v1'],
740
+ hookIds: [
741
+ 'domain-control.shared.build-unsigned',
742
+ 'domain-control.shared.assert-byte-budget',
743
+ 'domain-control.node.build-document',
744
+ ],
745
+ serialisationProfileId: null,
746
+ privacyProfileId: 'domain-control.manifest-sensitive.v1',
747
+ expiryPolicyId: 'domain-control.expiry.build-future.v1',
748
+ requestMode: 'none',
749
+ retentionEffect: 'none',
750
+ bindingState: 'declared_unenforced',
751
+ policyState: 'current',
752
+ },
753
+ {
754
+ id: 'domain-control.node-verify',
755
+ plane: 'node',
756
+ operation: 'verify',
757
+ acceptedContracts: [
758
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'direct' },
759
+ ],
760
+ emittedContract: null,
761
+ shapeIds: ['domain-control.manifest.v1-v2'],
762
+ boundProfileIds: ['domain-control.core-wire.v1'],
763
+ hookIds: [
764
+ 'domain-control.shared.normalise-document',
765
+ 'domain-control.node.verify-integrity',
766
+ ],
767
+ serialisationProfileId: null,
768
+ privacyProfileId: 'domain-control.manifest-sensitive.v1',
769
+ expiryPolicyId: 'domain-control.expiry.integrity-only.v1',
770
+ requestMode: 'none',
771
+ retentionEffect: 'none',
772
+ bindingState: 'declared_unenforced',
773
+ policyState: 'current',
774
+ },
775
+ {
776
+ id: 'domain-control.node-review',
777
+ plane: 'node',
778
+ operation: 'review',
779
+ acceptedContracts: [
780
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'embedded' },
781
+ ],
782
+ emittedContract: null,
783
+ shapeIds: ['domain-control.manifest.v1-v2'],
784
+ boundProfileIds: ['domain-control.core-wire.v1'],
785
+ hookIds: ['domain-control.node.verify-integrity', 'domain-control.node.review'],
786
+ serialisationProfileId: null,
787
+ privacyProfileId: 'domain-control.review-sensitive.v1',
788
+ expiryPolicyId: 'domain-control.expiry.report-currentness.v1',
789
+ requestMode: 'none',
790
+ retentionEffect: 'transient_report',
791
+ bindingState: 'declared_unenforced',
792
+ policyState: 'current',
793
+ },
794
+ {
795
+ id: 'domain-control.cli-core-review',
796
+ plane: 'cli',
797
+ operation: 'core-review',
798
+ acceptedContracts: [
799
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'embedded' },
800
+ ],
801
+ emittedContract: null,
802
+ shapeIds: ['domain-control.manifest.v1-v2'],
803
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-domain-control-file.v1'],
804
+ hookIds: ['domain-control.node.verify-integrity', 'domain-control.node.review'],
805
+ serialisationProfileId: null,
806
+ privacyProfileId: 'domain-control.review-sensitive.v1',
807
+ expiryPolicyId: 'domain-control.expiry.report-currentness.v1',
808
+ requestMode: 'none',
809
+ retentionEffect: 'transient_report',
810
+ bindingState: 'declared_unenforced',
811
+ policyState: 'current',
812
+ },
813
+ {
814
+ id: 'domain-control.cli-saved-lookup-review',
815
+ plane: 'cli',
816
+ operation: 'saved-lookup-review',
817
+ acceptedContracts: [
818
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'embedded' },
819
+ ],
820
+ emittedContract: null,
821
+ shapeIds: ['domain-control.manifest.v1-v2'],
822
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-domain-control-file.v1'],
823
+ hookIds: [
824
+ 'domain-control.node.verify-integrity',
825
+ 'domain-control.node.review',
826
+ 'domain-control.cli.saved-lookup-review',
827
+ ],
828
+ serialisationProfileId: null,
829
+ privacyProfileId: 'domain-control.review-sensitive.v1',
830
+ expiryPolicyId: 'domain-control.expiry.report-currentness.v1',
831
+ requestMode: 'none',
832
+ retentionEffect: 'transient_report',
833
+ bindingState: 'declared_unenforced',
834
+ policyState: 'current',
835
+ },
836
+ {
837
+ id: 'domain-control.cli-build',
838
+ plane: 'cli',
839
+ operation: 'build',
840
+ acceptedContracts: [
841
+ { schema: DOMAIN_CONTROL_MANIFEST_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_MANIFEST_INPUT_VERSION], mode: 'direct' },
842
+ ],
843
+ emittedContract: { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, version: DOMAIN_CONTROL_MANIFEST_VERSION },
844
+ shapeIds: ['domain-control.input.v1', 'domain-control.manifest.v1-v2'],
845
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-domain-control-file.v1'],
846
+ hookIds: [
847
+ 'domain-control.shared.measure-serialised-bytes',
848
+ 'domain-control.shared.assert-byte-budget',
849
+ 'domain-control.shared.serialise-document',
850
+ 'domain-control.node.build-document',
851
+ ],
852
+ serialisationProfileId: 'domain-control.manifest-json.v1',
853
+ privacyProfileId: 'domain-control.cli-manifest.v1',
854
+ expiryPolicyId: 'domain-control.expiry.build-future.v1',
855
+ requestMode: 'none',
856
+ retentionEffect: 'operator_controlled_output',
857
+ bindingState: 'declared_unenforced',
858
+ policyState: 'current',
859
+ },
860
+ {
861
+ id: 'domain-control.cli-offline-verify',
862
+ plane: 'cli',
863
+ operation: 'offline-verify',
864
+ acceptedContracts: [
865
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'direct' },
866
+ ],
867
+ emittedContract: null,
868
+ shapeIds: ['domain-control.manifest.v1-v2'],
869
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-portable-file.v1'],
870
+ hookIds: [
871
+ 'domain-control.cli.offline-structure',
872
+ 'domain-control.cli.offline-verify',
873
+ 'domain-control.node.verify-integrity',
874
+ ],
875
+ serialisationProfileId: null,
876
+ privacyProfileId: 'domain-control.metadata-only.v1',
877
+ expiryPolicyId: 'domain-control.expiry.integrity-only.v1',
878
+ requestMode: 'none',
879
+ retentionEffect: 'transient_report',
880
+ bindingState: 'declared_unenforced',
881
+ policyState: 'current',
882
+ },
883
+ {
884
+ id: 'domain-control.cli-interchange',
885
+ plane: 'cli',
886
+ operation: 'interchange',
887
+ acceptedContracts: [
888
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'direct' },
889
+ ],
890
+ emittedContract: null,
891
+ shapeIds: ['domain-control.manifest.v1-v2'],
892
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-portable-file.v1'],
893
+ hookIds: ['domain-control.cli.interchange-report', 'domain-control.cli.offline-verify'],
894
+ serialisationProfileId: null,
895
+ privacyProfileId: 'domain-control.metadata-only.v1',
896
+ expiryPolicyId: 'domain-control.expiry.integrity-only.v1',
897
+ requestMode: 'none',
898
+ retentionEffect: 'transient_report',
899
+ bindingState: 'declared_unenforced',
900
+ policyState: 'current',
901
+ },
902
+ {
903
+ id: 'domain-control.cli-sign',
904
+ plane: 'cli',
905
+ operation: 'sign',
906
+ acceptedContracts: [
907
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'direct' },
908
+ ],
909
+ emittedContract: null,
910
+ shapeIds: ['domain-control.manifest.v1-v2'],
911
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-portable-file.v1'],
912
+ hookIds: ['domain-control.cli.offline-verify', 'domain-control.cli.sign-package'],
913
+ serialisationProfileId: null,
914
+ privacyProfileId: 'domain-control.signed-wrapper.v1',
915
+ expiryPolicyId: 'domain-control.expiry.integrity-only.v1',
916
+ requestMode: 'none',
917
+ retentionEffect: 'operator_controlled_output',
918
+ bindingState: 'declared_unenforced',
919
+ policyState: 'current',
920
+ },
921
+ {
922
+ id: 'domain-control.cli-verify-signature',
923
+ plane: 'cli',
924
+ operation: 'verify-signature',
925
+ acceptedContracts: [
926
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'embedded' },
927
+ ],
928
+ emittedContract: null,
929
+ shapeIds: ['domain-control.manifest.v1-v2'],
930
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-portable-file.v1'],
931
+ hookIds: ['domain-control.cli.verify-signature', 'domain-control.cli.offline-verify'],
932
+ serialisationProfileId: null,
933
+ privacyProfileId: 'domain-control.metadata-only.v1',
934
+ expiryPolicyId: 'domain-control.expiry.integrity-only.v1',
935
+ requestMode: 'none',
936
+ retentionEffect: 'transient_report',
937
+ bindingState: 'declared_unenforced',
938
+ policyState: 'current',
939
+ },
940
+ {
941
+ id: 'domain-control.cli-sharing-review',
942
+ plane: 'cli',
943
+ operation: 'sharing-review',
944
+ acceptedContracts: [
945
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'direct' },
946
+ ],
947
+ emittedContract: null,
948
+ shapeIds: ['domain-control.manifest.v1-v2'],
949
+ boundProfileIds: ['domain-control.core-wire.v1', 'domain-control.cli-portable-file.v1'],
950
+ hookIds: ['domain-control.cli.sharing-review', 'domain-control.cli.offline-verify'],
951
+ serialisationProfileId: null,
952
+ privacyProfileId: 'domain-control.metadata-only.v1',
953
+ expiryPolicyId: 'domain-control.expiry.report-currentness.v1',
954
+ requestMode: 'none',
955
+ retentionEffect: 'transient_report',
956
+ bindingState: 'declared_unenforced',
957
+ policyState: 'target',
958
+ },
959
+ {
960
+ id: 'domain-control.cli-monitor',
961
+ plane: 'cli',
962
+ operation: 'monitor',
963
+ acceptedContracts: [
964
+ { schema: DOMAIN_CONTROL_MANIFEST_SCHEMA, versions: SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS, mode: 'direct' },
965
+ ],
966
+ emittedContract: null,
967
+ shapeIds: ['domain-control.manifest.v1-v2'],
968
+ boundProfileIds: [
969
+ 'domain-control.core-wire.v1',
970
+ 'domain-control.cli-monitor-file.v1',
971
+ 'domain-control.cli-monitor-action.v1',
972
+ ],
973
+ hookIds: ['domain-control.node.verify-integrity', 'domain-control.cli.monitor-once'],
974
+ serialisationProfileId: null,
975
+ privacyProfileId: 'domain-control.bounded-passive-monitor.v1',
976
+ expiryPolicyId: 'domain-control.expiry.require-current.v1',
977
+ requestMode: 'explicit_bounded_passive_deep',
978
+ retentionEffect: 'operator_controlled_output',
979
+ bindingState: 'declared_unenforced',
980
+ policyState: 'current',
981
+ },
982
+ ],
983
+ consumerRelationships: [],
984
+ },
985
+ });
986
+ function projectDomainControlManifestOperation() {
987
+ const routes = [];
988
+ let currentRoute = null;
989
+ for (const contract of DOMAIN_CONTROL_SCHEMA_LIFECYCLE.contracts) {
990
+ if (contract.schema !== DOMAIN_CONTROL_MANIFEST_SCHEMA)
991
+ continue;
992
+ if (contract.role !== 'document'
993
+ || !contract.readable
994
+ || contract.canonicalisation !== 'sorted-json-v2') {
995
+ throw new TypeError('Domain-control manifest lifecycle routes must be readable canonical documents.');
996
+ }
997
+ const route = Object.freeze({
998
+ version: contract.version,
999
+ canonicalization: contract.canonicalisation,
1000
+ explicit: true,
1001
+ });
1002
+ routes.push(route);
1003
+ if (contract.lifecycle === 'current' || contract.emitted) {
1004
+ if (currentRoute || contract.lifecycle !== 'current' || !contract.emitted) {
1005
+ throw new TypeError('Domain-control manifest lifecycle must have exactly one current emitted route.');
1006
+ }
1007
+ currentRoute = route;
1008
+ }
1009
+ }
1010
+ if (routes.length !== SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS.length
1011
+ || routes.some((route, index) => route.version !== SUPPORTED_DOMAIN_CONTROL_MANIFEST_VERSIONS[index])
1012
+ || currentRoute?.version !== DOMAIN_CONTROL_MANIFEST_VERSION
1013
+ || currentRoute.canonicalization !== 'sorted-json-v2') {
1014
+ throw new TypeError('Domain-control manifest lifecycle routes do not match the supported contract history.');
1015
+ }
1016
+ return Object.freeze({
1017
+ schema: DOMAIN_CONTROL_MANIFEST_SCHEMA,
1018
+ readableVersions: Object.freeze(routes.map((route) => route.version)),
1019
+ canonicalizationRoutes: Object.freeze(routes),
1020
+ currentVersion: DOMAIN_CONTROL_MANIFEST_VERSION,
1021
+ currentCanonicalization: currentRoute.canonicalization,
1022
+ });
1023
+ }
1024
+ export const DOMAIN_CONTROL_MANIFEST_OPERATION = projectDomainControlManifestOperation();
1025
+ export const DOMAIN_CONTROL_MANIFEST_READABLE_VERSIONS = DOMAIN_CONTROL_MANIFEST_OPERATION.readableVersions;
1026
+ export const DOMAIN_CONTROL_MANIFEST_CANONICALIZATION_ROUTES = DOMAIN_CONTROL_MANIFEST_OPERATION.canonicalizationRoutes;
1027
+ export const DOMAIN_CONTROL_MANIFEST_CURRENT_CANONICALIZATION = DOMAIN_CONTROL_MANIFEST_OPERATION.currentCanonicalization;