@slicedearth/whoisleuth-cli 2.4.0 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +2 -2
- package/cli/argument-values.mjs +55 -0
- package/cli/arguments.mjs +24 -470
- package/cli/artifact-validation/case-response.mjs +21 -6
- package/cli/artifact-validation/lookup-evidence.mjs +3 -3
- package/cli/artifact-validation/signed-review.mjs +59 -13
- package/cli/artifact-verify.mjs +2 -0
- package/cli/assurance-arguments.mjs +56 -0
- package/cli/assurance-command-definitions.mjs +179 -0
- package/cli/assurance-command-runner.mjs +1 -1
- package/cli/bounded-json.mjs +1 -1
- package/cli/bulk-checkpoint.mjs +1 -1
- package/cli/bulk-command-runner.mjs +2 -2
- package/cli/bulk.mjs +2 -3
- package/cli/case-command.mjs +20 -3
- package/cli/case-pack.mjs +12 -2
- package/cli/ci-report.mjs +6 -3
- package/cli/collection-arguments.mjs +123 -0
- package/cli/collection-command-definitions.mjs +330 -0
- package/cli/collection-preflight.mjs +8 -1
- package/cli/command-argument-grammar.mjs +8 -210
- package/cli/command-definition.mjs +329 -0
- package/cli/command-reference.mjs +55 -1388
- package/cli/command-seeds.mjs +18 -0
- package/cli/compare.mjs +1 -1
- package/cli/config-profile.mjs +1 -1
- package/cli/ct-event-intake.mjs +4 -4
- package/cli/discover.mjs +2 -2
- package/cli/discovery-observation-snapshot.mjs +2 -2
- package/cli/discovery-scan-command-runner.mjs +3 -3
- package/cli/discovery-scan.mjs +1 -1
- package/cli/discovery-snapshot.mjs +2 -2
- package/cli/discovery-workflow.mjs +4 -4
- package/cli/domain-control-monitor.mjs +6 -6
- package/cli/domain-control-observations.mjs +2 -1
- package/cli/errors.mjs +5 -6
- package/cli/evidence-arguments.mjs +46 -0
- package/cli/evidence-command-definitions.mjs +69 -0
- package/cli/evidence-command-runner.mjs +2 -3
- package/cli/evidence-signing.mjs +3 -2
- package/cli/external-observation-mapping.mjs +2 -2
- package/cli/formatters/terminal-command-formats.mjs +6 -0
- package/cli/formatters/terminal-lookup.mjs +6 -0
- package/cli/history-arguments.mjs +39 -0
- package/cli/history-command-definitions.mjs +88 -0
- package/cli/indicator-set-command.mjs +33 -0
- package/cli/inline-command-families.mjs +6 -47
- package/cli/inline-command-runner.mjs +4 -31
- package/cli/input.mjs +2 -2
- package/cli/intake-command.mjs +107 -0
- package/cli/interchange-report.mjs +4 -2
- package/cli/investigation-artifacts.mjs +1 -1
- package/cli/investigation-plan.mjs +32 -154
- package/cli/investigation-recipes.mjs +177 -0
- package/cli/investigation-run.mjs +78 -12
- package/cli/local-mmdb-review.mjs +197 -17
- package/cli/lookalike-calibration.mjs +1 -1
- package/cli/lookup-brief.mjs +2 -2
- package/cli/lookup-command-runner.mjs +18 -35
- package/cli/lookup-diff.mjs +10 -9
- package/cli/lookup-plan.mjs +10 -14
- package/cli/lookup-reconcile.mjs +6 -5
- package/cli/lookup-timeline.mjs +7 -6
- package/cli/mail-header-review.mjs +24 -247
- package/cli/mail-review.mjs +9 -7
- package/cli/network-arguments.mjs +51 -0
- package/cli/network-command-definitions.mjs +130 -0
- package/cli/network-command-runner.mjs +43 -31
- package/cli/offline-evidence-review.mjs +39 -6
- package/cli/posture.mjs +1 -1
- package/cli/registry-fixture-scaffold.mjs +1 -1
- package/cli/retained-artifact-diff.mjs +8 -7
- package/cli/review-arguments.mjs +131 -0
- package/cli/review-command-definitions.mjs +273 -0
- package/cli/review-command-runner.mjs +68 -158
- package/cli/risk-calibration.mjs +8 -8
- package/cli/runner.mjs +20 -32
- package/cli/saved-lookup.mjs +2 -2
- package/cli/selected-input-worker.mjs +63 -0
- package/cli/sharing-review.mjs +5 -64
- package/cli/source-reliability.mjs +2 -2
- package/cli/support-arguments.mjs +49 -0
- package/cli/support-command-definitions.mjs +209 -0
- package/cli/support-command-runner.mjs +2 -2
- package/cli/workflow-arguments.mjs +86 -0
- package/cli/workflow-command-definitions.mjs +78 -0
- package/cli/workflow-command-runner.mjs +8 -1
- package/docs/cli-reference.md +27 -0
- package/docs/cli.md +223 -2
- package/docs/contextual-reviews.md +155 -0
- package/lib/analyst-taxonomy.mjs +2 -40
- package/lib/application-version.mjs +1 -1
- package/lib/availability.mjs +13 -789
- package/lib/bounded-contract-normalizers.mjs +4 -0
- package/lib/bounded-json.mjs +2 -330
- package/lib/browser-library-profile.mjs +62 -84
- package/lib/candidate-provenance-bounds.mjs +2 -0
- package/lib/classify.mjs +1 -1
- package/lib/ct-query.mjs +2 -27
- package/lib/ct-response-bounds.mjs +2 -9
- package/lib/ct-search.mjs +83 -47
- package/lib/dmarc-discovery.mjs +62 -0
- package/lib/dns-convergence-review.mjs +21 -8
- package/lib/dns-delegation-health.mjs +12 -8
- package/lib/dns-inheritance-review.mjs +53 -63
- package/lib/dns-intelligence.mjs +9 -7
- package/lib/dns-query-coverage.mjs +40 -0
- package/lib/domain-assurance.mjs +1 -1
- package/lib/domain-change-packet.mjs +12 -13
- package/lib/domain-change-review.mjs +32 -14
- package/lib/domain-control-flight-recorder.mjs +103 -27
- package/lib/domain-control-manifest.mjs +25 -17
- package/lib/domain-posture-analysis.mjs +22 -5
- package/lib/domain-posture.mjs +16 -15
- package/lib/domain-registration.mjs +392 -0
- package/lib/evidence-export-privacy.mjs +22 -15
- package/lib/evidence-export.mjs +3 -3
- package/lib/evidence-report.mjs +4 -1
- package/lib/external-intelligence-risk.mjs +2 -124
- package/lib/generated/cisa-kev-catalog.mjs +41 -3
- package/lib/generated/registrar-standing-catalogue.mjs +18 -10
- package/lib/generated/retire-browser-catalog.mjs +332 -19
- package/lib/generated/{unicode-confusables-17.mjs → unicode-confusables.mjs} +33 -33
- package/lib/html-signals.mjs +7 -2
- package/lib/http-evidence-bounds.mjs +2 -8
- package/lib/http-intelligence.mjs +13 -1
- package/lib/idn-confusable-policy.mjs +6 -4
- package/lib/idn-confusables.mjs +1 -1
- package/lib/interchange-fidelity-registry.mjs +10 -0
- package/lib/lookup-contract-primitives.mjs +1 -1
- package/lib/lookup-diagnostics.mjs +1 -23
- package/lib/lookup-network-evidence-bounds.mjs +1 -10
- package/lib/lookup-progress.mjs +50 -1
- package/lib/lookup-response-contract.mjs +69 -40
- package/lib/lookup-response.mjs +5 -15
- package/lib/lookup-source-progress.mjs +8 -22
- package/lib/lookup.mjs +1 -1
- package/lib/opportunity-scoring.mjs +2 -107
- package/lib/outbound-identity.mjs +1 -1
- package/lib/page-fingerprints.mjs +18 -1
- package/lib/perceptual-hash-comparison.mjs +2 -34
- package/lib/perceptual-hash.mjs +36 -10
- package/lib/portable-generator.mjs +2 -29
- package/lib/project-metadata.mjs +2 -8
- package/lib/rdap-client.mjs +11 -7
- package/lib/registrable-domain.mjs +2 -56
- package/lib/registrar-standing-contract.mjs +1 -1
- package/lib/registrar-standing.mjs +9 -13
- package/lib/registry-capabilities.mjs +2 -2
- package/lib/registry-capability-catalogue.mjs +27 -19
- package/lib/risk-calibration-summary.mjs +2 -352
- package/lib/risk-scoring.mjs +2 -345
- package/lib/scoring-evidence-quality.mjs +2 -107
- package/lib/semantic-version.mjs +2 -54
- package/lib/service-binding-dns.mjs +27 -0
- package/lib/smtp-transport-review.mjs +48 -19
- package/lib/sslbl-certificates.generated.mjs +141 -139
- package/lib/static-html-analysis.mjs +1 -1
- package/lib/structured-data-identity.mjs +1 -1
- package/lib/threat-intelligence-manifests.mjs +1 -1
- package/lib/threat-intelligence-runtime.mjs +1 -1
- package/lib/threat-intelligence-targets.mjs +1 -1
- package/lib/threat-intelligence-types.mjs +2 -75
- package/lib/typosquat-generator.mjs +11 -2
- package/lib/website-enrichment.mjs +388 -0
- package/lib/whois-authority.mjs +43 -5
- package/lib/whois-normalization.mjs +3 -1
- package/lib/whois-parser.mjs +5 -3
- package/package.json +13 -14
- package/packages/analysis/analyst-taxonomy.mjs +40 -0
- package/packages/analysis/bounded-json.mjs +330 -0
- package/packages/analysis/candidate-provenance-bounds.mjs +4 -0
- package/packages/analysis/cli-argument-grammar.mjs +216 -0
- package/packages/analysis/ct-query.mjs +27 -0
- package/packages/analysis/ct-response-bounds.mjs +9 -0
- package/packages/analysis/external-intelligence-risk.mjs +124 -0
- package/packages/analysis/http-evidence-bounds.mjs +8 -0
- package/packages/analysis/lookup-network-evidence-bounds.mjs +10 -0
- package/packages/analysis/opportunity-scoring.mjs +107 -0
- package/packages/analysis/perceptual-hash-comparison.mjs +34 -0
- package/packages/analysis/portable-generator.mjs +29 -0
- package/packages/analysis/project-metadata.mjs +8 -0
- package/packages/analysis/registrable-domain.mjs +56 -0
- package/packages/analysis/risk-calibration-summary.mjs +352 -0
- package/packages/analysis/risk-scoring.mjs +345 -0
- package/packages/analysis/scoring-evidence-quality.mjs +107 -0
- package/packages/analysis/semantic-version.mjs +54 -0
- package/packages/analysis/threat-intelligence-types.mjs +75 -0
- package/packages/cases/case-evidence-links.mjs +135 -0
- package/packages/cases/case-evidence-model.mjs +78 -12
- package/packages/cases/case-evidence-quality.mjs +5 -0
- package/packages/cases/case-export-input.mjs +7 -5
- package/packages/cases/case-incident-context.mjs +52 -0
- package/packages/cases/case-markdown.mjs +11 -0
- package/packages/cases/case-migration-model.mjs +40 -24
- package/packages/cases/case-recheck-model.mjs +90 -32
- package/packages/cases/case-record-contracts.mjs +1 -1
- package/packages/cases/case-record-core.mjs +1 -1
- package/packages/cases/case-record-operations.mjs +40 -112
- package/packages/cases/case-record-projection.mjs +8 -1
- package/packages/cases/case-record-version-input.mjs +19 -0
- package/packages/cases/case-report.mjs +63 -27
- package/packages/cases/case-requested-evidence.mjs +146 -0
- package/packages/cases/case-response-actions.mjs +103 -1
- package/packages/cases/case-response-model.mjs +9 -1
- package/packages/cases/case-response-outcomes.mjs +29 -8
- package/packages/cases/case-response-packet-render.mjs +13 -9
- package/packages/cases/case-response-packet.mjs +25 -11
- package/packages/cases/case-response-records.mjs +0 -1
- package/packages/cases/case-response-review-inputs.mjs +14 -3
- package/packages/cases/case-storage-model.mjs +1 -1
- package/packages/cases/case-workflow-metadata.mjs +225 -0
- package/packages/cases/case-workflow-migration.mjs +43 -0
- package/packages/cases/http-summary.mjs +6 -1
- package/packages/comparison/favicon-similarity.mjs +1 -1
- package/packages/comparison/page-similarity.mjs +1 -1
- package/packages/comparison/relationship-evidence.mjs +21 -9
- package/packages/comparison/relationship-provenance.mjs +7 -1
- package/packages/contracts/analyst-interchange.mjs +28 -10
- package/packages/contracts/case-portability.mjs +118 -25
- package/packages/contracts/cli-command-semantics.mjs +2 -0
- package/packages/contracts/cli-grammar.mjs +6 -0
- package/packages/contracts/cli-lookup-brief.mjs +2 -0
- package/packages/contracts/context-review.mjs +24 -0
- package/packages/contracts/document-intake.mjs +11 -0
- package/packages/contracts/domain-control-flight-recorder.mjs +30 -14
- package/packages/contracts/domain-control-manifest.mjs +1 -1
- package/packages/contracts/domain-control-monitor.mjs +13 -2
- package/packages/contracts/domain-control-review.mjs +36 -15
- package/packages/contracts/har-review.mjs +2 -0
- package/packages/contracts/identity-events.mjs +4 -0
- package/packages/contracts/investigation-run.mjs +2 -0
- package/packages/contracts/ip-address.mjs +10 -0
- package/packages/contracts/mail-authentication.mjs +5 -0
- package/packages/contracts/message-intake.mjs +31 -0
- package/packages/contracts/offline-comparison.mjs +4 -1
- package/packages/contracts/passive-mail.mjs +10 -0
- package/packages/contracts/web-capture.mjs +2 -2
- package/packages/contracts/workspace-portability.mjs +63 -17
- package/packages/evidence/collection-quality.mjs +67 -0
- package/packages/evidence/dns-query-outcome.mjs +72 -0
- package/packages/evidence/email-recipient.mjs +18 -0
- package/packages/evidence/lookup-target.mjs +5 -1
- package/packages/evidence/observation.mjs +2 -0
- package/packages/evidence/png-pixels.mjs +117 -0
- package/packages/evidence/public-address-policy.mjs +83 -0
- package/packages/interchange/defensive-indicator-export.mjs +264 -0
- package/packages/interchange/external-findings-import.mjs +4 -12
- package/packages/interchange/managed-indicator-export.mjs +35 -0
- package/packages/interchange/managed-indicator-set.mjs +210 -0
- package/packages/interchange/misp-indicator-export.mjs +93 -0
- package/packages/interchange/sharing-policy.mjs +56 -0
- package/packages/interchange/stix-indicator-export.mjs +129 -0
- package/packages/interchange/web-capture-import.mjs +22 -15
- package/packages/investigation/acquisition-decision-packet.mjs +1 -1
- package/packages/investigation/bulk-mail-exposure.mjs +7 -13
- package/packages/investigation/capture-coverage.mjs +57 -0
- package/packages/investigation/connector-provenance-review.mjs +100 -0
- package/packages/investigation/context-review.mjs +35 -0
- package/packages/investigation/document-intake.mjs +81 -0
- package/packages/investigation/docx-intake.mjs +133 -0
- package/packages/investigation/domain-history-review.mjs +100 -0
- package/packages/investigation/domain-transition-review.mjs +47 -0
- package/packages/investigation/evidence-coverage-ledger.mjs +9 -1
- package/packages/investigation/har-intake.mjs +68 -0
- package/packages/investigation/identity-event-intake.mjs +131 -0
- package/packages/investigation/identity-incident-review.mjs +39 -0
- package/packages/investigation/incident-sequence-review.mjs +58 -0
- package/packages/investigation/intake-report.mjs +19 -0
- package/packages/investigation/investigation-manifest.mjs +2 -2
- package/packages/investigation/link-intake.mjs +179 -0
- package/packages/investigation/lookup-asset-graph.mjs +1 -1
- package/packages/investigation/mail-authentication-review.mjs +222 -0
- package/packages/investigation/mail-header-identity.mjs +209 -0
- package/packages/investigation/message-intake.mjs +195 -0
- package/packages/investigation/page-behaviour.mjs +113 -0
- package/packages/investigation/pdf-intake.mjs +155 -0
- package/packages/investigation/platform-continuity-review.mjs +60 -0
- package/packages/investigation/qr-intake.mjs +56 -0
- package/packages/investigation/requested-action-hints.mjs +11 -0
- package/packages/investigation/selected-input-review.mjs +17 -0
- package/packages/investigation/storefront-review.mjs +70 -0
- package/packages/workspace/brand-profile-model.mjs +2 -2
- package/packages/workspace/bulk-review-model.mjs +28 -26
- package/packages/workspace/bulk-session-model.mjs +23 -13
- package/packages/workspace/campaign-model.mjs +1 -1
- package/packages/workspace/detection-rule-model.mjs +1 -1
- package/packages/workspace/hostile-input.mjs +1 -1
- package/packages/workspace/investigation-guide.mjs +2 -2
- package/packages/workspace/investigation-template-model.mjs +26 -2
- package/packages/workspace/page-baseline.mjs +2 -2
- package/packages/workspace/relationship-observation-model.mjs +17 -13
- package/packages/workspace/shortlist-model.mjs +14 -5
- package/packages/workspace/watchlist-history.mjs +28 -12
- package/packages/workspace/watchlist-store.mjs +17 -5
- package/packages/workspace/website-snapshot-model.mjs +28 -3
- package/packages/workspace/workspace-archive-crypto.mjs +1 -1
- package/packages/workspace/workspace-archive.mjs +5 -4
- package/third-party-notices.txt +549 -16
- package/lib/hostname.mjs +0 -2
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
// Only the source metadata needed to qualify an observed relationship crosses
|
|
2
2
|
// this boundary. Collection and retention times are never source-time fallbacks.
|
|
3
|
-
import { normalizeDomain } from "../
|
|
3
|
+
import { normalizeDomain } from "../evidence/domain-name.mjs";
|
|
4
|
+
import { canonicalPublicIpAddress } from "../evidence/public-address-policy.mjs";
|
|
4
5
|
import { normalizeExplicitIsoTimestamp, readObservationEnvelope } from "../evidence/observation.mjs";
|
|
5
6
|
export const RELATIONSHIP_TYPES = Object.freeze([
|
|
6
7
|
'nameserver_set', 'ip_address', 'certificate', 'tracking_identifier', 'favicon', 'official_asset',
|
|
7
8
|
]);
|
|
9
|
+
export const NON_PUBLIC_RELATIONSHIP_LIMITATION = 'This is an equal non-public DNS answer, not evidence of shared public hosting. Private, loopback, reserved and sinkhole-style answers can recur independently.';
|
|
10
|
+
export const FAVICON_RELATIONSHIP_DESCRIPTION = 'Each domain is connected by exact or bounded perceptual favicon matches, directly or through another member. Not every pair necessarily matches.';
|
|
11
|
+
export function isNonPublicAddressRelationship(type, value) {
|
|
12
|
+
return type === 'ip_address' && !canonicalPublicIpAddress(value);
|
|
13
|
+
}
|
|
8
14
|
const SOURCES = ['dns', 'tls', 'http', 'page_identity', 'favicon', 'registration_or_dns', 'unknown'];
|
|
9
15
|
const SOURCES_BY_TYPE = {
|
|
10
16
|
nameserver_set: ['dns', 'registration_or_dns'], ip_address: ['dns'], certificate: ['tls'],
|
|
@@ -3,9 +3,9 @@ import { buildExtractedLifecycleFamily } from "./extracted-domain-lifecycle.mjs"
|
|
|
3
3
|
import { defineSchemaLifecycleFamily } from "./schema-lifecycle.mjs";
|
|
4
4
|
export const ANALYST_INTERCHANGE_CONTRACT_OWNER = 'packages/contracts/analyst-interchange.mts';
|
|
5
5
|
export const INVESTIGATION_CACAO_SPEC_VERSION = 'cacao-2.0';
|
|
6
|
-
export const INVESTIGATION_CACAO_PROFILE_VERSION =
|
|
7
|
-
export const INVESTIGATION_CACAO_PROFILE_SEMVER = '
|
|
8
|
-
export const INVESTIGATION_CACAO_SUPPORTED_PROFILE_VERSIONS = [INVESTIGATION_CACAO_PROFILE_VERSION];
|
|
6
|
+
export const INVESTIGATION_CACAO_PROFILE_VERSION = 3;
|
|
7
|
+
export const INVESTIGATION_CACAO_PROFILE_SEMVER = '3.0.0';
|
|
8
|
+
export const INVESTIGATION_CACAO_SUPPORTED_PROFILE_VERSIONS = [2, INVESTIGATION_CACAO_PROFILE_VERSION];
|
|
9
9
|
export const MAX_INVESTIGATION_CACAO_IMPORT_BYTES = 384 * 1024;
|
|
10
10
|
export const BRAND_PROTECTION_OPERATIONS_REPORT_SCHEMA = 'whoisleuth.brand-protection-operations-report';
|
|
11
11
|
export const BRAND_PROTECTION_OPERATIONS_REPORT_VERSION = 2;
|
|
@@ -18,6 +18,10 @@ export const STIX_INDICATOR_LIFECYCLE_SCHEMA = 'whoisleuth.internal.stix-indicat
|
|
|
18
18
|
export const STIX_INDICATOR_EXPORT_VERSION = 2;
|
|
19
19
|
export const MISP_INDICATOR_LIFECYCLE_SCHEMA = 'whoisleuth.internal.misp-indicators';
|
|
20
20
|
export const MISP_INDICATOR_EXPORT_VERSION = 2;
|
|
21
|
+
export const MANAGED_INDICATOR_SET_SCHEMA = 'whoisleuth.managed-indicator-set';
|
|
22
|
+
export const MANAGED_INDICATOR_SET_VERSION = 1;
|
|
23
|
+
export const MAX_MANAGED_INDICATOR_SET_BYTES = 4 * 1024 * 1024;
|
|
24
|
+
export const MAX_MANAGED_INDICATOR_PLAN_BYTES = 16 * 1024 * 1024;
|
|
21
25
|
export const DNS_CHANGE_REHEARSAL_VERSION = 2;
|
|
22
26
|
export const DNS_CHANGE_REHEARSAL_EXPORT_SCHEMA = 'whoisleuth.dns-change-rehearsal';
|
|
23
27
|
export const MAIL_REPORT_SCHEMA = 'whoisleuth.mail-report-review';
|
|
@@ -34,15 +38,16 @@ export const MAX_STATIC_PAGE_PATTERN_PACK_BYTES = 256 * 1024;
|
|
|
34
38
|
export const WEB_CAPTURE_SUMMARY_SCHEMA = 'whoisleuth.web-capture-summary';
|
|
35
39
|
export const WEB_CAPTURE_SUMMARY_VERSION = 1;
|
|
36
40
|
export const WEB_CAPTURE_MANIFEST_SCHEMA = 'whoisleuth.web-capture-manifest';
|
|
37
|
-
export const WEB_CAPTURE_MANIFEST_VERSION =
|
|
41
|
+
export const WEB_CAPTURE_MANIFEST_VERSION = 3;
|
|
42
|
+
export const WEB_CAPTURE_MANIFEST_SUPPORTED_VERSIONS = [2, WEB_CAPTURE_MANIFEST_VERSION];
|
|
38
43
|
export const MAX_WEB_CAPTURE_MANIFEST_BYTES = 1024 * 1024;
|
|
39
44
|
const CACAO_COMPATIBILITY = defineSchemaCompatibility({
|
|
40
45
|
id: 'export.investigation-cacao-profile', kind: 'export', schema: INVESTIGATION_CACAO_SPEC_VERSION,
|
|
41
46
|
currentVersion: INVESTIGATION_CACAO_PROFILE_VERSION, supportedVersions: INVESTIGATION_CACAO_SUPPORTED_PROFILE_VERSIONS,
|
|
42
|
-
acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: '
|
|
47
|
+
acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: 'normalize_to_current',
|
|
43
48
|
writeSemantics: 'non_destructive_merge', byteBudget: MAX_INVESTIGATION_CACAO_IMPORT_BYTES,
|
|
44
49
|
owner: ANALYST_INTERCHANGE_CONTRACT_OWNER,
|
|
45
|
-
note: 'Restricted CACAO 2.0 profile
|
|
50
|
+
note: 'Restricted CACAO 2.0 manual profile. Version 3 retains optional lesson-revision provenance; public profile 2 remains readable. Executable commands, branches, targets and credentials remain rejected.',
|
|
46
51
|
});
|
|
47
52
|
const OPERATIONS_REPORT_COMPATIBILITY = defineSchemaCompatibility({
|
|
48
53
|
id: 'export.brand-protection-operations-report', kind: 'export', schema: BRAND_PROTECTION_OPERATIONS_REPORT_SCHEMA,
|
|
@@ -72,6 +77,13 @@ const MISP_INDICATORS_COMPATIBILITY = defineSchemaCompatibility({
|
|
|
72
77
|
writeSemantics: 'read_only', byteBudget: null, owner: ANALYST_INTERCHANGE_CONTRACT_OWNER,
|
|
73
78
|
note: 'Unpublished, non-IDS, non-correlating event for reviewed import. Version 2 omits optional seen times when the source observation time is unknown.',
|
|
74
79
|
});
|
|
80
|
+
export const MANAGED_INDICATOR_SET_COMPATIBILITY = defineSchemaCompatibility({
|
|
81
|
+
id: 'export.managed-indicator-set', kind: 'export', schema: MANAGED_INDICATOR_SET_SCHEMA,
|
|
82
|
+
currentVersion: MANAGED_INDICATOR_SET_VERSION, supportedVersions: [MANAGED_INDICATOR_SET_VERSION],
|
|
83
|
+
acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: 'exact_current_only',
|
|
84
|
+
writeSemantics: 'read_only', byteBudget: MAX_MANAGED_INDICATOR_SET_BYTES, owner: ANALYST_INTERCHANGE_CONTRACT_OWNER,
|
|
85
|
+
note: 'File-backed managed indicator revisions retain original observations, stable identities, explicit renewals and permanent withdrawals. Known predecessors prevent history replacement; content digests do not authenticate authorship or an unavailable earlier chain.',
|
|
86
|
+
});
|
|
75
87
|
const WEB_CAPTURE_SUMMARY_COMPATIBILITY = defineSchemaCompatibility({
|
|
76
88
|
id: 'export.web-capture-summary', kind: 'export', schema: WEB_CAPTURE_SUMMARY_SCHEMA,
|
|
77
89
|
currentVersion: WEB_CAPTURE_SUMMARY_VERSION, supportedVersions: [WEB_CAPTURE_SUMMARY_VERSION],
|
|
@@ -81,11 +93,11 @@ const WEB_CAPTURE_SUMMARY_COMPATIBILITY = defineSchemaCompatibility({
|
|
|
81
93
|
});
|
|
82
94
|
const WEB_CAPTURE_MANIFEST_COMPATIBILITY = defineSchemaCompatibility({
|
|
83
95
|
id: 'export.web-capture-manifest', kind: 'export', schema: WEB_CAPTURE_MANIFEST_SCHEMA,
|
|
84
|
-
currentVersion: WEB_CAPTURE_MANIFEST_VERSION, supportedVersions:
|
|
96
|
+
currentVersion: WEB_CAPTURE_MANIFEST_VERSION, supportedVersions: WEB_CAPTURE_MANIFEST_SUPPORTED_VERSIONS,
|
|
85
97
|
acceptsUnversionedLegacy: false, futureVersionBehavior: 'reject', migration: 'read_only',
|
|
86
98
|
writeSemantics: 'read_only', byteBudget: MAX_WEB_CAPTURE_MANIFEST_BYTES,
|
|
87
99
|
owner: ANALYST_INTERCHANGE_CONTRACT_OWNER,
|
|
88
|
-
note: 'Metadata-only capture manifest
|
|
100
|
+
note: 'Metadata-only capture manifest. Version 3 adds bounded page and dependency observations; version 2 remains readable with those observations unavailable.',
|
|
89
101
|
});
|
|
90
102
|
const DEFENSIVE_MANIFEST_COMPATIBILITY = defineSchemaCompatibility({
|
|
91
103
|
id: 'export.defensive-indicator-manifest', kind: 'export', schema: DEFENSIVE_INDICATOR_MANIFEST_SCHEMA,
|
|
@@ -141,12 +153,17 @@ export const ANALYST_INTERCHANGE_LIFECYCLE_FAMILY = defineSchemaLifecycleFamily(
|
|
|
141
153
|
includedCategories: ['reviewed-indicators', 'source-identity', 'provenance', 'completeness', 'omitted-counts', 'limitations'],
|
|
142
154
|
excludedCategories: ['credentials', 'cookies', 'message-content', 'raw-upstream-responses', 'expanded-contacts'],
|
|
143
155
|
formats: [
|
|
156
|
+
{ descriptor: MANAGED_INDICATOR_SET_COMPATIBILITY, lifecycleSchema: MANAGED_INDICATOR_SET_SCHEMA,
|
|
157
|
+
requiredKeys: ['schema', 'version', 'id', 'producerId', 'revisionId', 'name', 'revision', 'createdAt', 'modifiedAt', 'previous', 'entries', 'integrity'], optionalKeys: [],
|
|
158
|
+
hook: { module: 'packages/interchange/managed-indicator-set.mts', exportName: 'validateManagedIndicatorSet', role: 'structure_validator', runtime: 'shared' },
|
|
159
|
+
fixtures: [{ id: 'managed-indicator-set-v1', path: `${F}managed-indicator-set-v1.json`, bytes: 1_193, sha256: '3a4ffb7256e696d1f1b3bae14743bb8c03ddeb0922186868e935f5a489ba3985', version: MANAGED_INDICATOR_SET_VERSION }] },
|
|
144
160
|
{ descriptor: CACAO_COMPATIBILITY, lifecycleSchema: INVESTIGATION_CACAO_SPEC_VERSION,
|
|
145
161
|
requiredKeys: ['type', 'spec_version', 'id', 'name', 'created', 'modified', 'workflow_start', 'workflow', 'extension_definitions'],
|
|
146
162
|
optionalKeys: ['description', 'playbook_types', 'playbook_activities', 'created_by', 'playbook_extensions', 'agent_definitions', 'x_whoisleuth_profile_version'],
|
|
147
163
|
hook: { module: 'packages/interchange/investigation-playbook-interchange.mts', exportName: 'parseCacaoInvestigationPlaybook', role: 'normaliser', runtime: 'shared' },
|
|
148
164
|
fixtures: [
|
|
149
|
-
{ id: 'investigation-cacao-profile-v2', path: `${F}investigation-cacao-profile-v2.json`, bytes: 4_091, sha256: '7e9a3de6e12b83477690c0c58e03e6efbbb8b0c11fd98dc8470bdb6784d42358', version:
|
|
165
|
+
{ id: 'investigation-cacao-profile-v2', path: `${F}investigation-cacao-profile-v2.json`, bytes: 4_091, sha256: '7e9a3de6e12b83477690c0c58e03e6efbbb8b0c11fd98dc8470bdb6784d42358', version: 2 },
|
|
166
|
+
{ id: 'investigation-cacao-profile-v3', path: `${F}investigation-cacao-profile-v3.json`, bytes: 4_067, sha256: '608cbb7875c3448ca11f6f8cb2f96ae098e18316532a8f651bbe540ca7f25a2d', version: INVESTIGATION_CACAO_PROFILE_VERSION },
|
|
150
167
|
] },
|
|
151
168
|
{ descriptor: OPERATIONS_REPORT_COMPATIBILITY, lifecycleSchema: BRAND_PROTECTION_OPERATIONS_REPORT_SCHEMA,
|
|
152
169
|
requiredKeys: ['schema', 'version', 'generatedAt', 'window', 'limitations'], optionalKeys: ['sourceState', 'summary', 'counts', 'states', 'actionTypes', 'durations', 'denominators', 'omissions'],
|
|
@@ -182,7 +199,8 @@ export const ANALYST_INTERCHANGE_LIFECYCLE_FAMILY = defineSchemaLifecycleFamily(
|
|
|
182
199
|
requiredKeys: ['schema', 'schemaVersion', 'source', 'captures'], optionalKeys: [],
|
|
183
200
|
hook: { module: 'packages/interchange/web-capture-import.mts', exportName: 'parseWebCaptureManifest', role: 'normaliser', runtime: 'shared' },
|
|
184
201
|
fixtures: [
|
|
185
|
-
{ id: 'web-capture-manifest-v2', path: `${F}web-capture-manifest-v2.json`, bytes: 494, sha256: 'a2208dc956a832d70e37cd9a5929db81d29148856c485e4fd6ce5b123de5b8e6', version:
|
|
202
|
+
{ id: 'web-capture-manifest-v2', path: `${F}web-capture-manifest-v2.json`, bytes: 494, sha256: 'a2208dc956a832d70e37cd9a5929db81d29148856c485e4fd6ce5b123de5b8e6', version: 2 },
|
|
203
|
+
{ id: 'web-capture-manifest-v3', path: `${F}web-capture-manifest-v3.json`, bytes: 868, sha256: 'bca4e8cb539ac6035dd44586fa7e27774766a14dadbc4fc73cad2b71dace2ac8', version: WEB_CAPTURE_MANIFEST_VERSION },
|
|
186
204
|
] },
|
|
187
205
|
{ descriptor: DEFENSIVE_MANIFEST_COMPATIBILITY, lifecycleSchema: DEFENSIVE_INDICATOR_MANIFEST_SCHEMA,
|
|
188
206
|
requiredKeys: ['schema', 'version', 'generatedAt'], optionalKeys: ['expiresAt', 'reviewRequired', 'explicitSelection', 'includeWildcards', 'entries', 'indicators', 'exclusions', 'limitations'],
|
|
@@ -3,14 +3,15 @@ import { defineSchemaCompatibility } from "./schema-compatibility.mjs";
|
|
|
3
3
|
import { defineSchemaLifecycleFamily } from "./schema-lifecycle.mjs";
|
|
4
4
|
export const CASE_CONTRACT_OWNER = 'packages/contracts/case-portability.mts';
|
|
5
5
|
export const MAX_CASE_OBJECTIVE_LENGTH = 320;
|
|
6
|
-
export
|
|
7
|
-
//
|
|
8
|
-
// readers
|
|
9
|
-
export const
|
|
10
|
-
export const
|
|
11
|
-
export const
|
|
12
|
-
export const
|
|
13
|
-
export const
|
|
6
|
+
// These published export names identify a format checkpoint, not the newest
|
|
7
|
+
// application patch. Release verification reads the preceding tag's durable
|
|
8
|
+
// commitments directly. Historical readers use fixed schema epochs below.
|
|
9
|
+
export const LATEST_PUBLIC_APPLICATION_VERSION = '2.4.0';
|
|
10
|
+
export const LATEST_PUBLIC_CASE_SCHEMA_VERSION = 16;
|
|
11
|
+
export const LATEST_PUBLIC_CASE_REPORT_SCHEMA_VERSION = 12;
|
|
12
|
+
export const LATEST_PUBLIC_CASE_RESPONSE_PACKET_VERSION = 10;
|
|
13
|
+
export const LATEST_PUBLIC_CASE_RESPONSE_REVIEW_INPUTS_VERSION = 4;
|
|
14
|
+
export const LATEST_PUBLIC_WORKSPACE_ARCHIVE_VERSION = 9;
|
|
14
15
|
export const CASE_PORTABILITY_IDENTITY_CONSTANTS = Object.freeze([
|
|
15
16
|
'LATEST_PUBLIC_APPLICATION_VERSION',
|
|
16
17
|
'LATEST_PUBLIC_CASE_SCHEMA_VERSION',
|
|
@@ -27,6 +28,7 @@ export const CASE_PORTABILITY_IDENTITY_CONSTANTS = Object.freeze([
|
|
|
27
28
|
'PUBLISHED_V2_3_CASE_REPORT_SCHEMA_VERSION',
|
|
28
29
|
'PUBLISHED_V2_3_CASE_RESPONSE_PACKET_VERSION',
|
|
29
30
|
'PUBLISHED_V2_3_CASE_RESPONSE_REVIEW_INPUTS_VERSION',
|
|
31
|
+
'PUBLISHED_V2_3_WORKSPACE_ARCHIVE_VERSION',
|
|
30
32
|
'CASE_BROWSER_STORE_LIFECYCLE_SCHEMA',
|
|
31
33
|
'CASE_EXPORT_LIFECYCLE_SCHEMA',
|
|
32
34
|
'CASE_SCHEMA_VERSION',
|
|
@@ -158,12 +160,14 @@ export const PUBLISHED_V2_CASE_SCHEMA_VERSION = 13;
|
|
|
158
160
|
export const PUBLISHED_V2_2_CASE_SCHEMA_VERSION = 14;
|
|
159
161
|
export const PUBLISHED_V2_3_CASE_SCHEMA_VERSION = 15;
|
|
160
162
|
export const INCIDENT_CASE_SCHEMA_VERSION = 16;
|
|
161
|
-
export const
|
|
163
|
+
export const EVIDENCE_FOLLOW_UP_CASE_SCHEMA_VERSION = 17;
|
|
164
|
+
export const CASE_SCHEMA_VERSION = EVIDENCE_FOLLOW_UP_CASE_SCHEMA_VERSION;
|
|
162
165
|
export const CASE_BROWSER_SUPPORTED_VERSIONS = Object.freeze([
|
|
163
166
|
PUBLIC_CASE_SCHEMA_VERSION,
|
|
164
167
|
PUBLISHED_V2_CASE_SCHEMA_VERSION,
|
|
165
168
|
PUBLISHED_V2_2_CASE_SCHEMA_VERSION,
|
|
166
169
|
PUBLISHED_V2_3_CASE_SCHEMA_VERSION,
|
|
170
|
+
INCIDENT_CASE_SCHEMA_VERSION,
|
|
167
171
|
CASE_SCHEMA_VERSION,
|
|
168
172
|
]);
|
|
169
173
|
export const CASE_IMPORT_VERSIONS = CASE_BROWSER_SUPPORTED_VERSIONS;
|
|
@@ -172,11 +176,12 @@ export const PUBLIC_CASE_REPORT_SCHEMA_VERSION = 8;
|
|
|
172
176
|
export const PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION = 9;
|
|
173
177
|
export const PUBLISHED_V2_2_CASE_REPORT_SCHEMA_VERSION = 10;
|
|
174
178
|
export const PUBLISHED_V2_3_CASE_REPORT_SCHEMA_VERSION = 11;
|
|
175
|
-
export const CASE_REPORT_SCHEMA_VERSION =
|
|
179
|
+
export const CASE_REPORT_SCHEMA_VERSION = 13;
|
|
176
180
|
export const CASE_REPORT_OUTPUT_VERSIONS = Object.freeze([
|
|
177
181
|
PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION,
|
|
178
182
|
PUBLISHED_V2_2_CASE_REPORT_SCHEMA_VERSION,
|
|
179
183
|
PUBLISHED_V2_3_CASE_REPORT_SCHEMA_VERSION,
|
|
184
|
+
LATEST_PUBLIC_CASE_REPORT_SCHEMA_VERSION,
|
|
180
185
|
CASE_REPORT_SCHEMA_VERSION,
|
|
181
186
|
]);
|
|
182
187
|
export const CASE_RESPONSE_PACKET_SCHEMA = 'whoisleuth.case-response-packet';
|
|
@@ -184,12 +189,13 @@ export const PUBLIC_CASE_RESPONSE_PACKET_VERSION = 6;
|
|
|
184
189
|
export const PUBLISHED_V2_CASE_RESPONSE_PACKET_VERSION = 7;
|
|
185
190
|
export const PUBLISHED_V2_2_CASE_RESPONSE_PACKET_VERSION = 8;
|
|
186
191
|
export const PUBLISHED_V2_3_CASE_RESPONSE_PACKET_VERSION = 9;
|
|
187
|
-
export const CASE_RESPONSE_PACKET_VERSION =
|
|
192
|
+
export const CASE_RESPONSE_PACKET_VERSION = 11;
|
|
188
193
|
export const CASE_RESPONSE_PACKET_OUTPUT_VERSIONS = Object.freeze([
|
|
189
194
|
PUBLIC_CASE_RESPONSE_PACKET_VERSION,
|
|
190
195
|
PUBLISHED_V2_CASE_RESPONSE_PACKET_VERSION,
|
|
191
196
|
PUBLISHED_V2_2_CASE_RESPONSE_PACKET_VERSION,
|
|
192
197
|
PUBLISHED_V2_3_CASE_RESPONSE_PACKET_VERSION,
|
|
198
|
+
LATEST_PUBLIC_CASE_RESPONSE_PACKET_VERSION,
|
|
193
199
|
CASE_RESPONSE_PACKET_VERSION,
|
|
194
200
|
]);
|
|
195
201
|
export const SUPPORTED_CASE_RESPONSE_PACKET_VERSIONS = CASE_RESPONSE_PACKET_OUTPUT_VERSIONS;
|
|
@@ -197,16 +203,17 @@ export const CASE_RESPONSE_REVIEW_INPUTS_SCHEMA = 'whoisleuth.case-response-revi
|
|
|
197
203
|
export const PUBLISHED_V2_CASE_RESPONSE_REVIEW_INPUTS_VERSION = 1;
|
|
198
204
|
export const PUBLISHED_V2_2_CASE_RESPONSE_REVIEW_INPUTS_VERSION = 2;
|
|
199
205
|
export const PUBLISHED_V2_3_CASE_RESPONSE_REVIEW_INPUTS_VERSION = 3;
|
|
200
|
-
export const CASE_RESPONSE_REVIEW_INPUTS_VERSION =
|
|
206
|
+
export const CASE_RESPONSE_REVIEW_INPUTS_VERSION = 5;
|
|
201
207
|
export const SUPPORTED_CASE_RESPONSE_REVIEW_INPUTS_VERSIONS = Object.freeze([
|
|
202
208
|
PUBLISHED_V2_CASE_RESPONSE_REVIEW_INPUTS_VERSION,
|
|
203
209
|
PUBLISHED_V2_2_CASE_RESPONSE_REVIEW_INPUTS_VERSION,
|
|
204
210
|
PUBLISHED_V2_3_CASE_RESPONSE_REVIEW_INPUTS_VERSION,
|
|
211
|
+
LATEST_PUBLIC_CASE_RESPONSE_REVIEW_INPUTS_VERSION,
|
|
205
212
|
CASE_RESPONSE_REVIEW_INPUTS_VERSION,
|
|
206
213
|
]);
|
|
207
214
|
export const CLI_CASE_PACK_SCHEMA = 'whoisleuth.cli.case-pack';
|
|
208
215
|
export const CLI_CASE_PACK_VERSION = 2;
|
|
209
|
-
export const CLI_CASE_PACK_WRITER_FIXTURE_ID = 'cli-case-pack-v2-case-
|
|
216
|
+
export const CLI_CASE_PACK_WRITER_FIXTURE_ID = 'cli-case-pack-v2-case-v17-current';
|
|
210
217
|
export const CLI_CASE_PACK_INPUT_CASE_VERSIONS = Object.freeze(CASE_IMPORT_VERSIONS.filter((version) => version >= PUBLISHED_V2_3_CASE_SCHEMA_VERSION));
|
|
211
218
|
export const SUPPORTED_CLI_CASE_PACK_VERSIONS = Object.freeze([CLI_CASE_PACK_VERSION]);
|
|
212
219
|
export const CLI_CASE_PACK_ROOT_KEYS = Object.freeze(['version', 'exportedAt', 'cases', 'packet', 'integrity']);
|
|
@@ -225,6 +232,7 @@ export const CLI_CASE_PACK_CASE_REPORT_EPOCHS = Object.freeze([
|
|
|
225
232
|
Object.freeze({ caseVersions: Object.freeze([PUBLISHED_V2_CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([PUBLISHED_V2_CASE_REPORT_SCHEMA_VERSION]) }),
|
|
226
233
|
Object.freeze({ caseVersions: Object.freeze([PUBLISHED_V2_2_CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([PUBLISHED_V2_2_CASE_REPORT_SCHEMA_VERSION]) }),
|
|
227
234
|
Object.freeze({ caseVersions: Object.freeze([PUBLISHED_V2_3_CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([PUBLISHED_V2_3_CASE_REPORT_SCHEMA_VERSION]) }),
|
|
235
|
+
Object.freeze({ caseVersions: Object.freeze([INCIDENT_CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([LATEST_PUBLIC_CASE_REPORT_SCHEMA_VERSION]) }),
|
|
228
236
|
Object.freeze({ caseVersions: Object.freeze([CASE_SCHEMA_VERSION]), reportVersions: Object.freeze([CASE_REPORT_SCHEMA_VERSION]) }),
|
|
229
237
|
]);
|
|
230
238
|
export function caseReportVersionMatchesCase(caseVersion, reportVersion) {
|
|
@@ -237,12 +245,13 @@ export const WORKSPACE_ARCHIVE_SCHEMA = 'whoisleuth.workspace-archive';
|
|
|
237
245
|
export const PUBLIC_WORKSPACE_ARCHIVE_VERSION = 5;
|
|
238
246
|
export const PUBLISHED_V2_WORKSPACE_ARCHIVE_VERSION = 6;
|
|
239
247
|
export const PUBLISHED_V2_2_WORKSPACE_ARCHIVE_VERSION = 7;
|
|
248
|
+
export const PUBLISHED_V2_3_WORKSPACE_ARCHIVE_VERSION = 8;
|
|
240
249
|
export const WORKSPACE_ARCHIVE_VERSION = 9;
|
|
241
250
|
export const SUPPORTED_WORKSPACE_ARCHIVE_VERSIONS = Object.freeze([
|
|
242
251
|
PUBLIC_WORKSPACE_ARCHIVE_VERSION,
|
|
243
252
|
PUBLISHED_V2_WORKSPACE_ARCHIVE_VERSION,
|
|
244
253
|
PUBLISHED_V2_2_WORKSPACE_ARCHIVE_VERSION,
|
|
245
|
-
|
|
254
|
+
PUBLISHED_V2_3_WORKSPACE_ARCHIVE_VERSION,
|
|
246
255
|
WORKSPACE_ARCHIVE_VERSION,
|
|
247
256
|
]);
|
|
248
257
|
export function isSupportedWorkspaceArchiveVersion(value) {
|
|
@@ -448,7 +457,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
448
457
|
version: PUBLIC_CASE_SCHEMA_VERSION,
|
|
449
458
|
role: 'historical',
|
|
450
459
|
expectation: 'normalises_to_current_output',
|
|
451
|
-
expectedOutputFixtureId: 'browser-case-
|
|
460
|
+
expectedOutputFixtureId: 'browser-case-v17',
|
|
452
461
|
shapeId: `case.browser-store.v${PUBLIC_CASE_SCHEMA_VERSION}`,
|
|
453
462
|
scope: 'repository',
|
|
454
463
|
}),
|
|
@@ -462,7 +471,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
462
471
|
version: PUBLISHED_V2_CASE_SCHEMA_VERSION,
|
|
463
472
|
role: 'historical',
|
|
464
473
|
expectation: 'normalises_to_current_output',
|
|
465
|
-
expectedOutputFixtureId: 'browser-case-
|
|
474
|
+
expectedOutputFixtureId: 'browser-case-v17',
|
|
466
475
|
shapeId: `case.browser-store.v${PUBLISHED_V2_CASE_SCHEMA_VERSION}`,
|
|
467
476
|
scope: 'repository',
|
|
468
477
|
}),
|
|
@@ -476,7 +485,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
476
485
|
version: PUBLISHED_V2_2_CASE_SCHEMA_VERSION,
|
|
477
486
|
role: 'historical',
|
|
478
487
|
expectation: 'normalises_to_current_output',
|
|
479
|
-
expectedOutputFixtureId: 'browser-case-
|
|
488
|
+
expectedOutputFixtureId: 'browser-case-v17',
|
|
480
489
|
shapeId: `case.browser-store.v${PUBLISHED_V2_2_CASE_SCHEMA_VERSION}`,
|
|
481
490
|
scope: 'repository',
|
|
482
491
|
}),
|
|
@@ -490,7 +499,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
490
499
|
version: PUBLISHED_V2_3_CASE_SCHEMA_VERSION,
|
|
491
500
|
role: 'historical',
|
|
492
501
|
expectation: 'normalises_to_current_output',
|
|
493
|
-
expectedOutputFixtureId: 'browser-case-
|
|
502
|
+
expectedOutputFixtureId: 'browser-case-v17',
|
|
494
503
|
shapeId: `case.browser-store.v${PUBLISHED_V2_3_CASE_SCHEMA_VERSION}`,
|
|
495
504
|
scope: 'repository',
|
|
496
505
|
}),
|
|
@@ -501,6 +510,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
501
510
|
sha256: 'e0d9dd7d1da29ca31e1b6ccd0c514c44267d84fe9db2eff0ffce23c51fb04ce4',
|
|
502
511
|
contentDigestSha256: null,
|
|
503
512
|
schema: CASE_BROWSER_STORE_LIFECYCLE_SCHEMA,
|
|
513
|
+
version: INCIDENT_CASE_SCHEMA_VERSION,
|
|
514
|
+
role: 'historical',
|
|
515
|
+
expectation: 'normalises_to_current_output',
|
|
516
|
+
expectedOutputFixtureId: 'browser-case-v17',
|
|
517
|
+
shapeId: `case.browser-store.v${INCIDENT_CASE_SCHEMA_VERSION}`,
|
|
518
|
+
scope: 'repository',
|
|
519
|
+
}),
|
|
520
|
+
Object.freeze({
|
|
521
|
+
id: 'browser-case-v17',
|
|
522
|
+
path: 'test/fixtures/case-lifecycle/browser-case-v17.json',
|
|
523
|
+
bytes: 3312,
|
|
524
|
+
sha256: '8de3bb904b09ec07994d832738b148321902d91c4351763eebdc0cf908bf5429',
|
|
525
|
+
contentDigestSha256: null,
|
|
526
|
+
schema: CASE_BROWSER_STORE_LIFECYCLE_SCHEMA,
|
|
504
527
|
version: CASE_SCHEMA_VERSION,
|
|
505
528
|
role: 'current',
|
|
506
529
|
expectation: 'accepted_exact',
|
|
@@ -518,7 +541,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
518
541
|
version: PUBLIC_CASE_SCHEMA_VERSION,
|
|
519
542
|
role: 'historical',
|
|
520
543
|
expectation: 'normalises_to_current_output',
|
|
521
|
-
expectedOutputFixtureId: 'case-export-
|
|
544
|
+
expectedOutputFixtureId: 'case-export-v17',
|
|
522
545
|
shapeId: `case.export.v${PUBLIC_CASE_SCHEMA_VERSION}`,
|
|
523
546
|
scope: 'repository',
|
|
524
547
|
}),
|
|
@@ -532,7 +555,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
532
555
|
version: PUBLISHED_V2_CASE_SCHEMA_VERSION,
|
|
533
556
|
role: 'historical',
|
|
534
557
|
expectation: 'normalises_to_current_output',
|
|
535
|
-
expectedOutputFixtureId: 'case-export-
|
|
558
|
+
expectedOutputFixtureId: 'case-export-v17',
|
|
536
559
|
shapeId: `case.export.v${PUBLISHED_V2_CASE_SCHEMA_VERSION}`,
|
|
537
560
|
scope: 'repository',
|
|
538
561
|
}),
|
|
@@ -546,7 +569,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
546
569
|
version: PUBLISHED_V2_2_CASE_SCHEMA_VERSION,
|
|
547
570
|
role: 'historical',
|
|
548
571
|
expectation: 'normalises_to_current_output',
|
|
549
|
-
expectedOutputFixtureId: 'case-export-
|
|
572
|
+
expectedOutputFixtureId: 'case-export-v17',
|
|
550
573
|
shapeId: `case.export.v${PUBLISHED_V2_2_CASE_SCHEMA_VERSION}`,
|
|
551
574
|
scope: 'repository',
|
|
552
575
|
}),
|
|
@@ -560,7 +583,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
560
583
|
version: PUBLISHED_V2_3_CASE_SCHEMA_VERSION,
|
|
561
584
|
role: 'historical',
|
|
562
585
|
expectation: 'normalises_to_current_output',
|
|
563
|
-
expectedOutputFixtureId: 'case-export-
|
|
586
|
+
expectedOutputFixtureId: 'case-export-v17',
|
|
564
587
|
shapeId: `case.export.v${PUBLISHED_V2_3_CASE_SCHEMA_VERSION}`,
|
|
565
588
|
scope: 'repository',
|
|
566
589
|
}),
|
|
@@ -571,6 +594,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
571
594
|
sha256: 'b0c14fd4d391b1067f101d61c1549c28570999c9cebb58aed21e164d7af56ad8',
|
|
572
595
|
contentDigestSha256: null,
|
|
573
596
|
schema: CASE_EXPORT_LIFECYCLE_SCHEMA,
|
|
597
|
+
version: INCIDENT_CASE_SCHEMA_VERSION,
|
|
598
|
+
role: 'historical',
|
|
599
|
+
expectation: 'normalises_to_current_output',
|
|
600
|
+
expectedOutputFixtureId: 'case-export-v17',
|
|
601
|
+
shapeId: `case.export.v${INCIDENT_CASE_SCHEMA_VERSION}`,
|
|
602
|
+
scope: 'repository',
|
|
603
|
+
}),
|
|
604
|
+
Object.freeze({
|
|
605
|
+
id: 'case-export-v17',
|
|
606
|
+
path: 'test/fixtures/case-lifecycle/case-export-v17.json',
|
|
607
|
+
bytes: 3356,
|
|
608
|
+
sha256: 'bbce977c1045fd2b5d576619f07c6cc19388d3d192f671f467ab0ad069f01e8b',
|
|
609
|
+
contentDigestSha256: null,
|
|
610
|
+
schema: CASE_EXPORT_LIFECYCLE_SCHEMA,
|
|
574
611
|
version: CASE_SCHEMA_VERSION,
|
|
575
612
|
role: 'current',
|
|
576
613
|
expectation: 'accepted_exact',
|
|
@@ -641,6 +678,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
641
678
|
sha256: '175b9ab720d95e497eb89a73f437b00c5db9595833b02b033a09bb526a926f36',
|
|
642
679
|
contentDigestSha256: null,
|
|
643
680
|
schema: CASE_REPORT_SCHEMA,
|
|
681
|
+
version: LATEST_PUBLIC_CASE_REPORT_SCHEMA_VERSION,
|
|
682
|
+
role: 'historical',
|
|
683
|
+
expectation: 'accepted_exact',
|
|
684
|
+
expectedOutputFixtureId: null,
|
|
685
|
+
shapeId: `case.report.v${LATEST_PUBLIC_CASE_REPORT_SCHEMA_VERSION}`,
|
|
686
|
+
scope: 'repository',
|
|
687
|
+
}),
|
|
688
|
+
Object.freeze({
|
|
689
|
+
id: 'case-report-v13',
|
|
690
|
+
path: 'test/fixtures/case-lifecycle/case-report-v13.json',
|
|
691
|
+
bytes: 4894,
|
|
692
|
+
sha256: '3b0e69f800a2b7a087a0ffcdf81ebbe4237863f42aea7812fd0d0f6b600b8426',
|
|
693
|
+
contentDigestSha256: null,
|
|
694
|
+
schema: CASE_REPORT_SCHEMA,
|
|
644
695
|
version: CASE_REPORT_SCHEMA_VERSION,
|
|
645
696
|
role: 'current',
|
|
646
697
|
expectation: 'accepted_exact',
|
|
@@ -697,6 +748,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
697
748
|
sha256: '991475b878f65d9673e60c776162daf921ec5915e16715080ea0534516cff9c4',
|
|
698
749
|
contentDigestSha256: 'sha256:97cfe929ace59edb46ee0b84e6135614aba782e170e730c3de3fb24b82413162',
|
|
699
750
|
schema: CASE_RESPONSE_PACKET_SCHEMA,
|
|
751
|
+
version: LATEST_PUBLIC_CASE_RESPONSE_PACKET_VERSION,
|
|
752
|
+
role: 'historical',
|
|
753
|
+
expectation: 'accepted_exact',
|
|
754
|
+
expectedOutputFixtureId: null,
|
|
755
|
+
shapeId: `case.response-packet.v${LATEST_PUBLIC_CASE_RESPONSE_PACKET_VERSION}`,
|
|
756
|
+
scope: 'repository',
|
|
757
|
+
}),
|
|
758
|
+
Object.freeze({
|
|
759
|
+
id: 'case-response-packet-v11',
|
|
760
|
+
path: 'test/fixtures/case-lifecycle/case-response-packet-v11.json',
|
|
761
|
+
bytes: 12276,
|
|
762
|
+
sha256: '42817b82fbba58930866d9d4f5554732f56c143fd7a64c6e0acab57b66ddfdce',
|
|
763
|
+
contentDigestSha256: "sha256:603558cc7a9112ab759b7dd01f44c53c9408ed6d71db19f562fced2629d5c437",
|
|
764
|
+
schema: CASE_RESPONSE_PACKET_SCHEMA,
|
|
700
765
|
version: CASE_RESPONSE_PACKET_VERSION,
|
|
701
766
|
role: 'current',
|
|
702
767
|
expectation: 'accepted_exact',
|
|
@@ -753,6 +818,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
753
818
|
sha256: 'b054fc8405663992055ec6c07998fd19ab2f12dcc581b87b42f773b1ab4acec7',
|
|
754
819
|
contentDigestSha256: null,
|
|
755
820
|
schema: CASE_RESPONSE_REVIEW_INPUTS_SCHEMA,
|
|
821
|
+
version: LATEST_PUBLIC_CASE_RESPONSE_REVIEW_INPUTS_VERSION,
|
|
822
|
+
role: 'historical',
|
|
823
|
+
expectation: 'accepted_exact',
|
|
824
|
+
expectedOutputFixtureId: null,
|
|
825
|
+
shapeId: `case.response-review-inputs.v${LATEST_PUBLIC_CASE_RESPONSE_REVIEW_INPUTS_VERSION}`,
|
|
826
|
+
scope: 'repository',
|
|
827
|
+
}),
|
|
828
|
+
Object.freeze({
|
|
829
|
+
id: 'case-response-review-inputs-v5',
|
|
830
|
+
path: 'test/fixtures/case-lifecycle/case-response-review-inputs-v5.json',
|
|
831
|
+
bytes: 7604,
|
|
832
|
+
sha256: '4a54acbc37ee4384c7a2b5c6168d3fffce6757e259d5314da537c8d423c8bee4',
|
|
833
|
+
contentDigestSha256: null,
|
|
834
|
+
schema: CASE_RESPONSE_REVIEW_INPUTS_SCHEMA,
|
|
756
835
|
version: CASE_RESPONSE_REVIEW_INPUTS_VERSION,
|
|
757
836
|
role: 'current',
|
|
758
837
|
expectation: 'accepted_exact',
|
|
@@ -831,8 +910,8 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
831
910
|
scope: 'repository',
|
|
832
911
|
}),
|
|
833
912
|
Object.freeze({
|
|
834
|
-
id:
|
|
835
|
-
path:
|
|
913
|
+
id: 'cli-case-pack-v2-case-v16-current',
|
|
914
|
+
path: 'test/fixtures/case-lifecycle/cli-case-pack-v2-case-v16-current.json',
|
|
836
915
|
bytes: 9602,
|
|
837
916
|
sha256: '2ac29a7b64b3d8930e92f6ab6b826566061224f281799f9b4b15c0acc98550f0',
|
|
838
917
|
contentDigestSha256: 'sha256:c6e3cfbe171a85e9318a0a6780d54dc4ad3e662113a75f483fd527c2e36e0143',
|
|
@@ -844,6 +923,20 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
844
923
|
shapeId: 'case.cli-pack.current',
|
|
845
924
|
scope: 'repository',
|
|
846
925
|
}),
|
|
926
|
+
Object.freeze({
|
|
927
|
+
id: CLI_CASE_PACK_WRITER_FIXTURE_ID,
|
|
928
|
+
path: `test/fixtures/case-lifecycle/${CLI_CASE_PACK_WRITER_FIXTURE_ID}.json`,
|
|
929
|
+
bytes: 9874,
|
|
930
|
+
sha256: '3b25440521ddcc1e3ea65a0e56907df4fb725e27b91415c8f1afabab1c4f7e58',
|
|
931
|
+
contentDigestSha256: 'sha256:3cbf9f6dcacdc8efdaa55319e5ce7068a5cf2ea116c80e9ff8ccf6d2dc8741c6',
|
|
932
|
+
schema: CLI_CASE_PACK_SCHEMA,
|
|
933
|
+
version: CLI_CASE_PACK_VERSION,
|
|
934
|
+
role: 'current',
|
|
935
|
+
expectation: 'accepted_exact',
|
|
936
|
+
expectedOutputFixtureId: null,
|
|
937
|
+
shapeId: 'case.cli-pack.current',
|
|
938
|
+
scope: 'repository',
|
|
939
|
+
}),
|
|
847
940
|
Object.freeze({
|
|
848
941
|
id: 'workspace-archive-v5-public',
|
|
849
942
|
path: 'test/fixtures/case-lifecycle/workspace-archive-v5-public.json',
|
|
@@ -893,7 +986,7 @@ const CASE_LIFECYCLE_FIXTURES = Object.freeze([
|
|
|
893
986
|
sha256: '747062e2dbbcf96724b19718d36bf0dc50b08e96d8adb670115d2315032b6c05',
|
|
894
987
|
contentDigestSha256: null,
|
|
895
988
|
schema: WORKSPACE_ARCHIVE_SCHEMA,
|
|
896
|
-
version:
|
|
989
|
+
version: PUBLISHED_V2_3_WORKSPACE_ARCHIVE_VERSION,
|
|
897
990
|
role: 'historical',
|
|
898
991
|
expectation: 'normalises_to_current_output',
|
|
899
992
|
expectedOutputFixtureId: `workspace-archive-v${WORKSPACE_ARCHIVE_VERSION}-empty-current`,
|
|
@@ -76,9 +76,11 @@ export const CLI_COMMAND_SEMANTICS = Object.freeze({
|
|
|
76
76
|
'page-compare': semantic('investigate', CAPABILITY_IDS.OFFLINE_REVIEW),
|
|
77
77
|
'mail-review': semantic('investigate', CAPABILITY_IDS.OFFLINE_REVIEW),
|
|
78
78
|
'mail-headers': semantic('investigate', CAPABILITY_IDS.OFFLINE_REVIEW),
|
|
79
|
+
intake: semantic('investigate', CAPABILITY_IDS.OFFLINE_REVIEW),
|
|
79
80
|
'review-evidence': semantic('investigate', CAPABILITY_IDS.PORTABLE_EVIDENCE),
|
|
80
81
|
brief: semantic('investigate', CAPABILITY_IDS.OFFLINE_REVIEW),
|
|
81
82
|
case: semantic('respond', CAPABILITY_IDS.ANALYST_CASES),
|
|
83
|
+
'indicator-set': semantic('respond', CAPABILITY_IDS.PORTABLE_EVIDENCE),
|
|
82
84
|
'case-pack': semantic('respond', CAPABILITY_IDS.PORTABLE_EVIDENCE),
|
|
83
85
|
'domain-control': semantic('assure', CAPABILITY_IDS.PORTABLE_EVIDENCE),
|
|
84
86
|
'monitor-once': semantic('assure', CAPABILITY_IDS.LOOKUP),
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MAX_INVESTIGATION_MANIFEST_ARTIFACTS } from "./investigation-package-limits.mjs";
|
|
2
|
+
export const MAX_CLI_ARGUMENTS = MAX_INVESTIGATION_MANIFEST_ARTIFACTS + 32;
|
|
3
|
+
export const MAX_CLI_ARGUMENT_LENGTH = 1024;
|
|
4
|
+
export function hasUnsafeCliText(value) {
|
|
5
|
+
return /[\x00-\x1f\x7f-\x9f]|\p{Default_Ignorable_Code_Point}/u.test(value);
|
|
6
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Common presentation of bounded, analyst-selected contextual evidence. */
|
|
2
|
+
export const CONTEXT_REVIEW_SCHEMA = 'whoisleuth.context-review';
|
|
3
|
+
export const CONTEXT_REVIEW_VERSION = 1;
|
|
4
|
+
export const DOMAIN_HISTORY_INPUT_SCHEMA = 'whoisleuth.domain-history.input';
|
|
5
|
+
export const DOMAIN_HISTORY_INPUT_VERSION = 1;
|
|
6
|
+
export const PLATFORM_CONTINUITY_INPUT_SCHEMA = 'whoisleuth.platform-continuity.input';
|
|
7
|
+
export const PLATFORM_CONTINUITY_INPUT_VERSION = 1;
|
|
8
|
+
export const STOREFRONT_INPUT_SCHEMA = 'whoisleuth.storefront-review.input';
|
|
9
|
+
export const STOREFRONT_INPUT_VERSION = 1;
|
|
10
|
+
export const CONNECTOR_INPUT_SCHEMA = 'whoisleuth.connector-review.input';
|
|
11
|
+
export const CONNECTOR_INPUT_VERSION = 1;
|
|
12
|
+
export const INCIDENT_SEQUENCE_INPUT_SCHEMA = 'whoisleuth.incident-sequence.input';
|
|
13
|
+
export const INCIDENT_SEQUENCE_INPUT_VERSION = 1;
|
|
14
|
+
export const CONTEXT_INPUT_CONTRACTS = [
|
|
15
|
+
{ schema: DOMAIN_HISTORY_INPUT_SCHEMA, version: DOMAIN_HISTORY_INPUT_VERSION },
|
|
16
|
+
{ schema: PLATFORM_CONTINUITY_INPUT_SCHEMA, version: PLATFORM_CONTINUITY_INPUT_VERSION },
|
|
17
|
+
{ schema: STOREFRONT_INPUT_SCHEMA, version: STOREFRONT_INPUT_VERSION },
|
|
18
|
+
{ schema: CONNECTOR_INPUT_SCHEMA, version: CONNECTOR_INPUT_VERSION },
|
|
19
|
+
{ schema: INCIDENT_SEQUENCE_INPUT_SCHEMA, version: INCIDENT_SEQUENCE_INPUT_VERSION },
|
|
20
|
+
];
|
|
21
|
+
export const CONTEXT_INPUT_SCHEMAS = CONTEXT_INPUT_CONTRACTS.map(input => input.schema);
|
|
22
|
+
export const MAX_CONTEXT_INPUT_BYTES = 16 * 1024 * 1024;
|
|
23
|
+
export const MAX_CONTEXT_RECORDS = 200;
|
|
24
|
+
export const CONTEXT_REVIEW_KINDS = ['domain_history', 'platform_continuity', 'storefront', 'connector', 'incident_sequence'];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Input admission, decoded XML, page work and pixels are independently bounded. */
|
|
2
|
+
export const MAX_DOCUMENT_PARTS = 512;
|
|
3
|
+
export const MAX_DOCUMENT_PAGES = 256;
|
|
4
|
+
export const MAX_DOCUMENT_DECODED_BYTES = 32 * 1024 * 1024;
|
|
5
|
+
export const MAX_DOCUMENT_TEXT_BYTES = 8 * 1024 * 1024;
|
|
6
|
+
export const MAX_DOCUMENT_XML_NODES = 200_000;
|
|
7
|
+
export const MAX_DOCUMENT_PAGE_OPERATIONS = 200_000;
|
|
8
|
+
export const MAX_DOCUMENT_XML_DEPTH = 64;
|
|
9
|
+
export const MAX_DOCUMENT_IMAGE_PIXELS = 16 * 1024 * 1024;
|
|
10
|
+
export const MAX_DOCUMENT_TOTAL_IMAGE_PIXELS = 64 * 1024 * 1024;
|
|
11
|
+
export const DOCUMENT_REVIEW_DEADLINE_MS = 60_000;
|
|
@@ -5,8 +5,8 @@ import { MAX_DOMAIN_CONTROL_MONITOR_CONCURRENCY, MAX_DOMAIN_CONTROL_MONITOR_DOMA
|
|
|
5
5
|
export const DOMAIN_CONTROL_FLIGHT_RECORDER_INPUT_SCHEMA = 'whoisleuth.domain-control-flight-recorder.input';
|
|
6
6
|
export const DOMAIN_CONTROL_FLIGHT_RECORDER_SCHEMA = 'whoisleuth.domain-control-flight-recorder';
|
|
7
7
|
export const PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION = 1;
|
|
8
|
-
export const DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION =
|
|
9
|
-
export const SUPPORTED_DOMAIN_CONTROL_FLIGHT_RECORDER_VERSIONS = [PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION, DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION];
|
|
8
|
+
export const DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION = 3;
|
|
9
|
+
export const SUPPORTED_DOMAIN_CONTROL_FLIGHT_RECORDER_VERSIONS = [PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION, 2, DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION];
|
|
10
10
|
export const MIN_FLIGHT_RECORDER_OBSERVATIONS = 1;
|
|
11
11
|
export const MAX_FLIGHT_RECORDER_OBSERVATIONS = 200;
|
|
12
12
|
export const MAX_FLIGHT_RECORDER_WINDOWS = 40;
|
|
@@ -95,11 +95,14 @@ export const PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_EVENT_KEYS = Object.freeze([
|
|
|
95
95
|
'approvedWindow',
|
|
96
96
|
'explanation',
|
|
97
97
|
]);
|
|
98
|
-
export const
|
|
99
|
-
export const
|
|
98
|
+
export const SOURCE_TIMED_FLIGHT_RECORDER_EVENT_KEYS = Object.freeze([...PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_EVENT_KEYS, 'capturedAt']);
|
|
99
|
+
export const DOMAIN_CONTROL_FLIGHT_RECORDER_EVENT_KEYS = Object.freeze([...SOURCE_TIMED_FLIGHT_RECORDER_EVENT_KEYS, 'collectionDepth', 'changeInterval']);
|
|
100
|
+
export const FLIGHT_RECORDER_CHANGE_INTERVAL_KEYS = Object.freeze(['after', 'by', 'incompleteObservations']);
|
|
101
|
+
export const HISTORICAL_FLIGHT_RECORDER_APPROVED_WINDOW_KEYS = Object.freeze([
|
|
100
102
|
'id',
|
|
101
103
|
'reason',
|
|
102
104
|
]);
|
|
105
|
+
export const DOMAIN_CONTROL_FLIGHT_RECORDER_APPROVED_WINDOW_KEYS = Object.freeze([...HISTORICAL_FLIGHT_RECORDER_APPROVED_WINDOW_KEYS, 'startsAt', 'endsAt']);
|
|
103
106
|
export const PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_SUMMARY_KEYS = Object.freeze([
|
|
104
107
|
'firstObservations',
|
|
105
108
|
'observedChanges',
|
|
@@ -115,10 +118,14 @@ export const PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_LIMITATIONS = Object.freeze([
|
|
|
115
118
|
'Approved windows label expected timing but do not delete evidence or establish that a change was authorised, successful, safe, or complete.',
|
|
116
119
|
'Observed changes can reflect publication lag or different collection conditions and require analyst review.',
|
|
117
120
|
]);
|
|
118
|
-
export const
|
|
121
|
+
export const SOURCE_TIMED_FLIGHT_RECORDER_LIMITATIONS = Object.freeze([
|
|
119
122
|
...PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_LIMITATIONS,
|
|
120
123
|
'Capture time and source observation time remain separate. Unknown, conflicting or non-increasing source times cannot establish an observed change.',
|
|
121
124
|
]);
|
|
125
|
+
export const DOMAIN_CONTROL_FLIGHT_RECORDER_LIMITATIONS = Object.freeze([
|
|
126
|
+
...SOURCE_TIMED_FLIGHT_RECORDER_LIMITATIONS,
|
|
127
|
+
'A change interval is bounded by comparable complete source observations, not an exact change time. Incomplete observations inside it remain explicit. An approved window must contain the whole interval.',
|
|
128
|
+
]);
|
|
122
129
|
export const DOMAIN_CONTROL_FLIGHT_RECORDER_INPUT_COMPATIBILITY = defineSchemaCompatibility({
|
|
123
130
|
id: 'cli.domain-control-flight-recorder-input',
|
|
124
131
|
kind: 'cli_document',
|
|
@@ -224,14 +231,22 @@ export const DOMAIN_CONTROL_FLIGHT_RECORDER_SCHEMA_LIFECYCLE = defineSchemaLifec
|
|
|
224
231
|
scope: 'repository',
|
|
225
232
|
},
|
|
226
233
|
].flatMap((fixture) => {
|
|
227
|
-
const version = DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION;
|
|
228
|
-
const id = fixture.id.replace(/v\d+$/u, `v${version}`);
|
|
229
|
-
const content = fixture.role === 'input'
|
|
230
|
-
? { bytes: 2108, sha256: '6998ea864355dd0802b3b6f2c4905f8c84136ad0d4ac9cad1a0fd63dca523b60' }
|
|
231
|
-
: { bytes: 4649, sha256: '8f3168d101291166f34cede351bc176a934e7997920cd8c22ec00d642ec000df' };
|
|
232
234
|
return [
|
|
233
235
|
{ ...fixture, role: fixture.role === 'input' ? 'input' : 'historical', expectation: 'accepted_exact', expectedOutputFixtureId: null },
|
|
234
|
-
|
|
236
|
+
...[2, DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION].map(version => {
|
|
237
|
+
const id = fixture.id.replace(/v\d+$/u, `v${version}`);
|
|
238
|
+
const content = version === 2
|
|
239
|
+
? fixture.role === 'input'
|
|
240
|
+
? { bytes: 2108, sha256: '6998ea864355dd0802b3b6f2c4905f8c84136ad0d4ac9cad1a0fd63dca523b60' }
|
|
241
|
+
: { bytes: 4649, sha256: '8f3168d101291166f34cede351bc176a934e7997920cd8c22ec00d642ec000df' }
|
|
242
|
+
: fixture.role === 'input'
|
|
243
|
+
? { bytes: 2108, sha256: '3d9b91dfd34754482047cde64d6343676ec4747267677fcbcc989a65fbd9a6c6' }
|
|
244
|
+
: { bytes: 5597, sha256: 'ab6a82cfecfb8238a72fbe2dcd4a68a1fd888990e5070eff9d98a337796624d6' };
|
|
245
|
+
return { ...fixture, ...content, id, path: `test/fixtures/${id}.json`, version,
|
|
246
|
+
role: fixture.role === 'input' ? 'input' : version === DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION ? 'current' : 'historical',
|
|
247
|
+
expectation: version === DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION ? fixture.expectation : 'accepted_exact',
|
|
248
|
+
expectedOutputFixtureId: version === DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION ? fixture.expectedOutputFixtureId?.replace(/v\d+$/u, `v${version}`) ?? null : null };
|
|
249
|
+
}),
|
|
235
250
|
];
|
|
236
251
|
}),
|
|
237
252
|
metadata: {
|
|
@@ -257,11 +272,12 @@ export const DOMAIN_CONTROL_FLIGHT_RECORDER_SCHEMA_LIFECYCLE = defineSchemaLifec
|
|
|
257
272
|
versions: [version],
|
|
258
273
|
objects: [
|
|
259
274
|
{ path: '$', requiredKeys: DOMAIN_CONTROL_FLIGHT_RECORDER_ROOT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
|
|
260
|
-
{ path: '$.events[]', requiredKeys: version ===
|
|
261
|
-
{ path: '$.events[].approvedWindow', requiredKeys: DOMAIN_CONTROL_FLIGHT_RECORDER_APPROVED_WINDOW_KEYS, optionalKeys: [], unknownKeys: 'reject' },
|
|
275
|
+
{ path: '$.events[]', requiredKeys: version === 1 ? PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_EVENT_KEYS : version === 2 ? SOURCE_TIMED_FLIGHT_RECORDER_EVENT_KEYS : DOMAIN_CONTROL_FLIGHT_RECORDER_EVENT_KEYS, optionalKeys: [], unknownKeys: 'reject' },
|
|
276
|
+
{ path: '$.events[].approvedWindow', requiredKeys: version >= 3 ? DOMAIN_CONTROL_FLIGHT_RECORDER_APPROVED_WINDOW_KEYS : HISTORICAL_FLIGHT_RECORDER_APPROVED_WINDOW_KEYS, optionalKeys: [], unknownKeys: 'reject' },
|
|
277
|
+
...(version >= 3 ? [{ path: '$.events[].changeInterval', requiredKeys: FLIGHT_RECORDER_CHANGE_INTERVAL_KEYS, optionalKeys: [], unknownKeys: 'reject' }] : []),
|
|
262
278
|
{ path: '$.summary', requiredKeys: version === PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_VERSION ? PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_SUMMARY_KEYS : DOMAIN_CONTROL_FLIGHT_RECORDER_SUMMARY_KEYS, optionalKeys: [], unknownKeys: 'reject' },
|
|
263
279
|
],
|
|
264
|
-
fixedArrays: [{ path: '$.limitations', values: version ===
|
|
280
|
+
fixedArrays: [{ path: '$.limitations', values: version === 1 ? PUBLIC_DOMAIN_CONTROL_FLIGHT_RECORDER_LIMITATIONS : version === 2 ? SOURCE_TIMED_FLIGHT_RECORDER_LIMITATIONS : DOMAIN_CONTROL_FLIGHT_RECORDER_LIMITATIONS }],
|
|
265
281
|
normalisation: 'preserve_document',
|
|
266
282
|
target: null,
|
|
267
283
|
},
|
|
@@ -410,7 +410,7 @@ export const DOMAIN_CONTROL_SCHEMA_LIFECYCLE = defineSchemaLifecycleFamily({
|
|
|
410
410
|
bounds: [
|
|
411
411
|
{ id: 'exported-entries', path: '$.selectedDomains', phase: 'action', unit: 'entries', minimum: 1, maximum: MAX_DOMAIN_CONTROL_BROWSER_PROFILE_ENTRIES, handling: 'cap_operation' },
|
|
412
412
|
{ id: 'previewed-entries', path: '$.verifiedManifest.entries', phase: 'action', unit: 'entries', minimum: 1, maximum: MAX_DOMAIN_CONTROL_MANIFEST_ENTRIES, handling: 'reject' },
|
|
413
|
-
{ id: 'applied-baselines', path: '$.choices', phase: 'action', unit: 'entries', minimum: 0, maximum: MAX_DOMAIN_CONTROL_BROWSER_PROFILE_ENTRIES, handling: '
|
|
413
|
+
{ id: 'applied-baselines', path: '$.choices', phase: 'action', unit: 'entries', minimum: 0, maximum: MAX_DOMAIN_CONTROL_BROWSER_PROFILE_ENTRIES, handling: 'reject' },
|
|
414
414
|
],
|
|
415
415
|
},
|
|
416
416
|
{
|