@slicedearth/whoisleuth-cli 1.45.0 → 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 (268) hide show
  1. package/DISCLOSURE +7 -3
  2. package/NOTICE +5 -4
  3. package/README.md +74 -124
  4. package/SECURITY.md +6 -3
  5. package/bin/whoisleuth.mjs +7 -4
  6. package/cli/archive-inspect.mjs +28 -10
  7. package/cli/arguments.mjs +450 -173
  8. package/cli/artifact-structure.mjs +2507 -0
  9. package/cli/artifact-verify.mjs +286 -64
  10. package/cli/bounded-json.mjs +1 -0
  11. package/cli/bulk-checkpoint.mjs +35 -23
  12. package/cli/bulk-command-runner.mjs +2 -5
  13. package/cli/bulk.mjs +9 -2
  14. package/cli/case-pack.mjs +435 -46
  15. package/cli/ci-report.mjs +6 -1
  16. package/cli/collection-preflight.mjs +2 -2
  17. package/cli/command-catalogue.mjs +12 -3
  18. package/cli/command-reference.mjs +948 -106
  19. package/cli/completion.mjs +504 -218
  20. package/cli/config-profile.mjs +13 -3
  21. package/cli/ct-event-intake.mjs +32 -2
  22. package/cli/discover.mjs +7 -1
  23. package/cli/discovery-observation-snapshot.mjs +24 -28
  24. package/cli/discovery-scan-command-runner.mjs +13 -14
  25. package/cli/discovery-scan.mjs +17 -3
  26. package/cli/discovery-snapshot.mjs +15 -7
  27. package/cli/discovery-workflow.mjs +2 -3
  28. package/cli/doctor.mjs +2 -2
  29. package/cli/domain-control-monitor.mjs +215 -36
  30. package/cli/domain-control-observations.mjs +34 -17
  31. package/cli/errors.mjs +8 -3
  32. package/cli/evidence-command-runner.mjs +17 -11
  33. package/cli/evidence-signing.mjs +68 -50
  34. package/cli/export-evidence.mjs +11 -4
  35. package/cli/external-observation-mapping.mjs +3 -3
  36. package/cli/formatters/html.mjs +3 -3
  37. package/cli/formatters/json.mjs +20 -32
  38. package/cli/formatters/terminal.mjs +586 -22
  39. package/cli/input.mjs +62 -0
  40. package/cli/interactive-launcher.mjs +226 -0
  41. package/cli/interchange-report.mjs +226 -0
  42. package/cli/investigation-manifest.mjs +16 -17
  43. package/cli/investigation-plan.mjs +167 -16
  44. package/cli/investigation-run.mjs +80 -24
  45. package/cli/local-mmdb-review.mjs +45 -14
  46. package/cli/lookalike-calibration.mjs +3 -1
  47. package/cli/lookup-brief.mjs +13 -8
  48. package/cli/lookup-browser.mjs +844 -0
  49. package/cli/lookup-command-runner.mjs +96 -33
  50. package/cli/lookup-diff.mjs +11 -2
  51. package/cli/lookup-plan.mjs +1 -0
  52. package/cli/mail-review.mjs +206 -94
  53. package/cli/manual.mjs +5 -5
  54. package/cli/network-command-runner.mjs +78 -0
  55. package/cli/offline-evidence-review.mjs +45 -14
  56. package/cli/open-asset-model-bridge.mjs +1 -1
  57. package/cli/output-file.mjs +70 -14
  58. package/cli/page-compare.mjs +18 -10
  59. package/cli/progress-events.mjs +2 -1
  60. package/cli/progress.mjs +3 -3
  61. package/cli/registry-cohort.mjs +343 -61
  62. package/cli/registry-doctor.mjs +67 -28
  63. package/cli/registry-support.mjs +2 -1
  64. package/cli/retained-artifact-diff.mjs +375 -0
  65. package/cli/risk-calibration.mjs +89 -40
  66. package/cli/runner.mjs +322 -246
  67. package/cli/saved-lookup.mjs +439 -49
  68. package/cli/sharing-review.mjs +18 -7
  69. package/cli/source-reliability.mjs +75 -36
  70. package/cli/terminal-presentation.mjs +43 -18
  71. package/docs/cli-reference.md +125 -1334
  72. package/docs/cli.md +87 -236
  73. package/frontend/src/lib/analysis/domain-control-manifest-core.js +3 -0
  74. package/frontend/src/lib/analysis/domain-control-records.js +3 -0
  75. package/lib/application-version.mjs +3 -0
  76. package/lib/availability.mjs +72 -52
  77. package/lib/bounded-contract-normalizers.mjs +2 -4
  78. package/lib/bounded-file.mjs +91 -4
  79. package/lib/bounded-json.mjs +287 -0
  80. package/lib/browser-library-profile.mjs +1 -1
  81. package/lib/certificate-extension-profile.mjs +2 -1
  82. package/lib/classify.mjs +56 -5
  83. package/lib/client-behavior-profile.mjs +1 -1
  84. package/lib/credential-surface-profile.mjs +1 -1
  85. package/lib/cryptographic-assurance.mjs +173 -0
  86. package/lib/ct-query.mjs +3 -3
  87. package/lib/ct-search.mjs +120 -64
  88. package/lib/distributed-operation-budget.mjs +4 -2
  89. package/lib/dns-delegation-health.mjs +9 -6
  90. package/lib/dns-intelligence.mjs +4 -3
  91. package/lib/dns-resolver-selection.mjs +6 -4
  92. package/lib/dnssec-chain-validation.mjs +1052 -0
  93. package/lib/dnssec-evidence-validation.mjs +23 -10
  94. package/lib/domain-assurance.mjs +12 -12
  95. package/lib/domain-change-packet.mjs +7 -5
  96. package/lib/domain-control-flight-recorder.mjs +442 -78
  97. package/lib/domain-control-manifest.mjs +314 -171
  98. package/lib/domain-posture-analysis.mjs +5 -2
  99. package/lib/domain-posture.mjs +7 -4
  100. package/lib/encrypted-dns-contract.mjs +2 -3
  101. package/lib/evidence-export.mjs +1243 -88
  102. package/lib/evidence-report-markdown.mjs +3 -0
  103. package/lib/evidence-report.mjs +5 -0
  104. package/lib/external-intelligence-risk.mjs +26 -10
  105. package/lib/favicon.mjs +8 -5
  106. package/lib/feature-policy.mjs +1 -1
  107. package/lib/homepage-metadata-contract.mjs +290 -0
  108. package/lib/hostname.mjs +1 -1
  109. package/lib/html-signals.mjs +89 -5
  110. package/lib/http-evidence-bounds.mjs +3 -0
  111. package/lib/http-intelligence.mjs +332 -6
  112. package/lib/interchange-fidelity-registry.mjs +124 -0
  113. package/lib/local-geoip-evidence.mjs +2 -1
  114. package/lib/lookup-cache.mjs +6 -4
  115. package/lib/lookup-network-evidence-bounds.mjs +9 -0
  116. package/lib/lookup.mjs +27 -4
  117. package/lib/observed-network-context.mjs +1 -1
  118. package/lib/outbound-identity.mjs +2 -3
  119. package/lib/page-fingerprints.mjs +2 -2
  120. package/lib/page-role-profile.mjs +1 -1
  121. package/lib/perceptual-hash.mjs +12 -4
  122. package/lib/portable-generator.mjs +29 -0
  123. package/lib/provider-policy-admission.mjs +11 -4
  124. package/lib/rdap-bootstrap.mjs +76 -16
  125. package/lib/rdap-client.mjs +20 -12
  126. package/lib/rdap-normalization.mjs +324 -80
  127. package/lib/rdap-registrar.mjs +5 -1
  128. package/lib/rdap-transport.mjs +2 -2
  129. package/lib/rdap-validation.mjs +65 -14
  130. package/lib/rdap.mjs +2 -2
  131. package/lib/registrable-domain.mjs +36 -0
  132. package/lib/registry-capabilities.mjs +3 -0
  133. package/lib/registry-capability-catalogue.mjs +12 -2
  134. package/lib/registry-comparison.mjs +28 -11
  135. package/lib/registry-insights.mjs +7 -0
  136. package/lib/response-policy.mjs +27 -4
  137. package/lib/risk-calibration-summary.mjs +340 -0
  138. package/lib/risk-scoring.mjs +4 -3
  139. package/lib/rpki-evidence.mjs +9 -8
  140. package/lib/safe-fetch.mjs +121 -50
  141. package/lib/security-txt.mjs +27 -4
  142. package/lib/service-binding-dns.mjs +6 -1
  143. package/lib/smtp-transport-review.mjs +787 -0
  144. package/lib/sslbl-certificates.generated.mjs +136 -134
  145. package/lib/sslbl-intelligence.mjs +6 -8
  146. package/lib/static-html-analysis.mjs +301 -4
  147. package/lib/structured-data-identity.mjs +51 -19
  148. package/lib/threat-intelligence-fixtures.mjs +2 -4
  149. package/lib/threat-intelligence-manifests.mjs +2 -7
  150. package/lib/threat-intelligence-runtime.mjs +5 -15
  151. package/lib/threat-intelligence-types.mjs +21 -1
  152. package/lib/threatfox-intelligence.mjs +7 -3
  153. package/lib/tls-intelligence.mjs +15 -9
  154. package/lib/tlsa-evidence.mjs +37 -7
  155. package/lib/urlhaus-intelligence.mjs +4 -2
  156. package/lib/urlscan-intelligence.mjs +6 -5
  157. package/lib/website-security-posture.mjs +1 -1
  158. package/lib/website-technology.mjs +1 -1
  159. package/lib/whois-authority.mjs +43 -8
  160. package/lib/whois-chain.mjs +25 -3
  161. package/lib/whois-normalization.mjs +3 -1
  162. package/lib/whois-transport.mjs +12 -3
  163. package/lib/zone-intent-review.mjs +1 -1
  164. package/package.json +12 -4
  165. package/packages/cases/case-brand-profile-references.mjs +85 -0
  166. package/{frontend/src/lib/analysis/case-evidence-model.js → packages/cases/case-evidence-model.mjs} +43 -14
  167. package/packages/cases/case-investigation-branch-model.mjs +132 -0
  168. package/packages/cases/case-migration-model.mjs +476 -0
  169. package/{frontend/src/lib/analysis/case-model.js → packages/cases/case-model.mjs} +3 -3
  170. package/{frontend/src/lib/analysis/case-record-contracts.js → packages/cases/case-record-contracts.mjs} +3 -19
  171. package/{frontend/src/lib/analysis/case-record-core.js → packages/cases/case-record-core.mjs} +58 -31
  172. package/packages/cases/case-record-model.mjs +9 -0
  173. package/{frontend/src/lib/analysis/case-record-operations.js → packages/cases/case-record-operations.mjs} +106 -33
  174. package/{frontend/src/lib/analysis/case-report.js → packages/cases/case-report.mjs} +143 -16
  175. package/packages/cases/case-response-model.mjs +1604 -0
  176. package/packages/cases/case-response-packet.mjs +1312 -0
  177. package/{frontend/src/lib/analysis/case-storage-model.js → packages/cases/case-storage-model.mjs} +2 -2
  178. package/{frontend/src/lib/analysis/http-summary.js → packages/cases/http-summary.mjs} +1 -1
  179. package/packages/cases/opaque-reference-id.mjs +9 -0
  180. package/packages/comparison/comparison-ledger-bulk.mjs +366 -0
  181. package/packages/comparison/comparison-ledger-contract.mjs +241 -0
  182. package/packages/comparison/comparison-ledger-json.mjs +80 -0
  183. package/packages/comparison/comparison-ledger-serialization.mjs +52 -0
  184. package/packages/comparison/favicon-similarity.mjs +78 -0
  185. package/{frontend/src/lib/analysis/page-similarity.js → packages/comparison/page-similarity.mjs} +4 -3
  186. package/{frontend/src/lib/analysis/relationship-evidence.js → packages/comparison/relationship-evidence.mjs} +6 -7
  187. package/packages/contracts/analyst-review-state-contract.mjs +61 -0
  188. package/packages/contracts/analyst-review-state.mjs +50 -0
  189. package/packages/contracts/case-portability.mjs +1310 -0
  190. package/packages/contracts/cli-command-catalogue.mjs +2 -0
  191. package/packages/contracts/cli-lookup.mjs +394 -0
  192. package/packages/contracts/domain-control-flight-recorder.mjs +461 -0
  193. package/packages/contracts/domain-control-manifest.mjs +1027 -0
  194. package/packages/contracts/domain-control-monitor.mjs +310 -0
  195. package/packages/contracts/domain-control-review.mjs +828 -0
  196. package/packages/contracts/domain-name.mjs +4 -0
  197. package/packages/contracts/external-observation-interchange.mjs +224 -0
  198. package/packages/contracts/extracted-domain-lifecycle.mjs +218 -0
  199. package/packages/contracts/investigation-portability.mjs +331 -0
  200. package/packages/contracts/offline-comparison.mjs +160 -0
  201. package/packages/contracts/risk-calibration.mjs +1288 -0
  202. package/packages/contracts/schema-compatibility.mjs +71 -0
  203. package/packages/contracts/schema-lifecycle.mjs +1702 -0
  204. package/packages/contracts/sslbl-snapshot.mjs +17 -0
  205. package/packages/contracts/workspace-portability.mjs +1347 -0
  206. package/packages/evidence/artifact-integrity.mjs +65 -0
  207. package/packages/evidence/decision-fact.mjs +735 -0
  208. package/packages/evidence/domain-control-runtime.mjs +547 -0
  209. package/packages/evidence/domain-name.mjs +41 -0
  210. package/packages/evidence/observation.mjs +384 -0
  211. package/{frontend/src/lib/analysis/external-findings-import.js → packages/interchange/external-findings-import.mjs} +86 -20
  212. package/packages/interchange/retained-text.mjs +8 -0
  213. package/{frontend/src/lib/analysis/acquisition-decision-packet.js → packages/investigation/acquisition-decision-packet.mjs} +11 -8
  214. package/{frontend/src/lib/analysis/bulk-domain-comparison.js → packages/investigation/bulk-domain-comparison.mjs} +28 -9
  215. package/{frontend/src/lib/analysis/bulk-mail-exposure.js → packages/investigation/bulk-mail-exposure.mjs} +67 -18
  216. package/{frontend/src/lib/analysis/bulk-review-export.js → packages/investigation/bulk-review-export.mjs} +10 -9
  217. package/packages/investigation/bulk-review-policy.mjs +1 -0
  218. package/{frontend/src/lib/analysis/investigation-capsule.js → packages/investigation/investigation-capsule.mjs} +50 -18
  219. package/packages/investigation/lookup-artefact-inputs.mjs +1 -0
  220. package/{frontend/src/lib/analysis/lookup-asset-graph.js → packages/investigation/lookup-asset-graph.mjs} +4 -2
  221. package/packages/investigation/lookup-claim-passport.mjs +232 -0
  222. package/packages/investigation/lookup-claim-readiness.mjs +287 -0
  223. package/packages/investigation/lookup-investigation-brief.mjs +172 -0
  224. package/packages/monitoring/analyst-review-state.mjs +680 -0
  225. package/{frontend/src/lib/analysis/brand-profile-model.js → packages/workspace/brand-profile-model.mjs} +97 -50
  226. package/{frontend/src/lib/analysis/bulk-review-model.js → packages/workspace/bulk-review-model.mjs} +15 -15
  227. package/{frontend/src/lib/analysis/bulk-session-model.js → packages/workspace/bulk-session-model.mjs} +179 -39
  228. package/{frontend/src/lib/analysis/bulk-sort.js → packages/workspace/bulk-sort.mjs} +12 -5
  229. package/{frontend/src/lib/analysis/campaign-model.js → packages/workspace/campaign-model.mjs} +20 -22
  230. package/{frontend/src/lib/analysis/detection-rule-model.js → packages/workspace/detection-rule-model.mjs} +15 -17
  231. package/packages/workspace/hostile-input.mjs +172 -0
  232. package/{frontend/src/lib/analysis/investigation-guide.js → packages/workspace/investigation-guide.mjs} +51 -46
  233. package/{frontend/src/lib/analysis/investigation-template-model.js → packages/workspace/investigation-template-model.mjs} +15 -15
  234. package/{frontend/src/lib/analysis/page-baseline.js → packages/workspace/page-baseline.mjs} +6 -13
  235. package/{frontend/src/lib/analysis/relationship-observation-model.js → packages/workspace/relationship-observation-model.mjs} +13 -17
  236. package/{frontend/src/lib/analysis/shortlist-model.js → packages/workspace/shortlist-model.mjs} +20 -18
  237. package/{frontend/src/lib/analysis/watchlist-history.js → packages/workspace/watchlist-history.mjs} +9 -16
  238. package/{frontend/src/lib/analysis/watchlist-store.js → packages/workspace/watchlist-store.mjs} +24 -17
  239. package/{frontend/src/lib/analysis/website-snapshot-model.js → packages/workspace/website-snapshot-model.mjs} +18 -12
  240. package/{frontend/src/lib/analysis/workspace-archive-crypto.js → packages/workspace/workspace-archive-crypto.mjs} +49 -19
  241. package/{frontend/src/lib/analysis/workspace-archive.js → packages/workspace/workspace-archive.mjs} +195 -84
  242. package/third-party-notices.txt +112 -5834
  243. package/frontend/src/lib/analysis/artifact-integrity.js +0 -21
  244. package/frontend/src/lib/analysis/bulk-retry-plan.js +0 -79
  245. package/frontend/src/lib/analysis/bulk-source-coverage.js +0 -76
  246. package/frontend/src/lib/analysis/case-migration-model.js +0 -253
  247. package/frontend/src/lib/analysis/case-record-model.js +0 -7
  248. package/frontend/src/lib/analysis/case-response-model.js +0 -669
  249. package/frontend/src/lib/analysis/case-response-packet.js +0 -573
  250. package/frontend/src/lib/analysis/lookup-decision-support.js +0 -487
  251. package/frontend/src/lib/analysis/lookup-investigation-brief.js +0 -153
  252. package/frontend/src/lib/analysis/lookup-presentation.js +0 -58
  253. package/frontend/src/lib/analysis/lookup-response.js +0 -2
  254. package/frontend/src/lib/analysis/lookup-source-refresh.js +0 -277
  255. package/frontend/src/lib/analysis/lookup-summary-model.js +0 -398
  256. package/frontend/src/lib/analysis/scoring.js +0 -55
  257. package/frontend/src/lib/analysis/utils.js +0 -232
  258. package/frontend/src/lib/analysis/visualization-bounds.js +0 -26
  259. package/frontend/src/lib/analysis/visualization-force-graph.js +0 -352
  260. package/frontend/src/lib/analysis/visualization-matrix.js +0 -88
  261. package/frontend/src/lib/analysis/visualization-models.js +0 -369
  262. package/frontend/src/lib/analysis/visualization-time-series.js +0 -144
  263. package/lib/bounded-json-response.mjs +0 -157
  264. package/lib/lookup-response-contract.mjs +0 -346
  265. package/lib/observation.mjs +0 -114
  266. /package/{frontend/src/lib/analysis/acquisition-due-diligence.js → packages/investigation/acquisition-due-diligence.mjs} +0 -0
  267. /package/{frontend/src/lib/analysis/evidence-coverage-ledger.js → packages/investigation/evidence-coverage-ledger.mjs} +0 -0
  268. /package/{frontend/src/lib/analysis/dns-record-normalization.js → packages/workspace/dns-record-normalization.mjs} +0 -0
@@ -0,0 +1,828 @@
1
+ import { defineSchemaCompatibility } from "./schema-compatibility.mjs";
2
+ import { defineSchemaLifecycleFamily } from "./schema-lifecycle.mjs";
3
+ import { DOMAIN_CONTROL_MANIFEST_ENTRY_KEYS, DOMAIN_CONTROL_MANIFEST_INTEGRITY_KEYS, DOMAIN_CONTROL_MANIFEST_LIMITATIONS, DOMAIN_CONTROL_MANIFEST_ROOT_KEYS, DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH, DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, MAX_CANONICAL_DOMAIN_CONTROL_RECORDS, MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_DEPTH, MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_KEYS, MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_VALUES, MAX_DOMAIN_CONTROL_DOMAIN_LENGTH, MAX_DOMAIN_CONTROL_INPUT_RECORDS, MAX_DOMAIN_CONTROL_JSON_CONTAINER_ITEMS, MAX_DOMAIN_CONTROL_MANIFEST_BYTES, MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES, MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH, } from "./domain-control-manifest.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
+ import { MAX_CLI_LOOKUP_BYTES } from "./cli-lookup.mjs";
6
+ export const DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA = 'whoisleuth.domain-control-review-input';
7
+ export const DOMAIN_CONTROL_REVIEW_SCHEMA = 'whoisleuth.domain-control-review';
8
+ export const CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA = 'whoisleuth.cli.domain-control-review-input';
9
+ export const CLI_DOMAIN_CONTROL_REVIEW_SCHEMA = 'whoisleuth.cli.domain-control-review';
10
+ export const DOMAIN_CONTROL_REVIEW_VERSION = 1;
11
+ export const CLI_DOMAIN_CONTROL_REVIEW_VERSION = 1;
12
+ export const DOMAIN_CONTROL_REVIEW_OBSERVATION_FACTOR = 2;
13
+ export const MAX_DOMAIN_CONTROL_REVIEW_OBSERVATIONS = MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES
14
+ * DOMAIN_CONTROL_REVIEW_OBSERVATION_FACTOR;
15
+ export const MAX_DOMAIN_CONTROL_REVIEW_SOURCE_LENGTH = 120;
16
+ export const MAX_DOMAIN_CONTROL_REVIEW_TEXT_LENGTH = 500;
17
+ export const MAX_DOMAIN_CONTROL_REVIEW_INPUT_BYTES = 32 * 1024 * 1024;
18
+ export const MAX_DOMAIN_CONTROL_REVIEW_COMMAND_BYTES = MAX_DOMAIN_CONTROL_MANIFEST_BYTES;
19
+ export const MIN_DOMAIN_CONTROL_REVIEW_LOOKUPS = 1;
20
+ export const MAX_DOMAIN_CONTROL_REVIEW_LOOKUPS = MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES;
21
+ export const MAX_DOMAIN_CONTROL_REVIEW_JSON_DEPTH = MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_DEPTH;
22
+ export const MAX_DOMAIN_CONTROL_REVIEW_JSON_KEYS = MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_KEYS;
23
+ export const MAX_DOMAIN_CONTROL_REVIEW_JSON_VALUES = MAX_DOMAIN_CONTROL_CLI_REVIEW_JSON_VALUES;
24
+ export const DOMAIN_CONTROL_REVIEW_INPUT_KEYS = Object.freeze([
25
+ 'schema',
26
+ 'version',
27
+ 'manifest',
28
+ 'observations',
29
+ ]);
30
+ export const DOMAIN_CONTROL_REVIEW_OBSERVATION_KEYS = Object.freeze([
31
+ 'domain',
32
+ 'fields',
33
+ ]);
34
+ export const DOMAIN_CONTROL_REVIEW_FIELDS = Object.freeze([
35
+ 'nameservers',
36
+ 'ds',
37
+ 'mx',
38
+ 'caa',
39
+ 'tlsIssuer',
40
+ 'tlsSpkiSha256',
41
+ 'registrarLock',
42
+ ]);
43
+ export const MAX_DOMAIN_CONTROL_REVIEW_FIELDS = DOMAIN_CONTROL_REVIEW_FIELDS.length;
44
+ export const MAX_DOMAIN_CONTROL_REVIEW_FIELD_INPUT_VALUES = MAX_DOMAIN_CONTROL_INPUT_RECORDS;
45
+ export const MAX_DOMAIN_CONTROL_REVIEW_SOURCE_INPUT_LENGTH = MAX_DOMAIN_CONTROL_REVIEW_SOURCE_LENGTH
46
+ * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR;
47
+ export const MAX_DOMAIN_CONTROL_REVIEW_TEXT_INPUT_LENGTH = MAX_DOMAIN_CONTROL_REVIEW_TEXT_LENGTH
48
+ * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR;
49
+ export const MAX_DOMAIN_CONTROL_REVIEW_DOMAIN_INPUT_LENGTH = MAX_DOMAIN_CONTROL_DOMAIN_LENGTH
50
+ * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR;
51
+ export const MAX_DOMAIN_CONTROL_REVIEW_SPKI_INPUT_LENGTH = DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH
52
+ * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR;
53
+ export const DOMAIN_CONTROL_REVIEW_OBSERVATION_FIELD_KEYS = Object.freeze([
54
+ 'state',
55
+ 'values',
56
+ 'source',
57
+ 'observedAt',
58
+ ]);
59
+ export const DOMAIN_CONTROL_REVIEW_ROOT_KEYS = Object.freeze([
60
+ 'schema',
61
+ 'version',
62
+ 'generatedAt',
63
+ 'state',
64
+ 'manifest',
65
+ 'counts',
66
+ 'domains',
67
+ 'ignoredObservationCount',
68
+ 'limitations',
69
+ ]);
70
+ export const DOMAIN_CONTROL_REVIEW_MANIFEST_SUMMARY_KEYS = Object.freeze([
71
+ 'generatedAt',
72
+ 'expiresAt',
73
+ 'digestSha256',
74
+ 'expired',
75
+ ]);
76
+ export const DOMAIN_CONTROL_REVIEW_COUNT_KEYS = Object.freeze([
77
+ 'aligned',
78
+ 'drift',
79
+ 'partial',
80
+ 'unavailable',
81
+ 'unsupported',
82
+ 'not_configured',
83
+ 'due',
84
+ ]);
85
+ export const DOMAIN_CONTROL_REVIEW_DOMAIN_KEYS = Object.freeze([
86
+ 'domain',
87
+ 'state',
88
+ 'comparisons',
89
+ ]);
90
+ export const DOMAIN_CONTROL_REVIEW_COMPARISON_KEYS = Object.freeze([
91
+ 'field',
92
+ 'state',
93
+ 'desired',
94
+ 'observed',
95
+ 'source',
96
+ 'observedAt',
97
+ 'explanation',
98
+ ]);
99
+ export const DOMAIN_CONTROL_REVIEW_LIMITATIONS = Object.freeze([
100
+ 'This local review compares analyst-authored desired state with separately supplied observations and performs no collection or configuration change.',
101
+ 'Only complete observations can produce drift. Partial, unavailable, unsupported, or missing evidence remains inconclusive.',
102
+ 'A valid manifest digest or signature establishes file integrity, not the correctness of the desired state or supplied observations.',
103
+ ]);
104
+ export const CLI_DOMAIN_CONTROL_REVIEW_INPUT_KEYS = Object.freeze([
105
+ 'schema',
106
+ 'version',
107
+ 'manifest',
108
+ 'lookups',
109
+ ]);
110
+ export const CLI_DOMAIN_CONTROL_REVIEW_ROOT_KEYS = Object.freeze([
111
+ 'schema',
112
+ 'version',
113
+ 'generatedAt',
114
+ 'review',
115
+ 'observations',
116
+ 'input',
117
+ 'limitations',
118
+ ]);
119
+ export const CLI_DOMAIN_CONTROL_REVIEW_OBSERVATION_KEYS = Object.freeze([
120
+ 'domain',
121
+ 'observedAt',
122
+ 'collectionDepth',
123
+ 'fields',
124
+ ]);
125
+ export const CLI_DOMAIN_CONTROL_REVIEW_FIELD_KEYS = Object.freeze([
126
+ 'id',
127
+ 'source',
128
+ 'state',
129
+ 'values',
130
+ ]);
131
+ export const CLI_DOMAIN_CONTROL_REVIEW_INPUT_SUMMARY_KEYS = Object.freeze([
132
+ 'lookupsReceived',
133
+ 'latestDomainObservations',
134
+ 'ignoredHistoricalLookups',
135
+ ]);
136
+ export const CLI_DOMAIN_CONTROL_REVIEW_LIMITATIONS = Object.freeze([
137
+ 'The review uses only supplied saved Lookup documents and performs no request.',
138
+ 'The newest supplied observation per domain is used for desired-state comparison; all supplied observations remain available to a separate flight-recorder review.',
139
+ 'Raw RDAP, WHOIS, HTTP, TLS, and page payloads are not copied into this output.',
140
+ ]);
141
+ export const DOMAIN_CONTROL_REVIEW_INPUT_COMPATIBILITY = defineSchemaCompatibility({
142
+ id: 'cli.domain-control-review-core-input',
143
+ kind: 'cli_document',
144
+ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
145
+ currentVersion: DOMAIN_CONTROL_REVIEW_VERSION,
146
+ supportedVersions: [DOMAIN_CONTROL_REVIEW_VERSION],
147
+ acceptsUnversionedLegacy: false,
148
+ futureVersionBehavior: 'reject',
149
+ migration: 'exact_current_only',
150
+ writeSemantics: 'read_only',
151
+ byteBudget: null,
152
+ owner: 'packages/contracts/domain-control-review.mts',
153
+ note: 'Exact-current bounded desired-state manifest and separately attributed observation input for the offline core comparison.',
154
+ });
155
+ export const DOMAIN_CONTROL_REVIEW_COMPATIBILITY = defineSchemaCompatibility({
156
+ id: 'cli.domain-control-review',
157
+ kind: 'cli_document',
158
+ schema: DOMAIN_CONTROL_REVIEW_SCHEMA,
159
+ currentVersion: DOMAIN_CONTROL_REVIEW_VERSION,
160
+ supportedVersions: [DOMAIN_CONTROL_REVIEW_VERSION],
161
+ acceptsUnversionedLegacy: false,
162
+ futureVersionBehavior: 'reject',
163
+ migration: 'exact_current_only',
164
+ writeSemantics: 'read_only',
165
+ byteBudget: null,
166
+ owner: 'packages/contracts/domain-control-review.mts',
167
+ note: 'Offline desired-state comparison. Only complete separately attributed observations can produce drift.',
168
+ });
169
+ export const CLI_DOMAIN_CONTROL_REVIEW_INPUT_COMPATIBILITY = defineSchemaCompatibility({
170
+ id: 'cli.domain-control-review-input',
171
+ kind: 'cli_document',
172
+ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
173
+ currentVersion: CLI_DOMAIN_CONTROL_REVIEW_VERSION,
174
+ supportedVersions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION],
175
+ acceptsUnversionedLegacy: false,
176
+ futureVersionBehavior: 'reject',
177
+ migration: 'exact_current_only',
178
+ writeSemantics: 'read_only',
179
+ byteBudget: MAX_DOMAIN_CONTROL_REVIEW_INPUT_BYTES,
180
+ owner: 'packages/contracts/domain-control-review.mts',
181
+ note: 'Bounded desired-state manifest plus saved Lookups converted without new collection.',
182
+ });
183
+ export const CLI_DOMAIN_CONTROL_REVIEW_COMPATIBILITY = defineSchemaCompatibility({
184
+ id: 'cli.domain-control-observation-review',
185
+ kind: 'cli_document',
186
+ schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA,
187
+ currentVersion: CLI_DOMAIN_CONTROL_REVIEW_VERSION,
188
+ supportedVersions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION],
189
+ acceptsUnversionedLegacy: false,
190
+ futureVersionBehavior: 'not_applicable',
191
+ migration: 'read_only',
192
+ writeSemantics: 'read_only',
193
+ byteBudget: null,
194
+ owner: 'packages/contracts/domain-control-review.mts',
195
+ note: 'Compact source-qualified control observations and desired-state comparison.',
196
+ });
197
+ const CORE_REVIEW_SHAPES = [
198
+ {
199
+ id: 'domain-control-review.input.v1',
200
+ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
201
+ versions: [DOMAIN_CONTROL_REVIEW_VERSION],
202
+ objects: [
203
+ { path: '$', requiredKeys: DOMAIN_CONTROL_REVIEW_INPUT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
204
+ { path: '$.manifest', requiredKeys: DOMAIN_CONTROL_MANIFEST_ROOT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
205
+ { path: '$.manifest.entries[]', requiredKeys: DOMAIN_CONTROL_MANIFEST_ENTRY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
206
+ { path: '$.manifest.integrity', requiredKeys: DOMAIN_CONTROL_MANIFEST_INTEGRITY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
207
+ { path: '$.observations[]', requiredKeys: DOMAIN_CONTROL_REVIEW_OBSERVATION_KEYS, optionalKeys: [], unknownKeys: 'reject' },
208
+ { path: '$.observations[].fields', requiredKeys: [], optionalKeys: DOMAIN_CONTROL_REVIEW_FIELDS, unknownKeys: 'reject' },
209
+ ...DOMAIN_CONTROL_REVIEW_FIELDS.map((field) => ({
210
+ path: `$.observations[].fields.${field}`,
211
+ requiredKeys: DOMAIN_CONTROL_REVIEW_OBSERVATION_FIELD_KEYS,
212
+ optionalKeys: [],
213
+ unknownKeys: 'reject',
214
+ })),
215
+ ],
216
+ fixedArrays: [{ path: '$.manifest.limitations', values: DOMAIN_CONTROL_MANIFEST_LIMITATIONS }],
217
+ normalisation: 'input_to_current',
218
+ target: { schema: DOMAIN_CONTROL_REVIEW_SCHEMA, version: DOMAIN_CONTROL_REVIEW_VERSION },
219
+ },
220
+ {
221
+ id: 'domain-control-review.document.v1',
222
+ schema: DOMAIN_CONTROL_REVIEW_SCHEMA,
223
+ versions: [DOMAIN_CONTROL_REVIEW_VERSION],
224
+ objects: [
225
+ { path: '$', requiredKeys: DOMAIN_CONTROL_REVIEW_ROOT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
226
+ { path: '$.manifest', requiredKeys: DOMAIN_CONTROL_REVIEW_MANIFEST_SUMMARY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
227
+ { path: '$.counts', requiredKeys: DOMAIN_CONTROL_REVIEW_COUNT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
228
+ { path: '$.domains[]', requiredKeys: DOMAIN_CONTROL_REVIEW_DOMAIN_KEYS, optionalKeys: [], unknownKeys: 'reject' },
229
+ { path: '$.domains[].comparisons[]', requiredKeys: DOMAIN_CONTROL_REVIEW_COMPARISON_KEYS, optionalKeys: [], unknownKeys: 'reject' },
230
+ ],
231
+ fixedArrays: [{ path: '$.limitations', values: DOMAIN_CONTROL_REVIEW_LIMITATIONS }],
232
+ normalisation: 'preserve_document',
233
+ target: null,
234
+ },
235
+ ];
236
+ export const DOMAIN_CONTROL_REVIEW_SCHEMA_LIFECYCLE = defineSchemaLifecycleFamily({
237
+ id: 'domain-control-review',
238
+ owner: 'packages/contracts/domain-control-review.mts',
239
+ privacy: 'analyst_authored_sensitive',
240
+ compatibility: [
241
+ DOMAIN_CONTROL_REVIEW_INPUT_COMPATIBILITY,
242
+ DOMAIN_CONTROL_REVIEW_COMPATIBILITY,
243
+ CLI_DOMAIN_CONTROL_REVIEW_INPUT_COMPATIBILITY,
244
+ CLI_DOMAIN_CONTROL_REVIEW_COMPATIBILITY,
245
+ ],
246
+ contracts: [
247
+ {
248
+ compatibilityId: DOMAIN_CONTROL_REVIEW_INPUT_COMPATIBILITY.id,
249
+ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
250
+ version: DOMAIN_CONTROL_REVIEW_VERSION,
251
+ role: 'input',
252
+ lifecycle: 'current',
253
+ readable: true,
254
+ emitted: false,
255
+ exactKeys: true,
256
+ extensionPolicy: 'reject',
257
+ futureVersionBehaviour: 'reject',
258
+ migrationTarget: null,
259
+ canonicalisation: null,
260
+ byteBudget: null,
261
+ fixtureIds: ['domain-control-review-input-v1'],
262
+ },
263
+ {
264
+ compatibilityId: DOMAIN_CONTROL_REVIEW_COMPATIBILITY.id,
265
+ schema: DOMAIN_CONTROL_REVIEW_SCHEMA,
266
+ version: DOMAIN_CONTROL_REVIEW_VERSION,
267
+ role: 'document',
268
+ lifecycle: 'current',
269
+ readable: true,
270
+ emitted: true,
271
+ exactKeys: true,
272
+ extensionPolicy: 'reject',
273
+ futureVersionBehaviour: 'reject',
274
+ migrationTarget: null,
275
+ canonicalisation: null,
276
+ byteBudget: null,
277
+ fixtureIds: ['domain-control-review-v1'],
278
+ },
279
+ {
280
+ compatibilityId: CLI_DOMAIN_CONTROL_REVIEW_INPUT_COMPATIBILITY.id,
281
+ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
282
+ version: CLI_DOMAIN_CONTROL_REVIEW_VERSION,
283
+ role: 'input',
284
+ lifecycle: 'current',
285
+ readable: true,
286
+ emitted: true,
287
+ exactKeys: true,
288
+ extensionPolicy: 'reject',
289
+ futureVersionBehaviour: 'reject',
290
+ migrationTarget: null,
291
+ canonicalisation: null,
292
+ byteBudget: MAX_DOMAIN_CONTROL_REVIEW_INPUT_BYTES,
293
+ fixtureIds: ['cli-domain-control-review-input-v1'],
294
+ },
295
+ {
296
+ compatibilityId: CLI_DOMAIN_CONTROL_REVIEW_COMPATIBILITY.id,
297
+ schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA,
298
+ version: CLI_DOMAIN_CONTROL_REVIEW_VERSION,
299
+ role: 'document',
300
+ lifecycle: 'current',
301
+ readable: false,
302
+ emitted: true,
303
+ exactKeys: true,
304
+ extensionPolicy: 'reject',
305
+ futureVersionBehaviour: 'not_applicable',
306
+ migrationTarget: null,
307
+ canonicalisation: null,
308
+ byteBudget: null,
309
+ fixtureIds: ['cli-domain-control-review-v1'],
310
+ },
311
+ ],
312
+ fixtures: [
313
+ {
314
+ id: 'domain-control-review-input-v1',
315
+ path: 'test/fixtures/domain-control-review-input-v1.json',
316
+ bytes: 1_879,
317
+ sha256: 'ca6e894a67715fa93a872d189fe22a21dc516200f672546de7cc8ffe2df12329',
318
+ contentDigestSha256: null,
319
+ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
320
+ version: DOMAIN_CONTROL_REVIEW_VERSION,
321
+ role: 'input',
322
+ expectation: 'normalises_to_current_output',
323
+ expectedOutputFixtureId: 'domain-control-review-v1',
324
+ scope: 'repository',
325
+ },
326
+ {
327
+ id: 'domain-control-review-v1',
328
+ path: 'test/fixtures/domain-control-review-v1.json',
329
+ bytes: 3_954,
330
+ sha256: '1ac47d146aee742dd9e1c2b9755bfd8d59d1104b005bedd21d63f42c68d255ec',
331
+ contentDigestSha256: null,
332
+ schema: DOMAIN_CONTROL_REVIEW_SCHEMA,
333
+ version: DOMAIN_CONTROL_REVIEW_VERSION,
334
+ role: 'current',
335
+ expectation: 'accepted_exact',
336
+ expectedOutputFixtureId: null,
337
+ scope: 'repository',
338
+ },
339
+ {
340
+ id: 'cli-domain-control-review-input-v1',
341
+ path: 'test/fixtures/cli-domain-control-review-input-v1.json',
342
+ bytes: 3_757,
343
+ sha256: 'b4f2005738bf6d8f12433304f20b503eb3ee47778bef9daa1cf1d4fdddae8621',
344
+ contentDigestSha256: null,
345
+ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
346
+ version: CLI_DOMAIN_CONTROL_REVIEW_VERSION,
347
+ role: 'input',
348
+ expectation: 'normalises_to_current_output',
349
+ expectedOutputFixtureId: 'cli-domain-control-review-v1',
350
+ scope: 'repository',
351
+ },
352
+ {
353
+ id: 'cli-domain-control-review-v1',
354
+ path: 'test/fixtures/cli-domain-control-review-v1.json',
355
+ bytes: 7_952,
356
+ sha256: 'd6e24209da9d4e41d2065bab493c035adf117faa5bacc8c8ce30c56c8aef0b93',
357
+ contentDigestSha256: null,
358
+ schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA,
359
+ version: CLI_DOMAIN_CONTROL_REVIEW_VERSION,
360
+ role: 'current',
361
+ expectation: 'accepted_exact',
362
+ expectedOutputFixtureId: null,
363
+ scope: 'repository',
364
+ },
365
+ ],
366
+ metadata: {
367
+ metadataVersion: 2,
368
+ enforcement: 'declarative_only',
369
+ shapes: [
370
+ ...CORE_REVIEW_SHAPES,
371
+ {
372
+ id: 'domain-control-review.cli-input.v1',
373
+ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA,
374
+ versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION],
375
+ objects: [
376
+ { path: '$', requiredKeys: CLI_DOMAIN_CONTROL_REVIEW_INPUT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
377
+ { path: '$.manifest', requiredKeys: DOMAIN_CONTROL_MANIFEST_ROOT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
378
+ { path: '$.manifest.entries[]', requiredKeys: DOMAIN_CONTROL_MANIFEST_ENTRY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
379
+ { path: '$.manifest.integrity', requiredKeys: DOMAIN_CONTROL_MANIFEST_INTEGRITY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
380
+ ],
381
+ fixedArrays: [{ path: '$.manifest.limitations', values: DOMAIN_CONTROL_MANIFEST_LIMITATIONS }],
382
+ normalisation: 'input_to_current',
383
+ target: { schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA, version: CLI_DOMAIN_CONTROL_REVIEW_VERSION },
384
+ },
385
+ {
386
+ id: 'domain-control-review.cli-document.v1',
387
+ schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA,
388
+ versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION],
389
+ objects: [
390
+ { path: '$', requiredKeys: CLI_DOMAIN_CONTROL_REVIEW_ROOT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
391
+ { path: '$.review', requiredKeys: DOMAIN_CONTROL_REVIEW_ROOT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
392
+ { path: '$.review.manifest', requiredKeys: DOMAIN_CONTROL_REVIEW_MANIFEST_SUMMARY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
393
+ { path: '$.review.counts', requiredKeys: DOMAIN_CONTROL_REVIEW_COUNT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
394
+ { path: '$.review.domains[]', requiredKeys: DOMAIN_CONTROL_REVIEW_DOMAIN_KEYS, optionalKeys: [], unknownKeys: 'reject' },
395
+ { path: '$.review.domains[].comparisons[]', requiredKeys: DOMAIN_CONTROL_REVIEW_COMPARISON_KEYS, optionalKeys: [], unknownKeys: 'reject' },
396
+ { path: '$.observations[]', requiredKeys: CLI_DOMAIN_CONTROL_REVIEW_OBSERVATION_KEYS, optionalKeys: [], unknownKeys: 'reject' },
397
+ { path: '$.observations[].fields[]', requiredKeys: CLI_DOMAIN_CONTROL_REVIEW_FIELD_KEYS, optionalKeys: [], unknownKeys: 'reject' },
398
+ { path: '$.input', requiredKeys: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SUMMARY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
399
+ ],
400
+ fixedArrays: [
401
+ { path: '$.review.limitations', values: DOMAIN_CONTROL_REVIEW_LIMITATIONS },
402
+ { path: '$.limitations', values: CLI_DOMAIN_CONTROL_REVIEW_LIMITATIONS },
403
+ ],
404
+ normalisation: 'preserve_document',
405
+ target: null,
406
+ },
407
+ ],
408
+ boundProfiles: [
409
+ {
410
+ id: 'domain-control-review.core.v1',
411
+ bounds: [
412
+ { id: 'observations', path: '$.observations', phase: 'pre_accumulation', unit: 'items', minimum: 0, maximum: MAX_DOMAIN_CONTROL_REVIEW_OBSERVATIONS, handling: 'reject' },
413
+ { id: 'observation-fields', path: '$.observations[].fields', phase: 'pre_accumulation', unit: 'keys', minimum: 0, maximum: MAX_DOMAIN_CONTROL_REVIEW_FIELDS, handling: 'reject' },
414
+ ...DOMAIN_CONTROL_REVIEW_FIELDS.flatMap((field) => {
415
+ const boundId = field.replace(/([A-Z])/gu, '-$1').toLowerCase();
416
+ return [
417
+ { id: `${boundId}-input-values`, path: `$.observations[].fields.${field}.values`, phase: 'pre_accumulation', unit: 'items', minimum: 0, maximum: MAX_DOMAIN_CONTROL_REVIEW_FIELD_INPUT_VALUES, handling: 'reject' },
418
+ { id: `${boundId}-values`, path: `$.observations[].fields.${field}.values`, phase: 'normalised', unit: 'items', minimum: 0, maximum: MAX_CANONICAL_DOMAIN_CONTROL_RECORDS, handling: 'truncate' },
419
+ { id: `${boundId}-source-input`, path: `$.observations[].fields.${field}.source`, phase: 'pre_accumulation', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_SOURCE_INPUT_LENGTH, handling: 'reject' },
420
+ { id: `${boundId}-source`, path: `$.observations[].fields.${field}.source`, phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_SOURCE_LENGTH, handling: 'truncate' },
421
+ { id: `${boundId}-observed-at-input`, path: `$.observations[].fields.${field}.observedAt`, phase: 'pre_accumulation', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH * DOMAIN_CONTROL_TEXT_INPUT_BOUND_FACTOR, handling: 'reject' },
422
+ { id: `${boundId}-observed-at`, path: `$.observations[].fields.${field}.observedAt`, phase: 'normalised', unit: 'characters', minimum: 0, maximum: MAX_DOMAIN_CONTROL_TIMESTAMP_LENGTH, handling: 'reject' },
423
+ ];
424
+ }),
425
+ { id: 'nameserver-input-text', path: '$.observations[].fields.nameservers.values[]', phase: 'pre_accumulation', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_DOMAIN_INPUT_LENGTH, handling: 'reject' },
426
+ { id: 'nameserver-text', path: '$.observations[].fields.nameservers.values[]', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_DOMAIN_LENGTH, handling: 'truncate' },
427
+ { id: 'tls-issuer-input-text', path: '$.observations[].fields.tlsIssuer.values[]', phase: 'pre_accumulation', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_TEXT_INPUT_LENGTH, handling: 'reject' },
428
+ { id: 'tls-issuer-text', path: '$.observations[].fields.tlsIssuer.values[]', phase: 'normalised', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_TEXT_LENGTH, handling: 'truncate' },
429
+ { id: 'tls-spki-input-text', path: '$.observations[].fields.tlsSpkiSha256.values[]', phase: 'pre_accumulation', unit: 'characters', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_SPKI_INPUT_LENGTH, handling: 'reject' },
430
+ { id: 'tls-spki-text', path: '$.observations[].fields.tlsSpkiSha256.values[]', phase: 'normalised', unit: 'characters', minimum: DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH, maximum: DOMAIN_CONTROL_SPKI_SHA256_HEX_LENGTH, handling: 'reject' },
431
+ { id: 'output-domains', path: '$.domains', phase: 'normalised', unit: 'entries', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES, handling: 'reject' },
432
+ ],
433
+ },
434
+ {
435
+ id: 'domain-control-review.cli-library.v1',
436
+ bounds: [
437
+ { id: 'serialised-bytes', path: '$', phase: 'serialised', unit: 'bytes', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_INPUT_BYTES, handling: 'reject' },
438
+ { id: 'lookups', path: '$.lookups', phase: 'pre_accumulation', unit: 'items', minimum: MIN_DOMAIN_CONTROL_REVIEW_LOOKUPS, maximum: MAX_DOMAIN_CONTROL_REVIEW_LOOKUPS, handling: 'reject' },
439
+ { id: 'json-depth', path: '$', phase: 'pre_accumulation', unit: 'depth', minimum: 0, maximum: MAX_DOMAIN_CONTROL_REVIEW_JSON_DEPTH, handling: 'reject' },
440
+ { id: 'json-keys', path: '$', phase: 'pre_accumulation', unit: 'keys', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_JSON_KEYS, handling: 'reject' },
441
+ { id: 'json-values', path: '$', phase: 'pre_accumulation', unit: 'values', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_JSON_VALUES, handling: 'reject' },
442
+ { id: 'json-container-items', path: '$', phase: 'pre_accumulation', unit: 'items', minimum: 1, maximum: MAX_DOMAIN_CONTROL_JSON_CONTAINER_ITEMS, handling: 'reject' },
443
+ { id: 'saved-lookup-canonical-bytes', path: '$.lookups[]', phase: 'serialised', unit: 'bytes', minimum: 1, maximum: MAX_CLI_LOOKUP_BYTES, handling: 'reject' },
444
+ ],
445
+ },
446
+ {
447
+ id: 'domain-control-review.cli-command.v1',
448
+ bounds: [
449
+ { id: 'raw-input-bytes', path: '$', phase: 'raw_intake', unit: 'bytes', minimum: 1, maximum: MAX_DOMAIN_CONTROL_REVIEW_COMMAND_BYTES, handling: 'reject' },
450
+ ],
451
+ },
452
+ {
453
+ id: 'domain-control-review.monitor-action.v1',
454
+ bounds: [
455
+ { id: 'limit', path: '$.options.limit', phase: 'action', unit: 'entries', minimum: MIN_DOMAIN_CONTROL_MONITOR_DOMAINS, maximum: MAX_DOMAIN_CONTROL_MONITOR_DOMAINS, handling: 'reject' },
456
+ { id: 'concurrency', path: '$.options.concurrency', phase: 'action', unit: 'concurrency', minimum: MIN_DOMAIN_CONTROL_MONITOR_CONCURRENCY, maximum: MAX_DOMAIN_CONTROL_MONITOR_CONCURRENCY, handling: 'reject' },
457
+ ],
458
+ },
459
+ ],
460
+ hooks: [
461
+ { id: 'domain-control-review.node.verify-manifest', role: 'integrity_verifier', runtime: 'node', module: 'lib/domain-control-manifest.mts', exportName: 'verifyDomainControlManifest' },
462
+ { id: 'domain-control-review.node.build-core', role: 'reviewer', runtime: 'node', module: 'lib/domain-control-manifest.mts', exportName: 'reviewDomainControlManifest' },
463
+ { id: 'domain-control-review.node.validate-core', role: 'structure_validator', runtime: 'node', module: 'lib/domain-control-manifest.mts', exportName: 'validateDomainControlReviewDocument' },
464
+ { id: 'domain-control-review.node.format-core-terminal', role: 'serialiser', runtime: 'node', module: 'lib/domain-control-manifest.mts', exportName: 'formatDomainControlResult' },
465
+ { id: 'domain-control-review.cli.build-saved-lookup', role: 'reviewer', runtime: 'cli', module: 'cli/domain-control-observations.mts', exportName: 'buildCliDomainControlReview' },
466
+ { id: 'domain-control-review.cli.format-saved-terminal', role: 'serialiser', runtime: 'cli', module: 'cli/domain-control-observations.mts', exportName: 'formatCliDomainControlReview' },
467
+ { id: 'domain-control-review.cli.serialise-json', role: 'serialiser', runtime: 'cli', module: 'cli/formatters/json.mts', exportName: 'formatJsonDocument' },
468
+ { id: 'domain-control-review.cli.monitor', role: 'monitor', runtime: 'cli', module: 'cli/domain-control-monitor.mts', exportName: 'runDomainControlMonitor' },
469
+ ],
470
+ serialisationProfiles: [
471
+ {
472
+ id: 'domain-control-review.core-json.v1',
473
+ schema: DOMAIN_CONTROL_REVIEW_SCHEMA,
474
+ versions: [DOMAIN_CONTROL_REVIEW_VERSION],
475
+ mediaType: 'application/json',
476
+ encoding: 'utf-8',
477
+ bom: false,
478
+ indentSpaces: 2,
479
+ terminalLf: true,
480
+ propertyOrder: 'normalised_fixed',
481
+ canonicalisation: null,
482
+ integrity: 'none',
483
+ serializerHookId: 'domain-control-review.cli.serialise-json',
484
+ verifierHookIds: [],
485
+ },
486
+ {
487
+ id: 'domain-control-review.cli-json.v1',
488
+ schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA,
489
+ versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION],
490
+ mediaType: 'application/json',
491
+ encoding: 'utf-8',
492
+ bom: false,
493
+ indentSpaces: 2,
494
+ terminalLf: true,
495
+ propertyOrder: 'normalised_fixed',
496
+ canonicalisation: null,
497
+ integrity: 'none',
498
+ serializerHookId: 'domain-control-review.cli.serialise-json',
499
+ verifierHookIds: [],
500
+ },
501
+ ],
502
+ privacyProfiles: [
503
+ {
504
+ id: 'domain-control-review.sensitive.v1',
505
+ classification: 'analyst_authored_sensitive',
506
+ projection: 'review_output',
507
+ includedCategories: [
508
+ 'domain-identifiers',
509
+ 'desired-control-values',
510
+ 'observed-control-values',
511
+ 'observation-provenance',
512
+ 'observation-times',
513
+ 'document-times',
514
+ 'integrity-linkage',
515
+ ],
516
+ excludedCategories: ['analyst-notes', 'raw-upstream-payloads', 'contacts', 'credentials', 'cookies', 'sessions'],
517
+ notePolicy: 'discarded',
518
+ retention: 'transient_report',
519
+ network: 'none',
520
+ sharingReview: 'not_applicable',
521
+ },
522
+ {
523
+ id: 'domain-control-review.sensitive-output.v1',
524
+ classification: 'analyst_authored_sensitive',
525
+ projection: 'review_output',
526
+ includedCategories: [
527
+ 'domain-identifiers',
528
+ 'desired-control-values',
529
+ 'observed-control-values',
530
+ 'observation-provenance',
531
+ 'observation-times',
532
+ 'document-times',
533
+ 'integrity-linkage',
534
+ ],
535
+ excludedCategories: ['analyst-notes', 'raw-upstream-payloads', 'contacts', 'credentials', 'cookies', 'sessions'],
536
+ notePolicy: 'discarded',
537
+ retention: 'operator_controlled_output',
538
+ network: 'none',
539
+ sharingReview: 'required',
540
+ },
541
+ {
542
+ id: 'domain-control-review.monitor-output.v1',
543
+ classification: 'analyst_authored_sensitive',
544
+ projection: 'bounded_passive_monitor',
545
+ includedCategories: [
546
+ 'domain-identifiers',
547
+ 'desired-control-values',
548
+ 'observed-control-values',
549
+ 'observation-provenance',
550
+ 'observation-times',
551
+ 'request-metadata',
552
+ 'bounded-errors',
553
+ 'document-times',
554
+ 'integrity-linkage',
555
+ ],
556
+ excludedCategories: ['analyst-notes', 'raw-upstream-payloads', 'contacts', 'credentials', 'cookies', 'sessions'],
557
+ notePolicy: 'discarded',
558
+ retention: 'operator_controlled_output',
559
+ network: 'explicit_bounded_passive_deep',
560
+ sharingReview: 'required',
561
+ },
562
+ ],
563
+ expiryProfiles: [
564
+ {
565
+ id: 'domain-control-review.expiry-report.v1',
566
+ field: 'expiresAt',
567
+ anchor: 'checkedAt',
568
+ handling: 'report_expired',
569
+ phase: 'review',
570
+ maximumLifetimeDays: null,
571
+ },
572
+ {
573
+ id: 'domain-control-review.expiry-require-current.v1',
574
+ field: 'expiresAt',
575
+ anchor: 'checkedAt',
576
+ handling: 'reject_expired',
577
+ phase: 'pre_action',
578
+ maximumLifetimeDays: null,
579
+ },
580
+ ],
581
+ consumerEdges: [
582
+ {
583
+ id: 'domain-control-review.node-core',
584
+ plane: 'node',
585
+ operation: 'review',
586
+ acceptedContracts: [{ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
587
+ emittedContract: { schema: DOMAIN_CONTROL_REVIEW_SCHEMA, version: DOMAIN_CONTROL_REVIEW_VERSION },
588
+ shapeIds: ['domain-control-review.input.v1', 'domain-control-review.document.v1'],
589
+ boundProfileIds: ['domain-control-review.core.v1'],
590
+ hookIds: ['domain-control-review.node.verify-manifest', 'domain-control-review.node.build-core'],
591
+ serialisationProfileId: null,
592
+ privacyProfileId: 'domain-control-review.sensitive.v1',
593
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
594
+ requestMode: 'none',
595
+ retentionEffect: 'transient_report',
596
+ bindingState: 'declared_unenforced',
597
+ policyState: 'current',
598
+ },
599
+ {
600
+ id: 'domain-control-review.cli-core-json-stdout',
601
+ plane: 'cli',
602
+ operation: 'review-json-stdout',
603
+ acceptedContracts: [{ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
604
+ emittedContract: { schema: DOMAIN_CONTROL_REVIEW_SCHEMA, version: DOMAIN_CONTROL_REVIEW_VERSION },
605
+ shapeIds: ['domain-control-review.input.v1', 'domain-control-review.document.v1'],
606
+ boundProfileIds: ['domain-control-review.core.v1', 'domain-control-review.cli-command.v1'],
607
+ hookIds: [
608
+ 'domain-control-review.node.verify-manifest',
609
+ 'domain-control-review.node.build-core',
610
+ 'domain-control-review.cli.serialise-json',
611
+ ],
612
+ serialisationProfileId: 'domain-control-review.core-json.v1',
613
+ privacyProfileId: 'domain-control-review.sensitive.v1',
614
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
615
+ requestMode: 'none',
616
+ retentionEffect: 'transient_report',
617
+ bindingState: 'declared_unenforced',
618
+ policyState: 'current',
619
+ },
620
+ {
621
+ id: 'domain-control-review.cli-core-terminal-stdout',
622
+ plane: 'cli',
623
+ operation: 'review-terminal-stdout',
624
+ acceptedContracts: [{ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
625
+ emittedContract: { schema: DOMAIN_CONTROL_REVIEW_SCHEMA, version: DOMAIN_CONTROL_REVIEW_VERSION },
626
+ shapeIds: ['domain-control-review.input.v1', 'domain-control-review.document.v1'],
627
+ boundProfileIds: ['domain-control-review.core.v1', 'domain-control-review.cli-command.v1'],
628
+ hookIds: [
629
+ 'domain-control-review.node.verify-manifest',
630
+ 'domain-control-review.node.build-core',
631
+ 'domain-control-review.node.format-core-terminal',
632
+ ],
633
+ serialisationProfileId: null,
634
+ privacyProfileId: 'domain-control-review.sensitive.v1',
635
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
636
+ requestMode: 'none',
637
+ retentionEffect: 'transient_report',
638
+ bindingState: 'declared_unenforced',
639
+ policyState: 'current',
640
+ },
641
+ {
642
+ id: 'domain-control-review.cli-core-json-file',
643
+ plane: 'cli',
644
+ operation: 'review-json-file',
645
+ acceptedContracts: [{ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
646
+ emittedContract: { schema: DOMAIN_CONTROL_REVIEW_SCHEMA, version: DOMAIN_CONTROL_REVIEW_VERSION },
647
+ shapeIds: ['domain-control-review.input.v1', 'domain-control-review.document.v1'],
648
+ boundProfileIds: ['domain-control-review.core.v1', 'domain-control-review.cli-command.v1'],
649
+ hookIds: [
650
+ 'domain-control-review.node.verify-manifest',
651
+ 'domain-control-review.node.build-core',
652
+ 'domain-control-review.cli.serialise-json',
653
+ ],
654
+ serialisationProfileId: 'domain-control-review.core-json.v1',
655
+ privacyProfileId: 'domain-control-review.sensitive-output.v1',
656
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
657
+ requestMode: 'none',
658
+ retentionEffect: 'operator_controlled_output',
659
+ bindingState: 'declared_unenforced',
660
+ policyState: 'current',
661
+ },
662
+ {
663
+ id: 'domain-control-review.cli-core-terminal-file',
664
+ plane: 'cli',
665
+ operation: 'review-terminal-file',
666
+ acceptedContracts: [{ schema: DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
667
+ emittedContract: { schema: DOMAIN_CONTROL_REVIEW_SCHEMA, version: DOMAIN_CONTROL_REVIEW_VERSION },
668
+ shapeIds: ['domain-control-review.input.v1', 'domain-control-review.document.v1'],
669
+ boundProfileIds: ['domain-control-review.core.v1', 'domain-control-review.cli-command.v1'],
670
+ hookIds: [
671
+ 'domain-control-review.node.verify-manifest',
672
+ 'domain-control-review.node.build-core',
673
+ 'domain-control-review.node.format-core-terminal',
674
+ ],
675
+ serialisationProfileId: null,
676
+ privacyProfileId: 'domain-control-review.sensitive-output.v1',
677
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
678
+ requestMode: 'none',
679
+ retentionEffect: 'operator_controlled_output',
680
+ bindingState: 'declared_unenforced',
681
+ policyState: 'current',
682
+ },
683
+ {
684
+ id: 'domain-control-review.cli-saved-lookup-library',
685
+ plane: 'cli',
686
+ operation: 'review',
687
+ acceptedContracts: [{ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
688
+ emittedContract: { schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA, version: CLI_DOMAIN_CONTROL_REVIEW_VERSION },
689
+ shapeIds: ['domain-control-review.cli-input.v1', 'domain-control-review.cli-document.v1'],
690
+ boundProfileIds: ['domain-control-review.core.v1', 'domain-control-review.cli-library.v1'],
691
+ hookIds: [
692
+ 'domain-control-review.node.verify-manifest',
693
+ 'domain-control-review.node.build-core',
694
+ 'domain-control-review.cli.build-saved-lookup',
695
+ ],
696
+ serialisationProfileId: null,
697
+ privacyProfileId: 'domain-control-review.sensitive.v1',
698
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
699
+ requestMode: 'none',
700
+ retentionEffect: 'transient_report',
701
+ bindingState: 'declared_unenforced',
702
+ policyState: 'current',
703
+ },
704
+ {
705
+ id: 'domain-control-review.cli-saved-json-stdout',
706
+ plane: 'cli',
707
+ operation: 'review-json-stdout',
708
+ acceptedContracts: [{ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
709
+ emittedContract: { schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA, version: CLI_DOMAIN_CONTROL_REVIEW_VERSION },
710
+ shapeIds: ['domain-control-review.cli-input.v1', 'domain-control-review.cli-document.v1'],
711
+ boundProfileIds: [
712
+ 'domain-control-review.core.v1',
713
+ 'domain-control-review.cli-library.v1',
714
+ 'domain-control-review.cli-command.v1',
715
+ ],
716
+ hookIds: [
717
+ 'domain-control-review.node.verify-manifest',
718
+ 'domain-control-review.node.build-core',
719
+ 'domain-control-review.cli.build-saved-lookup',
720
+ 'domain-control-review.cli.serialise-json',
721
+ ],
722
+ serialisationProfileId: 'domain-control-review.cli-json.v1',
723
+ privacyProfileId: 'domain-control-review.sensitive.v1',
724
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
725
+ requestMode: 'none',
726
+ retentionEffect: 'transient_report',
727
+ bindingState: 'declared_unenforced',
728
+ policyState: 'current',
729
+ },
730
+ {
731
+ id: 'domain-control-review.cli-saved-terminal-stdout',
732
+ plane: 'cli',
733
+ operation: 'review-terminal-stdout',
734
+ acceptedContracts: [{ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
735
+ emittedContract: { schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA, version: CLI_DOMAIN_CONTROL_REVIEW_VERSION },
736
+ shapeIds: ['domain-control-review.cli-input.v1', 'domain-control-review.cli-document.v1'],
737
+ boundProfileIds: [
738
+ 'domain-control-review.core.v1',
739
+ 'domain-control-review.cli-library.v1',
740
+ 'domain-control-review.cli-command.v1',
741
+ ],
742
+ hookIds: [
743
+ 'domain-control-review.node.verify-manifest',
744
+ 'domain-control-review.node.build-core',
745
+ 'domain-control-review.cli.build-saved-lookup',
746
+ 'domain-control-review.cli.format-saved-terminal',
747
+ ],
748
+ serialisationProfileId: null,
749
+ privacyProfileId: 'domain-control-review.sensitive.v1',
750
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
751
+ requestMode: 'none',
752
+ retentionEffect: 'transient_report',
753
+ bindingState: 'declared_unenforced',
754
+ policyState: 'current',
755
+ },
756
+ {
757
+ id: 'domain-control-review.cli-saved-json-file',
758
+ plane: 'cli',
759
+ operation: 'review-json-file',
760
+ acceptedContracts: [{ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
761
+ emittedContract: { schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA, version: CLI_DOMAIN_CONTROL_REVIEW_VERSION },
762
+ shapeIds: ['domain-control-review.cli-input.v1', 'domain-control-review.cli-document.v1'],
763
+ boundProfileIds: [
764
+ 'domain-control-review.core.v1',
765
+ 'domain-control-review.cli-library.v1',
766
+ 'domain-control-review.cli-command.v1',
767
+ ],
768
+ hookIds: [
769
+ 'domain-control-review.node.verify-manifest',
770
+ 'domain-control-review.node.build-core',
771
+ 'domain-control-review.cli.build-saved-lookup',
772
+ 'domain-control-review.cli.serialise-json',
773
+ ],
774
+ serialisationProfileId: 'domain-control-review.cli-json.v1',
775
+ privacyProfileId: 'domain-control-review.sensitive-output.v1',
776
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
777
+ requestMode: 'none',
778
+ retentionEffect: 'operator_controlled_output',
779
+ bindingState: 'declared_unenforced',
780
+ policyState: 'current',
781
+ },
782
+ {
783
+ id: 'domain-control-review.cli-saved-terminal-file',
784
+ plane: 'cli',
785
+ operation: 'review-terminal-file',
786
+ acceptedContracts: [{ schema: CLI_DOMAIN_CONTROL_REVIEW_INPUT_SCHEMA, versions: [CLI_DOMAIN_CONTROL_REVIEW_VERSION], mode: 'direct' }],
787
+ emittedContract: { schema: CLI_DOMAIN_CONTROL_REVIEW_SCHEMA, version: CLI_DOMAIN_CONTROL_REVIEW_VERSION },
788
+ shapeIds: ['domain-control-review.cli-input.v1', 'domain-control-review.cli-document.v1'],
789
+ boundProfileIds: [
790
+ 'domain-control-review.core.v1',
791
+ 'domain-control-review.cli-library.v1',
792
+ 'domain-control-review.cli-command.v1',
793
+ ],
794
+ hookIds: [
795
+ 'domain-control-review.node.verify-manifest',
796
+ 'domain-control-review.node.build-core',
797
+ 'domain-control-review.cli.build-saved-lookup',
798
+ 'domain-control-review.cli.format-saved-terminal',
799
+ ],
800
+ serialisationProfileId: null,
801
+ privacyProfileId: 'domain-control-review.sensitive-output.v1',
802
+ expiryPolicyId: 'domain-control-review.expiry-report.v1',
803
+ requestMode: 'none',
804
+ retentionEffect: 'operator_controlled_output',
805
+ bindingState: 'declared_unenforced',
806
+ policyState: 'current',
807
+ },
808
+ {
809
+ id: 'domain-control-review.cli-monitor-embedding',
810
+ plane: 'cli',
811
+ operation: 'embed-review-after-bounded-passive-collection',
812
+ acceptedContracts: [{ schema: DOMAIN_CONTROL_REVIEW_SCHEMA, versions: [DOMAIN_CONTROL_REVIEW_VERSION], mode: 'embedded' }],
813
+ emittedContract: null,
814
+ shapeIds: ['domain-control-review.document.v1'],
815
+ boundProfileIds: ['domain-control-review.monitor-action.v1'],
816
+ hookIds: ['domain-control-review.node.validate-core', 'domain-control-review.cli.monitor'],
817
+ serialisationProfileId: null,
818
+ privacyProfileId: 'domain-control-review.monitor-output.v1',
819
+ expiryPolicyId: 'domain-control-review.expiry-require-current.v1',
820
+ requestMode: 'explicit_bounded_passive_deep',
821
+ retentionEffect: 'operator_controlled_output',
822
+ bindingState: 'declared_unenforced',
823
+ policyState: 'current',
824
+ },
825
+ ],
826
+ consumerRelationships: [],
827
+ },
828
+ });