configproof 0.3.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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +217 -0
  3. package/dist/adapters/dotenv.d.ts +3 -0
  4. package/dist/adapters/dotenv.js +277 -0
  5. package/dist/adapters/dotenv.js.map +1 -0
  6. package/dist/adapters/native-env.d.ts +7 -0
  7. package/dist/adapters/native-env.js +196 -0
  8. package/dist/adapters/native-env.js.map +1 -0
  9. package/dist/adapters/registry.d.ts +7 -0
  10. package/dist/adapters/registry.js +30 -0
  11. package/dist/adapters/registry.js.map +1 -0
  12. package/dist/agent/server.d.ts +15 -0
  13. package/dist/agent/server.js +254 -0
  14. package/dist/agent/server.js.map +1 -0
  15. package/dist/analysis/diagnose.d.ts +64 -0
  16. package/dist/analysis/diagnose.js +142 -0
  17. package/dist/analysis/diagnose.js.map +1 -0
  18. package/dist/analysis/history.d.ts +52 -0
  19. package/dist/analysis/history.js +119 -0
  20. package/dist/analysis/history.js.map +1 -0
  21. package/dist/analysis/policy.d.ts +161 -0
  22. package/dist/analysis/policy.js +192 -0
  23. package/dist/analysis/policy.js.map +1 -0
  24. package/dist/analysis/provenance.d.ts +45 -0
  25. package/dist/analysis/provenance.js +144 -0
  26. package/dist/analysis/provenance.js.map +1 -0
  27. package/dist/cli.d.ts +2 -0
  28. package/dist/cli.js +286 -0
  29. package/dist/cli.js.map +1 -0
  30. package/dist/core/analyze.d.ts +46 -0
  31. package/dist/core/analyze.js +168 -0
  32. package/dist/core/analyze.js.map +1 -0
  33. package/dist/core/collect.d.ts +5 -0
  34. package/dist/core/collect.js +147 -0
  35. package/dist/core/collect.js.map +1 -0
  36. package/dist/core/export.d.ts +53 -0
  37. package/dist/core/export.js +155 -0
  38. package/dist/core/export.js.map +1 -0
  39. package/dist/core/io.d.ts +13 -0
  40. package/dist/core/io.js +100 -0
  41. package/dist/core/io.js.map +1 -0
  42. package/dist/core/privacy.d.ts +25 -0
  43. package/dist/core/privacy.js +113 -0
  44. package/dist/core/privacy.js.map +1 -0
  45. package/dist/core/schema.d.ts +2149 -0
  46. package/dist/core/schema.js +181 -0
  47. package/dist/core/schema.js.map +1 -0
  48. package/dist/demo.d.ts +1 -0
  49. package/dist/demo.js +45 -0
  50. package/dist/demo.js.map +1 -0
  51. package/dist/index.d.ts +23 -0
  52. package/dist/index.js +63 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/launcher.d.ts +27 -0
  55. package/dist/launcher.js +122 -0
  56. package/dist/launcher.js.map +1 -0
  57. package/dist/report/html.d.ts +5 -0
  58. package/dist/report/html.js +109 -0
  59. package/dist/report/html.js.map +1 -0
  60. package/dist/runtime/api.d.ts +44 -0
  61. package/dist/runtime/api.js +29 -0
  62. package/dist/runtime/api.js.map +1 -0
  63. package/dist/runtime/callsite.d.ts +3 -0
  64. package/dist/runtime/callsite.js +61 -0
  65. package/dist/runtime/callsite.js.map +1 -0
  66. package/dist/runtime/children.d.ts +8 -0
  67. package/dist/runtime/children.js +69 -0
  68. package/dist/runtime/children.js.map +1 -0
  69. package/dist/runtime/environment.d.ts +3 -0
  70. package/dist/runtime/environment.js +53 -0
  71. package/dist/runtime/environment.js.map +1 -0
  72. package/dist/runtime/preload.d.ts +1 -0
  73. package/dist/runtime/preload.js +117 -0
  74. package/dist/runtime/preload.js.map +1 -0
  75. package/dist/runtime/recorder.d.ts +59 -0
  76. package/dist/runtime/recorder.js +254 -0
  77. package/dist/runtime/recorder.js.map +1 -0
  78. package/dist/runtime/workers.d.ts +12 -0
  79. package/dist/runtime/workers.js +127 -0
  80. package/dist/runtime/workers.js.map +1 -0
  81. package/docs/ARCHITECTURE.md +54 -0
  82. package/docs/COMPATIBILITY.md +24 -0
  83. package/docs/PRIVACY.md +17 -0
  84. package/docs/VALIDATION.md +42 -0
  85. package/fixtures/bypass/app.cjs +6 -0
  86. package/fixtures/bypass/early.cjs +2 -0
  87. package/fixtures/child-process/child.cjs +2 -0
  88. package/fixtures/child-process/parent.cjs +5 -0
  89. package/fixtures/custom-target/app.cjs +4 -0
  90. package/fixtures/custom-target/sample.env +1 -0
  91. package/fixtures/esm/app.mjs +5 -0
  92. package/fixtures/exit-code/app.cjs +4 -0
  93. package/fixtures/failure-boundary/app.cjs +7 -0
  94. package/fixtures/load-order/app.cjs +9 -0
  95. package/fixtures/load-order/first.env +1 -0
  96. package/fixtures/load-order/second.env +1 -0
  97. package/fixtures/manifest.json +16 -0
  98. package/fixtures/native-env/app.cjs +6 -0
  99. package/fixtures/native-env/failure.cjs +4 -0
  100. package/fixtures/native-env/sample.env +1 -0
  101. package/fixtures/native-env/startup.cjs +2 -0
  102. package/fixtures/runtime-mutation/app.cjs +12 -0
  103. package/fixtures/source-map/input.ts +5 -0
  104. package/fixtures/source-map/tsconfig.json +7 -0
  105. package/fixtures/stale-inheritance/app.cjs +4 -0
  106. package/fixtures/stale-inheritance/sample.env +1 -0
  107. package/fixtures/v03-manifest.json +32 -0
  108. package/fixtures/worker/parent.cjs +3 -0
  109. package/fixtures/worker/worker.cjs +2 -0
  110. package/fixtures/worker-modes/parent.cjs +17 -0
  111. package/fixtures/worker-modes/worker.cjs +4 -0
  112. package/package.json +64 -0
  113. package/policies/configtrace-policy.yaml +23 -0
  114. package/policies/issue-share.yaml +12 -0
  115. package/policies/minimal.yaml +8 -0
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.coverageFor = coverageFor;
7
+ exports.collectTrace = collectTrace;
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const schema_1 = require("./schema");
11
+ const io_1 = require("./io");
12
+ function coverageFor(notices) {
13
+ const has = (n) => notices.includes(n);
14
+ return [
15
+ { feature: 'environment', status: 'limited', reasons: ['original_reference_bypass', ...(has('environment_replaced') ? ['environment_replaced'] : [])] },
16
+ { feature: 'startup', status: 'limited', reasons: ['startup_history_unknown', 'early_preloads_possible'] },
17
+ { feature: 'dotenv', status: has('dotenv_attached') ? 'limited' : 'not-observed', reasons: notices.filter(n => n.startsWith('dotenv_')) },
18
+ { feature: 'source-maps', status: has('source_maps_requested') ? 'limited' : 'not-observed', reasons: [has('source_maps_requested') ? 'source_maps_requested' : 'source_maps_opt_in'] },
19
+ { feature: 'children', status: has('children_opt_in') ? 'limited' : 'unsupported', reasons: notices.filter(n => n.startsWith('child') || n === 'sync_children_unobserved') },
20
+ { feature: 'native-env', status: has('native_env_attached') ? 'limited' : 'not-observed', reasons: notices.filter(n => n.startsWith('native_env_')) },
21
+ { feature: 'native', status: 'unsupported', reasons: ['native_access_unobserved'] },
22
+ { feature: 'workers', status: has('workers_opt_in') || has('worker_attached') ? 'limited' : 'unsupported', reasons: notices.filter(n => n.startsWith('worker')) },
23
+ { feature: 'adapters', status: has('custom_adapter_loaded') ? 'limited' : 'not-observed', reasons: notices.filter(n => n === 'custom_adapter_loaded' || n === 'adapter_failed') },
24
+ ];
25
+ }
26
+ /** Recover complete records without pretending that interrupted/malformed tails are complete. */
27
+ function collectTrace(config, result) {
28
+ const notices = new Set(['capture_unverified']);
29
+ const processes = [];
30
+ const events = [];
31
+ const adapters = [];
32
+ let aggregate = 0;
33
+ let files = [];
34
+ try {
35
+ files = node_fs_1.default.readdirSync(config.directory).filter(name => /^p_[a-f0-9]{24}\.jsonl$/.test(name));
36
+ }
37
+ catch {
38
+ notices.add('recorder_failed');
39
+ }
40
+ files.sort((a, b) => a.startsWith(config.rootId) ? -1 : b.startsWith(config.rootId) ? 1 : a.localeCompare(b));
41
+ if (files.length > schema_1.MAX_PROCESSES)
42
+ notices.add('process_limit');
43
+ for (const file of files.slice(0, schema_1.MAX_PROCESSES)) {
44
+ let raw;
45
+ try {
46
+ raw = (0, io_1.readBounded)(node_path_1.default.join(config.directory, file), config.maxBytes);
47
+ }
48
+ catch {
49
+ notices.add('invalid_stream');
50
+ continue;
51
+ }
52
+ aggregate += Buffer.byteLength(raw);
53
+ if (aggregate > schema_1.MAX_ARTIFACT_BYTES / 2) {
54
+ notices.add('aggregate_limit');
55
+ break;
56
+ }
57
+ let info;
58
+ let ended = false;
59
+ let sequence = -1;
60
+ const seen = new Map();
61
+ for (const line of raw.split('\n')) {
62
+ if (!line)
63
+ continue;
64
+ try {
65
+ const record = schema_1.StreamRecordSchema.parse(JSON.parse(line));
66
+ if (ended) {
67
+ notices.add('invalid_stream');
68
+ break;
69
+ }
70
+ if (record.type === 'start') {
71
+ if (info || record.process.id + '.jsonl' !== file) {
72
+ notices.add('invalid_stream');
73
+ break;
74
+ }
75
+ info = { ...record.process, ended: false, exitCode: null };
76
+ processes.push(info);
77
+ }
78
+ else if (!info) {
79
+ notices.add('invalid_stream');
80
+ break;
81
+ }
82
+ else if (record.type === 'notice')
83
+ notices.add(record.notice);
84
+ else if (record.type === 'adapter') {
85
+ if (record.declaration.processId !== info.id || adapters.length >= 512)
86
+ notices.add('invalid_stream');
87
+ else
88
+ adapters.push(record.declaration);
89
+ }
90
+ else if (record.type === 'end') {
91
+ info.ended = true;
92
+ info.exitCode = record.exitCode;
93
+ info.eventsDropped = record.eventsDropped;
94
+ ended = true;
95
+ if (record.eventsDropped)
96
+ notices.add('events_dropped');
97
+ }
98
+ else {
99
+ const e = record.event;
100
+ if (e.processId !== info.id || e.id !== `${info.id}:${e.seq}` || e.seq <= sequence || seen.has(e.id)) {
101
+ notices.add('invalid_stream');
102
+ break;
103
+ }
104
+ sequence = e.seq;
105
+ if (events.length >= schema_1.MAX_EVENTS) {
106
+ notices.add('aggregate_limit');
107
+ continue;
108
+ }
109
+ if (e.causedBy && (!seen.has(e.causedBy) || seen.get(e.causedBy)?.key !== e.key)) {
110
+ delete e.causedBy;
111
+ e.origin = { kind: 'unknown', confidence: 'unknown' };
112
+ notices.add('invalid_stream');
113
+ }
114
+ seen.set(e.id, e);
115
+ events.push(e);
116
+ }
117
+ }
118
+ catch {
119
+ notices.add('invalid_stream');
120
+ break;
121
+ }
122
+ }
123
+ if (!ended)
124
+ notices.add('missing_footer');
125
+ }
126
+ const ids = new Set(processes.map(p => p.id));
127
+ for (const e of events)
128
+ if (['child-spawn', 'worker-spawn'].includes(e.operation) && e.outcome === 'spawned' && e.childId && !ids.has(e.childId))
129
+ notices.add('missing_footer');
130
+ if (processes.some(p => p.role === 'worker' && !p.ended))
131
+ notices.add('worker_outlived_root');
132
+ for (const e of events)
133
+ if (e.operation === 'worker-spawn' && e.outcome === 'spawned' && e.childId && !ids.has(e.childId))
134
+ notices.add('worker_unconfirmed');
135
+ if (processes.some(p => p.role === 'child' && !p.ended))
136
+ notices.add('child_outlived_root');
137
+ const partialReasons = ['events_dropped', 'event_limit', 'byte_limit', 'key_limit', 'recorder_failed', 'missing_footer', 'invalid_stream', 'process_limit', 'aggregate_limit', 'child_outlived_root', 'environment_replaced', 'adapter_failed', 'worker_outlived_root', 'worker_unconfirmed'];
138
+ const rootFound = processes.some(p => p.id === config.rootId);
139
+ const status = !rootFound ? 'failed' : partialReasons.some(n => notices.has(n)) ? 'partial' : 'complete';
140
+ return {
141
+ schemaVersion: schema_1.SCHEMA_VERSION, toolVersion: schema_1.TOOL_VERSION, id: config.runId,
142
+ comparison: { domainId: config.comparison.domainId, mode: 'hmac-sha256' },
143
+ capture: { status, watch: config.watch, caseMode: process.platform === 'win32' ? 'insensitive' : 'sensitive', maxEventsPerProcess: config.maxEvents, notices: [...notices] },
144
+ result, processes, events, adapters, coverage: coverageFor([...notices]), exported: false,
145
+ };
146
+ }
147
+ //# sourceMappingURL=collect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../src/core/collect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ import { type Trace } from './schema';
3
+ export declare const ExportPolicySchema: z.ZodObject<{
4
+ paths: z.ZodDefault<z.ZodEnum<["relative", "basename", "omit"]>>;
5
+ keys: z.ZodDefault<z.ZodObject<{
6
+ redact: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
7
+ }, "strict", z.ZodTypeAny, {
8
+ redact: string[];
9
+ }, {
10
+ redact?: string[] | undefined;
11
+ }>>;
12
+ include: z.ZodDefault<z.ZodObject<{
13
+ callSites: z.ZodDefault<z.ZodBoolean>;
14
+ loaders: z.ZodDefault<z.ZodBoolean>;
15
+ comparisons: z.ZodDefault<z.ZodBoolean>;
16
+ }, "strict", z.ZodTypeAny, {
17
+ callSites: boolean;
18
+ loaders: boolean;
19
+ comparisons: boolean;
20
+ }, {
21
+ callSites?: boolean | undefined;
22
+ loaders?: boolean | undefined;
23
+ comparisons?: boolean | undefined;
24
+ }>>;
25
+ metadata: z.ZodDefault<z.ZodEnum<["minimal", "keep"]>>;
26
+ }, "strict", z.ZodTypeAny, {
27
+ keys: {
28
+ redact: string[];
29
+ };
30
+ paths: "relative" | "basename" | "omit";
31
+ include: {
32
+ callSites: boolean;
33
+ loaders: boolean;
34
+ comparisons: boolean;
35
+ };
36
+ metadata: "minimal" | "keep";
37
+ }, {
38
+ keys?: {
39
+ redact?: string[] | undefined;
40
+ } | undefined;
41
+ paths?: "relative" | "basename" | "omit" | undefined;
42
+ include?: {
43
+ callSites?: boolean | undefined;
44
+ loaders?: boolean | undefined;
45
+ comparisons?: boolean | undefined;
46
+ } | undefined;
47
+ metadata?: "minimal" | "keep" | undefined;
48
+ }>;
49
+ export type ExportPolicy = z.infer<typeof ExportPolicySchema>;
50
+ export declare function readExportPolicy(file?: string): ExportPolicy;
51
+ /** Sanitization cannot certify arbitrary metadata as non-sensitive. Review exports before sharing. */
52
+ export declare function sanitizeTraces(inputs: Trace[], suppliedPolicy: ExportPolicy): Trace[];
53
+ export declare function exportArtifacts(traces: Trace[], out: string, policy: ExportPolicy): string[];
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ExportPolicySchema = void 0;
7
+ exports.readExportPolicy = readExportPolicy;
8
+ exports.sanitizeTraces = sanitizeTraces;
9
+ exports.exportArtifacts = exportArtifacts;
10
+ const node_fs_1 = __importDefault(require("node:fs"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ const node_crypto_1 = require("node:crypto");
13
+ const yaml_1 = require("yaml");
14
+ const zod_1 = require("zod");
15
+ const schema_1 = require("./schema");
16
+ const privacy_1 = require("./privacy");
17
+ const io_1 = require("./io");
18
+ const html_1 = require("../report/html");
19
+ const analyze_1 = require("./analyze");
20
+ exports.ExportPolicySchema = zod_1.z.object({
21
+ paths: zod_1.z.enum(['relative', 'basename', 'omit']).default('basename'),
22
+ keys: zod_1.z.object({ redact: zod_1.z.array(zod_1.z.string().max(128)).max(64).default(['*']) }).strict().default({ redact: ['*'] }),
23
+ include: zod_1.z.object({ callSites: zod_1.z.boolean().default(true), loaders: zod_1.z.boolean().default(true), comparisons: zod_1.z.boolean().default(true) }).strict()
24
+ .default({ callSites: true, loaders: true, comparisons: true }),
25
+ metadata: zod_1.z.enum(['minimal', 'keep']).default('minimal'),
26
+ }).strict();
27
+ function readExportPolicy(file) {
28
+ if (!file)
29
+ return exports.ExportPolicySchema.parse({});
30
+ try {
31
+ const document = (0, yaml_1.parseDocument)((0, io_1.readBounded)(file, 65536), { uniqueKeys: true, schema: 'core', strict: true });
32
+ if (document.errors.length)
33
+ throw new Error('Invalid policy');
34
+ return exports.ExportPolicySchema.parse(document.toJS({ maxAliasCount: 0 }));
35
+ }
36
+ catch (error) {
37
+ if (error instanceof io_1.UserError)
38
+ throw error;
39
+ throw new io_1.UserError('Invalid export policy. Unknown fields and YAML aliases are not allowed.', 65);
40
+ }
41
+ }
42
+ /** Sanitization cannot certify arbitrary metadata as non-sensitive. Review exports before sharing. */
43
+ function sanitizeTraces(inputs, suppliedPolicy) {
44
+ const policy = exports.ExportPolicySchema.parse(suppliedPolicy);
45
+ const traces = inputs.map(t => schema_1.TraceSchema.parse(t));
46
+ if (!traces.length || traces.length > 2)
47
+ throw new io_1.UserError('Export accepts one trace or one deliberately paired set.');
48
+ if (traces.length === 2 && policy.include.comparisons &&
49
+ (traces[0].comparison.mode === 'none' || traces[0].comparison.mode !== traces[1].comparison.mode || traces[0].comparison.domainId !== traces[1].comparison.domainId)) {
50
+ throw new io_1.UserError('Pair export cannot establish equality across unrelated comparison domains. Export separately or disable comparisons.', 65);
51
+ }
52
+ const salt = (0, node_crypto_1.randomBytes)(32);
53
+ const domainId = (0, io_1.uniqueId)('share');
54
+ const keyMap = new Map();
55
+ const patterns = policy.keys.redact.map(p => (0, privacy_1.globToRegex)(p, traces.some(t => t.capture.caseMode === 'insensitive')));
56
+ const names = [...new Set(traces.flatMap(t => [...t.events.flatMap(e => e.key ? [e.key] : []), ...t.capture.watch.filter(k => !/[*?]/.test(k))]))].sort();
57
+ const occupied = new Set(names.map(n => n.toUpperCase()));
58
+ let aliasNumber = 0;
59
+ for (const name of names) {
60
+ let alias = name;
61
+ if (patterns.some(p => p.test(name))) {
62
+ do {
63
+ alias = `KEY_${++aliasNumber}`;
64
+ } while (occupied.has(alias.toUpperCase()));
65
+ occupied.add(alias.toUpperCase());
66
+ }
67
+ keyMap.set(name, alias);
68
+ }
69
+ const maskPath = (file) => {
70
+ if (policy.paths === 'omit')
71
+ return undefined;
72
+ if (file.startsWith('<external:'))
73
+ return '<external>';
74
+ if (node_path_1.default.isAbsolute(file) || node_path_1.default.win32.isAbsolute(file) || file.split(/[/\\]/).includes('..') || /^[a-z]+:\/\//i.test(file))
75
+ return '<outside-project>';
76
+ return policy.paths === 'basename' ? file.split(/[/\\]/).at(-1) || '<unknown>' : file;
77
+ };
78
+ return traces.map(trace => {
79
+ const pids = new Map(trace.processes.map((p, i) => [p.id, `p${i + 1}`]));
80
+ const kept = trace.events.filter(e => policy.include.loaders || !['candidate', 'skip', 'load'].includes(e.operation));
81
+ const ids = new Map(kept.map(e => [e.id, `${pids.get(e.processId)}:${e.seq}`]));
82
+ const mask = (value, originalKey) => {
83
+ if (!value || value.state !== 'present')
84
+ return value ? { ...value } : undefined;
85
+ if (!policy.include.comparisons)
86
+ return { state: 'omitted' };
87
+ return { state: 'present', empty: value.empty, token: (0, node_crypto_1.createHmac)('sha256', salt).update(JSON.stringify([trace.comparison.domainId, originalKey, value.token])).digest('hex') };
88
+ };
89
+ const events = kept.map(e => {
90
+ let origin = e.origin ? { ...e.origin, file: e.origin.file ? maskPath(e.origin.file) : undefined } : undefined;
91
+ if (!policy.include.loaders && origin && ['dotenv', 'native-env', 'adapter'].includes(origin.kind))
92
+ origin = { kind: 'unknown', confidence: 'unknown', file: undefined };
93
+ const siteFile = e.site?.file ? maskPath(e.site.file) : undefined;
94
+ return { ...e, id: ids.get(e.id), processId: pids.get(e.processId),
95
+ childId: e.childId ? pids.get(e.childId) : undefined,
96
+ key: e.key ? keyMap.get(e.key) : undefined,
97
+ value: mask(e.value, e.key || ''), before: mask(e.before, e.key || ''), candidate: mask(e.candidate, e.key || ''),
98
+ causedBy: e.causedBy ? ids.get(e.causedBy) : undefined, origin,
99
+ site: policy.include.callSites && e.site && siteFile ? { ...e.site, file: siteFile } : undefined, };
100
+ });
101
+ const extra = ['metadata_scrubbed'];
102
+ if (!policy.include.comparisons)
103
+ extra.push('comparison_removed');
104
+ if (!policy.include.loaders)
105
+ extra.push('loader_details_removed');
106
+ if (!policy.include.callSites)
107
+ extra.push('call_sites_removed');
108
+ const clean = {
109
+ schemaVersion: trace.schemaVersion, toolVersion: trace.toolVersion, id: (0, io_1.uniqueId)('r'),
110
+ comparison: { domainId, mode: policy.include.comparisons ? 'export-hmac' : 'none' },
111
+ capture: { ...trace.capture, watch: [...new Set(events.flatMap(e => e.key ? [e.key] : []))].slice(0, 256),
112
+ caseMode: trace.capture.caseMode, notices: [...new Set([...trace.capture.notices, ...extra])] },
113
+ result: { ...trace.result }, coverage: trace.coverage.map(c => ({ ...c, reasons: [...c.reasons] })),
114
+ processes: trace.processes.map(p => ({ ...p, id: pids.get(p.id), parentId: p.parentId ? pids.get(p.parentId) : undefined,
115
+ pid: policy.metadata === 'keep' ? p.pid : null, ppid: policy.metadata === 'keep' ? p.ppid : null,
116
+ threadId: policy.metadata === 'keep' ? p.threadId : undefined,
117
+ startedAt: policy.metadata === 'keep' ? p.startedAt : undefined, entry: maskPath(p.entry) || '<omitted>' })),
118
+ adapters: policy.metadata === 'keep' ? trace.adapters?.map(a => ({ ...a, processId: pids.get(a.processId) })) : undefined,
119
+ events, exported: true,
120
+ };
121
+ return schema_1.TraceSchema.parse(clean);
122
+ });
123
+ }
124
+ function exportArtifacts(traces, out, policy) {
125
+ const clean = sanitizeTraces(traces, policy);
126
+ if (clean.length === 1) {
127
+ (0, io_1.writeTrace)(out, clean[0]);
128
+ return [out];
129
+ }
130
+ const directory = node_path_1.default.resolve(out);
131
+ try {
132
+ node_fs_1.default.mkdirSync(directory, { recursive: false, mode: 0o700 });
133
+ }
134
+ catch {
135
+ throw new io_1.UserError('Pair-export output must be a new directory whose parent already exists.', 74);
136
+ }
137
+ try {
138
+ const a = node_path_1.default.join(directory, 'run-a.ct.json'), b = node_path_1.default.join(directory, 'run-b.ct.json');
139
+ (0, io_1.writeTrace)(a, clean[0]);
140
+ (0, io_1.writeTrace)(b, clean[1]);
141
+ const report = node_path_1.default.join(directory, 'comparison.html');
142
+ (0, io_1.writeNew)(report, (0, html_1.renderDiffHtml)(clean[0], clean[1], (0, analyze_1.diffTraces)(clean[0], clean[1])));
143
+ const manifest = node_path_1.default.join(directory, 'manifest.json');
144
+ (0, io_1.writeNew)(manifest, JSON.stringify({ schemaVersion: 'configtrace-share/1', reviewRequired: true,
145
+ files: ['run-a.ct.json', 'run-b.ct.json', 'comparison.html'],
146
+ policySummary: { paths: policy.paths, keyNames: 'policy-applied', metadata: policy.metadata, ...policy.include },
147
+ warning: 'Inspect key names, paths and application metadata before sharing. This is not a universal secret-safety certificate.' }, null, 2) + '\n');
148
+ return [a, b, report, manifest];
149
+ }
150
+ catch (error) {
151
+ node_fs_1.default.rmSync(directory, { recursive: true, force: true });
152
+ throw error;
153
+ }
154
+ }
155
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/core/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type Trace } from './schema';
2
+ export declare class UserError extends Error {
3
+ readonly exitCode: number;
4
+ constructor(message: string, exitCode?: number);
5
+ }
6
+ /** Never include arbitrary fs/parser messages: they can contain credentials or file contents. */
7
+ export declare function readBounded(file: string, max?: number): string;
8
+ /** Exclusive creation, restrictive permissions, no overwrite of a file or symlink. */
9
+ export declare function writeNew(file: string, data: string): void;
10
+ export declare function readTrace(file: string): Trace;
11
+ export declare function writeTrace(file: string, trace: Trace): void;
12
+ export declare function uniqueId(prefix?: string): string;
13
+ export declare function terminalSafe(input: string, multiline?: boolean): string;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UserError = void 0;
7
+ exports.readBounded = readBounded;
8
+ exports.writeNew = writeNew;
9
+ exports.readTrace = readTrace;
10
+ exports.writeTrace = writeTrace;
11
+ exports.uniqueId = uniqueId;
12
+ exports.terminalSafe = terminalSafe;
13
+ const node_fs_1 = __importDefault(require("node:fs"));
14
+ const node_path_1 = __importDefault(require("node:path"));
15
+ const node_crypto_1 = require("node:crypto");
16
+ const schema_1 = require("./schema");
17
+ class UserError extends Error {
18
+ exitCode;
19
+ constructor(message, exitCode = 64) {
20
+ super(message);
21
+ this.exitCode = exitCode;
22
+ this.name = 'UserError';
23
+ }
24
+ }
25
+ exports.UserError = UserError;
26
+ /** Never include arbitrary fs/parser messages: they can contain credentials or file contents. */
27
+ function readBounded(file, max = schema_1.MAX_ARTIFACT_BYTES) {
28
+ let fd;
29
+ try {
30
+ if (node_fs_1.default.lstatSync(file).isSymbolicLink())
31
+ throw new UserError('Symbolic-link inputs are not accepted.', 65);
32
+ fd = node_fs_1.default.openSync(file, node_fs_1.default.constants.O_RDONLY | (node_fs_1.default.constants.O_NOFOLLOW || 0));
33
+ const stat = node_fs_1.default.fstatSync(fd);
34
+ if (!stat.isFile() || stat.size > max)
35
+ throw new UserError('Input is not a regular file or exceeds its size limit.', 65);
36
+ const buffer = Buffer.alloc(Math.min(max + 1, stat.size + 1));
37
+ let offset = 0;
38
+ while (offset < buffer.length) {
39
+ const n = node_fs_1.default.readSync(fd, buffer, offset, buffer.length - offset, null);
40
+ if (n === 0)
41
+ break;
42
+ offset += n;
43
+ }
44
+ if (offset > max || offset > stat.size)
45
+ throw new UserError('Input changed while being read or exceeds its size limit.', 65);
46
+ return buffer.subarray(0, offset).toString('utf8');
47
+ }
48
+ catch (error) {
49
+ if (error instanceof UserError)
50
+ throw error;
51
+ throw new UserError('Unable to read input. Check its path and permissions.', 74);
52
+ }
53
+ finally {
54
+ if (fd !== undefined)
55
+ node_fs_1.default.closeSync(fd);
56
+ }
57
+ }
58
+ /** Exclusive creation, restrictive permissions, no overwrite of a file or symlink. */
59
+ function writeNew(file, data) {
60
+ let fd;
61
+ try {
62
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(node_path_1.default.resolve(file)), { recursive: true, mode: 0o700 });
63
+ fd = node_fs_1.default.openSync(file, 'wx', 0o600);
64
+ node_fs_1.default.writeFileSync(fd, data, 'utf8');
65
+ }
66
+ catch {
67
+ throw new UserError('Unable to create output. It may already exist or the directory is not writable.', 74);
68
+ }
69
+ finally {
70
+ if (fd !== undefined)
71
+ node_fs_1.default.closeSync(fd);
72
+ }
73
+ }
74
+ function readTrace(file) {
75
+ try {
76
+ return schema_1.TraceSchema.parse(JSON.parse(readBounded(file)));
77
+ }
78
+ catch (error) {
79
+ if (error instanceof UserError)
80
+ throw error;
81
+ throw new UserError('Invalid, oversized, or unsupported ConfigTrace artifact.', 65);
82
+ }
83
+ }
84
+ function writeTrace(file, trace) {
85
+ const checked = schema_1.TraceSchema.safeParse(trace);
86
+ if (!checked.success)
87
+ throw new UserError('Refusing to write an invalid trace artifact.', 74);
88
+ const data = JSON.stringify(checked.data, null, 2) + '\n';
89
+ if (Buffer.byteLength(data) > schema_1.MAX_ARTIFACT_BYTES)
90
+ throw new UserError('Artifact exceeds the output size limit.', 74);
91
+ writeNew(file, data);
92
+ }
93
+ function uniqueId(prefix = 'r') { return `${prefix}_${(0, node_crypto_1.randomBytes)(12).toString('hex')}`; }
94
+ function terminalSafe(input, multiline = false) {
95
+ const controls = multiline
96
+ ? /[\u0000-\u0008\u000b-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/g
97
+ : /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/g;
98
+ return input.replace(controls, '?');
99
+ }
100
+ //# sourceMappingURL=io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/core/io.ts"],"names":[],"mappings":";;;;;;AAUA,kCAoBC;AAGD,4BASC;AAED,8BAMC;AACD,gCAMC;AACD,4BAAyG;AACzG,oCAKC;AAhED,sDAAyB;AACzB,0DAA6B;AAC7B,6CAA0C;AAC1C,qCAAuE;AAEvE,MAAa,SAAU,SAAQ,KAAK;IACW;IAA7C,YAAY,OAAe,EAAkB,WAAW,EAAE;QAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAAhC,aAAQ,GAAR,QAAQ,CAAK;QAAoB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAAC,CAAC;CACzG;AAFD,8BAEC;AAED,iGAAiG;AACjG,SAAgB,WAAW,CAAC,IAAY,EAAE,GAAG,GAAG,2BAAkB;IAChE,IAAI,EAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,IAAI,iBAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE;YAAE,MAAM,IAAI,SAAS,CAAC,wCAAwC,EAAE,EAAE,CAAC,CAAC;QAC3G,EAAE,GAAG,iBAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,iBAAE,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,iBAAE,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,iBAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,GAAG;YAAE,MAAM,IAAI,SAAS,CAAC,wDAAwD,EAAE,EAAE,CAAC,CAAC;QACzH,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,iBAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC;YACxE,IAAI,CAAC,KAAK,CAAC;gBAAE,MAAM;YACnB,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;QACD,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,SAAS,CAAC,2DAA2D,EAAE,EAAE,CAAC,CAAC;QAC7H,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,SAAS;YAAE,MAAM,KAAK,CAAC;QAC5C,MAAM,IAAI,SAAS,CAAC,uDAAuD,EAAE,EAAE,CAAC,CAAC;IACnF,CAAC;YAAS,CAAC;QAAC,IAAI,EAAE,KAAK,SAAS;YAAE,iBAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAAC,CAAC;AACvD,CAAC;AAED,sFAAsF;AACtF,SAAgB,QAAQ,CAAC,IAAY,EAAE,IAAY;IACjD,IAAI,EAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,iBAAE,CAAC,SAAS,CAAC,mBAAI,CAAC,OAAO,CAAC,mBAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjF,EAAE,GAAG,iBAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACpC,iBAAE,CAAC,aAAa,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CAAC,iFAAiF,EAAE,EAAE,CAAC,CAAC;IAC7G,CAAC;YAAS,CAAC;QAAC,IAAI,EAAE,KAAK,SAAS;YAAE,iBAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAAC,CAAC;AACvD,CAAC;AAED,SAAgB,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC;QAAC,OAAO,oBAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAChE,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,YAAY,SAAS;YAAE,MAAM,KAAK,CAAC;QAC5C,MAAM,IAAI,SAAS,CAAC,0DAA0D,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC;AACH,CAAC;AACD,SAAgB,UAAU,CAAC,IAAY,EAAE,KAAY;IACnD,MAAM,OAAO,GAAG,oBAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,MAAM,IAAI,SAAS,CAAC,8CAA8C,EAAE,EAAE,CAAC,CAAC;IAC9F,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1D,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,2BAAkB;QAAE,MAAM,IAAI,SAAS,CAAC,yCAAyC,EAAE,EAAE,CAAC,CAAC;IACrH,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC;AACD,SAAgB,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAY,OAAO,GAAG,MAAM,IAAI,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACzG,SAAgB,YAAY,CAAC,KAAa,EAAE,SAAS,GAAG,KAAK;IAC3D,MAAM,QAAQ,GAAG,SAAS;QACxB,CAAC,CAAC,sEAAsE;QACxE,CAAC,CAAC,yDAAyD,CAAC;IAC9D,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type ComparisonKey, type SafeValue } from './schema';
2
+ export declare function createComparisonKey(): ComparisonKey;
3
+ export declare function writeComparisonKey(file: string): ComparisonKey;
4
+ export declare function readComparisonKey(file: string): ComparisonKey;
5
+ /** Length framing prevents collisions across key/value boundaries. No raw-value cache. */
6
+ export declare function fingerprint(key: ComparisonKey, name: string, value: string | undefined): SafeValue;
7
+ export declare function sameValue(a?: SafeValue, b?: SafeValue): boolean;
8
+ export declare function globToRegex(pattern: string, insensitive?: boolean): RegExp;
9
+ export declare function parseWatch(raw: string[]): string[];
10
+ export declare class WatchSet {
11
+ readonly patterns: string[];
12
+ readonly insensitive: boolean;
13
+ private readonly regex;
14
+ constructor(patterns: string[], insensitive: boolean);
15
+ canonical(key: string): string;
16
+ matches(key: unknown): key is string;
17
+ exact(): string[];
18
+ }
19
+ /** Metadata is minimized, not magically anonymized. Export can remove remaining project names. */
20
+ export declare class PathScrubber {
21
+ private readonly root;
22
+ private readonly salt;
23
+ constructor(root: string, salt: string);
24
+ scrub(input: string): string;
25
+ }