@mcoda/mswarm 0.1.90 → 0.1.91
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/codali-executor.d.ts +107 -6
- package/dist/codali-executor.d.ts.map +1 -1
- package/dist/codali-executor.js +500 -26
- package/dist/codali-executor.js.map +1 -1
- package/dist/runtime.d.ts +4 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +18 -5
- package/dist/runtime.js.map +1 -1
- package/dist/vendor/codali/cli/DatasetCommand.d.ts +38 -0
- package/dist/vendor/codali/cli/DatasetCommand.d.ts.map +1 -0
- package/dist/vendor/codali/cli/DatasetCommand.js +959 -0
- package/dist/vendor/codali/cli/EvalCommand.d.ts +3 -0
- package/dist/vendor/codali/cli/EvalCommand.d.ts.map +1 -1
- package/dist/vendor/codali/cli/EvalCommand.js +55 -1
- package/dist/vendor/codali/cli/ImprovementCommand.d.ts +97 -0
- package/dist/vendor/codali/cli/ImprovementCommand.d.ts.map +1 -0
- package/dist/vendor/codali/cli/ImprovementCommand.js +1879 -0
- package/dist/vendor/codali/cli.d.ts.map +1 -1
- package/dist/vendor/codali/cli.js +15 -0
- package/dist/vendor/codali/dataset-cli.d.ts +3 -0
- package/dist/vendor/codali/dataset-cli.d.ts.map +1 -0
- package/dist/vendor/codali/dataset-cli.js +30 -0
- package/dist/vendor/codali/eval/CodaliGatewayLiveHarness.d.ts +90 -1
- package/dist/vendor/codali/eval/CodaliGatewayLiveHarness.d.ts.map +1 -1
- package/dist/vendor/codali/eval/CodaliGatewayLiveHarness.js +443 -9
- package/dist/vendor/codali/eval/GatewayDatasetEval.d.ts +70 -0
- package/dist/vendor/codali/eval/GatewayDatasetEval.d.ts.map +1 -0
- package/dist/vendor/codali/eval/GatewayDatasetEval.js +477 -0
- package/dist/vendor/codali/eval/GatewayEvalSuite.d.ts +52 -0
- package/dist/vendor/codali/eval/GatewayEvalSuite.d.ts.map +1 -1
- package/dist/vendor/codali/eval/GatewayEvalSuite.js +135 -1
- package/dist/vendor/codali/gateway/CodaliGateway.d.ts +4 -0
- package/dist/vendor/codali/gateway/CodaliGateway.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/CodaliGateway.js +37 -1
- package/dist/vendor/codali/gateway/CodaliGatewaySchemas.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/CodaliGatewaySchemas.js +0 -4
- package/dist/vendor/codali/gateway/CodaliGatewayStore.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/CodaliGatewayStore.js +1 -0
- package/dist/vendor/codali/gateway/GatewayPlanner.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/GatewayPlanner.js +355 -41
- package/dist/vendor/codali/gateway/GatewayStateMachine.d.ts +1 -0
- package/dist/vendor/codali/gateway/GatewayStateMachine.d.ts.map +1 -1
- package/dist/vendor/codali/gateway/GatewayStateMachine.js +221 -5
- package/dist/vendor/codali/improvement/CandidateReleaseBuilder.d.ts +201 -0
- package/dist/vendor/codali/improvement/CandidateReleaseBuilder.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/CandidateReleaseBuilder.js +1175 -0
- package/dist/vendor/codali/improvement/DatasetEligibilityGate.d.ts +75 -0
- package/dist/vendor/codali/improvement/DatasetEligibilityGate.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/DatasetEligibilityGate.js +497 -0
- package/dist/vendor/codali/improvement/DatasetExportManifestReader.d.ts +88 -0
- package/dist/vendor/codali/improvement/DatasetExportManifestReader.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/DatasetExportManifestReader.js +333 -0
- package/dist/vendor/codali/improvement/DocdexRetrievalCandidateBuilder.d.ts +192 -0
- package/dist/vendor/codali/improvement/DocdexRetrievalCandidateBuilder.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/DocdexRetrievalCandidateBuilder.js +625 -0
- package/dist/vendor/codali/improvement/EvalReplayCandidateBuilder.d.ts +173 -0
- package/dist/vendor/codali/improvement/EvalReplayCandidateBuilder.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/EvalReplayCandidateBuilder.js +363 -0
- package/dist/vendor/codali/improvement/FineTuneJobPlanner.d.ts +281 -0
- package/dist/vendor/codali/improvement/FineTuneJobPlanner.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/FineTuneJobPlanner.js +823 -0
- package/dist/vendor/codali/improvement/ImprovementEvalRunner.d.ts +50 -0
- package/dist/vendor/codali/improvement/ImprovementEvalRunner.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/ImprovementEvalRunner.js +648 -0
- package/dist/vendor/codali/improvement/ImprovementPolicy.d.ts +272 -0
- package/dist/vendor/codali/improvement/ImprovementPolicy.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/ImprovementPolicy.js +1450 -0
- package/dist/vendor/codali/improvement/ModelRouterCandidateBuilder.d.ts +186 -0
- package/dist/vendor/codali/improvement/ModelRouterCandidateBuilder.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/ModelRouterCandidateBuilder.js +880 -0
- package/dist/vendor/codali/improvement/OperatorInspector.d.ts +182 -0
- package/dist/vendor/codali/improvement/OperatorInspector.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/OperatorInspector.js +604 -0
- package/dist/vendor/codali/improvement/ProductionGovernance.d.ts +91 -0
- package/dist/vendor/codali/improvement/ProductionGovernance.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/ProductionGovernance.js +329 -0
- package/dist/vendor/codali/improvement/PromptSchemaToolMetadataCandidateBuilder.d.ts +152 -0
- package/dist/vendor/codali/improvement/PromptSchemaToolMetadataCandidateBuilder.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/PromptSchemaToolMetadataCandidateBuilder.js +480 -0
- package/dist/vendor/codali/improvement/PublishOrchestrator.d.ts +113 -0
- package/dist/vendor/codali/improvement/PublishOrchestrator.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/PublishOrchestrator.js +590 -0
- package/dist/vendor/codali/improvement/ReleaseOutcomeReporter.d.ts +133 -0
- package/dist/vendor/codali/improvement/ReleaseOutcomeReporter.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/ReleaseOutcomeReporter.js +501 -0
- package/dist/vendor/codali/improvement/StorageServiceImprovementClient.d.ts +71 -0
- package/dist/vendor/codali/improvement/StorageServiceImprovementClient.d.ts.map +1 -0
- package/dist/vendor/codali/improvement/StorageServiceImprovementClient.js +245 -0
- package/dist/vendor/codali/index.d.ts +43 -0
- package/dist/vendor/codali/index.d.ts.map +1 -1
- package/dist/vendor/codali/index.js +21 -0
- package/dist/vendor/codali/runtime/CodaliRuntime.d.ts +0 -2
- package/dist/vendor/codali/runtime/CodaliRuntime.d.ts.map +1 -1
- package/dist/vendor/codali/runtime/CodaliRuntime.js +0 -5
- package/dist/vendor/codali/storage/CodaliDatasetPrivacyEngine.d.ts +138 -0
- package/dist/vendor/codali/storage/CodaliDatasetPrivacyEngine.d.ts.map +1 -0
- package/dist/vendor/codali/storage/CodaliDatasetPrivacyEngine.js +417 -0
- package/dist/vendor/codali/storage/CodaliFeedbackReviewIngestion.d.ts +50 -0
- package/dist/vendor/codali/storage/CodaliFeedbackReviewIngestion.d.ts.map +1 -0
- package/dist/vendor/codali/storage/CodaliFeedbackReviewIngestion.js +141 -0
- package/dist/vendor/codali/storage/CodaliStorageContracts.d.ts +337 -0
- package/dist/vendor/codali/storage/CodaliStorageContracts.d.ts.map +1 -0
- package/dist/vendor/codali/storage/CodaliStorageContracts.js +1555 -0
- package/dist/vendor/codali/storage/DatasetExportJob.d.ts +51 -0
- package/dist/vendor/codali/storage/DatasetExportJob.d.ts.map +1 -0
- package/dist/vendor/codali/storage/DatasetExportJob.js +358 -0
- package/dist/vendor/codali/storage/DatasetReviewQueue.d.ts +98 -0
- package/dist/vendor/codali/storage/DatasetReviewQueue.d.ts.map +1 -0
- package/dist/vendor/codali/storage/DatasetReviewQueue.js +426 -0
- package/dist/vendor/codali/storage/GatewayDatasetStore.d.ts +233 -0
- package/dist/vendor/codali/storage/GatewayDatasetStore.d.ts.map +1 -0
- package/dist/vendor/codali/storage/GatewayDatasetStore.js +2070 -0
- package/package.json +3 -3
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { type CodaliStorageObjectPrivacyFlags, type CodaliStorageObjectRef, type CodaliStorageObjectRetentionClass, type CodaliStoragePrivacyClassification, type CodaliStoragePrivacyMetadata } from "./CodaliStorageContracts.js";
|
|
2
|
+
export type CodaliDatasetPrivacyPurpose = "training" | "export" | "eval" | "replay" | "durable_persistence";
|
|
3
|
+
export type CodaliDatasetSecretFindingKind = "sensitive_key" | "bearer_token" | "openai_api_key" | "cloud_access_key" | "github_token" | "jwt" | "private_key" | "env_secret_assignment";
|
|
4
|
+
export type CodaliDatasetEligibilityBlockerCode = "secrets_detected" | "privacy_training_not_allowed" | "privacy_export_not_allowed" | "object_training_not_allowed" | "object_export_not_allowed" | "object_eval_not_allowed" | "object_replay_not_allowed" | "retention_do_not_store" | "redaction_required" | "policy_override_requires_admin_audit" | "policy_override_not_requested" | "policy_override_hard_blocked";
|
|
5
|
+
export interface CodaliDatasetSecretFinding {
|
|
6
|
+
kind: CodaliDatasetSecretFindingKind;
|
|
7
|
+
path: string;
|
|
8
|
+
redacted: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface CodaliDatasetSecretDetectionResult<TPayload = unknown> {
|
|
11
|
+
containsSecrets: boolean;
|
|
12
|
+
findings: CodaliDatasetSecretFinding[];
|
|
13
|
+
redactedPayload: TPayload;
|
|
14
|
+
}
|
|
15
|
+
export interface CodaliDatasetTenantScope {
|
|
16
|
+
tenantId: string;
|
|
17
|
+
tenantSalt: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CodaliDatasetIdentifierInput {
|
|
20
|
+
tenantId: string;
|
|
21
|
+
requesterId?: string;
|
|
22
|
+
conversationId?: string;
|
|
23
|
+
repoId?: string;
|
|
24
|
+
sourceId?: string;
|
|
25
|
+
reviewerId?: string;
|
|
26
|
+
deletionGroupId?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CodaliDatasetHashedIdentifiers {
|
|
29
|
+
tenantHash: string;
|
|
30
|
+
requesterHash?: string;
|
|
31
|
+
conversationHash?: string;
|
|
32
|
+
repoHash?: string;
|
|
33
|
+
sourceHash?: string;
|
|
34
|
+
reviewerHash?: string;
|
|
35
|
+
deletionGroupHash?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface CodaliDatasetPrivacyAllowances {
|
|
38
|
+
uploadAllowed?: boolean;
|
|
39
|
+
trainingAllowed?: boolean;
|
|
40
|
+
evalAllowed?: boolean;
|
|
41
|
+
replayAllowed?: boolean;
|
|
42
|
+
exportAllowed?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface CodaliDatasetPrivacyMetadataInput {
|
|
45
|
+
tenant: CodaliDatasetTenantScope;
|
|
46
|
+
identifiers: Omit<CodaliDatasetIdentifierInput, "tenantId">;
|
|
47
|
+
inputPayload?: unknown;
|
|
48
|
+
outputPayload?: unknown;
|
|
49
|
+
evidencePayloads?: unknown[];
|
|
50
|
+
classification?: CodaliStoragePrivacyClassification;
|
|
51
|
+
containsPersonalData?: boolean;
|
|
52
|
+
containsTenantPrivateData?: boolean;
|
|
53
|
+
containsSourceCode?: boolean;
|
|
54
|
+
containsCustomerData?: boolean;
|
|
55
|
+
personalDataRedacted?: boolean;
|
|
56
|
+
allowances?: CodaliDatasetPrivacyAllowances;
|
|
57
|
+
retentionClass?: CodaliStorageObjectRetentionClass;
|
|
58
|
+
policyTags?: string[];
|
|
59
|
+
retentionUntil?: string;
|
|
60
|
+
metadata?: Record<string, unknown>;
|
|
61
|
+
now?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface CodaliDatasetPrivacyEnvelope {
|
|
64
|
+
privacy: CodaliStoragePrivacyMetadata;
|
|
65
|
+
privacyFlags: CodaliStorageObjectPrivacyFlags;
|
|
66
|
+
hashedIdentifiers: CodaliDatasetHashedIdentifiers;
|
|
67
|
+
redactedPayloads: {
|
|
68
|
+
inputPayload?: unknown;
|
|
69
|
+
outputPayload?: unknown;
|
|
70
|
+
evidencePayloads?: unknown[];
|
|
71
|
+
};
|
|
72
|
+
secretFindings: CodaliDatasetSecretFinding[];
|
|
73
|
+
eligibility: {
|
|
74
|
+
trainingAllowed: boolean;
|
|
75
|
+
evalAllowed: boolean;
|
|
76
|
+
replayAllowed: boolean;
|
|
77
|
+
exportAllowed: boolean;
|
|
78
|
+
durablePersistenceAllowed: boolean;
|
|
79
|
+
blockers: CodaliDatasetEligibilityBlocker[];
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export interface CodaliDatasetEligibilityBlocker {
|
|
83
|
+
code: CodaliDatasetEligibilityBlockerCode;
|
|
84
|
+
message: string;
|
|
85
|
+
path?: string;
|
|
86
|
+
}
|
|
87
|
+
export interface CodaliDatasetEligibilityDecision {
|
|
88
|
+
purpose: CodaliDatasetPrivacyPurpose;
|
|
89
|
+
allowed: boolean;
|
|
90
|
+
blockers: CodaliDatasetEligibilityBlocker[];
|
|
91
|
+
auditEvents?: CodaliDatasetPolicyAuditEvent[];
|
|
92
|
+
}
|
|
93
|
+
export interface CodaliDatasetPolicyOverride {
|
|
94
|
+
purpose: CodaliDatasetPrivacyPurpose;
|
|
95
|
+
allow: boolean;
|
|
96
|
+
adminActorId?: string;
|
|
97
|
+
auditEventId?: string;
|
|
98
|
+
reason?: string;
|
|
99
|
+
approvedAt?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface CodaliDatasetPolicyAuditEvent {
|
|
102
|
+
auditEventId: string;
|
|
103
|
+
adminActorId: string;
|
|
104
|
+
purpose: CodaliDatasetPrivacyPurpose;
|
|
105
|
+
reason: string;
|
|
106
|
+
approvedAt: string;
|
|
107
|
+
originalBlockers: CodaliDatasetEligibilityBlockerCode[];
|
|
108
|
+
}
|
|
109
|
+
export interface CodaliDatasetPayloadReadInput<TPayload> {
|
|
110
|
+
purpose: Exclude<CodaliDatasetPrivacyPurpose, "durable_persistence">;
|
|
111
|
+
objectRef: CodaliStorageObjectRef;
|
|
112
|
+
privacy: CodaliStoragePrivacyMetadata;
|
|
113
|
+
policyOverride?: CodaliDatasetPolicyOverride;
|
|
114
|
+
readPayload: (objectRef: CodaliStorageObjectRef) => Promise<TPayload> | TPayload;
|
|
115
|
+
}
|
|
116
|
+
export type CodaliDatasetPayloadReadResult<TPayload> = {
|
|
117
|
+
ok: true;
|
|
118
|
+
decision: CodaliDatasetEligibilityDecision;
|
|
119
|
+
payload: TPayload;
|
|
120
|
+
} | {
|
|
121
|
+
ok: false;
|
|
122
|
+
decision: CodaliDatasetEligibilityDecision;
|
|
123
|
+
};
|
|
124
|
+
export declare class CodaliDatasetPrivacyError extends Error {
|
|
125
|
+
readonly decision: CodaliDatasetEligibilityDecision;
|
|
126
|
+
constructor(decision: CodaliDatasetEligibilityDecision);
|
|
127
|
+
}
|
|
128
|
+
export declare const detectAndRedactCodaliDatasetSecrets: <TPayload = unknown>(payload: TPayload) => CodaliDatasetSecretDetectionResult<TPayload>;
|
|
129
|
+
export declare const hashCodaliDatasetIdentifier: (tenant: CodaliDatasetTenantScope, scope: keyof CodaliDatasetHashedIdentifiers, value: string) => string;
|
|
130
|
+
export declare const hashCodaliDatasetIdentifiers: (tenant: CodaliDatasetTenantScope, identifiers: Omit<CodaliDatasetIdentifierInput, "tenantId">) => CodaliDatasetHashedIdentifiers;
|
|
131
|
+
export declare const evaluateCodaliDatasetDurablePersistence: (retentionClass: CodaliStorageObjectRetentionClass) => CodaliDatasetEligibilityDecision;
|
|
132
|
+
export declare const evaluateCodaliDatasetObjectPayloadRead: (purpose: Exclude<CodaliDatasetPrivacyPurpose, "durable_persistence">, objectRef: CodaliStorageObjectRef, privacy: CodaliStoragePrivacyMetadata) => CodaliDatasetEligibilityDecision;
|
|
133
|
+
export declare const applyCodaliDatasetPolicyOverride: (decision: CodaliDatasetEligibilityDecision, override?: CodaliDatasetPolicyOverride) => CodaliDatasetEligibilityDecision;
|
|
134
|
+
export declare const assertCodaliDatasetObjectPayloadReadAllowed: (purpose: Exclude<CodaliDatasetPrivacyPurpose, "durable_persistence">, objectRef: CodaliStorageObjectRef, privacy: CodaliStoragePrivacyMetadata) => void;
|
|
135
|
+
export declare const assertCodaliDatasetDurablePersistenceAllowed: (retentionClass: CodaliStorageObjectRetentionClass) => void;
|
|
136
|
+
export declare const readCodaliDatasetObjectPayload: <TPayload>(input: CodaliDatasetPayloadReadInput<TPayload>) => Promise<CodaliDatasetPayloadReadResult<TPayload>>;
|
|
137
|
+
export declare const generateCodaliDatasetPrivacyMetadata: (input: CodaliDatasetPrivacyMetadataInput) => CodaliDatasetPrivacyEnvelope;
|
|
138
|
+
//# sourceMappingURL=CodaliDatasetPrivacyEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodaliDatasetPrivacyEngine.d.ts","sourceRoot":"","sources":["../../src/storage/CodaliDatasetPrivacyEngine.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,+BAA+B,EACpC,KAAK,sBAAsB,EAC3B,KAAK,iCAAiC,EACtC,KAAK,kCAAkC,EACvC,KAAK,4BAA4B,EAClC,MAAM,6BAA6B,CAAC;AAErC,MAAM,MAAM,2BAA2B,GACnC,UAAU,GACV,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,qBAAqB,CAAC;AAE1B,MAAM,MAAM,8BAA8B,GACtC,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,kBAAkB,GAClB,cAAc,GACd,KAAK,GACL,aAAa,GACb,uBAAuB,CAAC;AAE5B,MAAM,MAAM,mCAAmC,GAC3C,kBAAkB,GAClB,8BAA8B,GAC9B,4BAA4B,GAC5B,6BAA6B,GAC7B,2BAA2B,GAC3B,yBAAyB,GACzB,2BAA2B,GAC3B,wBAAwB,GACxB,oBAAoB,GACpB,sCAAsC,GACtC,+BAA+B,GAC/B,8BAA8B,CAAC;AAEnC,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,8BAA8B,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kCAAkC,CAAC,QAAQ,GAAG,OAAO;IACpE,eAAe,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,eAAe,EAAE,QAAQ,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,8BAA8B;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA8B;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,iCAAiC;IAChD,MAAM,EAAE,wBAAwB,CAAC;IACjC,WAAW,EAAE,IAAI,CAAC,4BAA4B,EAAE,UAAU,CAAC,CAAC;IAC5D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,kCAAkC,CAAC;IACpD,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,8BAA8B,CAAC;IAC5C,cAAc,CAAC,EAAE,iCAAiC,CAAC;IACnD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,4BAA4B,CAAC;IACtC,YAAY,EAAE,+BAA+B,CAAC;IAC9C,iBAAiB,EAAE,8BAA8B,CAAC;IAClD,gBAAgB,EAAE;QAChB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;KAC9B,CAAC;IACF,cAAc,EAAE,0BAA0B,EAAE,CAAC;IAC7C,WAAW,EAAE;QACX,eAAe,EAAE,OAAO,CAAC;QACzB,WAAW,EAAE,OAAO,CAAC;QACrB,aAAa,EAAE,OAAO,CAAC;QACvB,aAAa,EAAE,OAAO,CAAC;QACvB,yBAAyB,EAAE,OAAO,CAAC;QACnC,QAAQ,EAAE,+BAA+B,EAAE,CAAC;KAC7C,CAAC;CACH;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,mCAAmC,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,2BAA2B,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,+BAA+B,EAAE,CAAC;IAC5C,WAAW,CAAC,EAAE,6BAA6B,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,2BAA2B,CAAC;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,6BAA6B;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,2BAA2B,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,mCAAmC,EAAE,CAAC;CACzD;AAED,MAAM,WAAW,6BAA6B,CAAC,QAAQ;IACrD,OAAO,EAAE,OAAO,CAAC,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;IACrE,SAAS,EAAE,sBAAsB,CAAC;IAClC,OAAO,EAAE,4BAA4B,CAAC;IACtC,cAAc,CAAC,EAAE,2BAA2B,CAAC;IAC7C,WAAW,EAAE,CAAC,SAAS,EAAE,sBAAsB,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;CAClF;AAED,MAAM,MAAM,8BAA8B,CAAC,QAAQ,IAC/C;IACE,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,gCAAgC,CAAC;IAC3C,OAAO,EAAE,QAAQ,CAAC;CACnB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,QAAQ,EAAE,gCAAgC,CAAC;CAC5C,CAAC;AAEN,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;gBAExC,QAAQ,EAAE,gCAAgC;CASvD;AA4ID,eAAO,MAAM,mCAAmC,GAAI,QAAQ,GAAG,OAAO,EACpE,SAAS,QAAQ,KAChB,kCAAkC,CAAC,QAAQ,CAQ7C,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,QAAQ,wBAAwB,EAChC,OAAO,MAAM,8BAA8B,EAC3C,OAAO,MAAM,KACZ,MAoBF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,QAAQ,wBAAwB,EAChC,aAAa,IAAI,CAAC,4BAA4B,EAAE,UAAU,CAAC,KAC1D,8BA4BF,CAAC;AAEF,eAAO,MAAM,uCAAuC,GAClD,gBAAgB,iCAAiC,KAChD,gCAeF,CAAC;AAEF,eAAO,MAAM,sCAAsC,GACjD,SAAS,OAAO,CAAC,2BAA2B,EAAE,qBAAqB,CAAC,EACpE,WAAW,sBAAsB,EACjC,SAAS,4BAA4B,KACpC,gCAiGF,CAAC;AAgBF,eAAO,MAAM,gCAAgC,GAC3C,UAAU,gCAAgC,EAC1C,WAAW,2BAA2B,KACrC,gCAkEF,CAAC;AAEF,eAAO,MAAM,2CAA2C,GACtD,SAAS,OAAO,CAAC,2BAA2B,EAAE,qBAAqB,CAAC,EACpE,WAAW,sBAAsB,EACjC,SAAS,4BAA4B,KACpC,IAOF,CAAC;AAEF,eAAO,MAAM,4CAA4C,GACvD,gBAAgB,iCAAiC,KAChD,IAGF,CAAC;AAEF,eAAO,MAAM,8BAA8B,GAAU,QAAQ,EAC3D,OAAO,6BAA6B,CAAC,QAAQ,CAAC,KAC7C,OAAO,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAiBlD,CAAC;AAEF,eAAO,MAAM,oCAAoC,GAC/C,OAAO,iCAAiC,KACvC,4BAiKF,CAAC"}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import { createHmac } from "node:crypto";
|
|
2
|
+
import { CODALI_STORAGE_CONTRACT_SCHEMA_VERSION, isCodaliStoragePrivacyExportAllowed, isCodaliStoragePrivacyTrainingAllowed, } from "./CodaliStorageContracts.js";
|
|
3
|
+
export class CodaliDatasetPrivacyError extends Error {
|
|
4
|
+
constructor(decision) {
|
|
5
|
+
super(`Codali dataset privacy check failed for ${decision.purpose}: ${decision.blockers
|
|
6
|
+
.map((blocker) => blocker.code)
|
|
7
|
+
.join(", ")}`);
|
|
8
|
+
this.name = "CodaliDatasetPrivacyError";
|
|
9
|
+
this.decision = decision;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const REDACTION_TOKEN = "[redacted]";
|
|
13
|
+
const SENSITIVE_KEY_PATTERNS = [
|
|
14
|
+
/(^|[_-])(api[_-]?key|access[_-]?key|secret|token|password|passwd|credential|authorization|auth[_-]?token|private[_-]?key|signing[_-]?key)([_-]|$)/i,
|
|
15
|
+
];
|
|
16
|
+
const SECRET_VALUE_PATTERNS = [
|
|
17
|
+
{
|
|
18
|
+
kind: "private_key",
|
|
19
|
+
pattern: /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,
|
|
20
|
+
},
|
|
21
|
+
{ kind: "bearer_token", pattern: /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}\b/g },
|
|
22
|
+
{ kind: "openai_api_key", pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g },
|
|
23
|
+
{ kind: "cloud_access_key", pattern: /\bAKIA[0-9A-Z]{16}\b/g },
|
|
24
|
+
{ kind: "github_token", pattern: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g },
|
|
25
|
+
{
|
|
26
|
+
kind: "jwt",
|
|
27
|
+
pattern: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
kind: "env_secret_assignment",
|
|
31
|
+
pattern: /\b(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY)=["']?[^"'\s]{8,}["']?/gi,
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
const PERSONAL_KEY_PATTERNS = [
|
|
35
|
+
/(^|[_-])(email|phone|ssn|person|user[_-]?id|requester)([_-]|$)/i,
|
|
36
|
+
];
|
|
37
|
+
const PERSONAL_VALUE_PATTERNS = [
|
|
38
|
+
/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,
|
|
39
|
+
];
|
|
40
|
+
const HARD_OVERRIDE_BLOCKERS = new Set([
|
|
41
|
+
"secrets_detected",
|
|
42
|
+
"retention_do_not_store",
|
|
43
|
+
"redaction_required",
|
|
44
|
+
]);
|
|
45
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
46
|
+
const hasText = (value) => typeof value === "string" && value.trim().length > 0;
|
|
47
|
+
const normalizeIdentifier = (value) => {
|
|
48
|
+
if (!hasText(value))
|
|
49
|
+
return undefined;
|
|
50
|
+
return value.trim();
|
|
51
|
+
};
|
|
52
|
+
const pathForKey = (basePath, key) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)
|
|
53
|
+
? `${basePath}.${key}`
|
|
54
|
+
: `${basePath}[${JSON.stringify(key)}]`;
|
|
55
|
+
const isSensitiveKey = (key) => SENSITIVE_KEY_PATTERNS.some((pattern) => pattern.test(key));
|
|
56
|
+
const isPersonalKey = (key) => PERSONAL_KEY_PATTERNS.some((pattern) => pattern.test(key));
|
|
57
|
+
const stringContainsPersonalData = (value) => PERSONAL_VALUE_PATTERNS.some((pattern) => {
|
|
58
|
+
pattern.lastIndex = 0;
|
|
59
|
+
return pattern.test(value);
|
|
60
|
+
});
|
|
61
|
+
const redactString = (value, path, findings) => {
|
|
62
|
+
let redacted = value;
|
|
63
|
+
for (const { kind, pattern } of SECRET_VALUE_PATTERNS) {
|
|
64
|
+
pattern.lastIndex = 0;
|
|
65
|
+
if (!pattern.test(redacted))
|
|
66
|
+
continue;
|
|
67
|
+
pattern.lastIndex = 0;
|
|
68
|
+
redacted = redacted.replace(pattern, () => {
|
|
69
|
+
findings.push({ kind, path, redacted: true });
|
|
70
|
+
return REDACTION_TOKEN;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return redacted;
|
|
74
|
+
};
|
|
75
|
+
const redactPayloadValue = (value, path, findings) => {
|
|
76
|
+
if (typeof value === "string")
|
|
77
|
+
return redactString(value, path, findings);
|
|
78
|
+
if (Array.isArray(value)) {
|
|
79
|
+
return value.map((item, index) => redactPayloadValue(item, `${path}[${index}]`, findings));
|
|
80
|
+
}
|
|
81
|
+
if (!isRecord(value))
|
|
82
|
+
return value;
|
|
83
|
+
const redacted = {};
|
|
84
|
+
for (const [key, child] of Object.entries(value)) {
|
|
85
|
+
const childPath = pathForKey(path, key);
|
|
86
|
+
if (isSensitiveKey(key) && child !== null && child !== undefined && child !== "") {
|
|
87
|
+
findings.push({ kind: "sensitive_key", path: childPath, redacted: true });
|
|
88
|
+
redacted[key] = REDACTION_TOKEN;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
redacted[key] = redactPayloadValue(child, childPath, findings);
|
|
92
|
+
}
|
|
93
|
+
return redacted;
|
|
94
|
+
};
|
|
95
|
+
const payloadContainsPersonalData = (value) => {
|
|
96
|
+
if (typeof value === "string")
|
|
97
|
+
return stringContainsPersonalData(value);
|
|
98
|
+
if (Array.isArray(value))
|
|
99
|
+
return value.some(payloadContainsPersonalData);
|
|
100
|
+
if (!isRecord(value))
|
|
101
|
+
return false;
|
|
102
|
+
return Object.entries(value).some(([key, child]) => isPersonalKey(key) || payloadContainsPersonalData(child));
|
|
103
|
+
};
|
|
104
|
+
const metadataContainsSecrets = (privacy) => privacy.metadata?.containsSecrets === true ||
|
|
105
|
+
privacy.metadata?.contains_secrets === true;
|
|
106
|
+
const addBlocker = (blockers, code, message, path) => {
|
|
107
|
+
blockers.push(path ? { code, message, path } : { code, message });
|
|
108
|
+
};
|
|
109
|
+
export const detectAndRedactCodaliDatasetSecrets = (payload) => {
|
|
110
|
+
const findings = [];
|
|
111
|
+
const redactedPayload = redactPayloadValue(payload, "$", findings);
|
|
112
|
+
return {
|
|
113
|
+
containsSecrets: findings.length > 0,
|
|
114
|
+
findings,
|
|
115
|
+
redactedPayload,
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
export const hashCodaliDatasetIdentifier = (tenant, scope, value) => {
|
|
119
|
+
const normalizedTenantId = tenant.tenantId.trim();
|
|
120
|
+
const normalizedTenantSalt = tenant.tenantSalt.trim();
|
|
121
|
+
const normalizedValue = value.trim();
|
|
122
|
+
if (!normalizedTenantId) {
|
|
123
|
+
throw new Error("tenantId is required for Codali dataset identifier hashing");
|
|
124
|
+
}
|
|
125
|
+
if (!normalizedTenantSalt) {
|
|
126
|
+
throw new Error("tenantSalt is required for Codali dataset identifier hashing");
|
|
127
|
+
}
|
|
128
|
+
if (!normalizedValue) {
|
|
129
|
+
throw new Error("value is required for Codali dataset identifier hashing");
|
|
130
|
+
}
|
|
131
|
+
const digest = createHmac("sha256", `${normalizedTenantSalt}:${normalizedTenantId}`)
|
|
132
|
+
.update(`${scope}:${normalizedValue}`)
|
|
133
|
+
.digest("hex");
|
|
134
|
+
return `sha256:${digest}`;
|
|
135
|
+
};
|
|
136
|
+
export const hashCodaliDatasetIdentifiers = (tenant, identifiers) => {
|
|
137
|
+
const tenantId = normalizeIdentifier(tenant.tenantId);
|
|
138
|
+
if (!tenantId) {
|
|
139
|
+
throw new Error("tenantId is required for Codali dataset identifier hashing");
|
|
140
|
+
}
|
|
141
|
+
const hashOptional = (scope, value) => {
|
|
142
|
+
const normalized = normalizeIdentifier(value);
|
|
143
|
+
return normalized
|
|
144
|
+
? hashCodaliDatasetIdentifier(tenant, scope, normalized)
|
|
145
|
+
: undefined;
|
|
146
|
+
};
|
|
147
|
+
return {
|
|
148
|
+
tenantHash: hashCodaliDatasetIdentifier(tenant, "tenantHash", tenantId),
|
|
149
|
+
requesterHash: hashOptional("requesterHash", identifiers.requesterId),
|
|
150
|
+
conversationHash: hashOptional("conversationHash", identifiers.conversationId),
|
|
151
|
+
repoHash: hashOptional("repoHash", identifiers.repoId),
|
|
152
|
+
sourceHash: hashOptional("sourceHash", identifiers.sourceId),
|
|
153
|
+
reviewerHash: hashOptional("reviewerHash", identifiers.reviewerId),
|
|
154
|
+
deletionGroupHash: hashOptional("deletionGroupHash", identifiers.deletionGroupId),
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
export const evaluateCodaliDatasetDurablePersistence = (retentionClass) => {
|
|
158
|
+
const blockers = [];
|
|
159
|
+
if (retentionClass === "do_not_store") {
|
|
160
|
+
addBlocker(blockers, "retention_do_not_store", "Durable persistence is rejected for retention_class=do_not_store.", "$.retentionClass");
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
purpose: "durable_persistence",
|
|
164
|
+
allowed: blockers.length === 0,
|
|
165
|
+
blockers,
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
export const evaluateCodaliDatasetObjectPayloadRead = (purpose, objectRef, privacy) => {
|
|
169
|
+
const blockers = [];
|
|
170
|
+
if (objectRef.retentionClass === "do_not_store") {
|
|
171
|
+
addBlocker(blockers, "retention_do_not_store", "Object payload reads are rejected for retention_class=do_not_store.", "$.retentionClass");
|
|
172
|
+
}
|
|
173
|
+
const containsSecrets = objectRef.privacyFlags.containsSecrets || metadataContainsSecrets(privacy);
|
|
174
|
+
if ((purpose === "training" || purpose === "export") && containsSecrets) {
|
|
175
|
+
addBlocker(blockers, "secrets_detected", "Records containing secrets cannot be training or export eligible.", "$.privacyFlags.containsSecrets");
|
|
176
|
+
}
|
|
177
|
+
if ((purpose === "training" || purpose === "export") &&
|
|
178
|
+
privacy.containsPersonalData &&
|
|
179
|
+
privacy.redactionStatus !== "redacted") {
|
|
180
|
+
addBlocker(blockers, "redaction_required", "Personal data must be redacted before training or export reads.", "$.privacy.redactionStatus");
|
|
181
|
+
}
|
|
182
|
+
if (purpose === "training") {
|
|
183
|
+
if (!isCodaliStoragePrivacyTrainingAllowed(privacy)) {
|
|
184
|
+
addBlocker(blockers, "privacy_training_not_allowed", "Privacy metadata does not allow training.", "$.privacy.trainingAllowed");
|
|
185
|
+
}
|
|
186
|
+
if (!objectRef.privacyFlags.trainingAllowed) {
|
|
187
|
+
addBlocker(blockers, "object_training_not_allowed", "Object privacy flags do not allow training.", "$.privacyFlags.trainingAllowed");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (purpose === "export") {
|
|
191
|
+
if (!isCodaliStoragePrivacyExportAllowed(privacy)) {
|
|
192
|
+
addBlocker(blockers, "privacy_export_not_allowed", "Privacy metadata does not allow export.", "$.privacy.exportAllowed");
|
|
193
|
+
}
|
|
194
|
+
if (!objectRef.privacyFlags.exportAllowed) {
|
|
195
|
+
addBlocker(blockers, "object_export_not_allowed", "Object privacy flags do not allow export.", "$.privacyFlags.exportAllowed");
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (purpose === "eval" && !objectRef.privacyFlags.evalAllowed) {
|
|
199
|
+
addBlocker(blockers, "object_eval_not_allowed", "Object privacy flags do not allow eval reads.", "$.privacyFlags.evalAllowed");
|
|
200
|
+
}
|
|
201
|
+
if (purpose === "replay" && !objectRef.privacyFlags.replayAllowed) {
|
|
202
|
+
addBlocker(blockers, "object_replay_not_allowed", "Object privacy flags do not allow replay reads.", "$.privacyFlags.replayAllowed");
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
purpose,
|
|
206
|
+
allowed: blockers.length === 0,
|
|
207
|
+
blockers,
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
const hasAdminAudit = (override) => override.allow === true &&
|
|
211
|
+
hasText(override.adminActorId) &&
|
|
212
|
+
hasText(override.auditEventId) &&
|
|
213
|
+
hasText(override.reason);
|
|
214
|
+
export const applyCodaliDatasetPolicyOverride = (decision, override) => {
|
|
215
|
+
if (!override)
|
|
216
|
+
return decision;
|
|
217
|
+
if (!override.allow || override.purpose !== decision.purpose) {
|
|
218
|
+
return decision.allowed
|
|
219
|
+
? decision
|
|
220
|
+
: {
|
|
221
|
+
...decision,
|
|
222
|
+
blockers: [
|
|
223
|
+
...decision.blockers,
|
|
224
|
+
{
|
|
225
|
+
code: "policy_override_not_requested",
|
|
226
|
+
message: "No matching policy override was requested.",
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
if (!hasAdminAudit(override)) {
|
|
232
|
+
return {
|
|
233
|
+
...decision,
|
|
234
|
+
allowed: false,
|
|
235
|
+
blockers: [
|
|
236
|
+
...decision.blockers,
|
|
237
|
+
{
|
|
238
|
+
code: "policy_override_requires_admin_audit",
|
|
239
|
+
message: "Policy overrides require an admin actor, audit event id, reason, and explicit allow=true.",
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
const hardBlockers = decision.blockers.filter((blocker) => HARD_OVERRIDE_BLOCKERS.has(blocker.code));
|
|
245
|
+
if (hardBlockers.length > 0) {
|
|
246
|
+
return {
|
|
247
|
+
...decision,
|
|
248
|
+
allowed: false,
|
|
249
|
+
blockers: [
|
|
250
|
+
...decision.blockers,
|
|
251
|
+
{
|
|
252
|
+
code: "policy_override_hard_blocked",
|
|
253
|
+
message: "Policy override cannot bypass secrets, required redaction, or do_not_store retention.",
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
const auditEvent = {
|
|
259
|
+
auditEventId: override.auditEventId.trim(),
|
|
260
|
+
adminActorId: override.adminActorId.trim(),
|
|
261
|
+
purpose: decision.purpose,
|
|
262
|
+
reason: override.reason.trim(),
|
|
263
|
+
approvedAt: override.approvedAt ?? new Date().toISOString(),
|
|
264
|
+
originalBlockers: decision.blockers.map((blocker) => blocker.code),
|
|
265
|
+
};
|
|
266
|
+
return {
|
|
267
|
+
purpose: decision.purpose,
|
|
268
|
+
allowed: true,
|
|
269
|
+
blockers: [],
|
|
270
|
+
auditEvents: [...(decision.auditEvents ?? []), auditEvent],
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
export const assertCodaliDatasetObjectPayloadReadAllowed = (purpose, objectRef, privacy) => {
|
|
274
|
+
const decision = evaluateCodaliDatasetObjectPayloadRead(purpose, objectRef, privacy);
|
|
275
|
+
if (!decision.allowed)
|
|
276
|
+
throw new CodaliDatasetPrivacyError(decision);
|
|
277
|
+
};
|
|
278
|
+
export const assertCodaliDatasetDurablePersistenceAllowed = (retentionClass) => {
|
|
279
|
+
const decision = evaluateCodaliDatasetDurablePersistence(retentionClass);
|
|
280
|
+
if (!decision.allowed)
|
|
281
|
+
throw new CodaliDatasetPrivacyError(decision);
|
|
282
|
+
};
|
|
283
|
+
export const readCodaliDatasetObjectPayload = async (input) => {
|
|
284
|
+
const baseDecision = evaluateCodaliDatasetObjectPayloadRead(input.purpose, input.objectRef, input.privacy);
|
|
285
|
+
const decision = applyCodaliDatasetPolicyOverride(baseDecision, input.policyOverride);
|
|
286
|
+
if (!decision.allowed)
|
|
287
|
+
return { ok: false, decision };
|
|
288
|
+
return {
|
|
289
|
+
ok: true,
|
|
290
|
+
decision,
|
|
291
|
+
payload: await input.readPayload(input.objectRef),
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
export const generateCodaliDatasetPrivacyMetadata = (input) => {
|
|
295
|
+
const inputSecrets = detectAndRedactCodaliDatasetSecrets(input.inputPayload);
|
|
296
|
+
const outputSecrets = detectAndRedactCodaliDatasetSecrets(input.outputPayload);
|
|
297
|
+
const evidenceSecrets = (input.evidencePayloads ?? []).map((payload) => detectAndRedactCodaliDatasetSecrets(payload));
|
|
298
|
+
const secretFindings = [
|
|
299
|
+
...inputSecrets.findings.map((finding) => ({
|
|
300
|
+
...finding,
|
|
301
|
+
path: `$.inputPayload${finding.path.slice(1)}`,
|
|
302
|
+
})),
|
|
303
|
+
...outputSecrets.findings.map((finding) => ({
|
|
304
|
+
...finding,
|
|
305
|
+
path: `$.outputPayload${finding.path.slice(1)}`,
|
|
306
|
+
})),
|
|
307
|
+
...evidenceSecrets.flatMap((result, index) => result.findings.map((finding) => ({
|
|
308
|
+
...finding,
|
|
309
|
+
path: `$.evidencePayloads[${index}]${finding.path.slice(1)}`,
|
|
310
|
+
}))),
|
|
311
|
+
];
|
|
312
|
+
const containsSecrets = secretFindings.length > 0;
|
|
313
|
+
const containsPersonalData = input.containsPersonalData === true ||
|
|
314
|
+
payloadContainsPersonalData(input.inputPayload) ||
|
|
315
|
+
payloadContainsPersonalData(input.outputPayload) ||
|
|
316
|
+
(input.evidencePayloads ?? []).some(payloadContainsPersonalData);
|
|
317
|
+
const retentionClass = input.retentionClass ?? "dataset";
|
|
318
|
+
const durablePersistence = evaluateCodaliDatasetDurablePersistence(retentionClass);
|
|
319
|
+
const durablePersistenceAllowed = durablePersistence.allowed;
|
|
320
|
+
const personalDataRedacted = input.personalDataRedacted === true;
|
|
321
|
+
const redactionStatus = containsSecrets
|
|
322
|
+
? containsPersonalData && !personalDataRedacted
|
|
323
|
+
? "pending"
|
|
324
|
+
: "redacted"
|
|
325
|
+
: containsPersonalData
|
|
326
|
+
? personalDataRedacted
|
|
327
|
+
? "redacted"
|
|
328
|
+
: "pending"
|
|
329
|
+
: "not_required";
|
|
330
|
+
const redactionReady = !containsPersonalData || redactionStatus === "redacted";
|
|
331
|
+
const trainingAllowed = input.allowances?.trainingAllowed === true &&
|
|
332
|
+
durablePersistenceAllowed &&
|
|
333
|
+
!containsSecrets &&
|
|
334
|
+
redactionReady;
|
|
335
|
+
const exportAllowed = input.allowances?.exportAllowed === true &&
|
|
336
|
+
durablePersistenceAllowed &&
|
|
337
|
+
!containsSecrets &&
|
|
338
|
+
redactionReady;
|
|
339
|
+
const uploadAllowed = input.allowances?.uploadAllowed === true &&
|
|
340
|
+
durablePersistenceAllowed &&
|
|
341
|
+
redactionReady &&
|
|
342
|
+
!containsSecrets;
|
|
343
|
+
const evalAllowed = input.allowances?.evalAllowed === true && durablePersistenceAllowed;
|
|
344
|
+
const replayAllowed = input.allowances?.replayAllowed === true && durablePersistenceAllowed;
|
|
345
|
+
const hashedIdentifiers = hashCodaliDatasetIdentifiers(input.tenant, {
|
|
346
|
+
...input.identifiers,
|
|
347
|
+
});
|
|
348
|
+
const metadata = {
|
|
349
|
+
...(input.metadata ?? {}),
|
|
350
|
+
containsSecrets,
|
|
351
|
+
secretFindingCount: secretFindings.length,
|
|
352
|
+
secretFindingKinds: Array.from(new Set(secretFindings.map((finding) => finding.kind))),
|
|
353
|
+
hashedIdentifiers,
|
|
354
|
+
retentionClass,
|
|
355
|
+
generatedAt: input.now ?? new Date().toISOString(),
|
|
356
|
+
};
|
|
357
|
+
const privacy = {
|
|
358
|
+
schemaVersion: CODALI_STORAGE_CONTRACT_SCHEMA_VERSION,
|
|
359
|
+
classification: input.classification ?? "internal",
|
|
360
|
+
containsPersonalData,
|
|
361
|
+
redactionStatus,
|
|
362
|
+
uploadAllowed,
|
|
363
|
+
exportAllowed,
|
|
364
|
+
trainingAllowed,
|
|
365
|
+
policyTags: input.policyTags,
|
|
366
|
+
retentionUntil: input.retentionUntil,
|
|
367
|
+
redactionSummary: containsSecrets
|
|
368
|
+
? `${secretFindings.length} secret finding(s) redacted.`
|
|
369
|
+
: undefined,
|
|
370
|
+
metadata,
|
|
371
|
+
};
|
|
372
|
+
const privacyFlags = {
|
|
373
|
+
containsPersonalData,
|
|
374
|
+
containsSecrets,
|
|
375
|
+
containsTenantPrivateData: input.containsTenantPrivateData === true,
|
|
376
|
+
containsSourceCode: input.containsSourceCode === true,
|
|
377
|
+
containsCustomerData: input.containsCustomerData === true,
|
|
378
|
+
trainingAllowed,
|
|
379
|
+
evalAllowed,
|
|
380
|
+
replayAllowed,
|
|
381
|
+
exportAllowed,
|
|
382
|
+
};
|
|
383
|
+
const blockers = [
|
|
384
|
+
...durablePersistence.blockers,
|
|
385
|
+
];
|
|
386
|
+
if (containsSecrets) {
|
|
387
|
+
addBlocker(blockers, "secrets_detected", "Records containing secrets cannot be training or export eligible.", "$.metadata.containsSecrets");
|
|
388
|
+
}
|
|
389
|
+
if (containsPersonalData && redactionStatus !== "redacted") {
|
|
390
|
+
addBlocker(blockers, "redaction_required", "Personal data must be redacted before training or export eligibility.", "$.redactionStatus");
|
|
391
|
+
}
|
|
392
|
+
if (input.allowances?.trainingAllowed === true && !trainingAllowed) {
|
|
393
|
+
addBlocker(blockers, "privacy_training_not_allowed", "Requested training eligibility was denied by privacy policy.", "$.trainingAllowed");
|
|
394
|
+
}
|
|
395
|
+
if (input.allowances?.exportAllowed === true && !exportAllowed) {
|
|
396
|
+
addBlocker(blockers, "privacy_export_not_allowed", "Requested export eligibility was denied by privacy policy.", "$.exportAllowed");
|
|
397
|
+
}
|
|
398
|
+
return {
|
|
399
|
+
privacy,
|
|
400
|
+
privacyFlags,
|
|
401
|
+
hashedIdentifiers,
|
|
402
|
+
redactedPayloads: {
|
|
403
|
+
inputPayload: inputSecrets.redactedPayload,
|
|
404
|
+
outputPayload: outputSecrets.redactedPayload,
|
|
405
|
+
evidencePayloads: evidenceSecrets.map((result) => result.redactedPayload),
|
|
406
|
+
},
|
|
407
|
+
secretFindings,
|
|
408
|
+
eligibility: {
|
|
409
|
+
trainingAllowed,
|
|
410
|
+
evalAllowed,
|
|
411
|
+
replayAllowed,
|
|
412
|
+
exportAllowed,
|
|
413
|
+
durablePersistenceAllowed,
|
|
414
|
+
blockers,
|
|
415
|
+
},
|
|
416
|
+
};
|
|
417
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type CodaliStorageCandidateRecordRef, type CodaliStorageDatasetRecord, type CodaliStorageFeedbackRecord, type CodaliStorageFeedbackSource, type CodaliStoragePrivacyMetadata, type CodaliStorageProductScope, type CodaliStorageRecordType, type CodaliStorageRequesterScope, type CodaliStorageReviewDecision, type CodaliStorageReviewerType, type CodaliStorageReviewPromotionTarget, type CodaliStorageReviewRecord, type CodaliStorageValidationIssue } from "./CodaliStorageContracts.js";
|
|
2
|
+
export declare class CodaliFeedbackReviewIngestionError extends Error {
|
|
3
|
+
readonly issues: CodaliStorageValidationIssue[];
|
|
4
|
+
constructor(message: string, issues: CodaliStorageValidationIssue[]);
|
|
5
|
+
}
|
|
6
|
+
export type CodaliFeedbackReviewRequesterScopeInput = Omit<CodaliStorageRequesterScope, "visibility" | "tenantWide"> & Partial<Pick<CodaliStorageRequesterScope, "visibility" | "tenantWide">>;
|
|
7
|
+
export interface CodaliFeedbackReviewScopeInput {
|
|
8
|
+
runId: string;
|
|
9
|
+
deletionGroupId?: string;
|
|
10
|
+
productScope: CodaliStorageProductScope;
|
|
11
|
+
requesterScope: CodaliFeedbackReviewRequesterScopeInput;
|
|
12
|
+
candidateRecords: CodaliStorageCandidateRecordRef[];
|
|
13
|
+
privacy?: Partial<CodaliStoragePrivacyMetadata>;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface BuildCodaliStorageFeedbackRecordInput extends CodaliFeedbackReviewScopeInput {
|
|
17
|
+
feedbackId: string;
|
|
18
|
+
createdAt?: string;
|
|
19
|
+
source: CodaliStorageFeedbackSource;
|
|
20
|
+
targetType: CodaliStorageRecordType;
|
|
21
|
+
targetId: string;
|
|
22
|
+
rating?: number;
|
|
23
|
+
comment?: string;
|
|
24
|
+
labels?: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface BuildCodaliStorageReviewRecordInput extends CodaliFeedbackReviewScopeInput {
|
|
27
|
+
reviewId: string;
|
|
28
|
+
createdAt?: string;
|
|
29
|
+
reviewerType: CodaliStorageReviewerType;
|
|
30
|
+
reviewerId?: string;
|
|
31
|
+
targetType: CodaliStorageRecordType;
|
|
32
|
+
targetId: string;
|
|
33
|
+
decision: CodaliStorageReviewDecision;
|
|
34
|
+
reasons?: string[];
|
|
35
|
+
labels?: string[];
|
|
36
|
+
promotionTarget?: CodaliStorageReviewPromotionTarget;
|
|
37
|
+
promotedRecordIds?: string[];
|
|
38
|
+
}
|
|
39
|
+
export interface ApplyCodaliStorageReviewPromotionInput {
|
|
40
|
+
review: CodaliStorageReviewRecord;
|
|
41
|
+
records: CodaliStorageDatasetRecord[];
|
|
42
|
+
reviewedAt?: string;
|
|
43
|
+
}
|
|
44
|
+
export declare const createCodaliFeedbackReviewLocalOnlyPrivacy: (overrides?: Partial<CodaliStoragePrivacyMetadata>) => CodaliStoragePrivacyMetadata;
|
|
45
|
+
export declare const defaultCodaliStorageReviewPromotionTarget: (decision: CodaliStorageReviewDecision) => CodaliStorageReviewPromotionTarget;
|
|
46
|
+
export declare const normalizeCodaliFeedbackReviewRequesterScope: (requesterScope: CodaliFeedbackReviewRequesterScopeInput) => CodaliStorageRequesterScope;
|
|
47
|
+
export declare const buildCodaliStorageFeedbackRecord: (input: BuildCodaliStorageFeedbackRecordInput) => CodaliStorageFeedbackRecord;
|
|
48
|
+
export declare const buildCodaliStorageReviewRecord: (input: BuildCodaliStorageReviewRecordInput) => CodaliStorageReviewRecord;
|
|
49
|
+
export declare const applyCodaliStorageReviewPromotion: (input: ApplyCodaliStorageReviewPromotionInput) => CodaliStorageDatasetRecord[];
|
|
50
|
+
//# sourceMappingURL=CodaliFeedbackReviewIngestion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodaliFeedbackReviewIngestion.d.ts","sourceRoot":"","sources":["../../src/storage/CodaliFeedbackReviewIngestion.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,+BAA+B,EACpC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,KAAK,kCAAkC,EACvC,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EAClC,MAAM,6BAA6B,CAAC;AAErC,qBAAa,kCAAmC,SAAQ,KAAK;IAGzD,QAAQ,CAAC,MAAM,EAAE,4BAA4B,EAAE;gBAD/C,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,4BAA4B,EAAE;CAKlD;AAED,MAAM,MAAM,uCAAuC,GACjD,IAAI,CAAC,2BAA2B,EAAE,YAAY,GAAG,YAAY,CAAC,GAC9D,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC;AAE1E,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,yBAAyB,CAAC;IACxC,cAAc,EAAE,uCAAuC,CAAC;IACxD,gBAAgB,EAAE,+BAA+B,EAAE,CAAC;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,qCACf,SAAQ,8BAA8B;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,2BAA2B,CAAC;IACpC,UAAU,EAAE,uBAAuB,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mCACf,SAAQ,8BAA8B;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,yBAAyB,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,uBAAuB,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,2BAA2B,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,kCAAkC,CAAC;IACrD,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,sCAAsC;IACrD,MAAM,EAAE,yBAAyB,CAAC;IAClC,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,0CAA0C,GACrD,YAAW,OAAO,CAAC,4BAA4B,CAAM,KACpD,4BAaD,CAAC;AAEH,eAAO,MAAM,yCAAyC,GACpD,UAAU,2BAA2B,KACpC,kCAIF,CAAC;AAEF,eAAO,MAAM,2CAA2C,GACtD,gBAAgB,uCAAuC,KACtD,2BAID,CAAC;AAEH,eAAO,MAAM,gCAAgC,GAC3C,OAAO,qCAAqC,KAC3C,2BAyBF,CAAC;AAEF,eAAO,MAAM,8BAA8B,GACzC,OAAO,mCAAmC,KACzC,yBA8BF,CAAC;AAEF,eAAO,MAAM,iCAAiC,GAC5C,OAAO,sCAAsC,KAC5C,0BAA0B,EA+C5B,CAAC"}
|