@fabricorg/platform 1.10.0 → 1.10.2
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/CHANGELOG.md +54 -0
- package/README.md +32 -3
- package/dist/actions/index.cjs +45 -26
- package/dist/actions/index.cjs.map +1 -1
- package/dist/actions/index.d.cts +225 -226
- package/dist/actions/index.d.ts +225 -226
- package/dist/actions/index.js +41 -2
- package/dist/actions/index.js.map +1 -1
- package/dist/adapters/index.cjs +696 -66
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +367 -365
- package/dist/adapters/index.d.ts +367 -365
- package/dist/adapters/index.js +682 -2
- package/dist/adapters/index.js.map +1 -1
- package/dist/agent-hitl/index.cjs +21 -10
- package/dist/agent-hitl/index.cjs.map +1 -1
- package/dist/agent-hitl/index.d.cts +30 -30
- package/dist/agent-hitl/index.d.ts +30 -30
- package/dist/agent-hitl/index.js +21 -2
- package/dist/agent-hitl/index.js.map +1 -1
- package/dist/certification/index.cjs +109 -24
- package/dist/certification/index.cjs.map +1 -1
- package/dist/certification/index.d.cts +33 -39
- package/dist/certification/index.d.ts +33 -39
- package/dist/certification/index.js +107 -8
- package/dist/certification/index.js.map +1 -1
- package/dist/discovery/index.cjs +12 -10
- package/dist/discovery/index.cjs.map +1 -1
- package/dist/discovery/index.d.cts +2 -10
- package/dist/discovery/index.d.ts +2 -10
- package/dist/discovery/index.js +12 -2
- package/dist/discovery/index.js.map +1 -1
- package/dist/engine-B4csEOEc.js +223 -0
- package/dist/engine-B4csEOEc.js.map +1 -0
- package/dist/engine-BqScuhrT.cjs +246 -0
- package/dist/engine-BqScuhrT.cjs.map +1 -0
- package/dist/events/index.cjs +39 -10
- package/dist/events/index.cjs.map +1 -1
- package/dist/events/index.d.cts +43 -43
- package/dist/events/index.d.ts +43 -43
- package/dist/events/index.js +39 -2
- package/dist/events/index.js.map +1 -1
- package/dist/evidence/index.cjs +12 -50
- package/dist/evidence/index.d.cts +2 -229
- package/dist/evidence/index.d.ts +2 -229
- package/dist/evidence/index.js +1 -5
- package/dist/evidence-BuCICb0c.js +516 -0
- package/dist/evidence-BuCICb0c.js.map +1 -0
- package/dist/evidence-Cq48eDvA.cjs +575 -0
- package/dist/evidence-Cq48eDvA.cjs.map +1 -0
- package/dist/governance/index.cjs +24 -18
- package/dist/governance/index.cjs.map +1 -1
- package/dist/governance/index.d.cts +80 -83
- package/dist/governance/index.d.ts +80 -83
- package/dist/governance/index.js +22 -2
- package/dist/governance/index.js.map +1 -1
- package/dist/ids/index.cjs +52 -22
- package/dist/ids/index.cjs.map +1 -1
- package/dist/ids/index.d.cts +17 -17
- package/dist/ids/index.d.ts +17 -17
- package/dist/ids/index.js +49 -2
- package/dist/ids/index.js.map +1 -1
- package/dist/index-9jasmw76.d.cts +124 -0
- package/dist/index-BXpeFdk2.d.cts +190 -0
- package/dist/index-BXpeFdk2.d.ts +190 -0
- package/dist/index-BnbsKZsT.d.cts +231 -0
- package/dist/index-CIl1rYRv.d.cts +11 -0
- package/dist/index-CIl1rYRv.d.ts +11 -0
- package/dist/index-CVHA1ypT.d.cts +262 -0
- package/dist/index-DZ4mnNb7.d.cts +78 -0
- package/dist/index-DZ4mnNb7.d.ts +78 -0
- package/dist/index-IqcDvl69.d.ts +124 -0
- package/dist/index-fmUiRBXu.d.cts +57 -0
- package/dist/index-fmUiRBXu.d.ts +57 -0
- package/dist/index-sPUPs8pr.d.ts +262 -0
- package/dist/index-z9-CYOIo.d.ts +231 -0
- package/dist/index.cjs +111 -393
- package/dist/index.d.cts +18 -17
- package/dist/index.d.ts +18 -17
- package/dist/index.js +19 -20
- package/dist/manifest/index.cjs +224 -35
- package/dist/manifest/index.cjs.map +1 -1
- package/dist/manifest/index.d.cts +130 -131
- package/dist/manifest/index.d.ts +130 -131
- package/dist/manifest/index.js +219 -7
- package/dist/manifest/index.js.map +1 -1
- package/dist/modules/index.cjs +281 -42
- package/dist/modules/index.cjs.map +1 -1
- package/dist/modules/index.d.cts +157 -159
- package/dist/modules/index.d.ts +157 -159
- package/dist/modules/index.js +274 -6
- package/dist/modules/index.js.map +1 -1
- package/dist/objects/index.cjs +355 -22
- package/dist/objects/index.cjs.map +1 -1
- package/dist/objects/index.d.cts +2 -77
- package/dist/objects/index.d.ts +2 -77
- package/dist/objects/index.js +352 -2
- package/dist/objects/index.js.map +1 -1
- package/dist/policies/index.cjs +14 -56
- package/dist/policies/index.d.cts +2 -261
- package/dist/policies/index.d.ts +2 -261
- package/dist/policies/index.js +1 -3
- package/dist/policies-DH_GCXQ-.js +627 -0
- package/dist/policies-DH_GCXQ-.js.map +1 -0
- package/dist/policies-Nxbp1CH8.cjs +698 -0
- package/dist/policies-Nxbp1CH8.cjs.map +1 -0
- package/dist/privacy/index.cjs +26 -43
- package/dist/privacy/index.cjs.map +1 -1
- package/dist/privacy/index.d.cts +2 -189
- package/dist/privacy/index.d.ts +2 -189
- package/dist/privacy/index.js +18 -3
- package/dist/privacy/index.js.map +1 -1
- package/dist/projections/index.cjs +241 -23
- package/dist/projections/index.cjs.map +1 -1
- package/dist/projections/index.d.cts +2 -125
- package/dist/projections/index.d.ts +2 -125
- package/dist/projections/index.js +238 -3
- package/dist/projections/index.js.map +1 -1
- package/dist/state-machines/index.cjs +76 -18
- package/dist/state-machines/index.cjs.map +1 -1
- package/dist/state-machines/index.d.cts +2 -55
- package/dist/state-machines/index.d.ts +2 -55
- package/dist/state-machines/index.js +74 -2
- package/dist/state-machines/index.js.map +1 -1
- package/dist/testing/index.cjs +27 -19
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +17 -19
- package/dist/testing/index.d.ts +17 -19
- package/dist/testing/index.js +25 -3
- package/dist/testing/index.js.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-2AE6TMAX.cjs +0 -44
- package/dist/chunk-2AE6TMAX.cjs.map +0 -1
- package/dist/chunk-6HY35TKB.cjs +0 -491
- package/dist/chunk-6HY35TKB.cjs.map +0 -1
- package/dist/chunk-6UGEIDLC.cjs +0 -26
- package/dist/chunk-6UGEIDLC.cjs.map +0 -1
- package/dist/chunk-7GAWSUOG.js +0 -64
- package/dist/chunk-7GAWSUOG.js.map +0 -1
- package/dist/chunk-A42JJIPL.cjs +0 -699
- package/dist/chunk-A42JJIPL.cjs.map +0 -1
- package/dist/chunk-AFXKSIVI.cjs +0 -540
- package/dist/chunk-AFXKSIVI.cjs.map +0 -1
- package/dist/chunk-B5DOGDPG.js +0 -42
- package/dist/chunk-B5DOGDPG.js.map +0 -1
- package/dist/chunk-BJGZE3GE.js +0 -20
- package/dist/chunk-BJGZE3GE.js.map +0 -1
- package/dist/chunk-CRZXTZ36.cjs +0 -258
- package/dist/chunk-CRZXTZ36.cjs.map +0 -1
- package/dist/chunk-D4SWRBUH.cjs +0 -22
- package/dist/chunk-D4SWRBUH.cjs.map +0 -1
- package/dist/chunk-DBTAUI6C.cjs +0 -395
- package/dist/chunk-DBTAUI6C.cjs.map +0 -1
- package/dist/chunk-EMSAFNPX.js +0 -98
- package/dist/chunk-EMSAFNPX.js.map +0 -1
- package/dist/chunk-F3E5SXPN.cjs +0 -28
- package/dist/chunk-F3E5SXPN.cjs.map +0 -1
- package/dist/chunk-HEYMMVDP.js +0 -480
- package/dist/chunk-HEYMMVDP.js.map +0 -1
- package/dist/chunk-IFW43ELT.cjs +0 -331
- package/dist/chunk-IFW43ELT.cjs.map +0 -1
- package/dist/chunk-LFE74IJX.js +0 -20
- package/dist/chunk-LFE74IJX.js.map +0 -1
- package/dist/chunk-LZSE6QGQ.cjs +0 -60
- package/dist/chunk-LZSE6QGQ.cjs.map +0 -1
- package/dist/chunk-MCWSUGB3.cjs +0 -102
- package/dist/chunk-MCWSUGB3.cjs.map +0 -1
- package/dist/chunk-MLBALEUR.js +0 -290
- package/dist/chunk-MLBALEUR.js.map +0 -1
- package/dist/chunk-NNXQZPB3.cjs +0 -31
- package/dist/chunk-NNXQZPB3.cjs.map +0 -1
- package/dist/chunk-OFCCZ27Z.js +0 -26
- package/dist/chunk-OFCCZ27Z.js.map +0 -1
- package/dist/chunk-PDN5DOLQ.js +0 -242
- package/dist/chunk-PDN5DOLQ.js.map +0 -1
- package/dist/chunk-PIDZQAEL.js +0 -50
- package/dist/chunk-PIDZQAEL.js.map +0 -1
- package/dist/chunk-PXD7NG6X.js +0 -686
- package/dist/chunk-PXD7NG6X.js.map +0 -1
- package/dist/chunk-Q4Q4JPR3.js +0 -524
- package/dist/chunk-Q4Q4JPR3.js.map +0 -1
- package/dist/chunk-RALMUSOX.js +0 -55
- package/dist/chunk-RALMUSOX.js.map +0 -1
- package/dist/chunk-SNTV45LH.cjs +0 -295
- package/dist/chunk-SNTV45LH.cjs.map +0 -1
- package/dist/chunk-TBS2S5AX.cjs +0 -40
- package/dist/chunk-TBS2S5AX.cjs.map +0 -1
- package/dist/chunk-TYNIFC7J.js +0 -253
- package/dist/chunk-TYNIFC7J.js.map +0 -1
- package/dist/chunk-UGWGHTNC.cjs +0 -56
- package/dist/chunk-UGWGHTNC.cjs.map +0 -1
- package/dist/chunk-WI7CWNYI.cjs +0 -68
- package/dist/chunk-WI7CWNYI.cjs.map +0 -1
- package/dist/chunk-WNZP53GI.js +0 -386
- package/dist/chunk-WNZP53GI.js.map +0 -1
- package/dist/chunk-WQ3BYI7T.cjs +0 -249
- package/dist/chunk-WQ3BYI7T.cjs.map +0 -1
- package/dist/chunk-Y2PJLRIY.js +0 -36
- package/dist/chunk-Y2PJLRIY.js.map +0 -1
- package/dist/chunk-ZAEVQSB5.js +0 -326
- package/dist/chunk-ZAEVQSB5.js.map +0 -1
- package/dist/chunk-ZMQTV5OJ.js +0 -27
- package/dist/chunk-ZMQTV5OJ.js.map +0 -1
- package/dist/evidence/index.cjs.map +0 -1
- package/dist/evidence/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/policies/index.cjs.map +0 -1
- package/dist/policies/index.js.map +0 -1
|
@@ -1,43 +1,37 @@
|
|
|
1
|
-
import { ActionCompletionMode } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
type ExecutionContractFindingCode = "missing_execution_contract" | "invalid_execution_dimension" | "missing_sensitivity" | "missing_completion_deadline" | "unexpected_completion_deadline";
|
|
11
|
-
interface ExecutionContractFinding {
|
|
12
|
-
code: ExecutionContractFindingCode;
|
|
13
|
-
actionId: string;
|
|
14
|
-
message: string;
|
|
1
|
+
import { ActionCompletionMode } from "../actions/index.js";
|
|
2
|
+
import { FabricModule } from "../modules/index.js";
|
|
3
|
+
import { ModuleManifest } from "../manifest/index.js";
|
|
4
|
+
//#region certification/index.d.ts
|
|
5
|
+
export type ExecutionContractFindingCode = "missing_execution_contract" | "invalid_execution_dimension" | "missing_sensitivity" | "missing_completion_deadline" | "unexpected_completion_deadline";
|
|
6
|
+
export interface ExecutionContractFinding {
|
|
7
|
+
code: ExecutionContractFindingCode;
|
|
8
|
+
actionId: string;
|
|
9
|
+
message: string;
|
|
15
10
|
}
|
|
16
|
-
interface ExecutionContractProfileOptions {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
export interface ExecutionContractProfileOptions {
|
|
12
|
+
/** Adapter and profile id. Defaults to the strict profile's id. */
|
|
13
|
+
id?: string;
|
|
14
|
+
/** Require `sensitivity`, which the base contract leaves optional. Defaults to true. */
|
|
15
|
+
requireSensitivity?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Completion modes that must declare `completionDeadlineMs`. Defaults to
|
|
18
|
+
* both modes that hand work off, since without a deadline nothing sweeps a
|
|
19
|
+
* callback that never comes.
|
|
20
|
+
*/
|
|
21
|
+
requireDeadlineFor?: readonly ActionCompletionMode[];
|
|
27
22
|
}
|
|
28
|
-
interface ExecutionContractProfile {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
23
|
+
export interface ExecutionContractProfile {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
validate(manifest: ModuleManifest): ExecutionContractFinding[];
|
|
26
|
+
assert(subject: FabricModule<unknown> | ModuleManifest): void;
|
|
27
|
+
/** For certification tooling: the compiler's conformance adapter shape. */
|
|
28
|
+
readonly adapter: {
|
|
29
|
+
id: string;
|
|
30
|
+
evaluate(manifest: ModuleManifest): ExecutionContractFinding[];
|
|
31
|
+
};
|
|
37
32
|
}
|
|
38
|
-
declare const STRICT_EXECUTION_CONTRACT_PROFILE_ID = "fabric.execution-contract.strict";
|
|
39
|
-
declare function executionContractProfile(options?: ExecutionContractProfileOptions): ExecutionContractProfile;
|
|
33
|
+
export declare const STRICT_EXECUTION_CONTRACT_PROFILE_ID = "fabric.execution-contract.strict";
|
|
34
|
+
export declare function executionContractProfile(options?: ExecutionContractProfileOptions): ExecutionContractProfile;
|
|
40
35
|
/** All six dimensions on every action, and a deadline wherever work is handed off. */
|
|
41
|
-
declare const STRICT_EXECUTION_CONTRACT_PROFILE: ExecutionContractProfile;
|
|
42
|
-
|
|
43
|
-
export { type ExecutionContractFinding, type ExecutionContractFindingCode, type ExecutionContractProfile, type ExecutionContractProfileOptions, STRICT_EXECUTION_CONTRACT_PROFILE, STRICT_EXECUTION_CONTRACT_PROFILE_ID, executionContractProfile };
|
|
36
|
+
export declare const STRICT_EXECUTION_CONTRACT_PROFILE: ExecutionContractProfile;
|
|
37
|
+
//#endregion
|
|
@@ -1,9 +1,108 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { exportModuleManifest } from "../manifest/index.js";
|
|
2
|
+
//#region certification/index.ts
|
|
3
|
+
const STRICT_EXECUTION_CONTRACT_PROFILE_ID = "fabric.execution-contract.strict";
|
|
4
|
+
/** The permitted values of each required dimension, mirrored from the action types. */
|
|
5
|
+
function permittedDimensions() {
|
|
6
|
+
return [
|
|
7
|
+
["connectivity", /* @__PURE__ */ new Set(["online-required", "offline-capturable"])],
|
|
8
|
+
["authorityMoment", /* @__PURE__ */ new Set([
|
|
9
|
+
"capture",
|
|
10
|
+
"execution",
|
|
11
|
+
"both"
|
|
12
|
+
])],
|
|
13
|
+
["idempotency", /* @__PURE__ */ new Set([
|
|
14
|
+
"required",
|
|
15
|
+
"supported",
|
|
16
|
+
"prohibited"
|
|
17
|
+
])],
|
|
18
|
+
["completion", /* @__PURE__ */ new Set([
|
|
19
|
+
"immediate",
|
|
20
|
+
"accepted",
|
|
21
|
+
"long-running"
|
|
22
|
+
])],
|
|
23
|
+
["consistency", /* @__PURE__ */ new Set(["authoritative-now", "provisional-until-reconciled"])]
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
const permittedSensitivities = () => /* @__PURE__ */ new Set([
|
|
27
|
+
"public",
|
|
28
|
+
"internal",
|
|
29
|
+
"confidential",
|
|
30
|
+
"restricted"
|
|
31
|
+
]);
|
|
32
|
+
function executionContractProfile(options = {}) {
|
|
33
|
+
const id = options.id ?? "fabric.execution-contract.strict";
|
|
34
|
+
const requireSensitivity = options.requireSensitivity ?? true;
|
|
35
|
+
const requireDeadlineFor = new Set(options.requireDeadlineFor ?? ["accepted", "long-running"]);
|
|
36
|
+
const dimensions = permittedDimensions();
|
|
37
|
+
const sensitivities = permittedSensitivities();
|
|
38
|
+
const validate = (manifest) => {
|
|
39
|
+
const findings = [];
|
|
40
|
+
for (const action of manifest.actions) {
|
|
41
|
+
const contract = action.execution;
|
|
42
|
+
if (!contract) {
|
|
43
|
+
findings.push({
|
|
44
|
+
code: "missing_execution_contract",
|
|
45
|
+
actionId: action.actionId,
|
|
46
|
+
message: `Action "${action.actionId}" declares no execution contract; connectivity, authorityMoment, idempotency, completion, and consistency are required.`
|
|
47
|
+
});
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
let complete = true;
|
|
51
|
+
for (const [dimension, permitted] of dimensions) {
|
|
52
|
+
const value = contract[dimension];
|
|
53
|
+
if (!permitted.has(value)) {
|
|
54
|
+
complete = false;
|
|
55
|
+
findings.push({
|
|
56
|
+
code: "invalid_execution_dimension",
|
|
57
|
+
actionId: action.actionId,
|
|
58
|
+
message: `Action "${action.actionId}" ${value === void 0 ? "declares no" : `declares an unknown`} ${dimension}${value === void 0 ? "" : ` "${String(value)}"`}; permitted values are ${[...permitted].map((item) => `"${String(item)}"`).join(", ")}.`
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (contract.sensitivity !== void 0 && !sensitivities.has(contract.sensitivity)) findings.push({
|
|
63
|
+
code: "invalid_execution_dimension",
|
|
64
|
+
actionId: action.actionId,
|
|
65
|
+
message: `Action "${action.actionId}" declares an unknown sensitivity "${String(contract.sensitivity)}"; permitted values are ${[...sensitivities].map((item) => `"${item}"`).join(", ")}.`
|
|
66
|
+
});
|
|
67
|
+
if (!complete) continue;
|
|
68
|
+
if (contract.completion === "immediate" && contract.completionDeadlineMs !== void 0) findings.push({
|
|
69
|
+
code: "unexpected_completion_deadline",
|
|
70
|
+
actionId: action.actionId,
|
|
71
|
+
message: `Action "${action.actionId}" declares immediate completion and a completionDeadlineMs; nothing external completes it.`
|
|
72
|
+
});
|
|
73
|
+
if (requireSensitivity && contract.sensitivity === void 0) findings.push({
|
|
74
|
+
code: "missing_sensitivity",
|
|
75
|
+
actionId: action.actionId,
|
|
76
|
+
message: `Action "${action.actionId}" declares no sensitivity; say whether its durable data is public, internal, confidential, or restricted.`
|
|
77
|
+
});
|
|
78
|
+
if (requireDeadlineFor.has(contract.completion) && !(typeof contract.completionDeadlineMs === "number" && contract.completionDeadlineMs > 0)) findings.push({
|
|
79
|
+
code: "missing_completion_deadline",
|
|
80
|
+
actionId: action.actionId,
|
|
81
|
+
message: `Action "${action.actionId}" declares ${contract.completion} completion and no completionDeadlineMs; a callback that never comes would never be noticed.`
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return findings;
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
id,
|
|
88
|
+
validate,
|
|
89
|
+
assert(subject) {
|
|
90
|
+
const manifest = isManifest(subject) ? subject : exportModuleManifest(subject);
|
|
91
|
+
const findings = validate(manifest);
|
|
92
|
+
if (findings.length > 0) throw new Error(`Execution-contract profile "${id}" failed for "${manifest.namespace}":\n${findings.map((finding) => `- ${finding.message}`).join("\n")}`);
|
|
93
|
+
},
|
|
94
|
+
adapter: {
|
|
95
|
+
id,
|
|
96
|
+
evaluate: validate
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** All six dimensions on every action, and a deadline wherever work is handed off. */
|
|
101
|
+
const STRICT_EXECUTION_CONTRACT_PROFILE = executionContractProfile();
|
|
102
|
+
function isManifest(subject) {
|
|
103
|
+
return typeof subject.manifestVersion === "number" && Array.isArray(subject.actions);
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { STRICT_EXECUTION_CONTRACT_PROFILE, STRICT_EXECUTION_CONTRACT_PROFILE_ID, executionContractProfile };
|
|
107
|
+
|
|
9
108
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../certification/index.ts"],"sourcesContent":["import type { ActionCompletionMode } from \"../actions\";\nimport { exportModuleManifest, type ModuleManifest } from \"../manifest\";\nimport type { FabricModule } from \"../modules\";\n\n// ── Execution-contract certification ────────────────────────────────────────\n//\n// The base types keep the execution contract optional, because making it\n// mandatory is a break for every existing manifest. A deployment that wants\n// the guarantee applies a profile at certification instead: every governed\n// action declares all six dimensions, and any action that hands work to an\n// external system says how long it may wait. The profile is a seam a\n// vertical applies, not content the platform assumes.\n\nexport type ExecutionContractFindingCode =\n\t| \"missing_execution_contract\"\n\t| \"invalid_execution_dimension\"\n\t| \"missing_sensitivity\"\n\t| \"missing_completion_deadline\"\n\t| \"unexpected_completion_deadline\";\n\nexport interface ExecutionContractFinding {\n\tcode: ExecutionContractFindingCode;\n\tactionId: string;\n\tmessage: string;\n}\n\nexport interface ExecutionContractProfileOptions {\n\t/** Adapter and profile id. Defaults to the strict profile's id. */\n\tid?: string;\n\t/** Require `sensitivity`, which the base contract leaves optional. Defaults to true. */\n\trequireSensitivity?: boolean;\n\t/**\n\t * Completion modes that must declare `completionDeadlineMs`. Defaults to\n\t * both modes that hand work off, since without a deadline nothing sweeps a\n\t * callback that never comes.\n\t */\n\trequireDeadlineFor?: readonly ActionCompletionMode[];\n}\n\nexport interface ExecutionContractProfile {\n\treadonly id: string;\n\tvalidate(manifest: ModuleManifest): ExecutionContractFinding[];\n\tassert(subject: FabricModule<unknown> | ModuleManifest): void;\n\t/** For certification tooling: the compiler's conformance adapter shape. */\n\treadonly adapter: { id: string; evaluate(manifest: ModuleManifest): ExecutionContractFinding[] };\n}\n\nexport const STRICT_EXECUTION_CONTRACT_PROFILE_ID = \"fabric.execution-contract.strict\";\n\n/** The permitted values of each required dimension, mirrored from the action types. */\nfunction permittedDimensions(): ReadonlyArray<[string, ReadonlySet<unknown>]> {\n\treturn [\n\t\t[\"connectivity\", new Set([\"online-required\", \"offline-capturable\"])],\n\t\t[\"authorityMoment\", new Set([\"capture\", \"execution\", \"both\"])],\n\t\t[\"idempotency\", new Set([\"required\", \"supported\", \"prohibited\"])],\n\t\t[\"completion\", new Set([\"immediate\", \"accepted\", \"long-running\"])],\n\t\t[\"consistency\", new Set([\"authoritative-now\", \"provisional-until-reconciled\"])],\n\t];\n}\nconst permittedSensitivities = (): ReadonlySet<string> => new Set([\"public\", \"internal\", \"confidential\", \"restricted\"]);\n\nexport function executionContractProfile(options: ExecutionContractProfileOptions = {}): ExecutionContractProfile {\n\tconst id = options.id ?? STRICT_EXECUTION_CONTRACT_PROFILE_ID;\n\tconst requireSensitivity = options.requireSensitivity ?? true;\n\tconst requireDeadlineFor = new Set<ActionCompletionMode>(options.requireDeadlineFor ?? [\"accepted\", \"long-running\"]);\n\tconst dimensions = permittedDimensions();\n\tconst sensitivities = permittedSensitivities();\n\tconst validate = (manifest: ModuleManifest): ExecutionContractFinding[] => {\n\t\tconst findings: ExecutionContractFinding[] = [];\n\t\tfor (const action of manifest.actions) {\n\t\t\tconst contract = action.execution;\n\t\t\tif (!contract) {\n\t\t\t\tfindings.push({\n\t\t\t\t\tcode: \"missing_execution_contract\",\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tmessage: `Action \"${action.actionId}\" declares no execution contract; connectivity, authorityMoment, idempotency, completion, and consistency are required.`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// The contract's presence proves nothing about its content: a manifest\n\t\t\t// reaches certification without passing through the registry, so each\n\t\t\t// dimension is checked against its permitted values here.\n\t\t\tlet complete = true;\n\t\t\tfor (const [dimension, permitted] of dimensions) {\n\t\t\t\tconst value = (contract as unknown as Record<string, unknown>)[dimension];\n\t\t\t\tif (!permitted.has(value)) {\n\t\t\t\t\tcomplete = false;\n\t\t\t\t\tfindings.push({\n\t\t\t\t\t\tcode: \"invalid_execution_dimension\",\n\t\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\t\tmessage: `Action \"${action.actionId}\" ${value === undefined ? \"declares no\" : `declares an unknown`} ${dimension}${value === undefined ? \"\" : ` \"${String(value)}\"`}; permitted values are ${[...permitted].map((item) => `\"${String(item)}\"`).join(\", \")}.`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (contract.sensitivity !== undefined && !sensitivities.has(contract.sensitivity)) {\n\t\t\t\tfindings.push({\n\t\t\t\t\tcode: \"invalid_execution_dimension\",\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tmessage: `Action \"${action.actionId}\" declares an unknown sensitivity \"${String(contract.sensitivity)}\"; permitted values are ${[...sensitivities].map((item) => `\"${item}\"`).join(\", \")}.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (!complete) continue;\n\t\t\tif (contract.completion === \"immediate\" && contract.completionDeadlineMs !== undefined) {\n\t\t\t\tfindings.push({\n\t\t\t\t\tcode: \"unexpected_completion_deadline\",\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tmessage: `Action \"${action.actionId}\" declares immediate completion and a completionDeadlineMs; nothing external completes it.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (requireSensitivity && contract.sensitivity === undefined) {\n\t\t\t\tfindings.push({\n\t\t\t\t\tcode: \"missing_sensitivity\",\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tmessage: `Action \"${action.actionId}\" declares no sensitivity; say whether its durable data is public, internal, confidential, or restricted.`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (requireDeadlineFor.has(contract.completion) && !(typeof contract.completionDeadlineMs === \"number\" && contract.completionDeadlineMs > 0)) {\n\t\t\t\tfindings.push({\n\t\t\t\t\tcode: \"missing_completion_deadline\",\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\tmessage: `Action \"${action.actionId}\" declares ${contract.completion} completion and no completionDeadlineMs; a callback that never comes would never be noticed.`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn findings;\n\t};\n\treturn {\n\t\tid,\n\t\tvalidate,\n\t\tassert(subject) {\n\t\t\tconst manifest = isManifest(subject) ? subject : exportModuleManifest(subject);\n\t\t\tconst findings = validate(manifest);\n\t\t\tif (findings.length > 0) {\n\t\t\t\tthrow new Error(`Execution-contract profile \"${id}\" failed for \"${manifest.namespace}\":\\n${findings.map((finding) => `- ${finding.message}`).join(\"\\n\")}`);\n\t\t\t}\n\t\t},\n\t\tadapter: { id, evaluate: validate },\n\t};\n}\n\n/** All six dimensions on every action, and a deadline wherever work is handed off. */\nexport const STRICT_EXECUTION_CONTRACT_PROFILE: ExecutionContractProfile = executionContractProfile();\n\nfunction isManifest(subject: FabricModule<unknown> | ModuleManifest): subject is ModuleManifest {\n\treturn typeof (subject as ModuleManifest).manifestVersion === \"number\" && Array.isArray((subject as ModuleManifest).actions);\n}\n"],"mappings":";;AA+CA,MAAa,uCAAuC;;AAGpD,SAAS,sBAAqE;CAC7E,OAAO;EACN,CAAC,gCAAgB,IAAI,IAAI,CAAC,mBAAmB,oBAAoB,CAAC,CAAC;EACnE,CAAC,mCAAmB,IAAI,IAAI;GAAC;GAAW;GAAa;EAAM,CAAC,CAAC;EAC7D,CAAC,+BAAe,IAAI,IAAI;GAAC;GAAY;GAAa;EAAY,CAAC,CAAC;EAChE,CAAC,8BAAc,IAAI,IAAI;GAAC;GAAa;GAAY;EAAc,CAAC,CAAC;EACjE,CAAC,+BAAe,IAAI,IAAI,CAAC,qBAAqB,8BAA8B,CAAC,CAAC;CAC/E;AACD;AACA,MAAM,+CAAoD,IAAI,IAAI;CAAC;CAAU;CAAY;CAAgB;AAAY,CAAC;AAEtH,SAAgB,yBAAyB,UAA2C,CAAC,GAA6B;CACjH,MAAM,KAAK,QAAQ,MAAA;CACnB,MAAM,qBAAqB,QAAQ,sBAAsB;CACzD,MAAM,qBAAqB,IAAI,IAA0B,QAAQ,sBAAsB,CAAC,YAAY,cAAc,CAAC;CACnH,MAAM,aAAa,oBAAoB;CACvC,MAAM,gBAAgB,uBAAuB;CAC7C,MAAM,YAAY,aAAyD;EAC1E,MAAM,WAAuC,CAAC;EAC9C,KAAK,MAAM,UAAU,SAAS,SAAS;GACtC,MAAM,WAAW,OAAO;GACxB,IAAI,CAAC,UAAU;IACd,SAAS,KAAK;KACb,MAAM;KACN,UAAU,OAAO;KACjB,SAAS,WAAW,OAAO,SAAS;IACrC,CAAC;IACD;GACD;GAIA,IAAI,WAAW;GACf,KAAK,MAAM,CAAC,WAAW,cAAc,YAAY;IAChD,MAAM,QAAS,SAAgD;IAC/D,IAAI,CAAC,UAAU,IAAI,KAAK,GAAG;KAC1B,WAAW;KACX,SAAS,KAAK;MACb,MAAM;MACN,UAAU,OAAO;MACjB,SAAS,WAAW,OAAO,SAAS,IAAI,UAAU,KAAA,IAAY,gBAAgB,sBAAsB,GAAG,YAAY,UAAU,KAAA,IAAY,KAAK,KAAK,OAAO,KAAK,EAAE,GAAG,yBAAyB,CAAC,GAAG,SAAS,CAAC,CAAC,KAAK,SAAS,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;KAC3P,CAAC;IACF;GACD;GACA,IAAI,SAAS,gBAAgB,KAAA,KAAa,CAAC,cAAc,IAAI,SAAS,WAAW,GAChF,SAAS,KAAK;IACb,MAAM;IACN,UAAU,OAAO;IACjB,SAAS,WAAW,OAAO,SAAS,qCAAqC,OAAO,SAAS,WAAW,EAAE,0BAA0B,CAAC,GAAG,aAAa,CAAC,CAAC,KAAK,SAAS,IAAI,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;GAC1L,CAAC;GAEF,IAAI,CAAC,UAAU;GACf,IAAI,SAAS,eAAe,eAAe,SAAS,yBAAyB,KAAA,GAC5E,SAAS,KAAK;IACb,MAAM;IACN,UAAU,OAAO;IACjB,SAAS,WAAW,OAAO,SAAS;GACrC,CAAC;GAEF,IAAI,sBAAsB,SAAS,gBAAgB,KAAA,GAClD,SAAS,KAAK;IACb,MAAM;IACN,UAAU,OAAO;IACjB,SAAS,WAAW,OAAO,SAAS;GACrC,CAAC;GAEF,IAAI,mBAAmB,IAAI,SAAS,UAAU,KAAK,EAAE,OAAO,SAAS,yBAAyB,YAAY,SAAS,uBAAuB,IACzI,SAAS,KAAK;IACb,MAAM;IACN,UAAU,OAAO;IACjB,SAAS,WAAW,OAAO,SAAS,aAAa,SAAS,WAAW;GACtE,CAAC;EAEH;EACA,OAAO;CACR;CACA,OAAO;EACN;EACA;EACA,OAAO,SAAS;GACf,MAAM,WAAW,WAAW,OAAO,IAAI,UAAU,qBAAqB,OAAO;GAC7E,MAAM,WAAW,SAAS,QAAQ;GAClC,IAAI,SAAS,SAAS,GACrB,MAAM,IAAI,MAAM,+BAA+B,GAAG,gBAAgB,SAAS,UAAU,MAAM,SAAS,KAAK,YAAY,KAAK,QAAQ,SAAS,CAAC,CAAC,KAAK,IAAI,GAAG;EAE3J;EACA,SAAS;GAAE;GAAI,UAAU;EAAS;CACnC;AACD;;AAGA,MAAa,oCAA8D,yBAAyB;AAEpG,SAAS,WAAW,SAA4E;CAC/F,OAAO,OAAQ,QAA2B,oBAAoB,YAAY,MAAM,QAAS,QAA2B,OAAO;AAC5H"}
|
package/dist/discovery/index.cjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region discovery/index.ts
|
|
3
|
+
function assertSurfaceDeclaration(value, label = "Contract") {
|
|
4
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${label}: discovery surface declaration must be an object`);
|
|
5
|
+
const { surface, surfaceReason } = value;
|
|
6
|
+
if (surface !== void 0 && surface !== "public" && surface !== "internal") throw new Error(`${label}: Unknown discovery surface`);
|
|
7
|
+
if (surface === "internal") {
|
|
8
|
+
if (typeof surfaceReason !== "string" || !surfaceReason.trim()) throw new Error(`${label}: Internal discovery surface requires a reason`);
|
|
9
|
+
} else if (surfaceReason !== void 0) throw new Error(`${label}: Discovery surface reason requires an internal surface`);
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
exports.assertSurfaceDeclaration = assertSurfaceDeclaration;
|
|
2
13
|
|
|
3
|
-
var chunkD4SWRBUH_cjs = require('../chunk-D4SWRBUH.cjs');
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Object.defineProperty(exports, "assertSurfaceDeclaration", {
|
|
8
|
-
enumerable: true,
|
|
9
|
-
get: function () { return chunkD4SWRBUH_cjs.assertSurfaceDeclaration; }
|
|
10
|
-
});
|
|
11
|
-
//# sourceMappingURL=index.cjs.map
|
|
12
14
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../discovery/index.ts"],"sourcesContent":["/** Portable discovery metadata. It never grants or denies runtime invocation authority. */\nexport interface SurfaceDeclaration {\n\t/** Omitted is public discovery; internal contracts are withheld from external catalogs. */\n\tsurface?: \"public\" | \"internal\";\n\t/** Required, non-blank explanation when surface is internal; never include sensitive data. */\n\tsurfaceReason?: string;\n}\n\nexport function assertSurfaceDeclaration(value: unknown, label = \"Contract\"): asserts value is SurfaceDeclaration {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value))\n\t\tthrow new Error(`${label}: discovery surface declaration must be an object`);\n\tconst { surface, surfaceReason } = value as SurfaceDeclaration;\n\tif (surface !== undefined && surface !== \"public\" && surface !== \"internal\") {\n\t\tthrow new Error(`${label}: Unknown discovery surface`);\n\t}\n\tif (surface === \"internal\") {\n\t\tif (typeof surfaceReason !== \"string\" || !surfaceReason.trim()) {\n\t\t\tthrow new Error(`${label}: Internal discovery surface requires a reason`);\n\t\t}\n\t} else if (surfaceReason !== undefined) {\n\t\tthrow new Error(`${label}: Discovery surface reason requires an internal surface`);\n\t}\n}\n"],"mappings":";;AAQA,SAAgB,yBAAyB,OAAgB,QAAQ,YAAiD;CACjH,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC7D,MAAM,IAAI,MAAM,GAAG,MAAM,kDAAkD;CAC5E,MAAM,EAAE,SAAS,kBAAkB;CACnC,IAAI,YAAY,KAAA,KAAa,YAAY,YAAY,YAAY,YAChE,MAAM,IAAI,MAAM,GAAG,MAAM,4BAA4B;CAEtD,IAAI,YAAY,YACX;MAAA,OAAO,kBAAkB,YAAY,CAAC,cAAc,KAAK,GAC5D,MAAM,IAAI,MAAM,GAAG,MAAM,+CAA+C;CAAA,OAEnE,IAAI,kBAAkB,KAAA,GAC5B,MAAM,IAAI,MAAM,GAAG,MAAM,wDAAwD;AAEnF"}
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** Omitted is public discovery; internal contracts are withheld from external catalogs. */
|
|
4
|
-
surface?: "public" | "internal";
|
|
5
|
-
/** Required, non-blank explanation when surface is internal; never include sensitive data. */
|
|
6
|
-
surfaceReason?: string;
|
|
7
|
-
}
|
|
8
|
-
declare function assertSurfaceDeclaration(value: unknown, label?: string): asserts value is SurfaceDeclaration;
|
|
9
|
-
|
|
10
|
-
export { type SurfaceDeclaration, assertSurfaceDeclaration };
|
|
1
|
+
import { n as assertSurfaceDeclaration, t as SurfaceDeclaration } from "../index-CIl1rYRv.cjs";
|
|
2
|
+
export { SurfaceDeclaration, assertSurfaceDeclaration };
|
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** Omitted is public discovery; internal contracts are withheld from external catalogs. */
|
|
4
|
-
surface?: "public" | "internal";
|
|
5
|
-
/** Required, non-blank explanation when surface is internal; never include sensitive data. */
|
|
6
|
-
surfaceReason?: string;
|
|
7
|
-
}
|
|
8
|
-
declare function assertSurfaceDeclaration(value: unknown, label?: string): asserts value is SurfaceDeclaration;
|
|
9
|
-
|
|
10
|
-
export { type SurfaceDeclaration, assertSurfaceDeclaration };
|
|
1
|
+
import { n as assertSurfaceDeclaration, t as SurfaceDeclaration } from "../index-CIl1rYRv.js";
|
|
2
|
+
export { SurfaceDeclaration, assertSurfaceDeclaration };
|
package/dist/discovery/index.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region discovery/index.ts
|
|
2
|
+
function assertSurfaceDeclaration(value, label = "Contract") {
|
|
3
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${label}: discovery surface declaration must be an object`);
|
|
4
|
+
const { surface, surfaceReason } = value;
|
|
5
|
+
if (surface !== void 0 && surface !== "public" && surface !== "internal") throw new Error(`${label}: Unknown discovery surface`);
|
|
6
|
+
if (surface === "internal") {
|
|
7
|
+
if (typeof surfaceReason !== "string" || !surfaceReason.trim()) throw new Error(`${label}: Internal discovery surface requires a reason`);
|
|
8
|
+
} else if (surfaceReason !== void 0) throw new Error(`${label}: Discovery surface reason requires an internal surface`);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { assertSurfaceDeclaration };
|
|
12
|
+
|
|
3
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../discovery/index.ts"],"sourcesContent":["/** Portable discovery metadata. It never grants or denies runtime invocation authority. */\nexport interface SurfaceDeclaration {\n\t/** Omitted is public discovery; internal contracts are withheld from external catalogs. */\n\tsurface?: \"public\" | \"internal\";\n\t/** Required, non-blank explanation when surface is internal; never include sensitive data. */\n\tsurfaceReason?: string;\n}\n\nexport function assertSurfaceDeclaration(value: unknown, label = \"Contract\"): asserts value is SurfaceDeclaration {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value))\n\t\tthrow new Error(`${label}: discovery surface declaration must be an object`);\n\tconst { surface, surfaceReason } = value as SurfaceDeclaration;\n\tif (surface !== undefined && surface !== \"public\" && surface !== \"internal\") {\n\t\tthrow new Error(`${label}: Unknown discovery surface`);\n\t}\n\tif (surface === \"internal\") {\n\t\tif (typeof surfaceReason !== \"string\" || !surfaceReason.trim()) {\n\t\t\tthrow new Error(`${label}: Internal discovery surface requires a reason`);\n\t\t}\n\t} else if (surfaceReason !== undefined) {\n\t\tthrow new Error(`${label}: Discovery surface reason requires an internal surface`);\n\t}\n}\n"],"mappings":";AAQA,SAAgB,yBAAyB,OAAgB,QAAQ,YAAiD;CACjH,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC7D,MAAM,IAAI,MAAM,GAAG,MAAM,kDAAkD;CAC5E,MAAM,EAAE,SAAS,kBAAkB;CACnC,IAAI,YAAY,KAAA,KAAa,YAAY,YAAY,YAAY,YAChE,MAAM,IAAI,MAAM,GAAG,MAAM,4BAA4B;CAEtD,IAAI,YAAY,YACX;MAAA,OAAO,kBAAkB,YAAY,CAAC,cAAc,KAAK,GAC5D,MAAM,IAAI,MAAM,GAAG,MAAM,+CAA+C;CAAA,OAEnE,IAAI,kBAAkB,KAAA,GAC5B,MAAM,IAAI,MAAM,GAAG,MAAM,wDAAwD;AAEnF"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
//#region privacy/engine.ts
|
|
3
|
+
const ANONYMIZATION_POLICY_VERSION = "adr-026-platform-anonymization-v1";
|
|
4
|
+
function normalizeKey(key) {
|
|
5
|
+
return key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
6
|
+
}
|
|
7
|
+
function stableChecksum(value) {
|
|
8
|
+
return createHash("sha256").update(JSON.stringify(value)).digest("hex");
|
|
9
|
+
}
|
|
10
|
+
function stableScopedToken(value, context, fieldPath) {
|
|
11
|
+
const scope = `${context.tenantId}:${context.spaceId ?? "global"}:${fieldPath}`;
|
|
12
|
+
return `tok_${createHash("sha256").update(`${context.policyVersion ?? "adr-026-platform-anonymization-v1"}:${scope}:${String(value)}`).digest("hex").slice(0, 24)}`;
|
|
13
|
+
}
|
|
14
|
+
function maskValue(value) {
|
|
15
|
+
if (value === null || value === void 0) return null;
|
|
16
|
+
const stringValue = String(value);
|
|
17
|
+
if (stringValue.length <= 4) return "****";
|
|
18
|
+
return `${"*".repeat(Math.max(stringValue.length - 4, 4))}${stringValue.slice(-4)}`;
|
|
19
|
+
}
|
|
20
|
+
function generalizeValue(value) {
|
|
21
|
+
if (typeof value === "number") return Math.round(value / 1e3) * 1e3;
|
|
22
|
+
if (typeof value === "string" && /^\d{5}(?:-\d{4})?$/.test(value)) return `${value.slice(0, 3)}**`;
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function applyMethod(value, method, context, path) {
|
|
26
|
+
switch (method) {
|
|
27
|
+
case "drop": return;
|
|
28
|
+
case "nullify": return null;
|
|
29
|
+
case "mask": return maskValue(value);
|
|
30
|
+
case "hash": return `sha256_${stableChecksum(value)}`;
|
|
31
|
+
case "tokenize": return stableScopedToken(value, context, path);
|
|
32
|
+
case "generalize": return generalizeValue(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function policyForPath(policies, path, key) {
|
|
36
|
+
const normalizedPath = normalizeKey(path);
|
|
37
|
+
const normalizedKey = key ? normalizeKey(key) : void 0;
|
|
38
|
+
return policies.find((policy) => {
|
|
39
|
+
const normalizedValue = normalizeKey(policy.value);
|
|
40
|
+
if (policy.match === "key") return normalizedValue === normalizedKey;
|
|
41
|
+
return normalizedValue === normalizedPath;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function isPlainObject(value) {
|
|
45
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
46
|
+
}
|
|
47
|
+
function anonymizeRecursive(value, context, dataClass, path, redactedFields, policies, key) {
|
|
48
|
+
const fieldPolicy = policyForPath(policies, path, key);
|
|
49
|
+
if (fieldPolicy && value !== null && value !== void 0) {
|
|
50
|
+
redactedFields.push({
|
|
51
|
+
fieldPath: path,
|
|
52
|
+
method: fieldPolicy.method,
|
|
53
|
+
policyVersion: context.policyVersion ?? "adr-026-platform-anonymization-v1",
|
|
54
|
+
jobId: context.jobId,
|
|
55
|
+
redactedAt: (context.redactedAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
56
|
+
reason: context.reason,
|
|
57
|
+
dataClass,
|
|
58
|
+
beforeChecksum: stableChecksum(value)
|
|
59
|
+
});
|
|
60
|
+
return applyMethod(value, fieldPolicy.method, context, path);
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(value)) return value.map((item, index) => anonymizeRecursive(item, context, dataClass, `${path}[${index}]`, redactedFields, policies));
|
|
63
|
+
if (!isPlainObject(value)) return value;
|
|
64
|
+
const result = {};
|
|
65
|
+
for (const [childKey, childValue] of Object.entries(value)) {
|
|
66
|
+
if (childKey === "_privacy") {
|
|
67
|
+
result[childKey] = childValue;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const anonymized = anonymizeRecursive(childValue, context, dataClass, `${path}.${childKey}`, redactedFields, policies, childKey);
|
|
71
|
+
if (anonymized !== void 0) result[childKey] = anonymized;
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
function buildMetadata(context, dataClass, redactedFields, preservedSemantics) {
|
|
76
|
+
return {
|
|
77
|
+
redactionState: "anonymized",
|
|
78
|
+
policyVersion: context.policyVersion ?? "adr-026-platform-anonymization-v1",
|
|
79
|
+
jobId: context.jobId,
|
|
80
|
+
redactedAt: (context.redactedAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
81
|
+
reason: context.reason,
|
|
82
|
+
dataClass,
|
|
83
|
+
redactedFields,
|
|
84
|
+
preservedSemantics: [...preservedSemantics]
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
var FieldRedactor = class {
|
|
88
|
+
redactField(value, method, context, path) {
|
|
89
|
+
return applyMethod(value, method, context, path);
|
|
90
|
+
}
|
|
91
|
+
mask(value) {
|
|
92
|
+
return maskValue(value);
|
|
93
|
+
}
|
|
94
|
+
hash(value) {
|
|
95
|
+
return `sha256_${stableChecksum(value)}`;
|
|
96
|
+
}
|
|
97
|
+
tokenize(value, context, path) {
|
|
98
|
+
return stableScopedToken(value, context, path);
|
|
99
|
+
}
|
|
100
|
+
generalize(value) {
|
|
101
|
+
return generalizeValue(value);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var AnonymizationEngine = class {
|
|
105
|
+
#policy;
|
|
106
|
+
constructor(policy) {
|
|
107
|
+
this.#policy = {
|
|
108
|
+
fields: policy.fields.map((field) => ({ ...field })),
|
|
109
|
+
preservedSemantics: [...policy.preservedSemantics ?? []]
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
anonymizeJsonValue(value, context, dataClass) {
|
|
113
|
+
return this.anonymizeJsonValueAtPath(value, context, dataClass, "$");
|
|
114
|
+
}
|
|
115
|
+
anonymizeJsonValueAtPath(value, context, dataClass, basePath) {
|
|
116
|
+
const redactedFields = [];
|
|
117
|
+
return {
|
|
118
|
+
value: anonymizeRecursive(value, context, dataClass, basePath, redactedFields, this.#policy.fields),
|
|
119
|
+
metadata: buildMetadata(context, dataClass, redactedFields, this.#policy.preservedSemantics ?? [])
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
anonymizeAssetEventPayload(event, context) {
|
|
123
|
+
const result = this.anonymizeJsonValue(event.payload, context, "asset_event");
|
|
124
|
+
return {
|
|
125
|
+
value: isPlainObject(result.value) ? {
|
|
126
|
+
...result.value,
|
|
127
|
+
_privacy: result.metadata
|
|
128
|
+
} : {
|
|
129
|
+
value: result.value,
|
|
130
|
+
_privacy: result.metadata
|
|
131
|
+
},
|
|
132
|
+
metadata: result.metadata
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
anonymizeEvidencePacket(packet, context) {
|
|
136
|
+
const result = this.anonymizeJsonValue(packet.packet, context, "evidence_packet");
|
|
137
|
+
const redactionMetadata = {
|
|
138
|
+
...isPlainObject(packet.redactionMetadata) ? packet.redactionMetadata : {},
|
|
139
|
+
lifecycleAnonymization: result.metadata
|
|
140
|
+
};
|
|
141
|
+
const anonymizedPacket = isPlainObject(result.value) ? {
|
|
142
|
+
...result.value,
|
|
143
|
+
_privacy: result.metadata
|
|
144
|
+
} : {
|
|
145
|
+
value: result.value,
|
|
146
|
+
_privacy: result.metadata
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
value: {
|
|
150
|
+
packet: anonymizedPacket,
|
|
151
|
+
redactionMetadata,
|
|
152
|
+
checksum: stableChecksum({
|
|
153
|
+
packet: anonymizedPacket,
|
|
154
|
+
redactionMetadata
|
|
155
|
+
})
|
|
156
|
+
},
|
|
157
|
+
metadata: result.metadata
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
buildAnonymizationLifecycleEvidence(input) {
|
|
161
|
+
const assetEvents = input.assetEvents ?? [];
|
|
162
|
+
const readModels = input.readModels ?? [];
|
|
163
|
+
const evidencePackets = input.evidencePackets ?? [];
|
|
164
|
+
const redactedFields = [
|
|
165
|
+
...assetEvents.flatMap((item) => item.metadata.redactedFields),
|
|
166
|
+
...readModels.flatMap((item) => item.metadata.redactedFields),
|
|
167
|
+
...evidencePackets.flatMap((item) => item.metadata.redactedFields)
|
|
168
|
+
];
|
|
169
|
+
return {
|
|
170
|
+
eventType: "AnonymizationApplied",
|
|
171
|
+
policyVersion: input.context.policyVersion ?? "adr-026-platform-anonymization-v1",
|
|
172
|
+
jobId: input.context.jobId,
|
|
173
|
+
reason: input.context.reason,
|
|
174
|
+
appliedAt: (input.context.redactedAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
175
|
+
tenantId: input.context.tenantId,
|
|
176
|
+
spaceId: input.context.spaceId ?? null,
|
|
177
|
+
counts: {
|
|
178
|
+
assetEvents: assetEvents.length,
|
|
179
|
+
readModels: readModels.length,
|
|
180
|
+
evidencePackets: evidencePackets.length,
|
|
181
|
+
redactedFields: redactedFields.length
|
|
182
|
+
},
|
|
183
|
+
records: [
|
|
184
|
+
...assetEvents.map((item) => ({
|
|
185
|
+
recordClass: "asset_event",
|
|
186
|
+
recordId: item.event.id,
|
|
187
|
+
subjectType: item.event.subjectType,
|
|
188
|
+
subjectId: item.event.subjectId,
|
|
189
|
+
fieldManifest: item.metadata.redactedFields.map(({ fieldPath, method, beforeChecksum }) => ({
|
|
190
|
+
fieldPath,
|
|
191
|
+
method,
|
|
192
|
+
beforeChecksum
|
|
193
|
+
}))
|
|
194
|
+
})),
|
|
195
|
+
...readModels.map((item) => ({
|
|
196
|
+
recordClass: "read_model",
|
|
197
|
+
recordId: item.record.id,
|
|
198
|
+
subjectType: item.modelKind,
|
|
199
|
+
subjectId: item.record.id,
|
|
200
|
+
fieldManifest: item.metadata.redactedFields.map(({ fieldPath, method, beforeChecksum }) => ({
|
|
201
|
+
fieldPath,
|
|
202
|
+
method,
|
|
203
|
+
beforeChecksum
|
|
204
|
+
}))
|
|
205
|
+
})),
|
|
206
|
+
...evidencePackets.map((item) => ({
|
|
207
|
+
recordClass: "evidence_packet",
|
|
208
|
+
recordId: item.packet.id,
|
|
209
|
+
fieldManifest: item.metadata.redactedFields.map(({ fieldPath, method, beforeChecksum }) => ({
|
|
210
|
+
fieldPath,
|
|
211
|
+
method,
|
|
212
|
+
beforeChecksum
|
|
213
|
+
}))
|
|
214
|
+
}))
|
|
215
|
+
],
|
|
216
|
+
preservedSemantics: [...this.#policy.preservedSemantics ?? []]
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
//#endregion
|
|
221
|
+
export { stableChecksum as i, AnonymizationEngine as n, FieldRedactor as r, ANONYMIZATION_POLICY_VERSION as t };
|
|
222
|
+
|
|
223
|
+
//# sourceMappingURL=engine-B4csEOEc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-B4csEOEc.js","names":[],"sources":["../privacy/engine.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport type {\n\tAnonymizationContext,\n\tAnonymizationFieldMetadata,\n\tAnonymizationMetadata,\n\tAnonymizationResult,\n\tPlatformDataClass,\n\tRedactionMethod,\n} from \"./index\";\n\nexport const ANONYMIZATION_POLICY_VERSION = \"adr-026-platform-anonymization-v1\";\n\ntype JsonObject = Record<string, unknown>;\n\nexport interface AnonymizationFieldPolicy {\n\tmethod: RedactionMethod;\n\tmatch: \"key\" | \"path\";\n\tvalue: string;\n}\n\nexport interface AnonymizationPolicy {\n\tfields: readonly AnonymizationFieldPolicy[];\n\tpreservedSemantics?: readonly string[];\n}\n\nexport interface AssetEventLike {\n\tid: string;\n\ttenantId: string;\n\tspaceId: string;\n\teventType: string;\n\tsubjectType: string;\n\tsubjectId: string;\n\tactionInvocationId: string;\n\tpayload: unknown;\n\tsequence: number;\n\toccurredAt: Date;\n\trecordedAt: Date;\n\tcorrelationId: string;\n\tcausationId?: string | null;\n}\n\nexport interface EvidencePacketLike {\n\tid: string;\n\tpacket: unknown;\n\tredactionMetadata: unknown;\n\tchecksum: string;\n}\n\nexport interface AnonymizationLifecycleEvidence {\n\teventType: \"AnonymizationApplied\";\n\tpolicyVersion: string;\n\tjobId: string;\n\treason: string;\n\tappliedAt: string;\n\ttenantId: string;\n\tspaceId: string | null;\n\tcounts: {\n\t\tassetEvents: number;\n\t\treadModels: number;\n\t\tevidencePackets: number;\n\t\tredactedFields: number;\n\t};\n\trecords: Array<{\n\t\trecordClass: PlatformDataClass;\n\t\trecordId: string;\n\t\tsubjectType?: string;\n\t\tsubjectId?: string;\n\t\tfieldManifest: Array<\n\t\t\tPick<AnonymizationFieldMetadata, \"fieldPath\" | \"method\" | \"beforeChecksum\">\n\t\t>;\n\t}>;\n\tpreservedSemantics: string[];\n}\n\nfunction normalizeKey(key: string): string {\n\treturn key.replace(/[^a-zA-Z0-9]/g, \"\").toLowerCase();\n}\n\nexport function stableChecksum(value: unknown): string {\n\treturn createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\");\n}\n\nfunction stableScopedToken(\n\tvalue: unknown,\n\tcontext: AnonymizationContext,\n\tfieldPath: string,\n): string {\n\tconst scope = `${context.tenantId}:${context.spaceId ?? \"global\"}:${fieldPath}`;\n\treturn `tok_${createHash(\"sha256\")\n\t\t.update(`${context.policyVersion ?? ANONYMIZATION_POLICY_VERSION}:${scope}:${String(value)}`)\n\t\t.digest(\"hex\")\n\t\t.slice(0, 24)}`;\n}\n\nfunction maskValue(value: unknown): string | null {\n\tif (value === null || value === undefined) {\n\t\treturn null;\n\t}\n\n\tconst stringValue = String(value);\n\tif (stringValue.length <= 4) {\n\t\treturn \"****\";\n\t}\n\n\treturn `${\"*\".repeat(Math.max(stringValue.length - 4, 4))}${stringValue.slice(-4)}`;\n}\n\nfunction generalizeValue(value: unknown): unknown {\n\tif (typeof value === \"number\") {\n\t\treturn Math.round(value / 1000) * 1000;\n\t}\n\n\tif (typeof value === \"string\" && /^\\d{5}(?:-\\d{4})?$/.test(value)) {\n\t\treturn `${value.slice(0, 3)}**`;\n\t}\n\n\treturn null;\n}\n\nfunction applyMethod(\n\tvalue: unknown,\n\tmethod: RedactionMethod,\n\tcontext: AnonymizationContext,\n\tpath: string,\n): unknown {\n\tswitch (method) {\n\t\tcase \"drop\":\n\t\t\treturn undefined;\n\t\tcase \"nullify\":\n\t\t\treturn null;\n\t\tcase \"mask\":\n\t\t\treturn maskValue(value);\n\t\tcase \"hash\":\n\t\t\treturn `sha256_${stableChecksum(value)}`;\n\t\tcase \"tokenize\":\n\t\t\treturn stableScopedToken(value, context, path);\n\t\tcase \"generalize\":\n\t\t\treturn generalizeValue(value);\n\t}\n}\n\nfunction policyForPath(policies: readonly AnonymizationFieldPolicy[], path: string, key?: string): AnonymizationFieldPolicy | undefined {\n\tconst normalizedPath = normalizeKey(path);\n\tconst normalizedKey = key ? normalizeKey(key) : undefined;\n\n\treturn policies.find((policy) => {\n\t\tconst normalizedValue = normalizeKey(policy.value);\n\t\tif (policy.match === \"key\") {\n\t\t\treturn normalizedValue === normalizedKey;\n\t\t}\n\n\t\treturn normalizedValue === normalizedPath;\n\t});\n}\n\nfunction isPlainObject(value: unknown): value is JsonObject {\n\treturn (\n\t\tBoolean(value) && typeof value === \"object\" && !Array.isArray(value) && !(value instanceof Date)\n\t);\n}\n\nfunction anonymizeRecursive(\n\tvalue: unknown,\n\tcontext: AnonymizationContext,\n\tdataClass: PlatformDataClass,\n\tpath: string,\n\tredactedFields: AnonymizationFieldMetadata[],\n\tpolicies: readonly AnonymizationFieldPolicy[],\n\tkey?: string,\n): unknown {\n\tconst fieldPolicy = policyForPath(policies, path, key);\n\tif (fieldPolicy && value !== null && value !== undefined) {\n\t\tredactedFields.push({\n\t\t\tfieldPath: path,\n\t\t\tmethod: fieldPolicy.method,\n\t\t\tpolicyVersion: context.policyVersion ?? ANONYMIZATION_POLICY_VERSION,\n\t\t\tjobId: context.jobId,\n\t\t\tredactedAt: (context.redactedAt ?? new Date()).toISOString(),\n\t\t\treason: context.reason,\n\t\t\tdataClass,\n\t\t\tbeforeChecksum: stableChecksum(value),\n\t\t});\n\n\t\treturn applyMethod(value, fieldPolicy.method, context, path);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((item, index) =>\n\t\t\tanonymizeRecursive(item, context, dataClass, `${path}[${index}]`, redactedFields, policies),\n\t\t);\n\t}\n\n\tif (!isPlainObject(value)) {\n\t\treturn value;\n\t}\n\n\tconst result: JsonObject = {};\n\tfor (const [childKey, childValue] of Object.entries(value)) {\n\t\tif (childKey === \"_privacy\") {\n\t\t\tresult[childKey] = childValue;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst anonymized = anonymizeRecursive(\n\t\t\tchildValue,\n\t\t\tcontext,\n\t\t\tdataClass,\n\t\t\t`${path}.${childKey}`,\n\t\t\tredactedFields,\n\t\t\tpolicies,\n\t\t\tchildKey,\n\t\t);\n\n\t\tif (anonymized !== undefined) {\n\t\t\tresult[childKey] = anonymized;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nfunction buildMetadata(\n\tcontext: AnonymizationContext,\n\tdataClass: PlatformDataClass,\n\tredactedFields: AnonymizationFieldMetadata[],\n\tpreservedSemantics: readonly string[],\n): AnonymizationMetadata {\n\treturn {\n\t\tredactionState: \"anonymized\",\n\t\tpolicyVersion: context.policyVersion ?? ANONYMIZATION_POLICY_VERSION,\n\t\tjobId: context.jobId,\n\t\tredactedAt: (context.redactedAt ?? new Date()).toISOString(),\n\t\treason: context.reason,\n\t\tdataClass,\n\t\tredactedFields,\n\t\tpreservedSemantics: [...preservedSemantics],\n\t};\n}\n\nexport class FieldRedactor {\n\tredactField(value: unknown, method: RedactionMethod, context: AnonymizationContext, path: string): unknown {\n\t\treturn applyMethod(value, method, context, path);\n\t}\n\n\tmask(value: unknown): string | null {\n\t\treturn maskValue(value);\n\t}\n\n\thash(value: unknown): string {\n\t\treturn `sha256_${stableChecksum(value)}`;\n\t}\n\n\ttokenize(value: unknown, context: AnonymizationContext, path: string): string {\n\t\treturn stableScopedToken(value, context, path);\n\t}\n\n\tgeneralize(value: unknown): unknown {\n\t\treturn generalizeValue(value);\n\t}\n}\n\nexport class AnonymizationEngine {\n\treadonly #policy: AnonymizationPolicy;\n\n\tconstructor(policy: AnonymizationPolicy) {\n\t\tthis.#policy = {\n\t\t\tfields: policy.fields.map((field) => ({ ...field })),\n\t\t\tpreservedSemantics: [...(policy.preservedSemantics ?? [])],\n\t\t};\n\t}\n\n\tanonymizeJsonValue<TValue>(\n\t\tvalue: TValue,\n\t\tcontext: AnonymizationContext,\n\t\tdataClass: PlatformDataClass,\n\t): AnonymizationResult<TValue> {\n\t\treturn this.anonymizeJsonValueAtPath(value, context, dataClass, \"$\");\n\t}\n\n\tanonymizeJsonValueAtPath<TValue>(\n\t\tvalue: TValue,\n\t\tcontext: AnonymizationContext,\n\t\tdataClass: PlatformDataClass,\n\t\tbasePath: string,\n\t): AnonymizationResult<TValue> {\n\t\tconst redactedFields: AnonymizationFieldMetadata[] = [];\n\t\tconst anonymizedValue = anonymizeRecursive(\n\t\t\tvalue,\n\t\t\tcontext,\n\t\t\tdataClass,\n\t\t\tbasePath,\n\t\t\tredactedFields,\n\t\t\tthis.#policy.fields,\n\t\t) as TValue;\n\n\t\treturn {\n\t\t\tvalue: anonymizedValue,\n\t\t\tmetadata: buildMetadata(context, dataClass, redactedFields, this.#policy.preservedSemantics ?? []),\n\t\t};\n\t}\n\n\tanonymizeAssetEventPayload(\n\t\tevent: AssetEventLike,\n\t\tcontext: AnonymizationContext,\n\t): AnonymizationResult<unknown> {\n\t\tconst result = this.anonymizeJsonValue(event.payload, context, \"asset_event\");\n\t\tconst payload = isPlainObject(result.value)\n\t\t\t? { ...result.value, _privacy: result.metadata }\n\t\t\t: { value: result.value, _privacy: result.metadata };\n\n\t\treturn { value: payload, metadata: result.metadata };\n\t}\n\n\tanonymizeEvidencePacket(\n\t\tpacket: EvidencePacketLike,\n\t\tcontext: AnonymizationContext,\n\t): AnonymizationResult<Pick<EvidencePacketLike, \"packet\" | \"redactionMetadata\" | \"checksum\">> {\n\t\tconst result = this.anonymizeJsonValue(packet.packet, context, \"evidence_packet\");\n\t\tconst redactionMetadata = {\n\t\t\t...(isPlainObject(packet.redactionMetadata) ? packet.redactionMetadata : {}),\n\t\t\tlifecycleAnonymization: result.metadata,\n\t\t};\n\t\tconst anonymizedPacket = isPlainObject(result.value)\n\t\t\t? { ...result.value, _privacy: result.metadata }\n\t\t\t: { value: result.value, _privacy: result.metadata };\n\n\t\treturn {\n\t\t\tvalue: {\n\t\t\t\tpacket: anonymizedPacket,\n\t\t\t\tredactionMetadata,\n\t\t\t\tchecksum: stableChecksum({ packet: anonymizedPacket, redactionMetadata }),\n\t\t\t},\n\t\t\tmetadata: result.metadata,\n\t\t};\n\t}\n\n\tbuildAnonymizationLifecycleEvidence(input: {\n\t\tcontext: AnonymizationContext;\n\t\tassetEvents?: Array<{ event: AssetEventLike; metadata: AnonymizationMetadata }>;\n\t\treadModels?: Array<{\n\t\t\tmodelKind: string;\n\t\t\trecord: JsonObject & { id: string };\n\t\t\tmetadata: AnonymizationMetadata;\n\t\t}>;\n\t\tevidencePackets?: Array<{ packet: EvidencePacketLike; metadata: AnonymizationMetadata }>;\n\t}): AnonymizationLifecycleEvidence {\n\t\tconst assetEvents = input.assetEvents ?? [];\n\t\tconst readModels = input.readModels ?? [];\n\t\tconst evidencePackets = input.evidencePackets ?? [];\n\t\tconst redactedFields = [\n\t\t\t...assetEvents.flatMap((item) => item.metadata.redactedFields),\n\t\t\t...readModels.flatMap((item) => item.metadata.redactedFields),\n\t\t\t...evidencePackets.flatMap((item) => item.metadata.redactedFields),\n\t\t];\n\n\t\treturn {\n\t\t\teventType: \"AnonymizationApplied\",\n\t\t\tpolicyVersion: input.context.policyVersion ?? ANONYMIZATION_POLICY_VERSION,\n\t\t\tjobId: input.context.jobId,\n\t\t\treason: input.context.reason,\n\t\t\tappliedAt: (input.context.redactedAt ?? new Date()).toISOString(),\n\t\t\ttenantId: input.context.tenantId,\n\t\t\tspaceId: input.context.spaceId ?? null,\n\t\t\tcounts: {\n\t\t\t\tassetEvents: assetEvents.length,\n\t\t\t\treadModels: readModels.length,\n\t\t\t\tevidencePackets: evidencePackets.length,\n\t\t\t\tredactedFields: redactedFields.length,\n\t\t\t},\n\t\t\trecords: [\n\t\t\t\t...assetEvents.map((item) => ({\n\t\t\t\t\trecordClass: \"asset_event\" as PlatformDataClass,\n\t\t\t\t\trecordId: item.event.id,\n\t\t\t\t\tsubjectType: item.event.subjectType,\n\t\t\t\t\tsubjectId: item.event.subjectId,\n\t\t\t\t\tfieldManifest: item.metadata.redactedFields.map(\n\t\t\t\t\t\t({ fieldPath, method, beforeChecksum }) => ({\n\t\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t\t\tmethod,\n\t\t\t\t\t\t\tbeforeChecksum,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t})),\n\t\t\t\t...readModels.map((item) => ({\n\t\t\t\t\trecordClass: \"read_model\" as PlatformDataClass,\n\t\t\t\t\trecordId: item.record.id,\n\t\t\t\t\tsubjectType: item.modelKind,\n\t\t\t\t\tsubjectId: item.record.id,\n\t\t\t\t\tfieldManifest: item.metadata.redactedFields.map(\n\t\t\t\t\t\t({ fieldPath, method, beforeChecksum }) => ({\n\t\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t\t\tmethod,\n\t\t\t\t\t\t\tbeforeChecksum,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t})),\n\t\t\t\t...evidencePackets.map((item) => ({\n\t\t\t\t\trecordClass: \"evidence_packet\" as PlatformDataClass,\n\t\t\t\t\trecordId: item.packet.id,\n\t\t\t\t\tfieldManifest: item.metadata.redactedFields.map(\n\t\t\t\t\t\t({ fieldPath, method, beforeChecksum }) => ({\n\t\t\t\t\t\t\tfieldPath,\n\t\t\t\t\t\t\tmethod,\n\t\t\t\t\t\t\tbeforeChecksum,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t})),\n\t\t\t],\n\t\t\tpreservedSemantics: [...(this.#policy.preservedSemantics ?? [])],\n\t\t};\n\t}\n}\n"],"mappings":"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"}
|