@bli-cockpit/telemetry-core 0.1.7 → 0.1.9
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/evidence-completeness.d.ts +15 -0
- package/dist/evidence-completeness.js +15 -2
- package/dist/evidence-upload.d.ts +78 -0
- package/dist/evidence-upload.js +2 -0
- package/dist/ingest-dto.d.ts +115 -0
- package/dist/ingest-dto.js +14 -0
- package/dist/privacy.d.ts +26 -0
- package/dist/privacy.js +2 -0
- package/dist/secret-guards.d.ts +55 -0
- package/dist/secret-guards.js +198 -9
- package/dist/source-adapter.d.ts +52 -0
- package/package.json +1 -1
|
@@ -58,6 +58,14 @@ export declare const EvidenceCompletenessTruncationMarkerSchema: z.ZodObject<{
|
|
|
58
58
|
included_bytes: z.ZodOptional<z.ZodNumber>;
|
|
59
59
|
}, z.core.$strict>;
|
|
60
60
|
export type EvidenceCompletenessTruncationMarker = z.infer<typeof EvidenceCompletenessTruncationMarkerSchema>;
|
|
61
|
+
export declare const EvidenceCompletenessRedactionMarkerSchema: z.ZodObject<{
|
|
62
|
+
source: z.ZodString;
|
|
63
|
+
status: z.ZodLiteral<"sanitized">;
|
|
64
|
+
mode: z.ZodString;
|
|
65
|
+
count: z.ZodNumber;
|
|
66
|
+
rule_ids: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
67
|
+
}, z.core.$strict>;
|
|
68
|
+
export type EvidenceCompletenessRedactionMarker = z.infer<typeof EvidenceCompletenessRedactionMarkerSchema>;
|
|
61
69
|
export declare const EvidenceCompletenessPayloadSchema: z.ZodObject<{
|
|
62
70
|
schema_version: z.ZodLiteral<"evidence-completeness.v1">;
|
|
63
71
|
status: z.ZodEnum<{
|
|
@@ -118,6 +126,13 @@ export declare const EvidenceCompletenessPayloadSchema: z.ZodObject<{
|
|
|
118
126
|
observed_bytes: z.ZodOptional<z.ZodNumber>;
|
|
119
127
|
included_bytes: z.ZodOptional<z.ZodNumber>;
|
|
120
128
|
}, z.core.$strict>>>;
|
|
129
|
+
redaction_markers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
130
|
+
source: z.ZodString;
|
|
131
|
+
status: z.ZodLiteral<"sanitized">;
|
|
132
|
+
mode: z.ZodString;
|
|
133
|
+
count: z.ZodNumber;
|
|
134
|
+
rule_ids: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
135
|
+
}, z.core.$strict>>>;
|
|
121
136
|
notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
122
137
|
}, z.core.$strict>;
|
|
123
138
|
export type EvidenceCompletenessPayload = z.infer<typeof EvidenceCompletenessPayloadSchema>;
|
|
@@ -49,6 +49,15 @@ export const EvidenceCompletenessTruncationMarkerSchema = z
|
|
|
49
49
|
included_bytes: EvidenceCountSchema.optional(),
|
|
50
50
|
})
|
|
51
51
|
.strict();
|
|
52
|
+
export const EvidenceCompletenessRedactionMarkerSchema = z
|
|
53
|
+
.object({
|
|
54
|
+
source: NonEmptyStringSchema,
|
|
55
|
+
status: z.literal("sanitized"),
|
|
56
|
+
mode: NonEmptyStringSchema,
|
|
57
|
+
count: EvidenceCountSchema,
|
|
58
|
+
rule_ids: z.array(NonEmptyStringSchema).default([]),
|
|
59
|
+
})
|
|
60
|
+
.strict();
|
|
52
61
|
export const EvidenceCompletenessPayloadSchema = z
|
|
53
62
|
.object({
|
|
54
63
|
schema_version: z.literal("evidence-completeness.v1"),
|
|
@@ -71,6 +80,9 @@ export const EvidenceCompletenessPayloadSchema = z
|
|
|
71
80
|
truncation_markers: z
|
|
72
81
|
.array(EvidenceCompletenessTruncationMarkerSchema)
|
|
73
82
|
.default([]),
|
|
83
|
+
redaction_markers: z
|
|
84
|
+
.array(EvidenceCompletenessRedactionMarkerSchema)
|
|
85
|
+
.default([]),
|
|
74
86
|
notes: z.array(NonEmptyStringSchema.max(160)).default([]),
|
|
75
87
|
})
|
|
76
88
|
.strict()
|
|
@@ -82,11 +94,12 @@ export const EvidenceCompletenessPayloadSchema = z
|
|
|
82
94
|
payload.caps.some((cap) => cap.applied) ||
|
|
83
95
|
payload.skip_reasons.length > 0 ||
|
|
84
96
|
payload.failure_reasons.length > 0 ||
|
|
85
|
-
payload.truncation_markers.length > 0
|
|
97
|
+
payload.truncation_markers.length > 0 ||
|
|
98
|
+
payload.redaction_markers.length > 0;
|
|
86
99
|
if (payload.status === "complete" && hasGap) {
|
|
87
100
|
context.addIssue({
|
|
88
101
|
code: "custom",
|
|
89
|
-
message: "complete evidence completeness cannot include skips, caps, truncations, deferrals, or
|
|
102
|
+
message: "complete evidence completeness cannot include skips, caps, truncations, deferrals, failures, or redactions",
|
|
90
103
|
path: ["status"],
|
|
91
104
|
});
|
|
92
105
|
}
|
|
@@ -46,6 +46,32 @@ export declare const RawEvidenceUploadBeginObjectSchema: z.ZodObject<{
|
|
|
46
46
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
47
47
|
media_type: z.ZodOptional<z.ZodString>;
|
|
48
48
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
49
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
50
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
51
|
+
status: z.ZodLiteral<"sanitized">;
|
|
52
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
53
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
54
|
+
local_collector: "local_collector";
|
|
55
|
+
server_commit: "server_commit";
|
|
56
|
+
legacy_upload: "legacy_upload";
|
|
57
|
+
}>>;
|
|
58
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
59
|
+
rule_id: z.ZodString;
|
|
60
|
+
match_count: z.ZodNumber;
|
|
61
|
+
redacted_char_count: z.ZodNumber;
|
|
62
|
+
}, z.core.$strict>>;
|
|
63
|
+
secret_like_match_count: z.ZodNumber;
|
|
64
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
65
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
66
|
+
start: z.ZodNumber;
|
|
67
|
+
end: z.ZodNumber;
|
|
68
|
+
rule_id: z.ZodString;
|
|
69
|
+
}, z.core.$strict>>>;
|
|
70
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
71
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
72
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
73
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
74
|
+
}, z.core.$strict>>;
|
|
49
75
|
}, z.core.$strict>;
|
|
50
76
|
chunk_size_bytes: z.ZodNumber;
|
|
51
77
|
chunk_count: z.ZodNumber;
|
|
@@ -116,6 +142,32 @@ export declare const RawEvidenceUploadBeginRequestSchema: z.ZodObject<{
|
|
|
116
142
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
117
143
|
media_type: z.ZodOptional<z.ZodString>;
|
|
118
144
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
145
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
146
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
147
|
+
status: z.ZodLiteral<"sanitized">;
|
|
148
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
149
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
150
|
+
local_collector: "local_collector";
|
|
151
|
+
server_commit: "server_commit";
|
|
152
|
+
legacy_upload: "legacy_upload";
|
|
153
|
+
}>>;
|
|
154
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
155
|
+
rule_id: z.ZodString;
|
|
156
|
+
match_count: z.ZodNumber;
|
|
157
|
+
redacted_char_count: z.ZodNumber;
|
|
158
|
+
}, z.core.$strict>>;
|
|
159
|
+
secret_like_match_count: z.ZodNumber;
|
|
160
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
161
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
162
|
+
start: z.ZodNumber;
|
|
163
|
+
end: z.ZodNumber;
|
|
164
|
+
rule_id: z.ZodString;
|
|
165
|
+
}, z.core.$strict>>>;
|
|
166
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
167
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
168
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
169
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
170
|
+
}, z.core.$strict>>;
|
|
119
171
|
}, z.core.$strict>;
|
|
120
172
|
chunk_size_bytes: z.ZodNumber;
|
|
121
173
|
chunk_count: z.ZodNumber;
|
|
@@ -253,6 +305,32 @@ export declare const RawEvidenceUploadCommitResponseSchema: z.ZodObject<{
|
|
|
253
305
|
content_hash_sha256: z.ZodString;
|
|
254
306
|
byte_size: z.ZodNumber;
|
|
255
307
|
chunk_count: z.ZodNumber;
|
|
308
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
309
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
310
|
+
status: z.ZodLiteral<"sanitized">;
|
|
311
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
312
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
313
|
+
local_collector: "local_collector";
|
|
314
|
+
server_commit: "server_commit";
|
|
315
|
+
legacy_upload: "legacy_upload";
|
|
316
|
+
}>>;
|
|
317
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
318
|
+
rule_id: z.ZodString;
|
|
319
|
+
match_count: z.ZodNumber;
|
|
320
|
+
redacted_char_count: z.ZodNumber;
|
|
321
|
+
}, z.core.$strict>>;
|
|
322
|
+
secret_like_match_count: z.ZodNumber;
|
|
323
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
324
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
325
|
+
start: z.ZodNumber;
|
|
326
|
+
end: z.ZodNumber;
|
|
327
|
+
rule_id: z.ZodString;
|
|
328
|
+
}, z.core.$strict>>>;
|
|
329
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
330
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
331
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
332
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
333
|
+
}, z.core.$strict>>;
|
|
256
334
|
}, z.core.$strict>;
|
|
257
335
|
export type RawEvidenceUploadCommitResponse = z.infer<typeof RawEvidenceUploadCommitResponseSchema>;
|
|
258
336
|
/**
|
package/dist/evidence-upload.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { CaptureProvenanceSchema, IsoDateTimeSchema, NonEmptyStringSchema, Sha256Schema, } from "./common.js";
|
|
3
3
|
import { RawEvidencePointerSchema } from "./privacy.js";
|
|
4
|
+
import { RawEvidenceRedactionMetadataSchema } from "./secret-guards.js";
|
|
4
5
|
/**
|
|
5
6
|
* Chunked raw-evidence upload wire contract.
|
|
6
7
|
*
|
|
@@ -117,6 +118,7 @@ export const RawEvidenceUploadCommitResponseSchema = z
|
|
|
117
118
|
content_hash_sha256: Sha256Schema,
|
|
118
119
|
byte_size: z.number().int().nonnegative(),
|
|
119
120
|
chunk_count: z.number().int().nonnegative(),
|
|
121
|
+
redaction: RawEvidenceRedactionMetadataSchema.optional(),
|
|
120
122
|
})
|
|
121
123
|
.strict();
|
|
122
124
|
/**
|
package/dist/ingest-dto.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export declare const WorktreeInventoryItemSchema: z.ZodObject<{
|
|
3
|
+
repo: z.ZodString;
|
|
4
|
+
repo_label: z.ZodOptional<z.ZodString>;
|
|
5
|
+
repo_fingerprint: z.ZodOptional<z.ZodString>;
|
|
6
|
+
repo_origin_url: z.ZodOptional<z.ZodString>;
|
|
7
|
+
head_sha: z.ZodOptional<z.ZodString>;
|
|
8
|
+
worktree_label: z.ZodOptional<z.ZodString>;
|
|
9
|
+
worktree_fingerprint: z.ZodString;
|
|
10
|
+
worktree_is_primary: z.ZodOptional<z.ZodBoolean>;
|
|
11
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
12
|
+
}, z.core.$strict>;
|
|
13
|
+
export type WorktreeInventoryItem = z.infer<typeof WorktreeInventoryItemSchema>;
|
|
2
14
|
export declare const TelemetryEventTypeSchema: z.ZodEnum<{
|
|
3
15
|
session_started: "session_started";
|
|
4
16
|
session_ended: "session_ended";
|
|
@@ -148,6 +160,13 @@ export declare const TelemetryIngestEventDtoSchema: z.ZodObject<{
|
|
|
148
160
|
observed_bytes: z.ZodOptional<z.ZodNumber>;
|
|
149
161
|
included_bytes: z.ZodOptional<z.ZodNumber>;
|
|
150
162
|
}, z.core.$strict>>>;
|
|
163
|
+
redaction_markers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
164
|
+
source: z.ZodString;
|
|
165
|
+
status: z.ZodLiteral<"sanitized">;
|
|
166
|
+
mode: z.ZodString;
|
|
167
|
+
count: z.ZodNumber;
|
|
168
|
+
rule_ids: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
169
|
+
}, z.core.$strict>>>;
|
|
151
170
|
notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
152
171
|
}, z.core.$strict>>;
|
|
153
172
|
ticket_binding: z.ZodOptional<z.ZodObject<{
|
|
@@ -269,6 +288,32 @@ export declare const TelemetryIngestEventDtoSchema: z.ZodObject<{
|
|
|
269
288
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
270
289
|
media_type: z.ZodOptional<z.ZodString>;
|
|
271
290
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
291
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
292
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
293
|
+
status: z.ZodLiteral<"sanitized">;
|
|
294
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
295
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
296
|
+
local_collector: "local_collector";
|
|
297
|
+
server_commit: "server_commit";
|
|
298
|
+
legacy_upload: "legacy_upload";
|
|
299
|
+
}>>;
|
|
300
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
301
|
+
rule_id: z.ZodString;
|
|
302
|
+
match_count: z.ZodNumber;
|
|
303
|
+
redacted_char_count: z.ZodNumber;
|
|
304
|
+
}, z.core.$strict>>;
|
|
305
|
+
secret_like_match_count: z.ZodNumber;
|
|
306
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
307
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
308
|
+
start: z.ZodNumber;
|
|
309
|
+
end: z.ZodNumber;
|
|
310
|
+
rule_id: z.ZodString;
|
|
311
|
+
}, z.core.$strict>>>;
|
|
312
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
313
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
314
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
315
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
316
|
+
}, z.core.$strict>>;
|
|
272
317
|
}, z.core.$strict>>>;
|
|
273
318
|
otel: z.ZodOptional<z.ZodObject<{
|
|
274
319
|
trace_id: z.ZodOptional<z.ZodString>;
|
|
@@ -442,6 +487,17 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
|
|
|
442
487
|
work_context_id: z.ZodString;
|
|
443
488
|
}, z.core.$strict>>;
|
|
444
489
|
}, z.core.$strict>;
|
|
490
|
+
worktree_inventory: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
491
|
+
repo: z.ZodString;
|
|
492
|
+
repo_label: z.ZodOptional<z.ZodString>;
|
|
493
|
+
repo_fingerprint: z.ZodOptional<z.ZodString>;
|
|
494
|
+
repo_origin_url: z.ZodOptional<z.ZodString>;
|
|
495
|
+
head_sha: z.ZodOptional<z.ZodString>;
|
|
496
|
+
worktree_label: z.ZodOptional<z.ZodString>;
|
|
497
|
+
worktree_fingerprint: z.ZodString;
|
|
498
|
+
worktree_is_primary: z.ZodOptional<z.ZodBoolean>;
|
|
499
|
+
branch: z.ZodOptional<z.ZodString>;
|
|
500
|
+
}, z.core.$strict>>>;
|
|
445
501
|
events: z.ZodArray<z.ZodObject<{
|
|
446
502
|
event_id: z.ZodString;
|
|
447
503
|
event_type: z.ZodEnum<{
|
|
@@ -577,6 +633,13 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
|
|
|
577
633
|
observed_bytes: z.ZodOptional<z.ZodNumber>;
|
|
578
634
|
included_bytes: z.ZodOptional<z.ZodNumber>;
|
|
579
635
|
}, z.core.$strict>>>;
|
|
636
|
+
redaction_markers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
637
|
+
source: z.ZodString;
|
|
638
|
+
status: z.ZodLiteral<"sanitized">;
|
|
639
|
+
mode: z.ZodString;
|
|
640
|
+
count: z.ZodNumber;
|
|
641
|
+
rule_ids: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
642
|
+
}, z.core.$strict>>>;
|
|
580
643
|
notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
581
644
|
}, z.core.$strict>>;
|
|
582
645
|
ticket_binding: z.ZodOptional<z.ZodObject<{
|
|
@@ -698,6 +761,32 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
|
|
|
698
761
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
699
762
|
media_type: z.ZodOptional<z.ZodString>;
|
|
700
763
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
764
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
765
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
766
|
+
status: z.ZodLiteral<"sanitized">;
|
|
767
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
768
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
769
|
+
local_collector: "local_collector";
|
|
770
|
+
server_commit: "server_commit";
|
|
771
|
+
legacy_upload: "legacy_upload";
|
|
772
|
+
}>>;
|
|
773
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
774
|
+
rule_id: z.ZodString;
|
|
775
|
+
match_count: z.ZodNumber;
|
|
776
|
+
redacted_char_count: z.ZodNumber;
|
|
777
|
+
}, z.core.$strict>>;
|
|
778
|
+
secret_like_match_count: z.ZodNumber;
|
|
779
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
780
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
781
|
+
start: z.ZodNumber;
|
|
782
|
+
end: z.ZodNumber;
|
|
783
|
+
rule_id: z.ZodString;
|
|
784
|
+
}, z.core.$strict>>>;
|
|
785
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
786
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
787
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
788
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
789
|
+
}, z.core.$strict>>;
|
|
701
790
|
}, z.core.$strict>>>;
|
|
702
791
|
otel: z.ZodOptional<z.ZodObject<{
|
|
703
792
|
trace_id: z.ZodOptional<z.ZodString>;
|
|
@@ -822,6 +911,32 @@ export declare const TelemetryIngestEnvelopeSchema: z.ZodObject<{
|
|
|
822
911
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
823
912
|
media_type: z.ZodOptional<z.ZodString>;
|
|
824
913
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
914
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
915
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
916
|
+
status: z.ZodLiteral<"sanitized">;
|
|
917
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
918
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
919
|
+
local_collector: "local_collector";
|
|
920
|
+
server_commit: "server_commit";
|
|
921
|
+
legacy_upload: "legacy_upload";
|
|
922
|
+
}>>;
|
|
923
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
924
|
+
rule_id: z.ZodString;
|
|
925
|
+
match_count: z.ZodNumber;
|
|
926
|
+
redacted_char_count: z.ZodNumber;
|
|
927
|
+
}, z.core.$strict>>;
|
|
928
|
+
secret_like_match_count: z.ZodNumber;
|
|
929
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
930
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
931
|
+
start: z.ZodNumber;
|
|
932
|
+
end: z.ZodNumber;
|
|
933
|
+
rule_id: z.ZodString;
|
|
934
|
+
}, z.core.$strict>>>;
|
|
935
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
936
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
937
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
938
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
939
|
+
}, z.core.$strict>>;
|
|
825
940
|
}, z.core.$strict>>>;
|
|
826
941
|
}, z.core.$strict>>>;
|
|
827
942
|
ticket_binding_candidates: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
package/dist/ingest-dto.js
CHANGED
|
@@ -7,6 +7,19 @@ import { SourceScanResultSchema } from "./source-adapter.js";
|
|
|
7
7
|
import { ExternalTraceSinkPointerSchema, NormalizedOtelTelemetrySchema, } from "./trace-sink.js";
|
|
8
8
|
import { EvidenceCompletenessPayloadSchema } from "./evidence-completeness.js";
|
|
9
9
|
import { LocalWorkContextSchema, TicketBindingCandidateSchema, } from "./work-context.js";
|
|
10
|
+
export const WorktreeInventoryItemSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
repo: NonEmptyStringSchema,
|
|
13
|
+
repo_label: NonEmptyStringSchema.optional(),
|
|
14
|
+
repo_fingerprint: NonEmptyStringSchema.optional(),
|
|
15
|
+
repo_origin_url: NonEmptyStringSchema.optional(),
|
|
16
|
+
head_sha: NonEmptyStringSchema.optional(),
|
|
17
|
+
worktree_label: NonEmptyStringSchema.optional(),
|
|
18
|
+
worktree_fingerprint: NonEmptyStringSchema,
|
|
19
|
+
worktree_is_primary: z.boolean().optional(),
|
|
20
|
+
branch: NonEmptyStringSchema.optional(),
|
|
21
|
+
})
|
|
22
|
+
.strict();
|
|
10
23
|
export const TelemetryEventTypeSchema = z.enum([
|
|
11
24
|
"session_started",
|
|
12
25
|
"session_ended",
|
|
@@ -83,6 +96,7 @@ export const TelemetryIngestEnvelopeSchema = z
|
|
|
83
96
|
collector_version: NonEmptyStringSchema,
|
|
84
97
|
session_reference: LocalUserSessionReferenceSchema,
|
|
85
98
|
work_context: LocalWorkContextSchema,
|
|
99
|
+
worktree_inventory: z.array(WorktreeInventoryItemSchema).default([]),
|
|
86
100
|
events: z.array(TelemetryIngestEventDtoSchema).min(1),
|
|
87
101
|
source_scan_results: z.array(SourceScanResultSchema).default([]),
|
|
88
102
|
})
|
package/dist/privacy.d.ts
CHANGED
|
@@ -66,6 +66,32 @@ export declare const RawEvidencePointerSchema: z.ZodObject<{
|
|
|
66
66
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
67
67
|
media_type: z.ZodOptional<z.ZodString>;
|
|
68
68
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
69
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
70
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
71
|
+
status: z.ZodLiteral<"sanitized">;
|
|
72
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
73
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
74
|
+
local_collector: "local_collector";
|
|
75
|
+
server_commit: "server_commit";
|
|
76
|
+
legacy_upload: "legacy_upload";
|
|
77
|
+
}>>;
|
|
78
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
79
|
+
rule_id: z.ZodString;
|
|
80
|
+
match_count: z.ZodNumber;
|
|
81
|
+
redacted_char_count: z.ZodNumber;
|
|
82
|
+
}, z.core.$strict>>;
|
|
83
|
+
secret_like_match_count: z.ZodNumber;
|
|
84
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
85
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
86
|
+
start: z.ZodNumber;
|
|
87
|
+
end: z.ZodNumber;
|
|
88
|
+
rule_id: z.ZodString;
|
|
89
|
+
}, z.core.$strict>>>;
|
|
90
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
91
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
92
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
93
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
94
|
+
}, z.core.$strict>>;
|
|
69
95
|
}, z.core.$strict>;
|
|
70
96
|
export type RawEvidencePointer = z.infer<typeof RawEvidencePointerSchema>;
|
|
71
97
|
export declare const RedactionMetadataSchema: z.ZodObject<{
|
package/dist/privacy.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { IsoDateTimeSchema, NonEmptyStringSchema, Sha256Schema, } from "./common.js";
|
|
3
|
+
import { RawEvidenceRedactionMetadataSchema } from "./secret-guards.js";
|
|
3
4
|
export const PrivacyClassificationSchema = z.enum([
|
|
4
5
|
"metadata",
|
|
5
6
|
"redacted_summary",
|
|
@@ -93,6 +94,7 @@ export const RawEvidencePointerSchema = z
|
|
|
93
94
|
byte_size: z.number().int().nonnegative().optional(),
|
|
94
95
|
media_type: NonEmptyStringSchema.optional(),
|
|
95
96
|
redacted_summary: z.string().trim().min(1).max(4000).optional(),
|
|
97
|
+
redaction: RawEvidenceRedactionMetadataSchema.optional(),
|
|
96
98
|
})
|
|
97
99
|
.strict()
|
|
98
100
|
.superRefine((pointer, context) => {
|
package/dist/secret-guards.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
/**
|
|
2
3
|
* Secret-like content + file-name guards shared by the local collector
|
|
3
4
|
* (attribution, collection) and the dashboard commit-time guard. Keeping a
|
|
@@ -24,3 +25,57 @@
|
|
|
24
25
|
export declare const SECRET_FILE_SEGMENT_PATTERN: RegExp;
|
|
25
26
|
export declare function isSecretLikePathSegment(value: string): boolean;
|
|
26
27
|
export declare function containsSecretLikeContent(value: string): boolean;
|
|
28
|
+
export declare const RawEvidenceRedactionSourceSchema: z.ZodEnum<{
|
|
29
|
+
local_collector: "local_collector";
|
|
30
|
+
server_commit: "server_commit";
|
|
31
|
+
legacy_upload: "legacy_upload";
|
|
32
|
+
}>;
|
|
33
|
+
export type RawEvidenceRedactionSource = z.infer<typeof RawEvidenceRedactionSourceSchema>;
|
|
34
|
+
export declare const RawEvidenceRedactionRuleCountSchema: z.ZodObject<{
|
|
35
|
+
rule_id: z.ZodString;
|
|
36
|
+
match_count: z.ZodNumber;
|
|
37
|
+
redacted_char_count: z.ZodNumber;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export type RawEvidenceRedactionRuleCount = z.infer<typeof RawEvidenceRedactionRuleCountSchema>;
|
|
40
|
+
export declare const RawEvidenceRedactionRangeSchema: z.ZodObject<{
|
|
41
|
+
start: z.ZodNumber;
|
|
42
|
+
end: z.ZodNumber;
|
|
43
|
+
rule_id: z.ZodString;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export type RawEvidenceRedactionRange = z.infer<typeof RawEvidenceRedactionRangeSchema>;
|
|
46
|
+
export declare const RawEvidenceRedactionMetadataSchema: z.ZodObject<{
|
|
47
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
48
|
+
status: z.ZodLiteral<"sanitized">;
|
|
49
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
50
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
51
|
+
local_collector: "local_collector";
|
|
52
|
+
server_commit: "server_commit";
|
|
53
|
+
legacy_upload: "legacy_upload";
|
|
54
|
+
}>>;
|
|
55
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
56
|
+
rule_id: z.ZodString;
|
|
57
|
+
match_count: z.ZodNumber;
|
|
58
|
+
redacted_char_count: z.ZodNumber;
|
|
59
|
+
}, z.core.$strict>>;
|
|
60
|
+
secret_like_match_count: z.ZodNumber;
|
|
61
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
62
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
63
|
+
start: z.ZodNumber;
|
|
64
|
+
end: z.ZodNumber;
|
|
65
|
+
rule_id: z.ZodString;
|
|
66
|
+
}, z.core.$strict>>>;
|
|
67
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
68
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
69
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
70
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
71
|
+
}, z.core.$strict>;
|
|
72
|
+
export type RawEvidenceRedactionMetadata = z.infer<typeof RawEvidenceRedactionMetadataSchema>;
|
|
73
|
+
export interface SecretRedactionResult {
|
|
74
|
+
redacted: boolean;
|
|
75
|
+
text: string;
|
|
76
|
+
metadata: RawEvidenceRedactionMetadata | null;
|
|
77
|
+
}
|
|
78
|
+
export declare function redactSecretLikeContent(value: string, options?: {
|
|
79
|
+
appliedBy?: RawEvidenceRedactionSource;
|
|
80
|
+
redactedFields?: string[];
|
|
81
|
+
}): SecretRedactionResult;
|
package/dist/secret-guards.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
/**
|
|
2
3
|
* Secret-like content + file-name guards shared by the local collector
|
|
3
4
|
* (attribution, collection) and the dashboard commit-time guard. Keeping a
|
|
@@ -32,14 +33,7 @@ const PRIVILEGED_SUPABASE_KEY_NAME = ["SUPABASE", "SERVICE", "ROLE", "KEY"].join
|
|
|
32
33
|
const SUPABASE_SERVICE_ROLE_NAME = ["SUPABASE", "SERVICE", "ROLE"].join("_");
|
|
33
34
|
const OPENAI_KEY_NAME = ["OPENAI", "API", "KEY"].join("_");
|
|
34
35
|
const MEM0_KEY_NAME = ["MEM0", "API", "KEY"].join("_");
|
|
35
|
-
|
|
36
|
-
* Credential names that are only a leak when assigned a value (D13). The value
|
|
37
|
-
* shape mirrors the long-standing generic pattern: an assignment operator
|
|
38
|
-
* followed by a 12+ char opaque value. A bare env var reference (name only) and
|
|
39
|
-
* `GRANT ... TO service_role` (no assignment) do not match; the same name with
|
|
40
|
-
* an assigned value does.
|
|
41
|
-
*/
|
|
42
|
-
const SECRET_NAME_WITH_VALUE_PATTERN = new RegExp(`\\b(?:${[
|
|
36
|
+
const SECRET_NAME_PATTERN_SOURCE = [
|
|
43
37
|
"(?:NEXT_PUBLIC_)?SUPABASE_ANON_KEY",
|
|
44
38
|
PRIVILEGED_SUPABASE_KEY_NAME,
|
|
45
39
|
SUPABASE_SERVICE_ROLE_NAME,
|
|
@@ -53,7 +47,15 @@ const SECRET_NAME_WITH_VALUE_PATTERN = new RegExp(`\\b(?:${[
|
|
|
53
47
|
"private[_-]?key",
|
|
54
48
|
"client[_-]?secret",
|
|
55
49
|
"secret[_-]?access[_-]?key",
|
|
56
|
-
].join("|")
|
|
50
|
+
].join("|");
|
|
51
|
+
/**
|
|
52
|
+
* Credential names that are only a leak when assigned a value (D13). The value
|
|
53
|
+
* shape mirrors the long-standing generic pattern: an assignment operator
|
|
54
|
+
* followed by a 12+ char opaque value. A bare env var reference (name only) and
|
|
55
|
+
* `GRANT ... TO service_role` (no assignment) do not match; the same name with
|
|
56
|
+
* an assigned value does.
|
|
57
|
+
*/
|
|
58
|
+
const SECRET_NAME_WITH_VALUE_PATTERN = new RegExp(`\\b(?:${SECRET_NAME_PATTERN_SOURCE})\\b\\s*[:=]\\s*["']?[A-Za-z0-9_./+=-]{12,}`, "i");
|
|
57
59
|
/**
|
|
58
60
|
* Self-identifying secret values — blocked regardless of context because the
|
|
59
61
|
* token shape itself is the credential, with no benign reading.
|
|
@@ -80,3 +82,190 @@ const SECRET_LIKE_CONTENT_PATTERNS = [
|
|
|
80
82
|
export function containsSecretLikeContent(value) {
|
|
81
83
|
return SECRET_LIKE_CONTENT_PATTERNS.some((pattern) => pattern.test(value));
|
|
82
84
|
}
|
|
85
|
+
export const RawEvidenceRedactionSourceSchema = z.enum([
|
|
86
|
+
"local_collector",
|
|
87
|
+
"server_commit",
|
|
88
|
+
"legacy_upload",
|
|
89
|
+
]);
|
|
90
|
+
export const RawEvidenceRedactionRuleCountSchema = z
|
|
91
|
+
.object({
|
|
92
|
+
rule_id: z.string().trim().min(1).max(80),
|
|
93
|
+
match_count: z.number().int().nonnegative(),
|
|
94
|
+
redacted_char_count: z.number().int().nonnegative(),
|
|
95
|
+
})
|
|
96
|
+
.strict();
|
|
97
|
+
export const RawEvidenceRedactionRangeSchema = z
|
|
98
|
+
.object({
|
|
99
|
+
start: z.number().int().nonnegative(),
|
|
100
|
+
end: z.number().int().positive(),
|
|
101
|
+
rule_id: z.string().trim().min(1).max(80),
|
|
102
|
+
})
|
|
103
|
+
.strict()
|
|
104
|
+
.superRefine((range, context) => {
|
|
105
|
+
if (range.end <= range.start) {
|
|
106
|
+
context.addIssue({
|
|
107
|
+
code: "custom",
|
|
108
|
+
message: "redaction range end must be greater than start",
|
|
109
|
+
path: ["end"],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
export const RawEvidenceRedactionMetadataSchema = z
|
|
114
|
+
.object({
|
|
115
|
+
schema_version: z.literal("raw-evidence-redaction.v1"),
|
|
116
|
+
status: z.literal("sanitized"),
|
|
117
|
+
mode: z.literal("deterministic_text_replacement"),
|
|
118
|
+
applied_by: z.array(RawEvidenceRedactionSourceSchema).min(1),
|
|
119
|
+
rule_counts: z.array(RawEvidenceRedactionRuleCountSchema).min(1),
|
|
120
|
+
secret_like_match_count: z.number().int().positive(),
|
|
121
|
+
redacted_fields: z.array(z.string().trim().min(1).max(160)).default([]),
|
|
122
|
+
redacted_ranges: z.array(RawEvidenceRedactionRangeSchema).max(200).default([]),
|
|
123
|
+
original_content_hash_sha256: z.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
124
|
+
sanitized_content_hash_sha256: z.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
125
|
+
original_byte_size: z.number().int().nonnegative().optional(),
|
|
126
|
+
sanitized_byte_size: z.number().int().nonnegative().optional(),
|
|
127
|
+
})
|
|
128
|
+
.strict();
|
|
129
|
+
const SECRET_ASSIGNMENT_REDACTION_PATTERN = new RegExp(`(\\b(?:${SECRET_NAME_PATTERN_SOURCE})\\b\\s*[:=]\\s*["']?)([A-Za-z0-9_./+=-]{12,})`, "gi");
|
|
130
|
+
const SECRET_REDACTION_RULES = [
|
|
131
|
+
{
|
|
132
|
+
ruleId: "credential_assignment",
|
|
133
|
+
pattern: SECRET_ASSIGNMENT_REDACTION_PATTERN,
|
|
134
|
+
secretGroup: 2,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
ruleId: "private_key_block",
|
|
138
|
+
pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
ruleId: "private_key_header",
|
|
142
|
+
pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----/g,
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
ruleId: "bearer_token",
|
|
146
|
+
pattern: /\b(Bearer\s+)([A-Za-z0-9._~+/=-]{16,})/gi,
|
|
147
|
+
secretGroup: 2,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
ruleId: "jwt",
|
|
151
|
+
pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
ruleId: "stripe_token",
|
|
155
|
+
pattern: /\b(?:sk|pk)_(?:live|test)_[A-Za-z0-9]{16,}/g,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
ruleId: "openai_token",
|
|
159
|
+
pattern: /\bsk-[A-Za-z0-9_-]{16,}/g,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
ruleId: "github_token",
|
|
163
|
+
pattern: /\b(?:gh[pousr]_[A-Za-z0-9_]{16,}|github_pat_[A-Za-z0-9_]{20,})/g,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
ruleId: "linear_token",
|
|
167
|
+
pattern: /\blin_api_[A-Za-z0-9]{16,}/g,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
ruleId: "supabase_secret_token",
|
|
171
|
+
pattern: /\bsb_secret_[A-Za-z0-9_]{16,}/g,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
ruleId: "slack_token",
|
|
175
|
+
pattern: /\bxox[baprs]-[A-Za-z0-9-]{16,}/g,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
ruleId: "aws_access_key_id",
|
|
179
|
+
pattern: /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
ruleId: "langfuse_token",
|
|
183
|
+
pattern: /\b(?:pk|sk)-lf-[A-Za-z0-9_-]{16,}\b/gi,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
ruleId: "mem0_token",
|
|
187
|
+
pattern: /\bm0[-_][A-Za-z0-9_-]{16,}\b/gi,
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
export function redactSecretLikeContent(value, options = {}) {
|
|
191
|
+
const matches = findSecretRedactionMatches(value);
|
|
192
|
+
if (matches.length === 0) {
|
|
193
|
+
return { redacted: false, text: value, metadata: null };
|
|
194
|
+
}
|
|
195
|
+
let text = "";
|
|
196
|
+
let cursor = 0;
|
|
197
|
+
const ruleCounts = new Map();
|
|
198
|
+
for (const match of matches) {
|
|
199
|
+
text += value.slice(cursor, match.start);
|
|
200
|
+
text += `[REDACTED:${match.ruleId}]`;
|
|
201
|
+
cursor = match.end;
|
|
202
|
+
const existing = ruleCounts.get(match.ruleId) ?? {
|
|
203
|
+
rule_id: match.ruleId,
|
|
204
|
+
match_count: 0,
|
|
205
|
+
redacted_char_count: 0,
|
|
206
|
+
};
|
|
207
|
+
existing.match_count += 1;
|
|
208
|
+
existing.redacted_char_count += match.end - match.start;
|
|
209
|
+
ruleCounts.set(match.ruleId, existing);
|
|
210
|
+
}
|
|
211
|
+
text += value.slice(cursor);
|
|
212
|
+
const metadata = RawEvidenceRedactionMetadataSchema.parse({
|
|
213
|
+
schema_version: "raw-evidence-redaction.v1",
|
|
214
|
+
status: "sanitized",
|
|
215
|
+
mode: "deterministic_text_replacement",
|
|
216
|
+
applied_by: [options.appliedBy ?? "local_collector"],
|
|
217
|
+
rule_counts: [...ruleCounts.values()].sort((a, b) => a.rule_id.localeCompare(b.rule_id)),
|
|
218
|
+
secret_like_match_count: matches.length,
|
|
219
|
+
redacted_fields: options.redactedFields ?? [],
|
|
220
|
+
redacted_ranges: matches.slice(0, 200).map((match) => ({
|
|
221
|
+
start: match.start,
|
|
222
|
+
end: match.end,
|
|
223
|
+
rule_id: match.ruleId,
|
|
224
|
+
})),
|
|
225
|
+
});
|
|
226
|
+
return { redacted: true, text, metadata };
|
|
227
|
+
}
|
|
228
|
+
function findSecretRedactionMatches(value) {
|
|
229
|
+
const candidates = [];
|
|
230
|
+
SECRET_REDACTION_RULES.forEach((rule, priority) => {
|
|
231
|
+
const pattern = cloneGlobalPattern(rule.pattern);
|
|
232
|
+
for (const match of value.matchAll(pattern)) {
|
|
233
|
+
const fullMatch = match[0];
|
|
234
|
+
const matchIndex = match.index;
|
|
235
|
+
if (!fullMatch || matchIndex === undefined)
|
|
236
|
+
continue;
|
|
237
|
+
const secret = rule.secretGroup ? match[rule.secretGroup] : fullMatch;
|
|
238
|
+
if (!secret)
|
|
239
|
+
continue;
|
|
240
|
+
const relativeStart = fullMatch.indexOf(secret);
|
|
241
|
+
if (relativeStart < 0)
|
|
242
|
+
continue;
|
|
243
|
+
candidates.push({
|
|
244
|
+
start: matchIndex + relativeStart,
|
|
245
|
+
end: matchIndex + relativeStart + secret.length,
|
|
246
|
+
ruleId: rule.ruleId,
|
|
247
|
+
priority,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
candidates.sort((a, b) => {
|
|
252
|
+
if (a.start !== b.start)
|
|
253
|
+
return a.start - b.start;
|
|
254
|
+
if (a.priority !== b.priority)
|
|
255
|
+
return a.priority - b.priority;
|
|
256
|
+
return b.end - b.start - (a.end - a.start);
|
|
257
|
+
});
|
|
258
|
+
const accepted = [];
|
|
259
|
+
let lastEnd = -1;
|
|
260
|
+
for (const candidate of candidates) {
|
|
261
|
+
if (candidate.start < lastEnd)
|
|
262
|
+
continue;
|
|
263
|
+
accepted.push(candidate);
|
|
264
|
+
lastEnd = candidate.end;
|
|
265
|
+
}
|
|
266
|
+
return accepted;
|
|
267
|
+
}
|
|
268
|
+
function cloneGlobalPattern(pattern) {
|
|
269
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
270
|
+
return new RegExp(pattern.source, flags);
|
|
271
|
+
}
|
package/dist/source-adapter.d.ts
CHANGED
|
@@ -74,6 +74,32 @@ export declare const SourceScanEventSummarySchema: z.ZodObject<{
|
|
|
74
74
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
75
75
|
media_type: z.ZodOptional<z.ZodString>;
|
|
76
76
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
77
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
78
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
79
|
+
status: z.ZodLiteral<"sanitized">;
|
|
80
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
81
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
82
|
+
local_collector: "local_collector";
|
|
83
|
+
server_commit: "server_commit";
|
|
84
|
+
legacy_upload: "legacy_upload";
|
|
85
|
+
}>>;
|
|
86
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
87
|
+
rule_id: z.ZodString;
|
|
88
|
+
match_count: z.ZodNumber;
|
|
89
|
+
redacted_char_count: z.ZodNumber;
|
|
90
|
+
}, z.core.$strict>>;
|
|
91
|
+
secret_like_match_count: z.ZodNumber;
|
|
92
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
93
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
94
|
+
start: z.ZodNumber;
|
|
95
|
+
end: z.ZodNumber;
|
|
96
|
+
rule_id: z.ZodString;
|
|
97
|
+
}, z.core.$strict>>>;
|
|
98
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
99
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
100
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
}, z.core.$strict>>;
|
|
77
103
|
}, z.core.$strict>>>;
|
|
78
104
|
}, z.core.$strict>;
|
|
79
105
|
export type SourceScanEventSummary = z.infer<typeof SourceScanEventSummarySchema>;
|
|
@@ -162,6 +188,32 @@ export declare const SourceScanResultSchema: z.ZodObject<{
|
|
|
162
188
|
byte_size: z.ZodOptional<z.ZodNumber>;
|
|
163
189
|
media_type: z.ZodOptional<z.ZodString>;
|
|
164
190
|
redacted_summary: z.ZodOptional<z.ZodString>;
|
|
191
|
+
redaction: z.ZodOptional<z.ZodObject<{
|
|
192
|
+
schema_version: z.ZodLiteral<"raw-evidence-redaction.v1">;
|
|
193
|
+
status: z.ZodLiteral<"sanitized">;
|
|
194
|
+
mode: z.ZodLiteral<"deterministic_text_replacement">;
|
|
195
|
+
applied_by: z.ZodArray<z.ZodEnum<{
|
|
196
|
+
local_collector: "local_collector";
|
|
197
|
+
server_commit: "server_commit";
|
|
198
|
+
legacy_upload: "legacy_upload";
|
|
199
|
+
}>>;
|
|
200
|
+
rule_counts: z.ZodArray<z.ZodObject<{
|
|
201
|
+
rule_id: z.ZodString;
|
|
202
|
+
match_count: z.ZodNumber;
|
|
203
|
+
redacted_char_count: z.ZodNumber;
|
|
204
|
+
}, z.core.$strict>>;
|
|
205
|
+
secret_like_match_count: z.ZodNumber;
|
|
206
|
+
redacted_fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
207
|
+
redacted_ranges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
208
|
+
start: z.ZodNumber;
|
|
209
|
+
end: z.ZodNumber;
|
|
210
|
+
rule_id: z.ZodString;
|
|
211
|
+
}, z.core.$strict>>>;
|
|
212
|
+
original_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
213
|
+
sanitized_content_hash_sha256: z.ZodOptional<z.ZodString>;
|
|
214
|
+
original_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
215
|
+
sanitized_byte_size: z.ZodOptional<z.ZodNumber>;
|
|
216
|
+
}, z.core.$strict>>;
|
|
165
217
|
}, z.core.$strict>>>;
|
|
166
218
|
}, z.core.$strict>>>;
|
|
167
219
|
ticket_binding_candidates: z.ZodDefault<z.ZodArray<z.ZodObject<{
|