pi-harness-runtime 1.1.396 → 1.1.397
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/AGENTS.md +54 -7
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/connection-runtime/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/durable-review/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-sink/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/logging/README.md +41 -6
- package/packages/logging/dist/classification.d.ts +65 -0
- package/packages/logging/dist/classification.d.ts.map +1 -0
- package/packages/logging/dist/classification.js +155 -0
- package/packages/logging/dist/classification.js.map +1 -0
- package/packages/logging/dist/config.d.ts +9 -0
- package/packages/logging/dist/config.d.ts.map +1 -1
- package/packages/logging/dist/config.js +40 -3
- package/packages/logging/dist/config.js.map +1 -1
- package/packages/logging/dist/index.d.ts +9 -1
- package/packages/logging/dist/index.d.ts.map +1 -1
- package/packages/logging/dist/index.js +10 -1
- package/packages/logging/dist/index.js.map +1 -1
- package/packages/logging/dist/ingest/schema.d.ts +60 -0
- package/packages/logging/dist/ingest/schema.d.ts.map +1 -0
- package/packages/logging/dist/ingest/schema.js +245 -0
- package/packages/logging/dist/ingest/schema.js.map +1 -0
- package/packages/logging/dist/installation.d.ts +32 -0
- package/packages/logging/dist/installation.d.ts.map +1 -0
- package/packages/logging/dist/installation.js +64 -0
- package/packages/logging/dist/installation.js.map +1 -0
- package/packages/logging/dist/sensitive-keys.d.ts +12 -0
- package/packages/logging/dist/sensitive-keys.d.ts.map +1 -0
- package/packages/logging/dist/sensitive-keys.js +39 -0
- package/packages/logging/dist/sensitive-keys.js.map +1 -0
- package/packages/logging/dist/server/credentials.d.ts +85 -0
- package/packages/logging/dist/server/credentials.d.ts.map +1 -0
- package/packages/logging/dist/server/credentials.js +147 -0
- package/packages/logging/dist/server/credentials.js.map +1 -0
- package/packages/logging/dist/server/http.d.ts +36 -0
- package/packages/logging/dist/server/http.d.ts.map +1 -0
- package/packages/logging/dist/server/http.js +139 -0
- package/packages/logging/dist/server/http.js.map +1 -0
- package/packages/logging/dist/server/index-store.d.ts +95 -0
- package/packages/logging/dist/server/index-store.d.ts.map +1 -0
- package/packages/logging/dist/server/index-store.js +190 -0
- package/packages/logging/dist/server/index-store.js.map +1 -0
- package/packages/logging/dist/server/index.d.ts +22 -0
- package/packages/logging/dist/server/index.d.ts.map +1 -0
- package/packages/logging/dist/server/index.js +15 -0
- package/packages/logging/dist/server/index.js.map +1 -0
- package/packages/logging/dist/server/keys.d.ts +22 -0
- package/packages/logging/dist/server/keys.d.ts.map +1 -0
- package/packages/logging/dist/server/keys.js +24 -0
- package/packages/logging/dist/server/keys.js.map +1 -0
- package/packages/logging/dist/server/outbox-worker.d.ts +55 -0
- package/packages/logging/dist/server/outbox-worker.d.ts.map +1 -0
- package/packages/logging/dist/server/outbox-worker.js +95 -0
- package/packages/logging/dist/server/outbox-worker.js.map +1 -0
- package/packages/logging/dist/server/outbox.d.ts +112 -0
- package/packages/logging/dist/server/outbox.d.ts.map +1 -0
- package/packages/logging/dist/server/outbox.js +247 -0
- package/packages/logging/dist/server/outbox.js.map +1 -0
- package/packages/logging/dist/server/service.d.ts +83 -0
- package/packages/logging/dist/server/service.d.ts.map +1 -0
- package/packages/logging/dist/server/service.js +144 -0
- package/packages/logging/dist/server/service.js.map +1 -0
- package/packages/logging/dist/shipper.d.ts +20 -4
- package/packages/logging/dist/shipper.d.ts.map +1 -1
- package/packages/logging/dist/shipper.js +31 -5
- package/packages/logging/dist/shipper.js.map +1 -1
- package/packages/logging/dist/singleton.d.ts.map +1 -1
- package/packages/logging/dist/singleton.js +3 -0
- package/packages/logging/dist/singleton.js.map +1 -1
- package/packages/logging/dist/types.d.ts +28 -1
- package/packages/logging/dist/types.d.ts.map +1 -1
- package/packages/logging/dist/types.js +8 -0
- package/packages/logging/dist/types.js.map +1 -1
- package/packages/logging/package.json +1 -1
- package/packages/logging/src/classification.ts +175 -0
- package/packages/logging/src/config.ts +60 -3
- package/packages/logging/src/index.ts +45 -1
- package/packages/logging/src/ingest/schema.ts +295 -0
- package/packages/logging/src/installation.ts +76 -0
- package/packages/logging/src/sensitive-keys.ts +40 -0
- package/packages/logging/src/server/credentials.ts +198 -0
- package/packages/logging/src/server/http.ts +170 -0
- package/packages/logging/src/server/index-store.ts +242 -0
- package/packages/logging/src/server/index.ts +56 -0
- package/packages/logging/src/server/keys.ts +32 -0
- package/packages/logging/src/server/outbox-worker.ts +124 -0
- package/packages/logging/src/server/outbox.ts +316 -0
- package/packages/logging/src/server/service.ts +196 -0
- package/packages/logging/src/shipper.ts +54 -8
- package/packages/logging/src/singleton.ts +3 -0
- package/packages/logging/src/types.ts +29 -1
- package/packages/logging/test/classification.test.ts +137 -0
- package/packages/logging/test/identity-transport.test.ts +197 -0
- package/packages/logging/test/ingest-schema.test.ts +184 -0
- package/packages/logging/test/integration.test.ts +9 -4
- package/packages/logging/test/log-http.test.ts +246 -0
- package/packages/logging/test/server.test.ts +444 -0
- package/packages/logging/test/shipper.test.ts +11 -11
- package/packages/logging/test/spool.test.ts +4 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/permission-mode/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/voice-api/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
- package/scripts/unified-webhook-server.ts +86 -81
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What may leave the machine.
|
|
3
|
+
*
|
|
4
|
+
* The local log file keeps everything. The centralized archive keeps what an
|
|
5
|
+
* operator actually needs: service state, event codes, sanitized errors,
|
|
6
|
+
* durations and opaque identifiers.
|
|
7
|
+
*
|
|
8
|
+
* Two rules decide:
|
|
9
|
+
*
|
|
10
|
+
* 1. The event decides. A catch-all mirror of a local log line
|
|
11
|
+
* (`harness.log`) or anything that smells like a prompt, a response or
|
|
12
|
+
* command output never leaves the machine.
|
|
13
|
+
* 2. The payload decides. A message only travels when it looks like a
|
|
14
|
+
* sanitized summary: short, one line, no path and no URL with a query
|
|
15
|
+
* string. Fields with a private key name are dropped.
|
|
16
|
+
*
|
|
17
|
+
* The diagnostic mode (`PI_LOG_DIAGNOSTIC=1`) relaxes rule 2 for a user who
|
|
18
|
+
* explicitly asked for more, and nothing else.
|
|
19
|
+
*/
|
|
20
|
+
import type { LogRecord } from "./types.js";
|
|
21
|
+
export interface ClassificationPolicy {
|
|
22
|
+
/** Events that may go remote. */
|
|
23
|
+
remoteEvents: RegExp[];
|
|
24
|
+
/** Events that never go remote, whatever the level is. */
|
|
25
|
+
localEvents: RegExp[];
|
|
26
|
+
/** Keep a message even when it does not look sanitized. */
|
|
27
|
+
allowRawMessages: boolean;
|
|
28
|
+
/** Maximum length of a message that is kept. */
|
|
29
|
+
maxMessageLength: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Events that stay local.
|
|
33
|
+
*
|
|
34
|
+
* `harness.log` is the mirror of the catch-all local log line - it carries
|
|
35
|
+
* whatever the harness printed, so it is never remote.
|
|
36
|
+
*/
|
|
37
|
+
export declare const DEFAULT_LOCAL_EVENTS: RegExp[];
|
|
38
|
+
/**
|
|
39
|
+
* Events that may go remote.
|
|
40
|
+
*
|
|
41
|
+
* They are structured: a service state change, a session lifecycle event, a
|
|
42
|
+
* validation tier, a provider or quota event.
|
|
43
|
+
*/
|
|
44
|
+
export declare const DEFAULT_REMOTE_EVENTS: RegExp[];
|
|
45
|
+
export declare const DEFAULT_CLASSIFICATION_POLICY: ClassificationPolicy;
|
|
46
|
+
/**
|
|
47
|
+
* True when a message looks like a sanitized summary and may travel.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isSanitizedMessage(message: string, policy: ClassificationPolicy): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Classify one record.
|
|
52
|
+
*
|
|
53
|
+
* "remote" means the record may be shipped; "local" means it must stay on
|
|
54
|
+
* the machine.
|
|
55
|
+
*/
|
|
56
|
+
export declare function classifyRecord(record: LogRecord, policy?: ClassificationPolicy): "remote" | "local";
|
|
57
|
+
/**
|
|
58
|
+
* Build the version of a record that may leave the machine.
|
|
59
|
+
*
|
|
60
|
+
* Returns null when the record must stay local.
|
|
61
|
+
*/
|
|
62
|
+
export declare function prepareRemoteRecord(record: LogRecord, policy?: ClassificationPolicy): LogRecord | null;
|
|
63
|
+
/** Keep only the records that may leave the machine. */
|
|
64
|
+
export declare function filterRemoteRecords(records: LogRecord[], policy?: ClassificationPolicy): LogRecord[];
|
|
65
|
+
//# sourceMappingURL=classification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.d.ts","sourceRoot":"","sources":["../src/classification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACpC,iCAAiC;IACjC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,2DAA2D;IAC3D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAUxC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAiBzC,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,oBAK3C,CAAC;AAKF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAOzF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,SAAS,EACjB,MAAM,GAAE,oBAAoD,GAC1D,QAAQ,GAAG,OAAO,CAapB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,GAAE,oBAAoD,GAC1D,SAAS,GAAG,IAAI,CA8BlB;AAED,wDAAwD;AACxD,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,SAAS,EAAE,EACpB,MAAM,GAAE,oBAAoD,GAC1D,SAAS,EAAE,CAOb"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What may leave the machine.
|
|
3
|
+
*
|
|
4
|
+
* The local log file keeps everything. The centralized archive keeps what an
|
|
5
|
+
* operator actually needs: service state, event codes, sanitized errors,
|
|
6
|
+
* durations and opaque identifiers.
|
|
7
|
+
*
|
|
8
|
+
* Two rules decide:
|
|
9
|
+
*
|
|
10
|
+
* 1. The event decides. A catch-all mirror of a local log line
|
|
11
|
+
* (`harness.log`) or anything that smells like a prompt, a response or
|
|
12
|
+
* command output never leaves the machine.
|
|
13
|
+
* 2. The payload decides. A message only travels when it looks like a
|
|
14
|
+
* sanitized summary: short, one line, no path and no URL with a query
|
|
15
|
+
* string. Fields with a private key name are dropped.
|
|
16
|
+
*
|
|
17
|
+
* The diagnostic mode (`PI_LOG_DIAGNOSTIC=1`) relaxes rule 2 for a user who
|
|
18
|
+
* explicitly asked for more, and nothing else.
|
|
19
|
+
*/
|
|
20
|
+
import { isLocalOnlyFieldKey } from "./sensitive-keys.js";
|
|
21
|
+
/**
|
|
22
|
+
* Events that stay local.
|
|
23
|
+
*
|
|
24
|
+
* `harness.log` is the mirror of the catch-all local log line - it carries
|
|
25
|
+
* whatever the harness printed, so it is never remote.
|
|
26
|
+
*/
|
|
27
|
+
export const DEFAULT_LOCAL_EVENTS = [
|
|
28
|
+
/^harness\.log$/,
|
|
29
|
+
/prompt/i,
|
|
30
|
+
/response/i,
|
|
31
|
+
/transcript/i,
|
|
32
|
+
/output/i,
|
|
33
|
+
/command/i,
|
|
34
|
+
/content/i,
|
|
35
|
+
/message\.text/i,
|
|
36
|
+
/notification\.text/i,
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* Events that may go remote.
|
|
40
|
+
*
|
|
41
|
+
* They are structured: a service state change, a session lifecycle event, a
|
|
42
|
+
* validation tier, a provider or quota event.
|
|
43
|
+
*/
|
|
44
|
+
export const DEFAULT_REMOTE_EVENTS = [
|
|
45
|
+
/^harness\.service-diagnostics\./,
|
|
46
|
+
/^harness\.session\./,
|
|
47
|
+
/^harness\.startup\./,
|
|
48
|
+
/^harness\.shutdown\./,
|
|
49
|
+
/^harness\.planner\.decision$/,
|
|
50
|
+
/^harness\.glm-quota\.quota$/,
|
|
51
|
+
/^validation\./,
|
|
52
|
+
/^tier\./,
|
|
53
|
+
/^service\./,
|
|
54
|
+
/^session\./,
|
|
55
|
+
/^startup\./,
|
|
56
|
+
/^config\./,
|
|
57
|
+
/^provider\./,
|
|
58
|
+
/^quota\./,
|
|
59
|
+
/^logging\./,
|
|
60
|
+
/^jest\./,
|
|
61
|
+
];
|
|
62
|
+
export const DEFAULT_CLASSIFICATION_POLICY = {
|
|
63
|
+
remoteEvents: DEFAULT_REMOTE_EVENTS,
|
|
64
|
+
localEvents: DEFAULT_LOCAL_EVENTS,
|
|
65
|
+
allowRawMessages: false,
|
|
66
|
+
maxMessageLength: 200,
|
|
67
|
+
};
|
|
68
|
+
const ABSOLUTE_PATH = /(?:^|\s)\/(?:[\w.-]+\/)+[\w.-]+/;
|
|
69
|
+
const URL_WITH_QUERY = /https?:\/\/\S+\?\S+/;
|
|
70
|
+
/**
|
|
71
|
+
* True when a message looks like a sanitized summary and may travel.
|
|
72
|
+
*/
|
|
73
|
+
export function isSanitizedMessage(message, policy) {
|
|
74
|
+
if (policy.allowRawMessages)
|
|
75
|
+
return true;
|
|
76
|
+
if (message.length > policy.maxMessageLength)
|
|
77
|
+
return false;
|
|
78
|
+
if (message.includes("\n"))
|
|
79
|
+
return false;
|
|
80
|
+
if (ABSOLUTE_PATH.test(message))
|
|
81
|
+
return false;
|
|
82
|
+
if (URL_WITH_QUERY.test(message))
|
|
83
|
+
return false;
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Classify one record.
|
|
88
|
+
*
|
|
89
|
+
* "remote" means the record may be shipped; "local" means it must stay on
|
|
90
|
+
* the machine.
|
|
91
|
+
*/
|
|
92
|
+
export function classifyRecord(record, policy = DEFAULT_CLASSIFICATION_POLICY) {
|
|
93
|
+
for (const pattern of policy.localEvents) {
|
|
94
|
+
if (pattern.test(record.event))
|
|
95
|
+
return "local";
|
|
96
|
+
}
|
|
97
|
+
for (const pattern of policy.remoteEvents) {
|
|
98
|
+
if (pattern.test(record.event))
|
|
99
|
+
return "remote";
|
|
100
|
+
}
|
|
101
|
+
// Errors stay valuable even when the event is unknown: the message and
|
|
102
|
+
// the fields are sanitized anyway.
|
|
103
|
+
if (record.level === "warn" || record.level === "error")
|
|
104
|
+
return "remote";
|
|
105
|
+
// Unknown events are local by default: an allowlist is safer than a
|
|
106
|
+
// denylist.
|
|
107
|
+
return "local";
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Build the version of a record that may leave the machine.
|
|
111
|
+
*
|
|
112
|
+
* Returns null when the record must stay local.
|
|
113
|
+
*/
|
|
114
|
+
export function prepareRemoteRecord(record, policy = DEFAULT_CLASSIFICATION_POLICY) {
|
|
115
|
+
if (classifyRecord(record, policy) === "local")
|
|
116
|
+
return null;
|
|
117
|
+
const remote = {
|
|
118
|
+
ts: record.ts,
|
|
119
|
+
level: record.level,
|
|
120
|
+
source: record.source,
|
|
121
|
+
event: record.event,
|
|
122
|
+
};
|
|
123
|
+
if (record.message !== undefined && isSanitizedMessage(record.message, policy)) {
|
|
124
|
+
remote.message = record.message;
|
|
125
|
+
}
|
|
126
|
+
if (record.sessionId)
|
|
127
|
+
remote.sessionId = record.sessionId;
|
|
128
|
+
if (typeof record.durationMs === "number")
|
|
129
|
+
remote.durationMs = record.durationMs;
|
|
130
|
+
if (record.fields) {
|
|
131
|
+
const fields = {};
|
|
132
|
+
for (const [key, value] of Object.entries(record.fields)) {
|
|
133
|
+
if (isLocalOnlyFieldKey(key))
|
|
134
|
+
continue;
|
|
135
|
+
fields[key] = value;
|
|
136
|
+
}
|
|
137
|
+
if (Object.keys(fields).length > 0)
|
|
138
|
+
remote.fields = fields;
|
|
139
|
+
}
|
|
140
|
+
if (record.error) {
|
|
141
|
+
remote.error = { ...record.error };
|
|
142
|
+
}
|
|
143
|
+
return remote;
|
|
144
|
+
}
|
|
145
|
+
/** Keep only the records that may leave the machine. */
|
|
146
|
+
export function filterRemoteRecords(records, policy = DEFAULT_CLASSIFICATION_POLICY) {
|
|
147
|
+
const remote = [];
|
|
148
|
+
for (const record of records) {
|
|
149
|
+
const prepared = prepareRemoteRecord(record, policy);
|
|
150
|
+
if (prepared)
|
|
151
|
+
remote.push(prepared);
|
|
152
|
+
}
|
|
153
|
+
return remote;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=classification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.js","sourceRoot":"","sources":["../src/classification.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Secrets are never hardcoded here. A key file that is missing simply means
|
|
8
8
|
* the corresponding transport is not configured.
|
|
9
9
|
*/
|
|
10
|
+
import { type ClassificationPolicy } from "./classification.js";
|
|
10
11
|
import type { LogBufferOptions } from "./buffer.js";
|
|
11
12
|
import type { SamplingPolicy } from "./sampler.js";
|
|
12
13
|
import type { LogTransport } from "./types.js";
|
|
@@ -16,6 +17,10 @@ export interface LogSinkConfig {
|
|
|
16
17
|
enabled: boolean;
|
|
17
18
|
/** Application name reported with every batch. */
|
|
18
19
|
app: string;
|
|
20
|
+
/** Version of the emitting application. */
|
|
21
|
+
appVersion?: string;
|
|
22
|
+
/** Stable id of this installation. */
|
|
23
|
+
installationId: string;
|
|
19
24
|
/** Transports in delivery priority order. */
|
|
20
25
|
transports: LogTransport[];
|
|
21
26
|
/** Directory of the local spool (undefined when logging is off). */
|
|
@@ -23,6 +28,8 @@ export interface LogSinkConfig {
|
|
|
23
28
|
sampling: Partial<SamplingPolicy>;
|
|
24
29
|
buffer: LogBufferOptions;
|
|
25
30
|
flushIntervalMs: number;
|
|
31
|
+
/** What may leave the machine. */
|
|
32
|
+
classification: ClassificationPolicy;
|
|
26
33
|
/** Human readable notes about what was enabled and why. */
|
|
27
34
|
notes: string[];
|
|
28
35
|
}
|
|
@@ -30,6 +37,8 @@ export interface ResolveConfigOptions {
|
|
|
30
37
|
env?: Record<string, string | undefined>;
|
|
31
38
|
/** Directory holding the credential key files. */
|
|
32
39
|
keysDir?: string;
|
|
40
|
+
/** Overrides the installation id (tests, containers). */
|
|
41
|
+
installationId?: string;
|
|
33
42
|
}
|
|
34
43
|
export declare function defaultKeysDir(): string;
|
|
35
44
|
export declare function defaultSpoolDir(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,EAEN,KAAK,oBAAoB,EACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,CAAC;AAE3E,MAAM,WAAW,aAAa;IAC7B,sEAAsE;IACtE,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAClC,MAAM,EAAE,gBAAgB,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,cAAc,EAAE,oBAAoB,CAAC;IACrC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAoBD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAiBD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAuHtF"}
|
|
@@ -12,6 +12,8 @@ import { homedir } from "node:os";
|
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
import { createR2Transport } from "./transports/r2.js";
|
|
14
14
|
import { createWebhookTransport } from "./transports/webhook.js";
|
|
15
|
+
import { resolveInstallationId } from "./installation.js";
|
|
16
|
+
import { DEFAULT_CLASSIFICATION_POLICY, } from "./classification.js";
|
|
15
17
|
function readKeyFile(keysDir, name) {
|
|
16
18
|
const file = join(keysDir, name);
|
|
17
19
|
if (!existsSync(file))
|
|
@@ -32,6 +34,19 @@ export function defaultKeysDir() {
|
|
|
32
34
|
export function defaultSpoolDir() {
|
|
33
35
|
return join(homedir(), ".pi-harness-runtime", "logs", "spool");
|
|
34
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Build the classification policy.
|
|
39
|
+
*
|
|
40
|
+
* `PI_LOG_DIAGNOSTIC=1` is the explicit, user controlled diagnostic mode: it
|
|
41
|
+
* lets messages travel that the default policy keeps local. It never widens
|
|
42
|
+
* the event allowlist - only the message rule.
|
|
43
|
+
*/
|
|
44
|
+
function classificationFor(env) {
|
|
45
|
+
const diagnostic = env.PI_LOG_DIAGNOSTIC === "1" || env.PI_LOG_DIAGNOSTIC === "true";
|
|
46
|
+
if (!diagnostic)
|
|
47
|
+
return DEFAULT_CLASSIFICATION_POLICY;
|
|
48
|
+
return { ...DEFAULT_CLASSIFICATION_POLICY, allowRawMessages: true };
|
|
49
|
+
}
|
|
35
50
|
/**
|
|
36
51
|
* Build the log sink configuration from the environment and the key files.
|
|
37
52
|
*/
|
|
@@ -40,14 +55,17 @@ export function resolveLogSinkConfig(options = {}) {
|
|
|
40
55
|
const keysDir = options.keysDir ?? defaultKeysDir();
|
|
41
56
|
const mode = (env.PI_LOG_SINK ?? "auto");
|
|
42
57
|
const notes = [];
|
|
58
|
+
const installationId = options.installationId ?? env.PI_LOG_INSTALLATION_ID ?? resolveInstallationId();
|
|
43
59
|
if (mode === "off") {
|
|
44
60
|
return {
|
|
45
61
|
enabled: false,
|
|
46
62
|
app: env.PI_LOG_APP ?? "pi-harness",
|
|
63
|
+
installationId,
|
|
47
64
|
transports: [],
|
|
48
65
|
sampling: {},
|
|
49
66
|
buffer: {},
|
|
50
67
|
flushIntervalMs: 0,
|
|
68
|
+
classification: classificationFor(env),
|
|
51
69
|
notes: ["logging disabled by PI_LOG_SINK=off"],
|
|
52
70
|
};
|
|
53
71
|
}
|
|
@@ -60,7 +78,19 @@ export function resolveLogSinkConfig(options = {}) {
|
|
|
60
78
|
readKeyFile(keysDir, "r2-endpoint.txt") ??
|
|
61
79
|
(accountId ? `https://${accountId}.r2.cloudflarestorage.com` : undefined);
|
|
62
80
|
const r2Ready = Boolean(bucket && accessKeyId && secretAccessKey && endpoint);
|
|
63
|
-
const
|
|
81
|
+
const webhookUrl = env.PI_LOG_WEBHOOK_URL;
|
|
82
|
+
/*
|
|
83
|
+
* Transport selection.
|
|
84
|
+
*
|
|
85
|
+
* The transports form a FALLBACK chain, not a broadcast: the first
|
|
86
|
+
* transport that accepts the batch wins and the later ones are not
|
|
87
|
+
* called. `auto` therefore prefers the webhook ingress when one is
|
|
88
|
+
* configured: the server is the single writer to R2, so client machines
|
|
89
|
+
* never need R2 credentials at all.
|
|
90
|
+
*/
|
|
91
|
+
const wantR2 = mode === "r2" ||
|
|
92
|
+
mode === "r2+webhook" ||
|
|
93
|
+
(mode === "auto" && r2Ready && !webhookUrl);
|
|
64
94
|
if (wantR2) {
|
|
65
95
|
if (r2Ready) {
|
|
66
96
|
transports.push(createR2Transport({
|
|
@@ -76,7 +106,6 @@ export function resolveLogSinkConfig(options = {}) {
|
|
|
76
106
|
notes.push("r2 requested but credentials are incomplete - transport skipped");
|
|
77
107
|
}
|
|
78
108
|
}
|
|
79
|
-
const webhookUrl = env.PI_LOG_WEBHOOK_URL;
|
|
80
109
|
const wantWebhook = mode === "webhook" || mode === "r2+webhook" || (mode === "auto" && Boolean(webhookUrl));
|
|
81
110
|
if (wantWebhook) {
|
|
82
111
|
if (webhookUrl) {
|
|
@@ -85,6 +114,9 @@ export function resolveLogSinkConfig(options = {}) {
|
|
|
85
114
|
token: env.PI_LOG_WEBHOOK_TOKEN,
|
|
86
115
|
}));
|
|
87
116
|
notes.push(`webhook enabled (${webhookUrl})`);
|
|
117
|
+
if (mode === "auto") {
|
|
118
|
+
notes.push("webhook is the client ingress point - the server writes to R2 (direct r2 transport skipped)");
|
|
119
|
+
}
|
|
88
120
|
}
|
|
89
121
|
else {
|
|
90
122
|
notes.push("webhook requested but PI_LOG_WEBHOOK_URL is not set - transport skipped");
|
|
@@ -93,9 +125,10 @@ export function resolveLogSinkConfig(options = {}) {
|
|
|
93
125
|
if (transports.length === 0) {
|
|
94
126
|
notes.push("no transport configured - logs stay local");
|
|
95
127
|
}
|
|
96
|
-
|
|
128
|
+
const config = {
|
|
97
129
|
enabled: true,
|
|
98
130
|
app: env.PI_LOG_APP ?? "pi-harness",
|
|
131
|
+
installationId,
|
|
99
132
|
transports,
|
|
100
133
|
spoolDir: env.PI_LOG_SPOOL_DIR ?? defaultSpoolDir(),
|
|
101
134
|
sampling: {
|
|
@@ -108,7 +141,11 @@ export function resolveLogSinkConfig(options = {}) {
|
|
|
108
141
|
maxBatchSize: readNumber(env, "PI_LOG_BATCH_SIZE", 100),
|
|
109
142
|
},
|
|
110
143
|
flushIntervalMs: readNumber(env, "PI_LOG_FLUSH_INTERVAL_MS", 15_000),
|
|
144
|
+
classification: classificationFor(env),
|
|
111
145
|
notes,
|
|
112
146
|
};
|
|
147
|
+
if (env.PI_LOG_APP_VERSION)
|
|
148
|
+
config.appVersion = env.PI_LOG_APP_VERSION;
|
|
149
|
+
return config;
|
|
113
150
|
}
|
|
114
151
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* webhook server provides the live path, and the local spool is the
|
|
10
10
|
* fallback that keeps data when both are unavailable.
|
|
11
11
|
*/
|
|
12
|
-
export { LOG_LEVEL_SEVERITY } from "./types.js";
|
|
12
|
+
export { LOG_LEVEL_SEVERITY, LOG_SCHEMA_VERSION } from "./types.js";
|
|
13
13
|
export type { FlushStats, LogBatch, LogErrorInfo, LogInput, LogLevel, LogRecord, LogTransport, } from "./types.js";
|
|
14
14
|
export { isSecretKey, isSensitiveValueKey, redactFields, redactText, redactValue, splitKeyTokens, } from "./redact.js";
|
|
15
15
|
export type { JsonValue, RedactionOptions } from "./redact.js";
|
|
@@ -27,6 +27,14 @@ export { LogShipper } from "./shipper.js";
|
|
|
27
27
|
export type { LogShipperOptions } from "./shipper.js";
|
|
28
28
|
export { centralDebug, centralError, centralInfo, centralLog, centralWarn, getCentralLogConfig, getCentralShipper, initCentralLogging, shutdownCentralLogging, } from "./singleton.js";
|
|
29
29
|
export type { InitCentralLoggingOptions } from "./singleton.js";
|
|
30
|
+
export { INSTALLATION_ID_FILE, defaultInstallationIdPath, isValidInstallationId, resolveInstallationId, } from "./installation.js";
|
|
31
|
+
export type { ResolveInstallationIdOptions } from "./installation.js";
|
|
32
|
+
export { DEFAULT_CLASSIFICATION_POLICY, DEFAULT_LOCAL_EVENTS, DEFAULT_REMOTE_EVENTS, classifyRecord, filterRemoteRecords, isSanitizedMessage, prepareRemoteRecord, } from "./classification.js";
|
|
33
|
+
export type { ClassificationPolicy } from "./classification.js";
|
|
34
|
+
export { LOCAL_ONLY_FIELD_KEYS, isLocalOnlyFieldKey } from "./sensitive-keys.js";
|
|
35
|
+
export { DEFAULT_BATCH_LIMITS, LOG_LEVELS, sanitizeRecord, validateBatch, } from "./ingest/schema.js";
|
|
36
|
+
export type { BatchValidationError, BatchValidationLimits, BatchValidationResult, SanitizeRecordResult, } from "./ingest/schema.js";
|
|
37
|
+
export * from "./server/index.js";
|
|
30
38
|
export { defaultKeysDir, defaultSpoolDir, resolveLogSinkConfig, } from "./config.js";
|
|
31
39
|
export type { LogSinkConfig, LogSinkMode, ResolveConfigOptions } from "./config.js";
|
|
32
40
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACpE,YAAY,EACX,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,YAAY,GACZ,MAAM,YAAY,CAAC;AAIpB,OAAO,EACN,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/D,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAIvE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAItD,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAIhE,OAAO,EACN,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAItE,OAAO,EACN,6BAA6B,EAC7B,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAIjF,OAAO,EACN,oBAAoB,EACpB,UAAU,EACV,cAAc,EACd,aAAa,GACb,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACX,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,GACpB,MAAM,oBAAoB,CAAC;AAI5B,cAAc,mBAAmB,CAAC;AAIlC,OAAO,EACN,cAAc,EACd,eAAe,EACf,oBAAoB,GACpB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* fallback that keeps data when both are unavailable.
|
|
11
11
|
*/
|
|
12
12
|
// --- Types -----------------------------------------------------------------
|
|
13
|
-
export { LOG_LEVEL_SEVERITY } from "./types.js";
|
|
13
|
+
export { LOG_LEVEL_SEVERITY, LOG_SCHEMA_VERSION } from "./types.js";
|
|
14
14
|
// --- Redaction -------------------------------------------------------------
|
|
15
15
|
export { isSecretKey, isSensitiveValueKey, redactFields, redactText, redactValue, splitKeyTokens, } from "./redact.js";
|
|
16
16
|
// --- Sampling --------------------------------------------------------------
|
|
@@ -26,6 +26,15 @@ export { createWebhookTransport } from "./transports/webhook.js";
|
|
|
26
26
|
export { LogShipper } from "./shipper.js";
|
|
27
27
|
// --- Process wide singleton -------------------------------------------------
|
|
28
28
|
export { centralDebug, centralError, centralInfo, centralLog, centralWarn, getCentralLogConfig, getCentralShipper, initCentralLogging, shutdownCentralLogging, } from "./singleton.js";
|
|
29
|
+
// --- Installation identity --------------------------------------------------
|
|
30
|
+
export { INSTALLATION_ID_FILE, defaultInstallationIdPath, isValidInstallationId, resolveInstallationId, } from "./installation.js";
|
|
31
|
+
// --- Classification (what may leave the machine) ----------------------------
|
|
32
|
+
export { DEFAULT_CLASSIFICATION_POLICY, DEFAULT_LOCAL_EVENTS, DEFAULT_REMOTE_EVENTS, classifyRecord, filterRemoteRecords, isSanitizedMessage, prepareRemoteRecord, } from "./classification.js";
|
|
33
|
+
export { LOCAL_ONLY_FIELD_KEYS, isLocalOnlyFieldKey } from "./sensitive-keys.js";
|
|
34
|
+
// --- Ingest contract (shared by client and server) -------------------------
|
|
35
|
+
export { DEFAULT_BATCH_LIMITS, LOG_LEVELS, sanitizeRecord, validateBatch, } from "./ingest/schema.js";
|
|
36
|
+
// --- Server side ------------------------------------------------------------
|
|
37
|
+
export * from "./server/index.js";
|
|
29
38
|
// --- Configuration ---------------------------------------------------------
|
|
30
39
|
export { defaultKeysDir, defaultSpoolDir, resolveLogSinkConfig, } from "./config.js";
|
|
31
40
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,8EAA8E;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,8EAA8E;AAE9E,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAWpE,8EAA8E;AAE9E,OAAO,EACN,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,cAAc,GACd,MAAM,aAAa,CAAC;AAGrB,8EAA8E;AAE9E,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGnE,8EAA8E;AAE9E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,8EAA8E;AAE9E,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,8EAA8E;AAE9E,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,+EAA+E;AAE/E,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,+EAA+E;AAE/E,OAAO,EACN,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,+EAA+E;AAE/E,OAAO,EACN,6BAA6B,EAC7B,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,8EAA8E;AAE9E,OAAO,EACN,oBAAoB,EACpB,UAAU,EACV,cAAc,EACd,aAAa,GACb,MAAM,oBAAoB,CAAC;AAQ5B,+EAA+E;AAE/E,cAAc,mBAAmB,CAAC;AAElC,8EAA8E;AAE9E,OAAO,EACN,cAAc,EACd,eAAe,EACf,oBAAoB,GACpB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ingest contract: strict validation and allowlisted redaction.
|
|
3
|
+
*
|
|
4
|
+
* The client and the server share this module, so both sides agree on what a
|
|
5
|
+
* batch is. The server never trusts the body:
|
|
6
|
+
*
|
|
7
|
+
* - the tenant comes from the authenticated credential, never from the JSON,
|
|
8
|
+
* - the batch is validated against a strict, versioned schema,
|
|
9
|
+
* - the records are rebuilt from an allowlist, so an unknown property can
|
|
10
|
+
* never smuggle data into the archive,
|
|
11
|
+
* - every string is redacted again on the server (defence in depth).
|
|
12
|
+
*/
|
|
13
|
+
import { type LogBatch, type LogLevel, type LogRecord } from "../types.js";
|
|
14
|
+
export declare const LOG_LEVELS: readonly LogLevel[];
|
|
15
|
+
export interface BatchValidationLimits {
|
|
16
|
+
/** Maximum number of records in one batch. */
|
|
17
|
+
maxRecords: number;
|
|
18
|
+
/** Maximum length of a single string value. */
|
|
19
|
+
maxStringLength: number;
|
|
20
|
+
/** Maximum number of structured fields per record. */
|
|
21
|
+
maxFieldKeys: number;
|
|
22
|
+
}
|
|
23
|
+
export declare const DEFAULT_BATCH_LIMITS: BatchValidationLimits;
|
|
24
|
+
export interface BatchValidationError {
|
|
25
|
+
code: string;
|
|
26
|
+
message: string;
|
|
27
|
+
}
|
|
28
|
+
export type BatchValidationResult = {
|
|
29
|
+
ok: true;
|
|
30
|
+
batch: LogBatch;
|
|
31
|
+
warnings: string[];
|
|
32
|
+
} | {
|
|
33
|
+
ok: false;
|
|
34
|
+
error: BatchValidationError;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Validate an inbound batch.
|
|
38
|
+
*
|
|
39
|
+
* Unknown properties are NOT an error here - the sanitizer drops them. Only a
|
|
40
|
+
* structurally broken batch is rejected.
|
|
41
|
+
*/
|
|
42
|
+
export declare function validateBatch(input: unknown, options?: {
|
|
43
|
+
limits?: Partial<BatchValidationLimits>;
|
|
44
|
+
}): BatchValidationResult;
|
|
45
|
+
export type SanitizeRecordResult = {
|
|
46
|
+
ok: true;
|
|
47
|
+
record: LogRecord;
|
|
48
|
+
} | {
|
|
49
|
+
ok: false;
|
|
50
|
+
error: BatchValidationError;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Rebuild one record from the allowlist and redact every string.
|
|
54
|
+
*
|
|
55
|
+
* Unknown properties are dropped, `error.name`, `error.message` and
|
|
56
|
+
* `error.stack` are redacted, and structured fields lose the keys that can
|
|
57
|
+
* carry private content.
|
|
58
|
+
*/
|
|
59
|
+
export declare function sanitizeRecord(input: unknown, limits?: Partial<BatchValidationLimits>): SanitizeRecordResult;
|
|
60
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/ingest/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAsB,KAAK,QAAQ,EAAqB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAElH,eAAO,MAAM,UAAU,EAAE,SAAS,QAAQ,EAAuC,CAAC;AAElF,MAAM,WAAW,qBAAqB;IACrC,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,eAAe,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,oBAAoB,EAAE,qBAIlC,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,qBAAqB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACjD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAc9C;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;CAAO,GACvD,qBAAqB,CAmHvB;AA6BD,MAAM,MAAM,oBAAoB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,KAAK,EAAE,OAAO,EACd,MAAM,GAAE,OAAO,CAAC,qBAAqB,CAAM,GACzC,oBAAoB,CAwEtB"}
|