@senpi/runtime 1.1.0-dev.runtime-phase-2.20260610125851 → 1.1.0-dev.runtime-phase-2.20260610130051
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/dsl/events/handlers.d.ts.map +1 -1
- package/dist/dsl/events/handlers.js +4 -0
- package/dist/dsl/events/handlers.js.map +1 -1
- package/dist/recording/emitter.d.ts +21 -0
- package/dist/recording/emitter.d.ts.map +1 -0
- package/dist/recording/emitter.js +2 -0
- package/dist/recording/emitter.js.map +1 -0
- package/dist/recording/identity.d.ts +34 -0
- package/dist/recording/identity.d.ts.map +1 -0
- package/dist/recording/identity.js +2 -0
- package/dist/recording/identity.js.map +1 -0
- package/dist/recording/index.d.ts +11 -0
- package/dist/recording/index.d.ts.map +1 -0
- package/dist/recording/index.js +2 -0
- package/dist/recording/index.js.map +1 -0
- package/dist/recording/noop-emitter.d.ts +17 -0
- package/dist/recording/noop-emitter.d.ts.map +1 -0
- package/dist/recording/noop-emitter.js +16 -0
- package/dist/recording/noop-emitter.js.map +1 -0
- package/dist/recording/otel/attributes.d.ts +35 -0
- package/dist/recording/otel/attributes.d.ts.map +1 -0
- package/dist/recording/otel/attributes.js +131 -0
- package/dist/recording/otel/attributes.js.map +1 -0
- package/dist/recording/otel/constants.d.ts +81 -0
- package/dist/recording/otel/constants.d.ts.map +1 -0
- package/dist/recording/otel/constants.js +96 -0
- package/dist/recording/otel/constants.js.map +1 -0
- package/dist/recording/otel/ids.d.ts +14 -0
- package/dist/recording/otel/ids.d.ts.map +1 -0
- package/dist/recording/otel/ids.js +12 -0
- package/dist/recording/otel/ids.js.map +1 -0
- package/dist/recording/otel/index.d.ts +13 -0
- package/dist/recording/otel/index.d.ts.map +1 -0
- package/dist/recording/otel/index.js +9 -0
- package/dist/recording/otel/index.js.map +1 -0
- package/dist/recording/otel/mappers.d.ts +42 -0
- package/dist/recording/otel/mappers.d.ts.map +1 -0
- package/dist/recording/otel/mappers.js +337 -0
- package/dist/recording/otel/mappers.js.map +1 -0
- package/dist/recording/otel/otel-emitter.d.ts +37 -0
- package/dist/recording/otel/otel-emitter.d.ts.map +1 -0
- package/dist/recording/otel/otel-emitter.js +75 -0
- package/dist/recording/otel/otel-emitter.js.map +1 -0
- package/dist/recording/otel/redaction.d.ts +31 -0
- package/dist/recording/otel/redaction.d.ts.map +1 -0
- package/dist/recording/otel/redaction.js +40 -0
- package/dist/recording/otel/redaction.js.map +1 -0
- package/dist/recording/records.d.ts +327 -0
- package/dist/recording/records.d.ts.map +1 -0
- package/dist/recording/records.js +14 -0
- package/dist/recording/records.js.map +1 -0
- package/dist/recording/transport/batcher.d.ts +59 -0
- package/dist/recording/transport/batcher.d.ts.map +1 -0
- package/dist/recording/transport/batcher.js +234 -0
- package/dist/recording/transport/batcher.js.map +1 -0
- package/dist/recording/transport/client.d.ts +41 -0
- package/dist/recording/transport/client.d.ts.map +1 -0
- package/dist/recording/transport/client.js +69 -0
- package/dist/recording/transport/client.js.map +1 -0
- package/dist/recording/transport/config.d.ts +53 -0
- package/dist/recording/transport/config.d.ts.map +1 -0
- package/dist/recording/transport/config.js +41 -0
- package/dist/recording/transport/config.js.map +1 -0
- package/dist/recording/transport/index.d.ts +16 -0
- package/dist/recording/transport/index.d.ts.map +1 -0
- package/dist/recording/transport/index.js +12 -0
- package/dist/recording/transport/index.js.map +1 -0
- package/dist/recording/transport/rows.d.ts +88 -0
- package/dist/recording/transport/rows.d.ts.map +1 -0
- package/dist/recording/transport/rows.js +15 -0
- package/dist/recording/transport/rows.js.map +1 -0
- package/dist/recording/wiring/emitter-factory.d.ts +39 -0
- package/dist/recording/wiring/emitter-factory.d.ts.map +1 -0
- package/dist/recording/wiring/emitter-factory.js +62 -0
- package/dist/recording/wiring/emitter-factory.js.map +1 -0
- package/dist/recording/wiring/identity.d.ts +27 -0
- package/dist/recording/wiring/identity.d.ts.map +1 -0
- package/dist/recording/wiring/identity.js +51 -0
- package/dist/recording/wiring/identity.js.map +1 -0
- package/dist/recording/wiring/index.d.ts +12 -0
- package/dist/recording/wiring/index.d.ts.map +1 -0
- package/dist/recording/wiring/index.js +9 -0
- package/dist/recording/wiring/index.js.map +1 -0
- package/dist/recording/wiring/record-builders.d.ts +68 -0
- package/dist/recording/wiring/record-builders.d.ts.map +1 -0
- package/dist/recording/wiring/record-builders.js +441 -0
- package/dist/recording/wiring/record-builders.js.map +1 -0
- package/dist/recording/wiring/subscriber.d.ts +21 -0
- package/dist/recording/wiring/subscriber.d.ts.map +1 -0
- package/dist/recording/wiring/subscriber.js +171 -0
- package/dist/recording/wiring/subscriber.js.map +1 -0
- package/dist/recording/wiring/values.d.ts +19 -0
- package/dist/recording/wiring/values.d.ts.map +1 -0
- package/dist/recording/wiring/values.js +49 -0
- package/dist/recording/wiring/values.js.map +1 -0
- package/dist/runtime/load-runtime-config.d.ts +9 -0
- package/dist/runtime/load-runtime-config.d.ts.map +1 -1
- package/dist/runtime/load-runtime-config.js +41 -1
- package/dist/runtime/load-runtime-config.js.map +1 -1
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +3 -2
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime/runtime-schema.d.ts +182 -0
- package/dist/runtime/runtime-schema.d.ts.map +1 -1
- package/dist/runtime/runtime-schema.js +17 -0
- package/dist/runtime/runtime-schema.js.map +1 -1
- package/dist/runtime/runtime.d.ts +15 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +246 -148
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/scanners/events.d.ts +6 -0
- package/dist/scanners/events.d.ts.map +1 -1
- package/dist/scanners/events.js.map +1 -1
- package/dist/scanners/runtime-module.d.ts.map +1 -1
- package/dist/scanners/runtime-module.js +9 -1
- package/dist/scanners/runtime-module.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../../src/recording/otel/redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EAEtB,MAAM,eAAe,CAAC;AAEvB,sGAAsG;AACtG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,qBAAqB,CAK1F;AAED,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAGjF;AAED,uGAAuG;AACvG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAEjF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redaction (Rule 6) — the only place sensitive data is scrubbed. It runs on **typed fields by
|
|
3
|
+
* name, before flattening**: the sensitive fields are enumerable, so this is deterministic and
|
|
4
|
+
* testable, more robust than scrubbing flattened keys after the fact.
|
|
5
|
+
*
|
|
6
|
+
* Policy (value-vs-risk, confirmed against the real producers):
|
|
7
|
+
* - **Drop the two genuinely-open bags wholesale.** `SignalSummary.meta` is bounded only for the
|
|
8
|
+
* scanners we ship, but the runtime exists to host arbitrary scanner implementations, so its
|
|
9
|
+
* contents can't be vouched for. `SignalDecision.payload` is raw LLM JSON validated only as "an
|
|
10
|
+
* object" (free-text + arbitrary keys + a nested scanner-meta passthrough). Neither ships; the
|
|
11
|
+
* high-value bounded data they'd carry is already on typed scalars / the per-signal child spans.
|
|
12
|
+
* - **Mask `RuntimeErrorRecord.stack`** (it can embed file paths / secrets) with {@link REDACT_MARKER}.
|
|
13
|
+
* - **Kept (NOT redacted), only length-capped at flatten time:** `SignalDecision.reasoning` and
|
|
14
|
+
* `PositionLifecycleRecord.reasoning` (high-value agent rationale — paired with the child spans
|
|
15
|
+
* they let you audit whether the reasoning matched the decision), and `RuntimeStateRecord.reason`
|
|
16
|
+
* (code-templated "why trading paused" string with live numbers, no user/LLM input).
|
|
17
|
+
* - `RuntimeStateRecord.metrics` is dropped — provably numeric/boolean, but not requested for now.
|
|
18
|
+
* - `RuntimeLifecycleRecord.config` is the *unresolved* config (placeholders intact, no inlined
|
|
19
|
+
* secrets), so it is only size-capped, never redacted.
|
|
20
|
+
*
|
|
21
|
+
* `decision.payload` is dropped by simply not flattening it in the mapper; this module clears the
|
|
22
|
+
* fields that must not survive even if a future mapper change tries to read them.
|
|
23
|
+
*/
|
|
24
|
+
import { REDACT_MARKER } from "./constants.js";
|
|
25
|
+
/** Drop `signal.meta` (open bag, arbitrary scanner contents). `reasoning` is kept (length-capped). */
|
|
26
|
+
export function redactSignalEvaluated(record) {
|
|
27
|
+
const evaluations = record.evaluations.map((ev) => ev.signal.meta === undefined ? ev : { ...ev, signal: { ...ev.signal, meta: undefined } });
|
|
28
|
+
return { ...record, evaluations };
|
|
29
|
+
}
|
|
30
|
+
/** Mask `stack` (may embed paths/secrets). The `message` is kept — it is the grouping context. */
|
|
31
|
+
export function redactRuntimeError(record) {
|
|
32
|
+
if (!record.stack)
|
|
33
|
+
return record;
|
|
34
|
+
return { ...record, stack: REDACT_MARKER };
|
|
35
|
+
}
|
|
36
|
+
/** Drop the `metrics` bag (not surfaced for now). `reason` is kept (code-templated, length-capped). */
|
|
37
|
+
export function redactRuntimeState(record) {
|
|
38
|
+
return { ...record, metrics: null };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=redaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.js","sourceRoot":"","sources":["../../../src/recording/otel/redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAQ/C,sGAAsG;AACtG,MAAM,UAAU,qBAAqB,CAAC,MAA6B;IACjE,MAAM,WAAW,GAAuB,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CACpE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CACzF,CAAC;IACF,OAAO,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,CAAC;AACpC,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC3D,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;AAC7C,CAAC;AAED,uGAAuG;AACvG,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC3D,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recording contract — the record types the runtime hands to a {@link RecordingEmitter}, covering
|
|
3
|
+
* domain events and runtime errors.
|
|
4
|
+
*
|
|
5
|
+
* Each record is one atomic "work unit": plain, immutable, serializable data with no methods or
|
|
6
|
+
* builder dance; variants are modelled with a discriminator field plus optionals. The types are
|
|
7
|
+
* transport-agnostic — nothing here knows about spans, attributes, or any wire format.
|
|
8
|
+
*
|
|
9
|
+
* Identity (service, recipe, runtime, strategy address, boot id) is stamped by the emitter and is
|
|
10
|
+
* never on a record — see {@link IdentityEnvelope}. Timestamps are epoch milliseconds; ISO strings
|
|
11
|
+
* from the bus are converted before they reach a record, so consumers never parse dates.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Trade direction as the bus reports it. The alias itself is non-null; sites that admit a
|
|
15
|
+
* non-directional signal widen it to `TradeDirection | null` (e.g. {@link SignalSummary}).
|
|
16
|
+
*/
|
|
17
|
+
export type TradeDirection = "LONG" | "SHORT";
|
|
18
|
+
/**
|
|
19
|
+
* Lightweight projection of a scanner signal as it appears on the bus, including the explainable
|
|
20
|
+
* `factors`/`meta` bags so the audit trail keeps the "why". Redacting sensitive `meta` is the
|
|
21
|
+
* adapter's job, not this contract's.
|
|
22
|
+
*/
|
|
23
|
+
export interface SignalSummary {
|
|
24
|
+
readonly signalType: string;
|
|
25
|
+
readonly asset: string;
|
|
26
|
+
readonly direction: TradeDirection | null;
|
|
27
|
+
readonly score: number;
|
|
28
|
+
/** Signal time, epoch ms. */
|
|
29
|
+
readonly timestamp: number;
|
|
30
|
+
readonly factors?: Record<string, boolean>;
|
|
31
|
+
readonly meta?: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
/** Coarse terminal classification of a scanner execution. */
|
|
34
|
+
export type ScannerRunOutcome = "complete" | "skipped" | "error";
|
|
35
|
+
/**
|
|
36
|
+
* One scanner execution attempt (the work unit). Folds the bus's `scanner:run:start` +
|
|
37
|
+
* terminal `scanner:run:{complete,skip,error}` events into a single atomic record so a
|
|
38
|
+
* duration is always derivable (`endedAt - startedAt`). Skip/error early-exit paths can
|
|
39
|
+
* terminate without a paired `scanner:run:start` event; in that case Task 4 fills `startedAt`
|
|
40
|
+
* with the run's attempt timestamp (which equals `endedAt`), so duration is 0 rather than absent.
|
|
41
|
+
* The skipped/disabled distinction lives on `outcome`/`statusDetail`, not on a missing start.
|
|
42
|
+
*/
|
|
43
|
+
export interface ScannerRunRecord {
|
|
44
|
+
readonly type: "scanner_run";
|
|
45
|
+
readonly scannerId: string;
|
|
46
|
+
readonly outcome: ScannerRunOutcome;
|
|
47
|
+
/** Raw engine status: `ok`|`heartbeat`|`skipped`|`halted`|`disabled`|`error`. */
|
|
48
|
+
readonly statusDetail?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Run start, epoch ms (from `scanner:run:start`). Required: on a no-start early-exit path Task 4
|
|
51
|
+
* sets it to the attempt timestamp (= `endedAt`), so a `Duration` is always derivable.
|
|
52
|
+
*/
|
|
53
|
+
readonly startedAt: number;
|
|
54
|
+
/** Run completion, epoch ms (terminal event timestamp). */
|
|
55
|
+
readonly endedAt: number;
|
|
56
|
+
readonly scannedCount?: number;
|
|
57
|
+
readonly actionableCount?: number;
|
|
58
|
+
readonly signalCount?: number;
|
|
59
|
+
readonly signals?: readonly SignalSummary[];
|
|
60
|
+
/** Per-scanner aggregated run metrics/details (`ScanResult.summary`). */
|
|
61
|
+
readonly summary?: Record<string, unknown>;
|
|
62
|
+
/** Explanation for a non-OK status (skip/error). */
|
|
63
|
+
readonly reason?: string;
|
|
64
|
+
/** Error message when `outcome === "error"`. */
|
|
65
|
+
readonly error?: string;
|
|
66
|
+
/** Error class name (`Error.name`) when `outcome === "error"` — the error-grouping key. */
|
|
67
|
+
readonly errorName?: string;
|
|
68
|
+
}
|
|
69
|
+
/** How the decision was produced (`emitTrackingDecision` reports this). */
|
|
70
|
+
export type DecisionMode = "llm" | "script" | "agent" | "rule" | "none";
|
|
71
|
+
/** Decision produced by the decision layer for an evaluation pass. */
|
|
72
|
+
export interface SignalDecision {
|
|
73
|
+
readonly execute: boolean;
|
|
74
|
+
/** Action type, e.g. `"open_position"`. */
|
|
75
|
+
readonly actionType: string;
|
|
76
|
+
/** Concrete action instance name. */
|
|
77
|
+
readonly actionName?: string;
|
|
78
|
+
/** Distinguishes a vestigial rule "decision" from a real LLM judgment. */
|
|
79
|
+
readonly mode?: DecisionMode;
|
|
80
|
+
readonly confidence: number;
|
|
81
|
+
/** Bar `confidence` was compared against (`min_confidence`); makes the below_confidence boundary reconstructable. */
|
|
82
|
+
readonly confidenceThreshold?: number;
|
|
83
|
+
readonly reasoning: string;
|
|
84
|
+
/** LLM-path auditing (from `ActionDecision.decisionTelemetry`). */
|
|
85
|
+
readonly model?: string;
|
|
86
|
+
readonly tokensUsed?: number | null;
|
|
87
|
+
readonly durationMs?: number;
|
|
88
|
+
/** Proposed per-asset overrides (leverage/margin/etc.) the decision emitted. */
|
|
89
|
+
readonly payload?: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
/** Coarse result of acting on an evaluated signal. */
|
|
92
|
+
export type SignalOutcomeResult = "executed" | "rejected" | "skipped" | "below_confidence" | "error";
|
|
93
|
+
/**
|
|
94
|
+
* Outcome of acting on a **single** signal within an evaluation pass. Outcomes are per-signal: the
|
|
95
|
+
* action loops over the batch producing one result each and decrements margin as it goes, so a
|
|
96
|
+
* later signal's outcome only makes sense alongside the earlier ones.
|
|
97
|
+
*
|
|
98
|
+
* `result` is the coarse classification. `reasonCode` is an open string for the granular per-signal
|
|
99
|
+
* reasons (e.g. `risk_gate_COOLDOWN`, `insufficient_margin`, `below_min_notional`,
|
|
100
|
+
* `position_open_failed`, `no_slots`, `invalid_direction`); keeping it an open string means new
|
|
101
|
+
* reasons can be carried without changing this type.
|
|
102
|
+
*/
|
|
103
|
+
export interface SignalOutcome {
|
|
104
|
+
readonly result: SignalOutcomeResult;
|
|
105
|
+
readonly summary?: string;
|
|
106
|
+
readonly reasonCode?: string;
|
|
107
|
+
readonly reason?: string;
|
|
108
|
+
readonly error?: string;
|
|
109
|
+
/** Error class name (`Error.name`, e.g. `"ZodError"`) — the natural error-grouping key. */
|
|
110
|
+
readonly errorName?: string;
|
|
111
|
+
readonly leverage?: number;
|
|
112
|
+
readonly marginAmount?: number;
|
|
113
|
+
readonly notionalValue?: number;
|
|
114
|
+
readonly orderId?: string;
|
|
115
|
+
readonly entryPrice?: number;
|
|
116
|
+
readonly size?: number;
|
|
117
|
+
/** Order-fill success flag from `CreatePositionOrderResult.filled` (boolean, not a quantity). */
|
|
118
|
+
readonly filled?: boolean | null;
|
|
119
|
+
/** Maker vs taker fill (`CreatePositionOrderResult.executionAsMaker`); `null` when unfilled. */
|
|
120
|
+
readonly executionAsMaker?: boolean | null;
|
|
121
|
+
readonly requiredMarginAmount?: number;
|
|
122
|
+
readonly availableMarginAmount?: number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* One evaluated signal paired with its outcome. Pairing (rather than two index-aligned arrays)
|
|
126
|
+
* keeps signal and outcome structurally bound, so no filter/sort/map can silently misalign them.
|
|
127
|
+
*/
|
|
128
|
+
export interface SignalEvaluation {
|
|
129
|
+
readonly signal: SignalSummary;
|
|
130
|
+
readonly outcome: SignalOutcome;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* One signal-evaluation work unit: the runtime hands a scan pass's batch to the action, which
|
|
134
|
+
* decides once, then acts on each signal serially. The whole pass is one record — a 3-signal batch
|
|
135
|
+
* is ONE record with three `evaluations`, not three records. Nesting the decision and per-signal
|
|
136
|
+
* outcomes keeps them bound together without a separate join key.
|
|
137
|
+
*/
|
|
138
|
+
export interface SignalEvaluatedRecord {
|
|
139
|
+
readonly type: "signal_evaluated";
|
|
140
|
+
readonly scannerId?: string;
|
|
141
|
+
/** Evaluation start, epoch ms. Required (see {@link ScannerRunRecord.startedAt}) so a `Duration` is always derivable. */
|
|
142
|
+
readonly startedAt: number;
|
|
143
|
+
/** Evaluation end, epoch ms. */
|
|
144
|
+
readonly endedAt: number;
|
|
145
|
+
/**
|
|
146
|
+
* Pass-level decision (the single `ActionDecision` the engine/LLM produces for this pass).
|
|
147
|
+
* Absent when the pass was filtered before a decision was produced.
|
|
148
|
+
*/
|
|
149
|
+
readonly decision?: SignalDecision;
|
|
150
|
+
/** One entry per signal in the evaluated batch; outcomes are per-signal. */
|
|
151
|
+
readonly evaluations: readonly SignalEvaluation[];
|
|
152
|
+
}
|
|
153
|
+
export type PositionLifecycleEvent = "opened" | "closed" | "flipped" | "increased" | "decreased" | "open_order_submitted";
|
|
154
|
+
/**
|
|
155
|
+
* A position lifecycle domain event observed on the bus. These are first-class events — they
|
|
156
|
+
* fire both as the outcome of acting on a signal *and* when the position-tracker scanner
|
|
157
|
+
* detects on-chain changes opened manually or by other tools — so they are recorded
|
|
158
|
+
* independently of {@link SignalEvaluatedRecord}.
|
|
159
|
+
*
|
|
160
|
+
* Variant-specific fields are optional; `event` discriminates which apply.
|
|
161
|
+
*/
|
|
162
|
+
export interface PositionLifecycleRecord {
|
|
163
|
+
readonly type: "position_lifecycle";
|
|
164
|
+
readonly event: PositionLifecycleEvent;
|
|
165
|
+
readonly occurredAt: number;
|
|
166
|
+
readonly asset: string;
|
|
167
|
+
/** Empty string / undefined for the main book. */
|
|
168
|
+
readonly dex?: string;
|
|
169
|
+
readonly direction?: TradeDirection | null;
|
|
170
|
+
readonly entryPrice?: number;
|
|
171
|
+
readonly size?: number;
|
|
172
|
+
readonly leverage?: number;
|
|
173
|
+
readonly leverageType?: string;
|
|
174
|
+
readonly margin?: number;
|
|
175
|
+
readonly unrealizedPnl?: number;
|
|
176
|
+
readonly roe?: number;
|
|
177
|
+
/** `null` when the venue reports no liquidation price. */
|
|
178
|
+
readonly liquidationPrice?: number | null;
|
|
179
|
+
readonly reason?: string;
|
|
180
|
+
readonly closeReason?: string;
|
|
181
|
+
readonly closedPrice?: number;
|
|
182
|
+
readonly closedSize?: number;
|
|
183
|
+
/** Maker vs taker on the close (`null` when unfilled). */
|
|
184
|
+
readonly executionAsMaker?: boolean | null;
|
|
185
|
+
readonly previousEntryPrice?: number;
|
|
186
|
+
readonly previousSize?: number;
|
|
187
|
+
readonly sizeDelta?: number;
|
|
188
|
+
readonly newAsset?: string;
|
|
189
|
+
readonly orderId?: string;
|
|
190
|
+
readonly orderType?: string;
|
|
191
|
+
readonly marginAmount?: number;
|
|
192
|
+
/** Order-fill success flag from `CreatePositionOrderResult.filled` (boolean, not a quantity). */
|
|
193
|
+
readonly filled?: boolean | null;
|
|
194
|
+
readonly reasoning?: string;
|
|
195
|
+
}
|
|
196
|
+
export type DslTransitionKind = "created" | "phase_changed" | "tier_advanced" | "sl_updated" | "closed" | "close_pending" | "settings_updated" | "deleted";
|
|
197
|
+
/** A tier in the exit ladder, as carried on `dsl.created`. */
|
|
198
|
+
export interface DslTierSummary {
|
|
199
|
+
readonly triggerPct: number;
|
|
200
|
+
readonly lockHwPct: number;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* A DSL exit-engine transition. One record per transition; `transition` discriminates which of the
|
|
204
|
+
* optional fields are populated. Periodic `dsl.heartbeat` is intentionally not modelled — it is a
|
|
205
|
+
* notification cadence, not a state transition.
|
|
206
|
+
*/
|
|
207
|
+
export interface DslTransitionRecord {
|
|
208
|
+
readonly type: "dsl_transition";
|
|
209
|
+
readonly transition: DslTransitionKind;
|
|
210
|
+
readonly occurredAt: number;
|
|
211
|
+
readonly asset: string;
|
|
212
|
+
readonly dex?: string;
|
|
213
|
+
/** Lifecycle event that produced the DSL row (`position_opened`|`..._increased`|`flipped`). */
|
|
214
|
+
readonly triggerReason?: string;
|
|
215
|
+
readonly preset?: string;
|
|
216
|
+
/** Exit ladder the position was created with (`dsl.created`). */
|
|
217
|
+
readonly tiers?: readonly DslTierSummary[];
|
|
218
|
+
readonly direction?: TradeDirection;
|
|
219
|
+
readonly entryPrice?: number;
|
|
220
|
+
readonly leverage?: number;
|
|
221
|
+
readonly margin?: number;
|
|
222
|
+
readonly size?: number;
|
|
223
|
+
readonly floorPrice?: number;
|
|
224
|
+
readonly newFloorPrice?: number;
|
|
225
|
+
readonly phase?: 1 | 2;
|
|
226
|
+
/**
|
|
227
|
+
* Current tier index. Normalizes the three bus spellings into one field — `tierIndex`
|
|
228
|
+
* (`dsl.phase_changed`), `tier` (`dsl.tier_advanced`), `currentTierIndex` (`dsl.closed`) — so
|
|
229
|
+
* downstream never has to know which event produced the record. `null` when no tier is active.
|
|
230
|
+
*/
|
|
231
|
+
readonly tierIndex?: number | null;
|
|
232
|
+
readonly lockHwPct?: number;
|
|
233
|
+
readonly triggerPct?: number;
|
|
234
|
+
readonly lockedProfitPct?: number;
|
|
235
|
+
readonly newSLPrice?: number;
|
|
236
|
+
readonly slOrderId?: number;
|
|
237
|
+
readonly reason?: string;
|
|
238
|
+
readonly closeReason?: string;
|
|
239
|
+
/** Position open time, epoch ms (on `closed`). */
|
|
240
|
+
readonly createdAt?: number;
|
|
241
|
+
readonly currentROE?: number;
|
|
242
|
+
readonly highWaterRoe?: number;
|
|
243
|
+
/** High-water *price* the trailing floor is relative to (`DslState.highWaterPrice`). */
|
|
244
|
+
readonly highWaterPrice?: number;
|
|
245
|
+
readonly peakROE?: number;
|
|
246
|
+
readonly lastPrice?: number;
|
|
247
|
+
readonly attempt?: number;
|
|
248
|
+
readonly updated?: readonly string[];
|
|
249
|
+
/**
|
|
250
|
+
* Senpi/MCP-side position id (`DslState.backendDslPositionId`). Captured opportunistically for
|
|
251
|
+
* exchange-side correlation — but **DSL-only**: the runtime must not treat this as a position
|
|
252
|
+
* identity, since DSL need not be active for a position to exist. `null` when not yet assigned.
|
|
253
|
+
*/
|
|
254
|
+
readonly backendDslPositionId?: string | null;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* A bucket-2 error that does not belong to a specific domain record (e.g. the bus's
|
|
258
|
+
* `signal_processing_error`). Errors that *do* have a home — scanner failures, action
|
|
259
|
+
* failures, DSL close failures — are carried on {@link ScannerRunRecord}, {@link SignalOutcome}
|
|
260
|
+
* and {@link DslTransitionRecord} respectively.
|
|
261
|
+
*/
|
|
262
|
+
export interface RuntimeErrorRecord {
|
|
263
|
+
readonly type: "runtime_error";
|
|
264
|
+
readonly occurredAt: number;
|
|
265
|
+
/** Where the error originated, e.g. `"signal_processing"`. */
|
|
266
|
+
readonly phase: string;
|
|
267
|
+
readonly message: string;
|
|
268
|
+
/** Error class name (`Error.name`, e.g. `"ZodError"`) — the natural error-grouping key. */
|
|
269
|
+
readonly errorName?: string;
|
|
270
|
+
readonly asset?: string;
|
|
271
|
+
readonly scannerId?: string;
|
|
272
|
+
readonly stack?: string;
|
|
273
|
+
}
|
|
274
|
+
export type RuntimeLifecyclePhase = "started" | "stopped";
|
|
275
|
+
/**
|
|
276
|
+
* Runtime session boundary. Marks process start/stop and carries session shape; `strategyAddress`
|
|
277
|
+
* is omitted because it lives on the identity envelope.
|
|
278
|
+
*/
|
|
279
|
+
export interface RuntimeLifecycleRecord {
|
|
280
|
+
readonly type: "runtime_lifecycle";
|
|
281
|
+
readonly phase: RuntimeLifecyclePhase;
|
|
282
|
+
readonly occurredAt: number;
|
|
283
|
+
readonly runtimeVersion?: string;
|
|
284
|
+
readonly hasDsl?: boolean;
|
|
285
|
+
readonly scannerCount?: number;
|
|
286
|
+
readonly actionCount?: number;
|
|
287
|
+
/**
|
|
288
|
+
* The **unresolved** runtime config at boot (raw YAML/config, `${VAR}` placeholders intact) — the
|
|
289
|
+
* retrospection snapshot of what this session ran. Deliberately NOT the resolved config: resolving
|
|
290
|
+
* `${VAR}` inlines secrets (e.g. `SENPI_API_KEY`), which `env-resolve.ts` forbids exporting. Keeping
|
|
291
|
+
* it unresolved needs no redaction and is the stabler artifact — it is also the input `configHash`
|
|
292
|
+
* is computed over, so blob and hash agree. See {@link IdentityEnvelope.configHash}.
|
|
293
|
+
*/
|
|
294
|
+
readonly config?: Record<string, unknown>;
|
|
295
|
+
readonly uptimeMs?: number;
|
|
296
|
+
}
|
|
297
|
+
export type RuntimeStatePhase = "paused" | "resumed";
|
|
298
|
+
/**
|
|
299
|
+
* A runtime trading-state transition — the runtime pausing or resuming its *own* trading on a
|
|
300
|
+
* cap/halt. Sibling to {@link RuntimeLifecycleRecord} on a different axis: lifecycle records the
|
|
301
|
+
* process (started/stopped); this records whether trading is active or self-paused.
|
|
302
|
+
*
|
|
303
|
+
* `paused` corresponds to the bus's `on_strategy_self_paused` / `on_daily_limit_hit` /
|
|
304
|
+
* `on_drawdown_cap_hit`, which fire on a `running → paused` edge carrying the breached `metrics`.
|
|
305
|
+
* `resumed` is the symmetric `paused → running` re-arm; modelling it here lets the emit be added
|
|
306
|
+
* later without changing this type. `strategyAddress` is omitted — it lives on the identity envelope.
|
|
307
|
+
*
|
|
308
|
+
* This is the "why did the runtime stop trading" signal — for observability and for an agent
|
|
309
|
+
* reasoning about self-imposed halts (raise a cap, wait for daily reset, investigate drawdown).
|
|
310
|
+
*/
|
|
311
|
+
export interface RuntimeStateRecord {
|
|
312
|
+
readonly type: "runtime_state";
|
|
313
|
+
readonly phase: RuntimeStatePhase;
|
|
314
|
+
readonly occurredAt: number;
|
|
315
|
+
/** Stable gate identifier (e.g. the cap/halt rule id). */
|
|
316
|
+
readonly gateId: string;
|
|
317
|
+
readonly gateName?: string;
|
|
318
|
+
/** Which hook produced the pause (`self_paused`|`daily_limit`|`drawdown_cap`). */
|
|
319
|
+
readonly source?: string;
|
|
320
|
+
/** Human-readable explanation with live numbers (the gate's `reason`). */
|
|
321
|
+
readonly reason?: string;
|
|
322
|
+
/** Breached-gate metrics bag (`pnlDelta`, `dailyLossLimitUsd`, `drawdownFromPeakPct`, …). */
|
|
323
|
+
readonly metrics?: Record<string, unknown> | null;
|
|
324
|
+
}
|
|
325
|
+
/** Discriminated union of every record type. */
|
|
326
|
+
export type RecordingRecord = ScannerRunRecord | SignalEvaluatedRecord | PositionLifecycleRecord | DslTransitionRecord | RuntimeErrorRecord | RuntimeLifecycleRecord | RuntimeStateRecord;
|
|
327
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/recording/records.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recording contract — the record types the runtime hands to a {@link RecordingEmitter}, covering
|
|
3
|
+
* domain events and runtime errors.
|
|
4
|
+
*
|
|
5
|
+
* Each record is one atomic "work unit": plain, immutable, serializable data with no methods or
|
|
6
|
+
* builder dance; variants are modelled with a discriminator field plus optionals. The types are
|
|
7
|
+
* transport-agnostic — nothing here knows about spans, attributes, or any wire format.
|
|
8
|
+
*
|
|
9
|
+
* Identity (service, recipe, runtime, strategy address, boot id) is stamped by the emitter and is
|
|
10
|
+
* never on a record — see {@link IdentityEnvelope}. Timestamps are epoch milliseconds; ISO strings
|
|
11
|
+
* from the bus are converted before they reach a record, so consumers never parse dates.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../../src/recording/records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Micro-batcher — two independent buffers (traces, logs). `enqueueTrace` /
|
|
3
|
+
* `enqueueLog` are cheap and non-blocking; rows ship on a timer interval, with
|
|
4
|
+
* an early flush when a buffer nears the byte cap.
|
|
5
|
+
*
|
|
6
|
+
* Reliability policy (lean, by design):
|
|
7
|
+
* - **Drop over block, always.** A full buffer or a failed flush NEVER blocks
|
|
8
|
+
* or throws into the caller. On any error: log, count the drop, move on.
|
|
9
|
+
* **No retry** — the seam is left for a later dedicated stage.
|
|
10
|
+
* - Two distinct signals are counted: *client-dropped* (never sent — overflow,
|
|
11
|
+
* oversized row, an oversized batch (413), or a transport/auth/5xx flush
|
|
12
|
+
* failure) vs *server-rejected* (a `200` that accepted fewer rows than were
|
|
13
|
+
* sent, or a `400` — a malformed row that got through the mapper; a mapper
|
|
14
|
+
* bug to surface, not a transport failure). The 200 shortfall is derived from
|
|
15
|
+
* `accepted`, not the response's `rejected` field: the service reports
|
|
16
|
+
* schema-validation drops only in `errors[]`, so trusting `rejected` alone
|
|
17
|
+
* would let mapper bugs go uncounted.
|
|
18
|
+
* - Flush-on-interval is primary; byte-cap early-flush is the only added
|
|
19
|
+
* trigger. Remaining buffers flush best-effort on shutdown (time-boxed by the
|
|
20
|
+
* client's per-request timeout).
|
|
21
|
+
*
|
|
22
|
+
* Each row is serialized exactly once (at enqueue, for byte accounting); the
|
|
23
|
+
* cached JSON is reused both to size the buffer and to frame the HTTP body, so
|
|
24
|
+
* the cap bounds the ACTUAL serialized body (envelope + separators included).
|
|
25
|
+
*/
|
|
26
|
+
import { type TelemetryClient } from "./client.js";
|
|
27
|
+
import type { TransportConfig } from "./config.js";
|
|
28
|
+
import type { LogRow, TraceRow } from "./rows.js";
|
|
29
|
+
/** Per-signal counters. */
|
|
30
|
+
export interface SignalStats {
|
|
31
|
+
/** Rows handed to `enqueue`. */
|
|
32
|
+
enqueued: number;
|
|
33
|
+
/** Rows the server accepted (sum of `accepted` across 2xx flushes). */
|
|
34
|
+
sent: number;
|
|
35
|
+
/** Rows never sent — overflow, oversized, or a transport/auth/5xx failure. */
|
|
36
|
+
clientDropped: number;
|
|
37
|
+
/** Rows the server refused — a 200's accepted-shortfall, or a whole 400 batch. */
|
|
38
|
+
serverRejected: number;
|
|
39
|
+
}
|
|
40
|
+
export interface BatcherStats {
|
|
41
|
+
traces: SignalStats;
|
|
42
|
+
logs: SignalStats;
|
|
43
|
+
}
|
|
44
|
+
export interface TelemetryBatcher {
|
|
45
|
+
enqueueTrace(row: TraceRow): void;
|
|
46
|
+
enqueueLog(row: LogRow): void;
|
|
47
|
+
/** Flush both buffers now (best-effort). */
|
|
48
|
+
flush(): Promise<void>;
|
|
49
|
+
/** Stop the timer and flush remaining rows (best-effort, time-boxed). */
|
|
50
|
+
shutdown(): Promise<void>;
|
|
51
|
+
/** Snapshot of per-signal counters. */
|
|
52
|
+
getStats(): BatcherStats;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a batcher. `client` is injectable for testing; by default it is built
|
|
56
|
+
* from `config`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createBatcher(config: TransportConfig, client?: TelemetryClient): TelemetryBatcher;
|
|
59
|
+
//# sourceMappingURL=batcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batcher.d.ts","sourceRoot":"","sources":["../../../src/recording/transport/batcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAA0C,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAKlD,2BAA2B;AAC3B,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;CACnB;AA2LD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IAClC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,yEAAyE;IACzE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,IAAI,YAAY,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,MAAM,GAAE,eAA+C,GACtD,gBAAgB,CAkClB"}
|