@fabricorg/platform 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-hitl/index.cjs +12 -0
- package/dist/agent-hitl/index.cjs.map +1 -0
- package/dist/agent-hitl/index.d.cts +34 -0
- package/dist/agent-hitl/index.d.ts +34 -0
- package/dist/agent-hitl/index.js +3 -0
- package/dist/agent-hitl/index.js.map +1 -0
- package/dist/chunk-F3E5SXPN.cjs +28 -0
- package/dist/chunk-F3E5SXPN.cjs.map +1 -0
- package/dist/chunk-OFCCZ27Z.js +26 -0
- package/dist/chunk-OFCCZ27Z.js.map +1 -0
- package/dist/chunk-X7WC4AYC.js +310 -0
- package/dist/chunk-X7WC4AYC.js.map +1 -0
- package/dist/chunk-YQEXO3IQ.cjs +320 -0
- package/dist/chunk-YQEXO3IQ.cjs.map +1 -0
- package/dist/index.cjs +99 -62
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -6
- package/dist/privacy/index.cjs +34 -2
- package/dist/privacy/index.d.cts +102 -1
- package/dist/privacy/index.d.ts +102 -1
- package/dist/privacy/index.js +1 -1
- package/package.json +207 -196
- package/dist/chunk-LHCSVEFT.cjs +0 -8
- package/dist/chunk-LHCSVEFT.cjs.map +0 -1
- package/dist/chunk-N24NLCZ6.js +0 -6
- package/dist/chunk-N24NLCZ6.js.map +0 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkF3E5SXPN_cjs = require('../chunk-F3E5SXPN.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "AgentActionPolicyRegistry", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkF3E5SXPN_cjs.AgentActionPolicyRegistry; }
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=index.cjs.map
|
|
12
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type AgentActionRoute = "auto-execute" | "needs-approval" | "escalate" | "rejected";
|
|
2
|
+
type AgentActionRiskTier = "low" | "medium" | "high";
|
|
3
|
+
interface AgentActionPolicyContext {
|
|
4
|
+
actionId: string;
|
|
5
|
+
actorId: string;
|
|
6
|
+
actorType: string;
|
|
7
|
+
tenantId: string;
|
|
8
|
+
spaceId: string;
|
|
9
|
+
parameters: Record<string, unknown>;
|
|
10
|
+
confidence?: number;
|
|
11
|
+
riskTier?: AgentActionRiskTier;
|
|
12
|
+
agentSessionId?: string;
|
|
13
|
+
agentRunId?: string;
|
|
14
|
+
}
|
|
15
|
+
interface AgentActionPolicyDecision {
|
|
16
|
+
route: AgentActionRoute;
|
|
17
|
+
riskTier: AgentActionRiskTier;
|
|
18
|
+
reason: string;
|
|
19
|
+
}
|
|
20
|
+
type AgentActionPolicyEvaluator = (context: AgentActionPolicyContext) => AgentActionPolicyDecision | Promise<AgentActionPolicyDecision>;
|
|
21
|
+
interface AgentActionPolicyDefinition {
|
|
22
|
+
actionId: string;
|
|
23
|
+
evaluator: AgentActionPolicyEvaluator;
|
|
24
|
+
description?: string;
|
|
25
|
+
}
|
|
26
|
+
declare class AgentActionPolicyRegistry {
|
|
27
|
+
private _policies;
|
|
28
|
+
register(definition: AgentActionPolicyDefinition): void;
|
|
29
|
+
resolve(actionId: string): AgentActionPolicyDefinition | undefined;
|
|
30
|
+
listAll(): AgentActionPolicyDefinition[];
|
|
31
|
+
clear(): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { type AgentActionPolicyContext, type AgentActionPolicyDecision, type AgentActionPolicyDefinition, type AgentActionPolicyEvaluator, AgentActionPolicyRegistry, type AgentActionRiskTier, type AgentActionRoute };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type AgentActionRoute = "auto-execute" | "needs-approval" | "escalate" | "rejected";
|
|
2
|
+
type AgentActionRiskTier = "low" | "medium" | "high";
|
|
3
|
+
interface AgentActionPolicyContext {
|
|
4
|
+
actionId: string;
|
|
5
|
+
actorId: string;
|
|
6
|
+
actorType: string;
|
|
7
|
+
tenantId: string;
|
|
8
|
+
spaceId: string;
|
|
9
|
+
parameters: Record<string, unknown>;
|
|
10
|
+
confidence?: number;
|
|
11
|
+
riskTier?: AgentActionRiskTier;
|
|
12
|
+
agentSessionId?: string;
|
|
13
|
+
agentRunId?: string;
|
|
14
|
+
}
|
|
15
|
+
interface AgentActionPolicyDecision {
|
|
16
|
+
route: AgentActionRoute;
|
|
17
|
+
riskTier: AgentActionRiskTier;
|
|
18
|
+
reason: string;
|
|
19
|
+
}
|
|
20
|
+
type AgentActionPolicyEvaluator = (context: AgentActionPolicyContext) => AgentActionPolicyDecision | Promise<AgentActionPolicyDecision>;
|
|
21
|
+
interface AgentActionPolicyDefinition {
|
|
22
|
+
actionId: string;
|
|
23
|
+
evaluator: AgentActionPolicyEvaluator;
|
|
24
|
+
description?: string;
|
|
25
|
+
}
|
|
26
|
+
declare class AgentActionPolicyRegistry {
|
|
27
|
+
private _policies;
|
|
28
|
+
register(definition: AgentActionPolicyDefinition): void;
|
|
29
|
+
resolve(actionId: string): AgentActionPolicyDefinition | undefined;
|
|
30
|
+
listAll(): AgentActionPolicyDefinition[];
|
|
31
|
+
clear(): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { type AgentActionPolicyContext, type AgentActionPolicyDecision, type AgentActionPolicyDefinition, type AgentActionPolicyEvaluator, AgentActionPolicyRegistry, type AgentActionRiskTier, type AgentActionRoute };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// agent-hitl/index.ts
|
|
4
|
+
var AgentActionPolicyRegistry = class {
|
|
5
|
+
_policies = /* @__PURE__ */ new Map();
|
|
6
|
+
register(definition) {
|
|
7
|
+
const existing = this._policies.get(definition.actionId);
|
|
8
|
+
if (existing && existing.evaluator !== definition.evaluator) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
`Conflicting agent action policy registration for "${definition.actionId}". A different evaluator is already registered.`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
this._policies.set(definition.actionId, definition);
|
|
14
|
+
}
|
|
15
|
+
resolve(actionId) {
|
|
16
|
+
return this._policies.get(actionId);
|
|
17
|
+
}
|
|
18
|
+
listAll() {
|
|
19
|
+
return Array.from(this._policies.values());
|
|
20
|
+
}
|
|
21
|
+
clear() {
|
|
22
|
+
this._policies.clear();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
exports.AgentActionPolicyRegistry = AgentActionPolicyRegistry;
|
|
27
|
+
//# sourceMappingURL=chunk-F3E5SXPN.cjs.map
|
|
28
|
+
//# sourceMappingURL=chunk-F3E5SXPN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../agent-hitl/index.ts"],"names":[],"mappings":";;;AAiCO,IAAM,4BAAN,MAAgC;AAAA,EAC9B,SAAA,uBAAgB,GAAA,EAAyC;AAAA,EAEjE,SAAS,UAAA,EAA+C;AACvD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,WAAW,QAAQ,CAAA;AACvD,IAAA,IAAI,QAAA,IAAY,QAAA,CAAS,SAAA,KAAc,UAAA,CAAW,SAAA,EAAW;AAC5D,MAAA,MAAM,IAAI,KAAA;AAAA,QACT,CAAA,kDAAA,EAAqD,WAAW,QAAQ,CAAA,+CAAA;AAAA,OAEzE;AAAA,IACD;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,UAAA,CAAW,QAAA,EAAU,UAAU,CAAA;AAAA,EACnD;AAAA,EAEA,QAAQ,QAAA,EAA2D;AAClE,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA;AAAA,EACnC;AAAA,EAEA,OAAA,GAAyC;AACxC,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC1C;AAAA,EAEA,KAAA,GAAc;AACb,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACtB;AACD","file":"chunk-F3E5SXPN.cjs","sourcesContent":["export type AgentActionRoute = \"auto-execute\" | \"needs-approval\" | \"escalate\" | \"rejected\";\n\nexport type AgentActionRiskTier = \"low\" | \"medium\" | \"high\";\n\nexport interface AgentActionPolicyContext {\n\tactionId: string;\n\tactorId: string;\n\tactorType: string;\n\ttenantId: string;\n\tspaceId: string;\n\tparameters: Record<string, unknown>;\n\tconfidence?: number;\n\triskTier?: AgentActionRiskTier;\n\tagentSessionId?: string;\n\tagentRunId?: string;\n}\n\nexport interface AgentActionPolicyDecision {\n\troute: AgentActionRoute;\n\triskTier: AgentActionRiskTier;\n\treason: string;\n}\n\nexport type AgentActionPolicyEvaluator = (\n\tcontext: AgentActionPolicyContext,\n) => AgentActionPolicyDecision | Promise<AgentActionPolicyDecision>;\n\nexport interface AgentActionPolicyDefinition {\n\tactionId: string;\n\tevaluator: AgentActionPolicyEvaluator;\n\tdescription?: string;\n}\n\nexport class AgentActionPolicyRegistry {\n\tprivate _policies = new Map<string, AgentActionPolicyDefinition>();\n\n\tregister(definition: AgentActionPolicyDefinition): void {\n\t\tconst existing = this._policies.get(definition.actionId);\n\t\tif (existing && existing.evaluator !== definition.evaluator) {\n\t\t\tthrow new Error(\n\t\t\t\t`Conflicting agent action policy registration for \"${definition.actionId}\". ` +\n\t\t\t\t\t`A different evaluator is already registered.`,\n\t\t\t);\n\t\t}\n\t\tthis._policies.set(definition.actionId, definition);\n\t}\n\n\tresolve(actionId: string): AgentActionPolicyDefinition | undefined {\n\t\treturn this._policies.get(actionId);\n\t}\n\n\tlistAll(): AgentActionPolicyDefinition[] {\n\t\treturn Array.from(this._policies.values());\n\t}\n\n\tclear(): void {\n\t\tthis._policies.clear();\n\t}\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// agent-hitl/index.ts
|
|
2
|
+
var AgentActionPolicyRegistry = class {
|
|
3
|
+
_policies = /* @__PURE__ */ new Map();
|
|
4
|
+
register(definition) {
|
|
5
|
+
const existing = this._policies.get(definition.actionId);
|
|
6
|
+
if (existing && existing.evaluator !== definition.evaluator) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
`Conflicting agent action policy registration for "${definition.actionId}". A different evaluator is already registered.`
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
this._policies.set(definition.actionId, definition);
|
|
12
|
+
}
|
|
13
|
+
resolve(actionId) {
|
|
14
|
+
return this._policies.get(actionId);
|
|
15
|
+
}
|
|
16
|
+
listAll() {
|
|
17
|
+
return Array.from(this._policies.values());
|
|
18
|
+
}
|
|
19
|
+
clear() {
|
|
20
|
+
this._policies.clear();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { AgentActionPolicyRegistry };
|
|
25
|
+
//# sourceMappingURL=chunk-OFCCZ27Z.js.map
|
|
26
|
+
//# sourceMappingURL=chunk-OFCCZ27Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../agent-hitl/index.ts"],"names":[],"mappings":";AAiCO,IAAM,4BAAN,MAAgC;AAAA,EAC9B,SAAA,uBAAgB,GAAA,EAAyC;AAAA,EAEjE,SAAS,UAAA,EAA+C;AACvD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,WAAW,QAAQ,CAAA;AACvD,IAAA,IAAI,QAAA,IAAY,QAAA,CAAS,SAAA,KAAc,UAAA,CAAW,SAAA,EAAW;AAC5D,MAAA,MAAM,IAAI,KAAA;AAAA,QACT,CAAA,kDAAA,EAAqD,WAAW,QAAQ,CAAA,+CAAA;AAAA,OAEzE;AAAA,IACD;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,UAAA,CAAW,QAAA,EAAU,UAAU,CAAA;AAAA,EACnD;AAAA,EAEA,QAAQ,QAAA,EAA2D;AAClE,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA;AAAA,EACnC;AAAA,EAEA,OAAA,GAAyC;AACxC,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAA;AAAA,EAC1C;AAAA,EAEA,KAAA,GAAc;AACb,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACtB;AACD","file":"chunk-OFCCZ27Z.js","sourcesContent":["export type AgentActionRoute = \"auto-execute\" | \"needs-approval\" | \"escalate\" | \"rejected\";\n\nexport type AgentActionRiskTier = \"low\" | \"medium\" | \"high\";\n\nexport interface AgentActionPolicyContext {\n\tactionId: string;\n\tactorId: string;\n\tactorType: string;\n\ttenantId: string;\n\tspaceId: string;\n\tparameters: Record<string, unknown>;\n\tconfidence?: number;\n\triskTier?: AgentActionRiskTier;\n\tagentSessionId?: string;\n\tagentRunId?: string;\n}\n\nexport interface AgentActionPolicyDecision {\n\troute: AgentActionRoute;\n\triskTier: AgentActionRiskTier;\n\treason: string;\n}\n\nexport type AgentActionPolicyEvaluator = (\n\tcontext: AgentActionPolicyContext,\n) => AgentActionPolicyDecision | Promise<AgentActionPolicyDecision>;\n\nexport interface AgentActionPolicyDefinition {\n\tactionId: string;\n\tevaluator: AgentActionPolicyEvaluator;\n\tdescription?: string;\n}\n\nexport class AgentActionPolicyRegistry {\n\tprivate _policies = new Map<string, AgentActionPolicyDefinition>();\n\n\tregister(definition: AgentActionPolicyDefinition): void {\n\t\tconst existing = this._policies.get(definition.actionId);\n\t\tif (existing && existing.evaluator !== definition.evaluator) {\n\t\t\tthrow new Error(\n\t\t\t\t`Conflicting agent action policy registration for \"${definition.actionId}\". ` +\n\t\t\t\t\t`A different evaluator is already registered.`,\n\t\t\t);\n\t\t}\n\t\tthis._policies.set(definition.actionId, definition);\n\t}\n\n\tresolve(actionId: string): AgentActionPolicyDefinition | undefined {\n\t\treturn this._policies.get(actionId);\n\t}\n\n\tlistAll(): AgentActionPolicyDefinition[] {\n\t\treturn Array.from(this._policies.values());\n\t}\n\n\tclear(): void {\n\t\tthis._policies.clear();\n\t}\n}\n"]}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
|
|
3
|
+
// privacy/engine.ts
|
|
4
|
+
var ANONYMIZATION_POLICY_VERSION = "adr-026-platform-anonymization-v1";
|
|
5
|
+
var DEFAULT_PRESERVED_SEMANTICS = [
|
|
6
|
+
"tenantId",
|
|
7
|
+
"spaceId",
|
|
8
|
+
"subjectType",
|
|
9
|
+
"subjectId",
|
|
10
|
+
"eventType",
|
|
11
|
+
"sequence",
|
|
12
|
+
"occurredAt",
|
|
13
|
+
"recordedAt",
|
|
14
|
+
"actionInvocationId",
|
|
15
|
+
"correlationId",
|
|
16
|
+
"causationId",
|
|
17
|
+
"financialDecisionFacts"
|
|
18
|
+
];
|
|
19
|
+
var FIELD_POLICIES = [
|
|
20
|
+
{ match: "key", value: "password", method: "drop" },
|
|
21
|
+
{ match: "key", value: "token", method: "drop" },
|
|
22
|
+
{ match: "key", value: "apiKey", method: "drop" },
|
|
23
|
+
{ match: "key", value: "authorization", method: "drop" },
|
|
24
|
+
{ match: "key", value: "ssn", method: "nullify" },
|
|
25
|
+
{ match: "key", value: "ssnLast4", method: "nullify" },
|
|
26
|
+
{ match: "key", value: "socialSecurityNumber", method: "nullify" },
|
|
27
|
+
{ match: "key", value: "dateOfBirth", method: "nullify" },
|
|
28
|
+
{ match: "key", value: "dob", method: "nullify" },
|
|
29
|
+
{ match: "key", value: "driverLicense", method: "nullify" },
|
|
30
|
+
{ match: "key", value: "firstName", method: "tokenize" },
|
|
31
|
+
{ match: "key", value: "middleName", method: "tokenize" },
|
|
32
|
+
{ match: "key", value: "lastName", method: "tokenize" },
|
|
33
|
+
{ match: "key", value: "fullName", method: "tokenize" },
|
|
34
|
+
{ match: "key", value: "name", method: "tokenize" },
|
|
35
|
+
{ match: "key", value: "email", method: "tokenize" },
|
|
36
|
+
{ match: "key", value: "emailAddress", method: "tokenize" },
|
|
37
|
+
{ match: "key", value: "phone", method: "tokenize" },
|
|
38
|
+
{ match: "key", value: "phoneNumber", method: "tokenize" },
|
|
39
|
+
{ match: "key", value: "mobilePhone", method: "tokenize" },
|
|
40
|
+
{ match: "key", value: "homePhone", method: "tokenize" },
|
|
41
|
+
{ match: "key", value: "workPhone", method: "tokenize" },
|
|
42
|
+
{ match: "key", value: "street", method: "nullify" },
|
|
43
|
+
{ match: "key", value: "streetAddress", method: "nullify" },
|
|
44
|
+
{ match: "key", value: "address", method: "nullify" },
|
|
45
|
+
{ match: "key", value: "mailingAddress", method: "nullify" },
|
|
46
|
+
{ match: "key", value: "partnerLeadId", method: "tokenize" },
|
|
47
|
+
{ match: "key", value: "externalLeadId", method: "tokenize" },
|
|
48
|
+
{ match: "key", value: "loanApplicationId", method: "tokenize" },
|
|
49
|
+
{ match: "key", value: "vin", method: "tokenize" },
|
|
50
|
+
{ match: "key", value: "rawVin", method: "tokenize" }
|
|
51
|
+
];
|
|
52
|
+
var NORMALIZED_FIELD_POLICIES = FIELD_POLICIES.map((policy) => ({
|
|
53
|
+
...policy,
|
|
54
|
+
value: normalizeKey(policy.value)
|
|
55
|
+
}));
|
|
56
|
+
function normalizeKey(key) {
|
|
57
|
+
return key.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
|
|
58
|
+
}
|
|
59
|
+
function stableChecksum(value) {
|
|
60
|
+
return createHash("sha256").update(JSON.stringify(value)).digest("hex");
|
|
61
|
+
}
|
|
62
|
+
function stableScopedToken(value, context, fieldPath) {
|
|
63
|
+
const scope = `${context.tenantId}:${context.spaceId ?? "global"}:${fieldPath}`;
|
|
64
|
+
return `tok_${createHash("sha256").update(`${context.policyVersion ?? ANONYMIZATION_POLICY_VERSION}:${scope}:${String(value)}`).digest("hex").slice(0, 24)}`;
|
|
65
|
+
}
|
|
66
|
+
function maskValue(value) {
|
|
67
|
+
if (value === null || value === void 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const stringValue = String(value);
|
|
71
|
+
if (stringValue.length <= 4) {
|
|
72
|
+
return "****";
|
|
73
|
+
}
|
|
74
|
+
return `${"*".repeat(Math.max(stringValue.length - 4, 4))}${stringValue.slice(-4)}`;
|
|
75
|
+
}
|
|
76
|
+
function generalizeValue(value) {
|
|
77
|
+
if (typeof value === "number") {
|
|
78
|
+
return Math.round(value / 1e3) * 1e3;
|
|
79
|
+
}
|
|
80
|
+
if (typeof value === "string" && /^\d{5}(?:-\d{4})?$/.test(value)) {
|
|
81
|
+
return `${value.slice(0, 3)}**`;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
function applyMethod(value, method, context, path) {
|
|
86
|
+
switch (method) {
|
|
87
|
+
case "drop":
|
|
88
|
+
return void 0;
|
|
89
|
+
case "nullify":
|
|
90
|
+
return null;
|
|
91
|
+
case "mask":
|
|
92
|
+
return maskValue(value);
|
|
93
|
+
case "hash":
|
|
94
|
+
return `sha256_${stableChecksum(value)}`;
|
|
95
|
+
case "tokenize":
|
|
96
|
+
return stableScopedToken(value, context, path);
|
|
97
|
+
case "generalize":
|
|
98
|
+
return generalizeValue(value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function policyForPath(path, key) {
|
|
102
|
+
const normalizedPath = normalizeKey(path);
|
|
103
|
+
const normalizedKey = key ? normalizeKey(key) : void 0;
|
|
104
|
+
return NORMALIZED_FIELD_POLICIES.find((policy) => {
|
|
105
|
+
if (policy.match === "key") {
|
|
106
|
+
return policy.value === normalizedKey;
|
|
107
|
+
}
|
|
108
|
+
return policy.value === normalizedPath;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function isPlainObject(value) {
|
|
112
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
113
|
+
}
|
|
114
|
+
function anonymizeRecursive(value, context, dataClass, path, redactedFields, key) {
|
|
115
|
+
const fieldPolicy = policyForPath(path, key);
|
|
116
|
+
if (fieldPolicy && value !== null && value !== void 0) {
|
|
117
|
+
redactedFields.push({
|
|
118
|
+
fieldPath: path,
|
|
119
|
+
method: fieldPolicy.method,
|
|
120
|
+
policyVersion: context.policyVersion ?? ANONYMIZATION_POLICY_VERSION,
|
|
121
|
+
jobId: context.jobId,
|
|
122
|
+
redactedAt: (context.redactedAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
123
|
+
reason: context.reason,
|
|
124
|
+
dataClass,
|
|
125
|
+
beforeChecksum: stableChecksum(value)
|
|
126
|
+
});
|
|
127
|
+
return applyMethod(value, fieldPolicy.method, context, path);
|
|
128
|
+
}
|
|
129
|
+
if (Array.isArray(value)) {
|
|
130
|
+
return value.map(
|
|
131
|
+
(item, index) => anonymizeRecursive(item, context, dataClass, `${path}[${index}]`, redactedFields)
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
if (!isPlainObject(value)) {
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
const result = {};
|
|
138
|
+
for (const [childKey, childValue] of Object.entries(value)) {
|
|
139
|
+
if (childKey === "_privacy") {
|
|
140
|
+
result[childKey] = childValue;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const anonymized = anonymizeRecursive(
|
|
144
|
+
childValue,
|
|
145
|
+
context,
|
|
146
|
+
dataClass,
|
|
147
|
+
`${path}.${childKey}`,
|
|
148
|
+
redactedFields,
|
|
149
|
+
childKey
|
|
150
|
+
);
|
|
151
|
+
if (anonymized !== void 0) {
|
|
152
|
+
result[childKey] = anonymized;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
function buildMetadata(context, dataClass, redactedFields) {
|
|
158
|
+
return {
|
|
159
|
+
redactionState: "anonymized",
|
|
160
|
+
policyVersion: context.policyVersion ?? ANONYMIZATION_POLICY_VERSION,
|
|
161
|
+
jobId: context.jobId,
|
|
162
|
+
redactedAt: (context.redactedAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
163
|
+
reason: context.reason,
|
|
164
|
+
dataClass,
|
|
165
|
+
redactedFields,
|
|
166
|
+
preservedSemantics: DEFAULT_PRESERVED_SEMANTICS
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
var FieldRedactor = class {
|
|
170
|
+
redactField(value, method, context, path) {
|
|
171
|
+
return applyMethod(value, method, context, path);
|
|
172
|
+
}
|
|
173
|
+
mask(value) {
|
|
174
|
+
return maskValue(value);
|
|
175
|
+
}
|
|
176
|
+
hash(value) {
|
|
177
|
+
return `sha256_${stableChecksum(value)}`;
|
|
178
|
+
}
|
|
179
|
+
tokenize(value, context, path) {
|
|
180
|
+
return stableScopedToken(value, context, path);
|
|
181
|
+
}
|
|
182
|
+
generalize(value) {
|
|
183
|
+
return generalizeValue(value);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
var AnonymizationEngine = class {
|
|
187
|
+
anonymizeJsonValue(value, context, dataClass) {
|
|
188
|
+
return this.anonymizeJsonValueAtPath(value, context, dataClass, "$");
|
|
189
|
+
}
|
|
190
|
+
anonymizeJsonValueAtPath(value, context, dataClass, basePath) {
|
|
191
|
+
const redactedFields = [];
|
|
192
|
+
const anonymizedValue = anonymizeRecursive(
|
|
193
|
+
value,
|
|
194
|
+
context,
|
|
195
|
+
dataClass,
|
|
196
|
+
basePath,
|
|
197
|
+
redactedFields
|
|
198
|
+
);
|
|
199
|
+
return {
|
|
200
|
+
value: anonymizedValue,
|
|
201
|
+
metadata: buildMetadata(context, dataClass, redactedFields)
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
anonymizeAssetEventPayload(event, context) {
|
|
205
|
+
const result = this.anonymizeJsonValue(event.payload, context, "asset_event");
|
|
206
|
+
const payload = isPlainObject(result.value) ? { ...result.value, _privacy: result.metadata } : { value: result.value, _privacy: result.metadata };
|
|
207
|
+
return { value: payload, metadata: result.metadata };
|
|
208
|
+
}
|
|
209
|
+
anonymizeEvidencePacket(packet, context) {
|
|
210
|
+
const result = this.anonymizeJsonValue(packet.packet, context, "evidence_packet");
|
|
211
|
+
const redactionMetadata = {
|
|
212
|
+
...isPlainObject(packet.redactionMetadata) ? packet.redactionMetadata : {},
|
|
213
|
+
lifecycleAnonymization: result.metadata
|
|
214
|
+
};
|
|
215
|
+
const anonymizedPacket = isPlainObject(result.value) ? { ...result.value, _privacy: result.metadata } : { value: result.value, _privacy: result.metadata };
|
|
216
|
+
return {
|
|
217
|
+
value: {
|
|
218
|
+
packet: anonymizedPacket,
|
|
219
|
+
redactionMetadata,
|
|
220
|
+
checksum: stableChecksum({ packet: anonymizedPacket, redactionMetadata })
|
|
221
|
+
},
|
|
222
|
+
metadata: result.metadata
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
buildAnonymizationLifecycleEvidence(input) {
|
|
226
|
+
const assetEvents = input.assetEvents ?? [];
|
|
227
|
+
const readModels = input.readModels ?? [];
|
|
228
|
+
const evidencePackets = input.evidencePackets ?? [];
|
|
229
|
+
const redactedFields = [
|
|
230
|
+
...assetEvents.flatMap((item) => item.metadata.redactedFields),
|
|
231
|
+
...readModels.flatMap((item) => item.metadata.redactedFields),
|
|
232
|
+
...evidencePackets.flatMap((item) => item.metadata.redactedFields)
|
|
233
|
+
];
|
|
234
|
+
return {
|
|
235
|
+
eventType: "AnonymizationApplied",
|
|
236
|
+
policyVersion: input.context.policyVersion ?? ANONYMIZATION_POLICY_VERSION,
|
|
237
|
+
jobId: input.context.jobId,
|
|
238
|
+
reason: input.context.reason,
|
|
239
|
+
appliedAt: (input.context.redactedAt ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
240
|
+
tenantId: input.context.tenantId,
|
|
241
|
+
spaceId: input.context.spaceId ?? null,
|
|
242
|
+
counts: {
|
|
243
|
+
assetEvents: assetEvents.length,
|
|
244
|
+
readModels: readModels.length,
|
|
245
|
+
evidencePackets: evidencePackets.length,
|
|
246
|
+
redactedFields: redactedFields.length
|
|
247
|
+
},
|
|
248
|
+
records: [
|
|
249
|
+
...assetEvents.map((item) => ({
|
|
250
|
+
recordClass: "asset_event",
|
|
251
|
+
recordId: item.event.id,
|
|
252
|
+
subjectType: item.event.subjectType,
|
|
253
|
+
subjectId: item.event.subjectId,
|
|
254
|
+
fieldManifest: item.metadata.redactedFields.map(
|
|
255
|
+
({ fieldPath, method, beforeChecksum }) => ({
|
|
256
|
+
fieldPath,
|
|
257
|
+
method,
|
|
258
|
+
beforeChecksum
|
|
259
|
+
})
|
|
260
|
+
)
|
|
261
|
+
})),
|
|
262
|
+
...readModels.map((item) => ({
|
|
263
|
+
recordClass: "read_model",
|
|
264
|
+
recordId: item.record.id,
|
|
265
|
+
subjectType: item.modelKind,
|
|
266
|
+
subjectId: item.record.id,
|
|
267
|
+
fieldManifest: item.metadata.redactedFields.map(
|
|
268
|
+
({ fieldPath, method, beforeChecksum }) => ({
|
|
269
|
+
fieldPath,
|
|
270
|
+
method,
|
|
271
|
+
beforeChecksum
|
|
272
|
+
})
|
|
273
|
+
)
|
|
274
|
+
})),
|
|
275
|
+
...evidencePackets.map((item) => ({
|
|
276
|
+
recordClass: "evidence_packet",
|
|
277
|
+
recordId: item.packet.id,
|
|
278
|
+
fieldManifest: item.metadata.redactedFields.map(
|
|
279
|
+
({ fieldPath, method, beforeChecksum }) => ({
|
|
280
|
+
fieldPath,
|
|
281
|
+
method,
|
|
282
|
+
beforeChecksum
|
|
283
|
+
})
|
|
284
|
+
)
|
|
285
|
+
}))
|
|
286
|
+
],
|
|
287
|
+
preservedSemantics: DEFAULT_PRESERVED_SEMANTICS
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// privacy/index.ts
|
|
293
|
+
var PLATFORM_PRIVACY_POLICY_VERSION = "fabric-platform-privacy-v1";
|
|
294
|
+
var defaultEngine = new AnonymizationEngine();
|
|
295
|
+
function anonymizeJsonValue(value, context, dataClass) {
|
|
296
|
+
return defaultEngine.anonymizeJsonValue(value, context, dataClass);
|
|
297
|
+
}
|
|
298
|
+
function anonymizeAssetEventPayload(event, context) {
|
|
299
|
+
return defaultEngine.anonymizeAssetEventPayload(event, context);
|
|
300
|
+
}
|
|
301
|
+
function anonymizeEvidencePacket(packet, context) {
|
|
302
|
+
return defaultEngine.anonymizeEvidencePacket(packet, context);
|
|
303
|
+
}
|
|
304
|
+
function buildAnonymizationLifecycleEvidence(input) {
|
|
305
|
+
return defaultEngine.buildAnonymizationLifecycleEvidence(input);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export { ANONYMIZATION_POLICY_VERSION, AnonymizationEngine, FieldRedactor, PLATFORM_PRIVACY_POLICY_VERSION, anonymizeAssetEventPayload, anonymizeEvidencePacket, anonymizeJsonValue, buildAnonymizationLifecycleEvidence, stableChecksum };
|
|
309
|
+
//# sourceMappingURL=chunk-X7WC4AYC.js.map
|
|
310
|
+
//# sourceMappingURL=chunk-X7WC4AYC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../privacy/engine.ts","../privacy/index.ts"],"names":[],"mappings":"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","file":"chunk-X7WC4AYC.js","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\ninterface FieldPolicy {\n\tmethod: RedactionMethod;\n\tmatch: \"key\" | \"path\";\n\tvalue: 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\nconst DEFAULT_PRESERVED_SEMANTICS = [\n\t\"tenantId\",\n\t\"spaceId\",\n\t\"subjectType\",\n\t\"subjectId\",\n\t\"eventType\",\n\t\"sequence\",\n\t\"occurredAt\",\n\t\"recordedAt\",\n\t\"actionInvocationId\",\n\t\"correlationId\",\n\t\"causationId\",\n\t\"financialDecisionFacts\",\n];\n\nconst FIELD_POLICIES: FieldPolicy[] = [\n\t{ match: \"key\", value: \"password\", method: \"drop\" },\n\t{ match: \"key\", value: \"token\", method: \"drop\" },\n\t{ match: \"key\", value: \"apiKey\", method: \"drop\" },\n\t{ match: \"key\", value: \"authorization\", method: \"drop\" },\n\t{ match: \"key\", value: \"ssn\", method: \"nullify\" },\n\t{ match: \"key\", value: \"ssnLast4\", method: \"nullify\" },\n\t{ match: \"key\", value: \"socialSecurityNumber\", method: \"nullify\" },\n\t{ match: \"key\", value: \"dateOfBirth\", method: \"nullify\" },\n\t{ match: \"key\", value: \"dob\", method: \"nullify\" },\n\t{ match: \"key\", value: \"driverLicense\", method: \"nullify\" },\n\t{ match: \"key\", value: \"firstName\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"middleName\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"lastName\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"fullName\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"name\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"email\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"emailAddress\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"phone\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"phoneNumber\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"mobilePhone\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"homePhone\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"workPhone\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"street\", method: \"nullify\" },\n\t{ match: \"key\", value: \"streetAddress\", method: \"nullify\" },\n\t{ match: \"key\", value: \"address\", method: \"nullify\" },\n\t{ match: \"key\", value: \"mailingAddress\", method: \"nullify\" },\n\t{ match: \"key\", value: \"partnerLeadId\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"externalLeadId\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"loanApplicationId\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"vin\", method: \"tokenize\" },\n\t{ match: \"key\", value: \"rawVin\", method: \"tokenize\" },\n];\n\nconst NORMALIZED_FIELD_POLICIES = FIELD_POLICIES.map((policy) => ({\n\t...policy,\n\tvalue: normalizeKey(policy.value),\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(path: string, key?: string): FieldPolicy | undefined {\n\tconst normalizedPath = normalizeKey(path);\n\tconst normalizedKey = key ? normalizeKey(key) : undefined;\n\n\treturn NORMALIZED_FIELD_POLICIES.find((policy) => {\n\t\tif (policy.match === \"key\") {\n\t\t\treturn policy.value === normalizedKey;\n\t\t}\n\n\t\treturn policy.value === 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\tkey?: string,\n): unknown {\n\tconst fieldPolicy = policyForPath(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),\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\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): 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: DEFAULT_PRESERVED_SEMANTICS,\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\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) as TValue;\n\n\t\treturn {\n\t\t\tvalue: anonymizedValue,\n\t\t\tmetadata: buildMetadata(context, dataClass, redactedFields),\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: DEFAULT_PRESERVED_SEMANTICS,\n\t\t};\n\t}\n}\n","export const PLATFORM_PRIVACY_POLICY_VERSION = \"fabric-platform-privacy-v1\";\n\nexport type RedactionMethod = \"nullify\" | \"mask\" | \"hash\" | \"tokenize\" | \"generalize\" | \"drop\";\n\nexport { ANONYMIZATION_POLICY_VERSION } from \"./engine\";\nexport {\n\tAnonymizationEngine,\n\tFieldRedactor,\n\tstableChecksum,\n\ttype AssetEventLike,\n\ttype EvidencePacketLike,\n\ttype AnonymizationLifecycleEvidence,\n} from \"./engine\";\n\nimport {\n\tAnonymizationEngine,\n\ttype AssetEventLike,\n\ttype EvidencePacketLike,\n\ttype AnonymizationLifecycleEvidence,\n} from \"./engine\";\n\nconst defaultEngine = new AnonymizationEngine();\n\nexport function anonymizeJsonValue<TValue>(\n\tvalue: TValue,\n\tcontext: import(\"./index\").AnonymizationContext,\n\tdataClass: import(\"./index\").PlatformDataClass,\n): import(\"./index\").AnonymizationResult<TValue> {\n\treturn defaultEngine.anonymizeJsonValue(value, context, dataClass);\n}\n\nexport function anonymizeAssetEventPayload(\n\tevent: AssetEventLike,\n\tcontext: import(\"./index\").AnonymizationContext,\n): import(\"./index\").AnonymizationResult<unknown> {\n\treturn defaultEngine.anonymizeAssetEventPayload(event, context);\n}\n\nexport function anonymizeEvidencePacket(\n\tpacket: EvidencePacketLike,\n\tcontext: import(\"./index\").AnonymizationContext,\n): import(\"./index\").AnonymizationResult<Pick<EvidencePacketLike, \"packet\" | \"redactionMetadata\" | \"checksum\">> {\n\treturn defaultEngine.anonymizeEvidencePacket(packet, context);\n}\n\nexport function buildAnonymizationLifecycleEvidence(input: {\n\tcontext: import(\"./index\").AnonymizationContext;\n\tassetEvents?: Array<{ event: AssetEventLike; metadata: import(\"./index\").AnonymizationMetadata }>;\n\treadModels?: Array<{\n\t\tmodelKind: string;\n\t\trecord: Record<string, unknown> & { id: string };\n\t\tmetadata: import(\"./index\").AnonymizationMetadata;\n\t}>;\n\tevidencePackets?: Array<{ packet: EvidencePacketLike; metadata: import(\"./index\").AnonymizationMetadata }>;\n}): AnonymizationLifecycleEvidence {\n\treturn defaultEngine.buildAnonymizationLifecycleEvidence(input);\n}\n\nexport type PlatformDataClass =\n\t| \"asset_event\"\n\t| \"read_model\"\n\t| \"raw_payload\"\n\t| \"evidence_packet\"\n\t| \"action_evidence\"\n\t| \"access_event\";\n\nexport interface RedactionRule {\n\tfieldPath: string;\n\tmethod: RedactionMethod;\n\treason: string;\n\tdataClass?: PlatformDataClass;\n}\n\nexport interface DataClassificationRule {\n\tfieldPath: string;\n\tclassification: string;\n\tcontainsDirectIdentifier?: boolean;\n\tcontainsSensitiveData?: boolean;\n}\n\nexport interface AnonymizationContext {\n\ttenantId: string;\n\tspaceId?: string | null;\n\tjobId: string;\n\treason: string;\n\tredactedAt?: Date;\n\tpolicyVersion?: string;\n}\n\nexport interface AnonymizationFieldMetadata {\n\tfieldPath: string;\n\tmethod: RedactionMethod;\n\tpolicyVersion: string;\n\tjobId: string;\n\tredactedAt: string;\n\treason: string;\n\tdataClass: PlatformDataClass;\n\tbeforeChecksum: string;\n}\n\nexport interface AnonymizationMetadata {\n\tredactionState: \"anonymized\";\n\tpolicyVersion: string;\n\tjobId: string;\n\tredactedAt: string;\n\treason: string;\n\tdataClass: PlatformDataClass;\n\tredactedFields: AnonymizationFieldMetadata[];\n\tpreservedSemantics: string[];\n}\n\nexport interface AnonymizationResult<TValue> {\n\tvalue: TValue;\n\tmetadata: AnonymizationMetadata;\n}\n\nexport interface AnalyticsDataContractSource {\n\tname: string;\n\tprivacyClass:\n\t\t| \"raw\"\n\t\t| \"operational_pii\"\n\t\t| \"tenant_scoped_tokenized\"\n\t\t| \"anonymized\"\n\t\t| \"aggregated\"\n\t\t| \"differentially_minimized\";\n\tcontainsDirectIdentifiers?: boolean;\n\tcontainsGloballyStablePersonTokens?: boolean;\n\tanonymizationPolicyVersion?: string;\n\tminimumGroupSize?: number;\n}\n\nexport interface AnalyticsDataContract {\n\tcontractId: string;\n\tstatus: \"draft\" | \"accepted\" | \"deprecated\";\n\tcrossTenant: boolean;\n\tacceptedBy?: string;\n\tacceptedAt?: string;\n\tadrReference?: string;\n\tsources: AnalyticsDataContractSource[];\n}\n\nexport interface AnalyticsEligibilityDecision {\n\teligible: boolean;\n\tpolicyVersion: string;\n\treasons: string[];\n}\n\nexport interface RetentionRule {\n\tdataClass: PlatformDataClass;\n\tretainForDays: number;\n\tafterRetention: \"delete\" | \"anonymize\" | \"archive\";\n\tlegalHoldExempt?: boolean;\n}\n"]}
|