@senpi/runtime 3.0.6-dev.skill-manager-v2.20260629194505 → 3.0.9-dev.runtime-phase-2.20260707070820
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/actions/action-events.d.ts +67 -0
- package/dist/actions/action-events.d.ts.map +1 -0
- package/dist/actions/action-events.js +164 -0
- package/dist/actions/action-events.js.map +1 -0
- package/dist/actions/close-position/close-position.action.d.ts +1 -1
- package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
- package/dist/actions/close-position/close-position.action.js +108 -86
- package/dist/actions/close-position/close-position.action.js.map +1 -1
- package/dist/actions/decision-engine.d.ts.map +1 -1
- package/dist/actions/decision-engine.js +40 -28
- package/dist/actions/decision-engine.js.map +1 -1
- package/dist/actions/event-derivation.d.ts +61 -0
- package/dist/actions/event-derivation.d.ts.map +1 -0
- package/dist/actions/event-derivation.js +180 -0
- package/dist/actions/event-derivation.js.map +1 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.d.ts +5 -9
- package/dist/actions/llm-decision/anthropic-llm-decision.d.ts.map +1 -1
- package/dist/actions/llm-decision/anthropic-llm-decision.js +6 -87
- package/dist/actions/llm-decision/anthropic-llm-decision.js.map +1 -1
- package/dist/actions/llm-decision/factory.d.ts +0 -6
- package/dist/actions/llm-decision/factory.d.ts.map +1 -1
- package/dist/actions/llm-decision/factory.js +0 -2
- package/dist/actions/llm-decision/factory.js.map +1 -1
- package/dist/actions/llm-decision/openclaw-llm-decision.d.ts.map +1 -1
- package/dist/actions/llm-decision/openclaw-llm-decision.js +26 -7
- package/dist/actions/llm-decision/openclaw-llm-decision.js.map +1 -1
- package/dist/actions/open-position/open-position.action.d.ts +1 -1
- package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
- package/dist/actions/open-position/open-position.action.js +282 -224
- package/dist/actions/open-position/open-position.action.js.map +1 -1
- package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -1
- package/dist/actions/position-tracker/position-tracker.action.js +3 -6
- package/dist/actions/position-tracker/position-tracker.action.js.map +1 -1
- package/dist/cli/guide-commands.d.ts.map +1 -1
- package/dist/cli/guide-commands.js +61 -0
- package/dist/cli/guide-commands.js.map +1 -1
- package/dist/cli/senpi-commands.d.ts +14 -0
- package/dist/cli/senpi-commands.d.ts.map +1 -1
- package/dist/cli/senpi-commands.js +390 -2
- package/dist/cli/senpi-commands.js.map +1 -1
- package/dist/dsl/engine-client/event-mapping.d.ts.map +1 -1
- package/dist/dsl/engine-client/event-mapping.js +0 -3
- package/dist/dsl/engine-client/event-mapping.js.map +1 -1
- package/dist/dsl/events/build-closed-event.d.ts.map +1 -1
- package/dist/dsl/events/build-closed-event.js +0 -1
- package/dist/dsl/events/build-closed-event.js.map +1 -1
- package/dist/dsl/events/handlers.d.ts.map +1 -1
- package/dist/dsl/events/handlers.js +2 -4
- package/dist/dsl/events/handlers.js.map +1 -1
- package/dist/dsl/events/initial-state.d.ts.map +1 -1
- package/dist/dsl/events/initial-state.js +1 -0
- package/dist/dsl/events/initial-state.js.map +1 -1
- package/dist/dsl/monitor/create-monitor.d.ts +3 -0
- package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
- package/dist/dsl/monitor/create-monitor.js +76 -58
- package/dist/dsl/monitor/create-monitor.js.map +1 -1
- package/dist/dsl/monitor/dsl-failure-events.d.ts +42 -0
- package/dist/dsl/monitor/dsl-failure-events.d.ts.map +1 -0
- package/dist/dsl/monitor/dsl-failure-events.js +73 -0
- package/dist/dsl/monitor/dsl-failure-events.js.map +1 -0
- package/dist/dsl/monitor/process-one-position.d.ts +2 -1
- package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
- package/dist/dsl/monitor/process-one-position.js +130 -196
- package/dist/dsl/monitor/process-one-position.js.map +1 -1
- package/dist/dsl/plugin/index.d.ts +10 -0
- package/dist/dsl/plugin/index.d.ts.map +1 -1
- package/dist/dsl/plugin/index.js +48 -4
- package/dist/dsl/plugin/index.js.map +1 -1
- package/dist/dsl/plugin/options.d.ts +3 -0
- package/dist/dsl/plugin/options.d.ts.map +1 -1
- package/dist/health/types.d.ts +14 -0
- package/dist/health/types.d.ts.map +1 -1
- package/dist/health/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +255 -77
- package/dist/index.js.map +1 -1
- package/dist/risk/risk-audit-log.d.ts +7 -0
- package/dist/risk/risk-audit-log.d.ts.map +1 -1
- package/dist/risk/risk-audit-log.js +48 -1
- package/dist/risk/risk-audit-log.js.map +1 -1
- package/dist/runtime/__tests__/helpers/runtime-gateway-harness.d.ts +2 -0
- package/dist/runtime/__tests__/helpers/runtime-gateway-harness.d.ts.map +1 -1
- package/dist/runtime/__tests__/helpers/runtime-gateway-harness.js +24 -3
- package/dist/runtime/__tests__/helpers/runtime-gateway-harness.js.map +1 -1
- package/dist/runtime/auto-update/coordinator.js +2 -2
- package/dist/runtime/auto-update/coordinator.js.map +1 -1
- package/dist/runtime/create-actions.d.ts.map +1 -1
- package/dist/runtime/create-actions.js +40 -15
- package/dist/runtime/create-actions.js.map +1 -1
- package/dist/runtime/create-runtime-context.d.ts +1 -1
- package/dist/runtime/create-runtime-context.d.ts.map +1 -1
- package/dist/runtime/create-scanner-module.d.ts +2 -1
- package/dist/runtime/create-scanner-module.d.ts.map +1 -1
- package/dist/runtime/create-scanner-module.js +2 -1
- package/dist/runtime/create-scanner-module.js.map +1 -1
- package/dist/runtime/domain-events.d.ts +43 -0
- package/dist/runtime/domain-events.d.ts.map +1 -0
- package/dist/runtime/domain-events.js +181 -0
- package/dist/runtime/domain-events.js.map +1 -0
- package/dist/runtime/lifecycle-events.d.ts +86 -0
- package/dist/runtime/lifecycle-events.d.ts.map +1 -0
- package/dist/runtime/lifecycle-events.js +200 -0
- package/dist/runtime/lifecycle-events.js.map +1 -0
- package/dist/runtime/notifications.js +2 -2
- package/dist/runtime/notifications.js.map +1 -1
- package/dist/{tracking → runtime}/position-id-registry.d.ts +14 -1
- package/dist/runtime/position-id-registry.d.ts.map +1 -0
- package/dist/{tracking → runtime}/position-id-registry.js +20 -3
- package/dist/runtime/position-id-registry.js.map +1 -0
- package/dist/runtime/run.d.ts +2 -4
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js.map +1 -1
- package/dist/runtime/runtime-schema.d.ts +276 -588
- package/dist/runtime/runtime-schema.d.ts.map +1 -1
- package/dist/runtime/runtime-schema.js +8 -28
- package/dist/runtime/runtime-schema.js.map +1 -1
- package/dist/runtime/runtime.d.ts +23 -9
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +276 -248
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/strategy-lifecycle.d.ts.map +1 -1
- package/dist/runtime/strategy-lifecycle.js +13 -1
- package/dist/runtime/strategy-lifecycle.js.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.d.ts +3 -0
- package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js +27 -53
- package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
- package/dist/runtime-api/intake/intake-events.d.ts +44 -0
- package/dist/runtime-api/intake/intake-events.d.ts.map +1 -0
- package/dist/runtime-api/intake/intake-events.js +131 -0
- package/dist/runtime-api/intake/intake-events.js.map +1 -0
- package/dist/runtime-api/intake/scanner-launcher.d.ts +2 -0
- package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
- package/dist/runtime-api/intake/scanner-launcher.js +58 -15
- package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
- package/dist/runtime-api/intake/scanner-registry.d.ts +3 -0
- package/dist/runtime-api/intake/scanner-registry.d.ts.map +1 -1
- package/dist/runtime-api/intake/scanner-registry.js +3 -0
- package/dist/runtime-api/intake/scanner-registry.js.map +1 -1
- package/dist/runtime-api/intake/supervisor-events.d.ts +61 -0
- package/dist/runtime-api/intake/supervisor-events.d.ts.map +1 -0
- package/dist/runtime-api/intake/supervisor-events.js +173 -0
- package/dist/runtime-api/intake/supervisor-events.js.map +1 -0
- package/dist/runtime-api/routes/signals.d.ts +1 -1
- package/dist/runtime-api/routes/signals.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.js +121 -35
- package/dist/runtime-api/routes/signals.js.map +1 -1
- package/dist/runtime-api/server.d.ts.map +1 -1
- package/dist/runtime-api/server.js +10 -1
- package/dist/runtime-api/server.js.map +1 -1
- package/dist/scanners/engine/data-providers.d.ts +3 -0
- package/dist/scanners/engine/data-providers.d.ts.map +1 -1
- package/dist/scanners/engine/data-providers.js.map +1 -1
- package/dist/scanners/engine/engine.d.ts +18 -0
- package/dist/scanners/engine/engine.d.ts.map +1 -1
- package/dist/scanners/engine/engine.js +96 -2
- package/dist/scanners/engine/engine.js.map +1 -1
- package/dist/scanners/engine/input-resolver.d.ts.map +1 -1
- package/dist/scanners/engine/input-resolver.js +9 -7
- package/dist/scanners/engine/input-resolver.js.map +1 -1
- package/dist/scanners/runtime-module.d.ts +3 -0
- package/dist/scanners/runtime-module.d.ts.map +1 -1
- package/dist/scanners/runtime-module.js +7 -0
- package/dist/scanners/runtime-module.js.map +1 -1
- package/dist/senpi/client.d.ts +10 -0
- package/dist/senpi/client.d.ts.map +1 -1
- package/dist/senpi/client.js +113 -46
- package/dist/senpi/client.js.map +1 -1
- package/dist/skills-manager/bootstrap.d.ts.map +1 -1
- package/dist/skills-manager/bootstrap.js +22 -33
- package/dist/skills-manager/bootstrap.js.map +1 -1
- package/dist/skills-manager/clone-groups.d.ts +20 -0
- package/dist/skills-manager/clone-groups.d.ts.map +1 -0
- package/dist/skills-manager/clone-groups.js +45 -0
- package/dist/skills-manager/clone-groups.js.map +1 -0
- package/dist/skills-manager/coordinator.d.ts.map +1 -1
- package/dist/skills-manager/coordinator.js +111 -75
- package/dist/skills-manager/coordinator.js.map +1 -1
- package/dist/skills-manager/manifest.d.ts +24 -0
- package/dist/skills-manager/manifest.d.ts.map +1 -1
- package/dist/skills-manager/manifest.js +23 -10
- package/dist/skills-manager/manifest.js.map +1 -1
- package/dist/skills-manager/skills-manifest.json +12 -7
- package/dist/skills-manager/types.d.ts +12 -0
- package/dist/skills-manager/types.d.ts.map +1 -1
- package/dist/state/state-events.d.ts +13 -0
- package/dist/state/state-events.d.ts.map +1 -0
- package/dist/state/state-events.js +22 -0
- package/dist/state/state-events.js.map +1 -0
- package/dist/state/state-manager.d.ts.map +1 -1
- package/dist/state/state-manager.js +14 -1
- package/dist/state/state-manager.js.map +1 -1
- package/dist/telemetry/attributes.d.ts +13 -0
- package/dist/telemetry/attributes.d.ts.map +1 -0
- package/dist/telemetry/attributes.js +22 -0
- package/dist/telemetry/attributes.js.map +1 -0
- package/dist/{tracking → telemetry}/context.d.ts +12 -5
- package/dist/telemetry/context.d.ts.map +1 -0
- package/dist/{tracking → telemetry}/context.js +4 -4
- package/dist/telemetry/context.js.map +1 -0
- package/dist/{recording/records.d.ts → telemetry/event-builders.d.ts} +145 -33
- package/dist/telemetry/event-builders.d.ts.map +1 -0
- package/dist/{recording/wiring/record-builders.js → telemetry/event-builders.js} +94 -40
- package/dist/telemetry/event-builders.js.map +1 -0
- package/dist/telemetry/event-store.d.ts +66 -0
- package/dist/telemetry/event-store.d.ts.map +1 -0
- package/dist/telemetry/event-store.js +202 -0
- package/dist/telemetry/event-store.js.map +1 -0
- package/dist/telemetry/identity.d.ts +72 -0
- package/dist/telemetry/identity.d.ts.map +1 -0
- package/dist/{recording/wiring → telemetry}/identity.js +6 -2
- package/dist/telemetry/identity.js.map +1 -0
- package/dist/telemetry/metrics.d.ts +169 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +437 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry/otel-sdk.d.ts +93 -0
- package/dist/telemetry/otel-sdk.d.ts.map +1 -0
- package/dist/telemetry/otel-sdk.js +297 -0
- package/dist/telemetry/otel-sdk.js.map +1 -0
- package/dist/telemetry/spans/constants.d.ts +12 -0
- package/dist/telemetry/spans/constants.d.ts.map +1 -0
- package/dist/telemetry/spans/constants.js +12 -0
- package/dist/telemetry/spans/constants.js.map +1 -0
- package/dist/telemetry/spans/gen-ai.d.ts +74 -0
- package/dist/telemetry/spans/gen-ai.d.ts.map +1 -0
- package/dist/telemetry/spans/gen-ai.js +339 -0
- package/dist/telemetry/spans/gen-ai.js.map +1 -0
- package/dist/telemetry/spans/index.d.ts +11 -0
- package/dist/telemetry/spans/index.d.ts.map +1 -0
- package/dist/telemetry/spans/index.js +11 -0
- package/dist/telemetry/spans/index.js.map +1 -0
- package/dist/{tracking → telemetry}/spans/redact-pii.d.ts +19 -21
- package/dist/telemetry/spans/redact-pii.d.ts.map +1 -0
- package/dist/{tracking → telemetry}/spans/redact-pii.js +35 -32
- package/dist/telemetry/spans/redact-pii.js.map +1 -0
- package/dist/telemetry/spans/sanitize-payload.d.ts.map +1 -0
- package/dist/telemetry/spans/sanitize-payload.js.map +1 -0
- package/dist/telemetry/spans/span-hooks.d.ts +18 -0
- package/dist/telemetry/spans/span-hooks.d.ts.map +1 -0
- package/dist/telemetry/spans/span-hooks.js +764 -0
- package/dist/telemetry/spans/span-hooks.js.map +1 -0
- package/dist/telemetry/tool-plane.d.ts +31 -0
- package/dist/telemetry/tool-plane.d.ts.map +1 -0
- package/dist/telemetry/tool-plane.js +70 -0
- package/dist/telemetry/tool-plane.js.map +1 -0
- package/dist/telemetry/trace-identity.d.ts +32 -0
- package/dist/telemetry/trace-identity.d.ts.map +1 -0
- package/dist/telemetry/trace-identity.js +62 -0
- package/dist/telemetry/trace-identity.js.map +1 -0
- package/dist/telemetry/tracing.d.ts +33 -0
- package/dist/telemetry/tracing.d.ts.map +1 -0
- package/dist/telemetry/tracing.js +70 -0
- package/dist/telemetry/tracing.js.map +1 -0
- package/dist/types/dsl/index.d.ts +8 -9
- package/dist/types/dsl/index.d.ts.map +1 -1
- package/dist/types/runtime.d.ts +1 -1
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/scanner.d.ts +2 -0
- package/dist/types/scanner.d.ts.map +1 -1
- package/dist/utils/event-catalog.d.ts +506 -0
- package/dist/utils/event-catalog.d.ts.map +1 -0
- package/dist/utils/event-catalog.js +142 -0
- package/dist/utils/event-catalog.js.map +1 -0
- package/dist/utils/logger.d.ts +63 -5
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +360 -27
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/wallet-address.d.ts +3 -0
- package/dist/utils/wallet-address.d.ts.map +1 -0
- package/dist/utils/wallet-address.js +17 -0
- package/dist/utils/wallet-address.js.map +1 -0
- package/openclaw.plugin.json +20 -6
- package/package.json +10 -2
- package/dist/actions/tracking-helpers.d.ts +0 -28
- package/dist/actions/tracking-helpers.d.ts.map +0 -1
- package/dist/actions/tracking-helpers.js +0 -93
- package/dist/actions/tracking-helpers.js.map +0 -1
- package/dist/recording/emitter.d.ts +0 -27
- package/dist/recording/emitter.d.ts.map +0 -1
- package/dist/recording/emitter.js +0 -2
- package/dist/recording/emitter.js.map +0 -1
- package/dist/recording/identity.d.ts +0 -34
- package/dist/recording/identity.d.ts.map +0 -1
- package/dist/recording/identity.js +0 -2
- package/dist/recording/identity.js.map +0 -1
- package/dist/recording/index.d.ts +0 -11
- package/dist/recording/index.d.ts.map +0 -1
- package/dist/recording/index.js +0 -2
- package/dist/recording/index.js.map +0 -1
- package/dist/recording/noop-emitter.d.ts +0 -23
- package/dist/recording/noop-emitter.d.ts.map +0 -1
- package/dist/recording/noop-emitter.js +0 -22
- package/dist/recording/noop-emitter.js.map +0 -1
- package/dist/recording/otel/attributes.d.ts +0 -35
- package/dist/recording/otel/attributes.d.ts.map +0 -1
- package/dist/recording/otel/attributes.js +0 -131
- package/dist/recording/otel/attributes.js.map +0 -1
- package/dist/recording/otel/constants.d.ts +0 -123
- package/dist/recording/otel/constants.d.ts.map +0 -1
- package/dist/recording/otel/constants.js +0 -172
- package/dist/recording/otel/constants.js.map +0 -1
- package/dist/recording/otel/ids.d.ts +0 -25
- package/dist/recording/otel/ids.d.ts.map +0 -1
- package/dist/recording/otel/ids.js +0 -37
- package/dist/recording/otel/ids.js.map +0 -1
- package/dist/recording/otel/index.d.ts +0 -13
- package/dist/recording/otel/index.d.ts.map +0 -1
- package/dist/recording/otel/index.js +0 -9
- package/dist/recording/otel/index.js.map +0 -1
- package/dist/recording/otel/mappers.d.ts +0 -100
- package/dist/recording/otel/mappers.d.ts.map +0 -1
- package/dist/recording/otel/mappers.js +0 -683
- package/dist/recording/otel/mappers.js.map +0 -1
- package/dist/recording/otel/otel-emitter.d.ts +0 -43
- package/dist/recording/otel/otel-emitter.d.ts.map +0 -1
- package/dist/recording/otel/otel-emitter.js +0 -99
- package/dist/recording/otel/otel-emitter.js.map +0 -1
- package/dist/recording/otel/redaction.d.ts +0 -47
- package/dist/recording/otel/redaction.d.ts.map +0 -1
- package/dist/recording/otel/redaction.js +0 -88
- package/dist/recording/otel/redaction.js.map +0 -1
- package/dist/recording/records.d.ts.map +0 -1
- package/dist/recording/records.js +0 -14
- package/dist/recording/records.js.map +0 -1
- package/dist/recording/transport/batcher.d.ts +0 -59
- package/dist/recording/transport/batcher.d.ts.map +0 -1
- package/dist/recording/transport/batcher.js +0 -234
- package/dist/recording/transport/batcher.js.map +0 -1
- package/dist/recording/transport/client.d.ts +0 -41
- package/dist/recording/transport/client.d.ts.map +0 -1
- package/dist/recording/transport/client.js +0 -69
- package/dist/recording/transport/client.js.map +0 -1
- package/dist/recording/transport/config.d.ts +0 -53
- package/dist/recording/transport/config.d.ts.map +0 -1
- package/dist/recording/transport/config.js +0 -41
- package/dist/recording/transport/config.js.map +0 -1
- package/dist/recording/transport/index.d.ts +0 -16
- package/dist/recording/transport/index.d.ts.map +0 -1
- package/dist/recording/transport/index.js +0 -12
- package/dist/recording/transport/index.js.map +0 -1
- package/dist/recording/transport/rows.d.ts +0 -88
- package/dist/recording/transport/rows.d.ts.map +0 -1
- package/dist/recording/transport/rows.js +0 -15
- package/dist/recording/transport/rows.js.map +0 -1
- package/dist/recording/wiring/emitter-factory.d.ts +0 -39
- package/dist/recording/wiring/emitter-factory.d.ts.map +0 -1
- package/dist/recording/wiring/emitter-factory.js +0 -62
- package/dist/recording/wiring/emitter-factory.js.map +0 -1
- package/dist/recording/wiring/identity.d.ts +0 -27
- package/dist/recording/wiring/identity.d.ts.map +0 -1
- package/dist/recording/wiring/identity.js.map +0 -1
- package/dist/recording/wiring/index.d.ts +0 -12
- package/dist/recording/wiring/index.d.ts.map +0 -1
- package/dist/recording/wiring/index.js +0 -9
- package/dist/recording/wiring/index.js.map +0 -1
- package/dist/recording/wiring/record-builders.d.ts +0 -107
- package/dist/recording/wiring/record-builders.d.ts.map +0 -1
- package/dist/recording/wiring/record-builders.js.map +0 -1
- package/dist/recording/wiring/subscriber.d.ts +0 -28
- package/dist/recording/wiring/subscriber.d.ts.map +0 -1
- package/dist/recording/wiring/subscriber.js +0 -173
- package/dist/recording/wiring/subscriber.js.map +0 -1
- package/dist/recording/wiring/values.d.ts +0 -19
- package/dist/recording/wiring/values.d.ts.map +0 -1
- package/dist/recording/wiring/values.js +0 -49
- package/dist/recording/wiring/values.js.map +0 -1
- package/dist/tracking/build-rehydrate-items.d.ts +0 -15
- package/dist/tracking/build-rehydrate-items.d.ts.map +0 -1
- package/dist/tracking/build-rehydrate-items.js +0 -19
- package/dist/tracking/build-rehydrate-items.js.map +0 -1
- package/dist/tracking/constants.d.ts +0 -24
- package/dist/tracking/constants.d.ts.map +0 -1
- package/dist/tracking/constants.js +0 -52
- package/dist/tracking/constants.js.map +0 -1
- package/dist/tracking/context.d.ts.map +0 -1
- package/dist/tracking/context.js.map +0 -1
- package/dist/tracking/index.d.ts +0 -16
- package/dist/tracking/index.d.ts.map +0 -1
- package/dist/tracking/index.js +0 -11
- package/dist/tracking/index.js.map +0 -1
- package/dist/tracking/plugin-event-tracker.d.ts +0 -13
- package/dist/tracking/plugin-event-tracker.d.ts.map +0 -1
- package/dist/tracking/plugin-event-tracker.js +0 -27
- package/dist/tracking/plugin-event-tracker.js.map +0 -1
- package/dist/tracking/position-id-registry.d.ts.map +0 -1
- package/dist/tracking/position-id-registry.js.map +0 -1
- package/dist/tracking/spans/constants.d.ts +0 -19
- package/dist/tracking/spans/constants.d.ts.map +0 -1
- package/dist/tracking/spans/constants.js +0 -31
- package/dist/tracking/spans/constants.js.map +0 -1
- package/dist/tracking/spans/fan-out-span-transport.d.ts +0 -22
- package/dist/tracking/spans/fan-out-span-transport.d.ts.map +0 -1
- package/dist/tracking/spans/fan-out-span-transport.js +0 -49
- package/dist/tracking/spans/fan-out-span-transport.js.map +0 -1
- package/dist/tracking/spans/index.d.ts +0 -13
- package/dist/tracking/spans/index.d.ts.map +0 -1
- package/dist/tracking/spans/index.js +0 -16
- package/dist/tracking/spans/index.js.map +0 -1
- package/dist/tracking/spans/otel/fit-row-budget.d.ts +0 -22
- package/dist/tracking/spans/otel/fit-row-budget.d.ts.map +0 -1
- package/dist/tracking/spans/otel/fit-row-budget.js +0 -91
- package/dist/tracking/spans/otel/fit-row-budget.js.map +0 -1
- package/dist/tracking/spans/otel/map-span-to-trace-row.d.ts +0 -16
- package/dist/tracking/spans/otel/map-span-to-trace-row.d.ts.map +0 -1
- package/dist/tracking/spans/otel/map-span-to-trace-row.js +0 -227
- package/dist/tracking/spans/otel/map-span-to-trace-row.js.map +0 -1
- package/dist/tracking/spans/otel/recording-span-transport.d.ts +0 -43
- package/dist/tracking/spans/otel/recording-span-transport.d.ts.map +0 -1
- package/dist/tracking/spans/otel/recording-span-transport.js +0 -67
- package/dist/tracking/spans/otel/recording-span-transport.js.map +0 -1
- package/dist/tracking/spans/otel/span-ids.d.ts +0 -22
- package/dist/tracking/spans/otel/span-ids.d.ts.map +0 -1
- package/dist/tracking/spans/otel/span-ids.js +0 -32
- package/dist/tracking/spans/otel/span-ids.js.map +0 -1
- package/dist/tracking/spans/plugin-span-tracker.d.ts +0 -9
- package/dist/tracking/spans/plugin-span-tracker.d.ts.map +0 -1
- package/dist/tracking/spans/plugin-span-tracker.js +0 -115
- package/dist/tracking/spans/plugin-span-tracker.js.map +0 -1
- package/dist/tracking/spans/redact-pii.d.ts.map +0 -1
- package/dist/tracking/spans/redact-pii.js.map +0 -1
- package/dist/tracking/spans/sanitize-payload.d.ts.map +0 -1
- package/dist/tracking/spans/sanitize-payload.js.map +0 -1
- package/dist/tracking/spans/span-hooks.d.ts +0 -28
- package/dist/tracking/spans/span-hooks.d.ts.map +0 -1
- package/dist/tracking/spans/span-hooks.js +0 -409
- package/dist/tracking/spans/span-hooks.js.map +0 -1
- package/dist/tracking/spans/span-tracker.d.ts +0 -133
- package/dist/tracking/spans/span-tracker.d.ts.map +0 -1
- package/dist/tracking/spans/span-tracker.js +0 -721
- package/dist/tracking/spans/span-tracker.js.map +0 -1
- package/dist/tracking/spans/span-transport.d.ts +0 -71
- package/dist/tracking/spans/span-transport.d.ts.map +0 -1
- package/dist/tracking/spans/span-transport.js +0 -240
- package/dist/tracking/spans/span-transport.js.map +0 -1
- package/dist/tracking/spans/types.d.ts +0 -101
- package/dist/tracking/spans/types.d.ts.map +0 -1
- package/dist/tracking/spans/types.js +0 -6
- package/dist/tracking/spans/types.js.map +0 -1
- package/dist/tracking/tracker.d.ts +0 -30
- package/dist/tracking/tracker.d.ts.map +0 -1
- package/dist/tracking/tracker.js +0 -66
- package/dist/tracking/tracker.js.map +0 -1
- package/dist/tracking/tracking-handler.d.ts +0 -12
- package/dist/tracking/tracking-handler.d.ts.map +0 -1
- package/dist/tracking/tracking-handler.js +0 -148
- package/dist/tracking/tracking-handler.js.map +0 -1
- package/dist/tracking/transport.d.ts +0 -35
- package/dist/tracking/transport.d.ts.map +0 -1
- package/dist/tracking/transport.js +0 -133
- package/dist/tracking/transport.js.map +0 -1
- package/dist/tracking/types.d.ts +0 -21
- package/dist/tracking/types.d.ts.map +0 -1
- package/dist/tracking/types.js +0 -6
- package/dist/tracking/types.js.map +0 -1
- /package/dist/{tracking → telemetry}/spans/sanitize-payload.d.ts +0 -0
- /package/dist/{tracking → telemetry}/spans/sanitize-payload.js +0 -0
|
@@ -5,12 +5,17 @@ import { dslTick, exchangeStopLossTriggerPx } from "../engine/index.js";
|
|
|
5
5
|
import { CLOSE_REASON, MAX_CONSECUTIVE_CLOSE_FAILURES, DSL_EXTERNAL_RETRIES, DSL_EXTERNAL_RETRY_DELAY_MS, DSL_EVENTS, EVENTS, DSL_PRICE_FETCH_FAILURE_WARN_THRESHOLD, DSL_HEARTBEAT_FIRST_HOUR_MS, DSL_HEARTBEAT_INTERVAL_MS, DSL_HEARTBEAT_TIER_SUPPRESS_MS, } from "../../constants/dsl/index.js";
|
|
6
6
|
import { logger } from "../../utils/logger/dsl.js";
|
|
7
7
|
import { withRetry } from "../../utils/retry.js";
|
|
8
|
+
import { withSpan } from "../../telemetry/tracing.js";
|
|
9
|
+
import { errorTypeOf } from "../../telemetry/spans/gen-ai.js";
|
|
10
|
+
import { recordDslDegradation } from "../../telemetry/metrics.js";
|
|
8
11
|
import { effectiveDex } from "./effective-dex.js";
|
|
9
12
|
import { shouldSyncExchangeSl } from "./exchange-sync.js";
|
|
10
13
|
import { mapTiersToEngineConfig, mapEnginePositionToStateFields, parseSlOrderId } from "../engine-client/config-mapping.js";
|
|
11
14
|
import { mapBackendEventToBusEvent } from "../engine-client/event-mapping.js";
|
|
12
15
|
import { buildDslClosedEventFromState } from "../events/build-closed-event.js";
|
|
13
16
|
import { parseCloseFillDetail } from "../../senpi/client.js";
|
|
17
|
+
import { emitEvent } from "../../actions/event-derivation.js";
|
|
18
|
+
import { buildSlSyncFailedEvent, buildPriceFetchStaleEvent, buildHandoffFailedEvent, } from "./dsl-failure-events.js";
|
|
14
19
|
/**
|
|
15
20
|
* Re-read the key under its per-key lock; if it is still active, archive it and return true.
|
|
16
21
|
* If a competing locked writer already archived/inactivated it, skip and return false (WARN).
|
|
@@ -60,11 +65,18 @@ async function setIfStillActive(stateManager, key, address, asset, buildNext, ct
|
|
|
60
65
|
function closedEmitStamps(state, fill = {}) {
|
|
61
66
|
return {
|
|
62
67
|
__positionId: state.positionId ?? state.correlationId,
|
|
63
|
-
__correlationId: state.correlationId,
|
|
64
68
|
...fill,
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
|
-
|
|
71
|
+
/** The position identity a DSL failure event pins onto its record. */
|
|
72
|
+
function failureContext(state) {
|
|
73
|
+
return {
|
|
74
|
+
asset: state.asset,
|
|
75
|
+
dex: state.dex || undefined,
|
|
76
|
+
positionId: state.positionId ?? state.correlationId,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export async function processOnePosition(ctx, key, state, price, span) {
|
|
68
80
|
const { tickId, ts, now: isoNow, stateManager, strategyStates, bus, isSlPlacementInProgress = () => false } = ctx;
|
|
69
81
|
const strategy = strategyStates.get(state.address);
|
|
70
82
|
if (!strategy) {
|
|
@@ -93,13 +105,15 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
93
105
|
});
|
|
94
106
|
if (state.slOrderId != null) {
|
|
95
107
|
try {
|
|
96
|
-
const status = await withRetry(() => strategy.getOrderStatus(state.slOrderId), {
|
|
108
|
+
const status = await withSpan("dsl.sl_check", {}, () => withRetry(() => strategy.getOrderStatus(state.slOrderId), {
|
|
97
109
|
retries: DSL_EXTERNAL_RETRIES,
|
|
98
110
|
delayMs: DSL_EXTERNAL_RETRY_DELAY_MS,
|
|
99
111
|
label: "getOrderStatus (SL-hit check)",
|
|
100
112
|
onRetry: (attempt, remaining, err) => logger.warn("[dsl] getOrderStatus retry", { asset: state.asset, attempt, remaining, err }),
|
|
101
|
-
});
|
|
113
|
+
}));
|
|
102
114
|
if (status?.filled) {
|
|
115
|
+
span.addEvent("external_close_detected", { source: "sl_order" });
|
|
116
|
+
span.setAttribute("senpi.dsl.close_reason", CLOSE_REASON.EXCHANGE_SL_HIT);
|
|
103
117
|
logger.info("[dsl] exchange SL filled, archiving position", {
|
|
104
118
|
tickId,
|
|
105
119
|
asset: state.asset,
|
|
@@ -145,10 +159,8 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
145
159
|
reason: closeReasonToUse,
|
|
146
160
|
attempt: next.consecutiveCloseFailures,
|
|
147
161
|
});
|
|
148
|
-
const closeStartedAt = Date.now();
|
|
149
|
-
let closeAttemptEmitted = false;
|
|
150
162
|
try {
|
|
151
|
-
const closeResult = await withRetry(() => strategy.closePosition(state.asset, closeReasonToUse, state.dex || undefined, {
|
|
163
|
+
const closeResult = await withSpan("dsl.close_attempt", { "senpi.dsl.attempt": next.consecutiveCloseFailures }, () => withRetry(() => strategy.closePosition(state.asset, closeReasonToUse, state.dex || undefined, {
|
|
152
164
|
orderType: ctx.closeOrderType,
|
|
153
165
|
feeOptimizedLimitOptions: ctx.feeOptimizedLimitOptions,
|
|
154
166
|
}), {
|
|
@@ -156,22 +168,8 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
156
168
|
delayMs: DSL_EXTERNAL_RETRY_DELAY_MS,
|
|
157
169
|
label: "closePosition (pendingClose)",
|
|
158
170
|
onRetry: (attempt, remaining, err) => logger.warn("[dsl] closePosition retry", { asset: state.asset, attempt, remaining, err }),
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
bus.emit("tracking.dsl_close_attempt", {
|
|
162
|
-
tickId,
|
|
163
|
-
key,
|
|
164
|
-
asset: state.asset,
|
|
165
|
-
dex,
|
|
166
|
-
positionId: state.positionId ?? state.correlationId,
|
|
167
|
-
startedAt: closeStartedAt,
|
|
168
|
-
endedAt: Date.now(),
|
|
169
|
-
outcome: "ok",
|
|
170
|
-
closeReason: closeReasonToUse,
|
|
171
|
-
attempt: next.consecutiveCloseFailures,
|
|
172
|
-
timestamp: isoNow(),
|
|
173
|
-
});
|
|
174
|
-
closeAttemptEmitted = true;
|
|
171
|
+
}));
|
|
172
|
+
span.setAttribute("senpi.dsl.close_reason", closeReasonToUse);
|
|
175
173
|
const closeFill = parseCloseFillDetail(closeResult);
|
|
176
174
|
logger.info("[dsl] closePosition succeeded, archiving (pendingClose)", {
|
|
177
175
|
tickId,
|
|
@@ -199,25 +197,6 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
199
197
|
}
|
|
200
198
|
catch (e) {
|
|
201
199
|
logger.warn("closePosition retry failed", { asset: state.asset, err: e });
|
|
202
|
-
// Telemetry-only fire-and-forget: the failed venue-call window (dsl.close_attempt, error).
|
|
203
|
-
// Guarded: when the ok emit already fired, the venue call itself succeeded — a later
|
|
204
|
-
// state-write throw must not be misattributed to the venue.
|
|
205
|
-
if (!closeAttemptEmitted) {
|
|
206
|
-
bus.emit("tracking.dsl_close_attempt", {
|
|
207
|
-
tickId,
|
|
208
|
-
key,
|
|
209
|
-
asset: state.asset,
|
|
210
|
-
dex,
|
|
211
|
-
positionId: state.positionId ?? state.correlationId,
|
|
212
|
-
startedAt: closeStartedAt,
|
|
213
|
-
endedAt: Date.now(),
|
|
214
|
-
outcome: "error",
|
|
215
|
-
closeReason: closeReasonToUse,
|
|
216
|
-
attempt: next.consecutiveCloseFailures,
|
|
217
|
-
error: String(e),
|
|
218
|
-
timestamp: isoNow(),
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
200
|
next.lastError = String(e);
|
|
222
201
|
next.lastErrorAt = ts;
|
|
223
202
|
const crossedThreshold = (next.consecutiveCloseFailures ?? 0) >= MAX_CONSECUTIVE_CLOSE_FAILURES;
|
|
@@ -249,7 +228,6 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
249
228
|
attempt: next.consecutiveCloseFailures,
|
|
250
229
|
triggerReason: state.triggerReason,
|
|
251
230
|
__positionId: state.positionId ?? state.correlationId,
|
|
252
|
-
__correlationId: state.correlationId,
|
|
253
231
|
timestamp: isoNow(),
|
|
254
232
|
});
|
|
255
233
|
}
|
|
@@ -259,18 +237,23 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
259
237
|
if (price == null) {
|
|
260
238
|
const next = { ...state, consecutiveFetchFailures: (state.consecutiveFetchFailures ?? 0) + 1 };
|
|
261
239
|
next.tickCount = (state.tickCount ?? 0) + 1;
|
|
240
|
+
// Edge-triggered: fire once when the streak first reaches the stale threshold (the alertable
|
|
241
|
+
// transition); the per-tick info line below covers ongoing visibility. A `>=` test (not `===`)
|
|
242
|
+
// latched on the state so a counter rehydrated at/above the threshold mid-stall (post-restart)
|
|
243
|
+
// still fires once; the priced-tick re-arm below clears the latch for the next stall.
|
|
244
|
+
const shouldEmitStale = next.consecutiveFetchFailures >= DSL_PRICE_FETCH_FAILURE_WARN_THRESHOLD &&
|
|
245
|
+
!state.priceFetchStaleEmitted;
|
|
246
|
+
if (shouldEmitStale)
|
|
247
|
+
next.priceFetchStaleEmitted = true;
|
|
262
248
|
await setIfStillActive(stateManager, key, state.address, state.asset, (current) => ({
|
|
263
249
|
...current,
|
|
264
250
|
consecutiveFetchFailures: (current.consecutiveFetchFailures ?? 0) + 1,
|
|
265
251
|
tickCount: (current.tickCount ?? 0) + 1,
|
|
252
|
+
...(shouldEmitStale ? { priceFetchStaleEmitted: true } : {}),
|
|
266
253
|
}), { tickId, skipMessage: "[dsl] skip no-price counter write: state already cleared (concurrent close)" });
|
|
267
|
-
if (
|
|
268
|
-
logger
|
|
269
|
-
|
|
270
|
-
key,
|
|
271
|
-
asset: state.asset,
|
|
272
|
-
consecutiveFetchFailures: next.consecutiveFetchFailures,
|
|
273
|
-
});
|
|
254
|
+
if (shouldEmitStale) {
|
|
255
|
+
emitEvent(logger, () => buildPriceFetchStaleEvent(failureContext(state), next.consecutiveFetchFailures));
|
|
256
|
+
recordDslDegradation({ failure: "price_stale" });
|
|
274
257
|
}
|
|
275
258
|
logger.info("[dsl] monitor no price for position, skipping dslTick", {
|
|
276
259
|
tickId,
|
|
@@ -281,8 +264,29 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
281
264
|
return;
|
|
282
265
|
}
|
|
283
266
|
const result = dslTick(state, price, ts);
|
|
267
|
+
if (result.floorChanged) {
|
|
268
|
+
span.addEvent("floorChanged", { "senpi.dsl.floor_price": result.state.floorPrice });
|
|
269
|
+
}
|
|
270
|
+
if (result.phaseChanged) {
|
|
271
|
+
span.addEvent("phaseChanged", { "senpi.dsl.phase": result.newPhase ?? 2 });
|
|
272
|
+
}
|
|
273
|
+
if (result.tierChanged && result.newTierIndex != null) {
|
|
274
|
+
span.addEvent("tier_advanced", { "senpi.dsl.tier_index": result.newTierIndex });
|
|
275
|
+
}
|
|
276
|
+
if ((result.state.currentBreachCount ?? 0) > (state.currentBreachCount ?? 0)) {
|
|
277
|
+
span.addEvent("breach_detected", {
|
|
278
|
+
count: result.state.currentBreachCount,
|
|
279
|
+
required: result.state.breachesRequired,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
span.setAttribute("senpi.dsl.phase", result.state.phase);
|
|
283
|
+
if (result.state.currentTierIndex != null) {
|
|
284
|
+
span.setAttribute("senpi.dsl.tier_index", result.state.currentTierIndex);
|
|
285
|
+
}
|
|
284
286
|
const next = { ...result.state };
|
|
285
287
|
next.consecutiveFetchFailures = 0;
|
|
288
|
+
// Re-arm the stale-event latch: the price is back, so the next stall fires a fresh event.
|
|
289
|
+
next.priceFetchStaleEmitted = false;
|
|
286
290
|
next.tickCount = (state.tickCount ?? 0) + 1;
|
|
287
291
|
next.lastError = null;
|
|
288
292
|
next.lastErrorAt = null;
|
|
@@ -314,6 +318,8 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
314
318
|
});
|
|
315
319
|
if (result.action === "close") {
|
|
316
320
|
const closeReasonToUse = result.closeReason ?? CLOSE_REASON.DSL_BREACH;
|
|
321
|
+
span.setAttribute("senpi.dsl.current_roe", next.currentROE);
|
|
322
|
+
span.setAttribute("senpi.dsl.floor_price", next.floorPrice);
|
|
317
323
|
if (closeReasonToUse === CLOSE_REASON.DSL_BREACH && next.phase === 2) {
|
|
318
324
|
logger.warn("[dsl] ignoring spurious dsl_breach close in phase 2 (exchange SL should exit)", {
|
|
319
325
|
tickId,
|
|
@@ -333,9 +339,12 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
333
339
|
// If backend owns Phase 2, also delete the position on the backend
|
|
334
340
|
if (next.handoffStatus === "ok" && next.backendDslPositionId && strategy) {
|
|
335
341
|
try {
|
|
336
|
-
await
|
|
337
|
-
|
|
338
|
-
|
|
342
|
+
await withSpan("dsl.handoff", { "senpi.dsl.handoff.op": "delete" }, async (handoffSpan) => {
|
|
343
|
+
await strategy.deleteRatchetStop({
|
|
344
|
+
asset: state.asset,
|
|
345
|
+
dex: state.dex || undefined,
|
|
346
|
+
});
|
|
347
|
+
handoffSpan.setAttribute("senpi.dsl.handoff.status", "ok");
|
|
339
348
|
});
|
|
340
349
|
logger.info("[dsl] deleted backend dsl position (global settings close)", {
|
|
341
350
|
tickId,
|
|
@@ -353,10 +362,8 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
let closeFill = {};
|
|
356
|
-
const closeStartedAt = Date.now();
|
|
357
|
-
let closeAttemptEmitted = false;
|
|
358
365
|
try {
|
|
359
|
-
const closeResult = await withRetry(() => strategy.closePosition(state.asset, closeReasonToUse, state.dex || undefined, {
|
|
366
|
+
const closeResult = await withSpan("dsl.close_attempt", { "senpi.dsl.attempt": (next.consecutiveCloseFailures ?? 0) + 1 }, () => withRetry(() => strategy.closePosition(state.asset, closeReasonToUse, state.dex || undefined, {
|
|
360
367
|
orderType: ctx.closeOrderType,
|
|
361
368
|
feeOptimizedLimitOptions: ctx.feeOptimizedLimitOptions,
|
|
362
369
|
}), {
|
|
@@ -364,23 +371,7 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
364
371
|
delayMs: DSL_EXTERNAL_RETRY_DELAY_MS,
|
|
365
372
|
label: "closePosition (dsl breach/timeout)",
|
|
366
373
|
onRetry: (attempt, remaining, err) => logger.warn("[dsl] closePosition retry", { asset: state.asset, attempt, remaining, err }),
|
|
367
|
-
});
|
|
368
|
-
// Telemetry-only fire-and-forget: the venue-call window for the dsl.close_attempt span.
|
|
369
|
-
// Emitted before any post-venue work (fill parsing) so its outcome reflects the venue call alone.
|
|
370
|
-
bus.emit("tracking.dsl_close_attempt", {
|
|
371
|
-
tickId,
|
|
372
|
-
key,
|
|
373
|
-
asset: state.asset,
|
|
374
|
-
dex,
|
|
375
|
-
positionId: state.positionId ?? state.correlationId,
|
|
376
|
-
startedAt: closeStartedAt,
|
|
377
|
-
endedAt: Date.now(),
|
|
378
|
-
outcome: "ok",
|
|
379
|
-
closeReason: closeReasonToUse,
|
|
380
|
-
attempt: (next.consecutiveCloseFailures ?? 0) + 1,
|
|
381
|
-
timestamp: isoNow(),
|
|
382
|
-
});
|
|
383
|
-
closeAttemptEmitted = true;
|
|
374
|
+
}));
|
|
384
375
|
closeFill = parseCloseFillDetail(closeResult);
|
|
385
376
|
}
|
|
386
377
|
catch (e) {
|
|
@@ -393,26 +384,9 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
393
384
|
lastError: String(e),
|
|
394
385
|
lastErrorAt: ts,
|
|
395
386
|
};
|
|
396
|
-
|
|
397
|
-
// Guarded: when the ok emit already fired, the venue call itself succeeded — a later
|
|
398
|
-
// post-venue throw must not be misattributed to the venue.
|
|
399
|
-
if (!closeAttemptEmitted) {
|
|
400
|
-
bus.emit("tracking.dsl_close_attempt", {
|
|
401
|
-
tickId,
|
|
402
|
-
key,
|
|
403
|
-
asset: state.asset,
|
|
404
|
-
dex,
|
|
405
|
-
positionId: state.positionId ?? state.correlationId,
|
|
406
|
-
startedAt: closeStartedAt,
|
|
407
|
-
endedAt: Date.now(),
|
|
408
|
-
outcome: "error",
|
|
409
|
-
closeReason: closeReasonToUse,
|
|
410
|
-
attempt: pending.consecutiveCloseFailures,
|
|
411
|
-
error: String(e),
|
|
412
|
-
timestamp: isoNow(),
|
|
413
|
-
});
|
|
414
|
-
}
|
|
387
|
+
span.addEvent("pendingClose_set", { attempt: pending.consecutiveCloseFailures });
|
|
415
388
|
if ((pending.consecutiveCloseFailures ?? 0) >= MAX_CONSECUTIVE_CLOSE_FAILURES) {
|
|
389
|
+
span.setAttribute("senpi.dsl.close_reason", CLOSE_REASON.CLOSE_POSITION_FAILED);
|
|
416
390
|
const failedCloseState = { ...pending, active: false, closedAt: isoNow(), closeReason: CLOSE_REASON.CLOSE_POSITION_FAILED };
|
|
417
391
|
const archived = await archiveIfStillActive(stateManager, key, state.address, state.asset, effectiveDex(state), () => failedCloseState, { tickId, skipMessage: "[dsl] skip breach close-fail archive: state already cleared (concurrent close)" });
|
|
418
392
|
if (!archived)
|
|
@@ -440,12 +414,12 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
440
414
|
attempt: pending.consecutiveCloseFailures,
|
|
441
415
|
triggerReason: state.triggerReason,
|
|
442
416
|
__positionId: state.positionId ?? state.correlationId,
|
|
443
|
-
__correlationId: state.correlationId,
|
|
444
417
|
timestamp: isoNow(),
|
|
445
418
|
});
|
|
446
419
|
}
|
|
447
420
|
return;
|
|
448
421
|
}
|
|
422
|
+
span.setAttribute("senpi.dsl.close_reason", closeReasonToUse);
|
|
449
423
|
logger.info("[dsl] closePosition succeeded, archiving (dsl breach/timeout)", {
|
|
450
424
|
tickId,
|
|
451
425
|
asset: state.asset,
|
|
@@ -488,7 +462,6 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
488
462
|
newFloorPrice: dslEffectiveFloor,
|
|
489
463
|
triggerReason: next.triggerReason,
|
|
490
464
|
__positionId: next.positionId ?? next.correlationId,
|
|
491
|
-
__correlationId: next.correlationId,
|
|
492
465
|
timestamp: ts,
|
|
493
466
|
direction: next.direction,
|
|
494
467
|
entryPrice: next.entryPrice,
|
|
@@ -519,13 +492,12 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
519
492
|
tierIndex: result.newTierIndex ?? 0,
|
|
520
493
|
triggerReason: next.triggerReason,
|
|
521
494
|
__positionId: next.positionId ?? next.correlationId,
|
|
522
|
-
__correlationId: next.correlationId,
|
|
523
495
|
timestamp: ts,
|
|
524
496
|
});
|
|
525
497
|
}
|
|
526
498
|
}
|
|
527
499
|
if (next.handoffStatus === "ok" && strategy) {
|
|
528
|
-
await handleHandoffOk(ctx, key, next, state, strategy);
|
|
500
|
+
await handleHandoffOk(ctx, key, next, state, strategy, span);
|
|
529
501
|
return;
|
|
530
502
|
}
|
|
531
503
|
// Catch-up: if position is already in Phase 2 but handoff was never attempted,
|
|
@@ -585,39 +557,22 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
585
557
|
phaseChanged: result.phaseChanged,
|
|
586
558
|
prevSlOrderId: next.slOrderId,
|
|
587
559
|
});
|
|
588
|
-
const slSyncStartedAt = Date.now();
|
|
589
|
-
let slUpdateEmitted = false;
|
|
590
560
|
try {
|
|
591
|
-
const res = await
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
// (`res.slOrderId`), the honest venue-call fact.
|
|
606
|
-
bus.emit("tracking.dsl_sl_update", {
|
|
607
|
-
tickId,
|
|
608
|
-
key,
|
|
609
|
-
asset: state.asset,
|
|
610
|
-
dex,
|
|
611
|
-
positionId: state.positionId ?? state.correlationId,
|
|
612
|
-
startedAt: slSyncStartedAt,
|
|
613
|
-
endedAt: slSyncEndedAt,
|
|
614
|
-
outcome: "ok",
|
|
615
|
-
newSLPrice: exchangeTriggerPx,
|
|
616
|
-
slOrderId: res.slOrderId,
|
|
617
|
-
syncReason,
|
|
618
|
-
timestamp: isoNow(),
|
|
561
|
+
const res = await withSpan("dsl.sl_update", {}, async (slSpan) => {
|
|
562
|
+
const r = await withRetry(() => strategy.editPosition({
|
|
563
|
+
coin: state.asset,
|
|
564
|
+
dex: state.dex || undefined,
|
|
565
|
+
stopLoss: { triggerPx: exchangeTriggerPx },
|
|
566
|
+
}), {
|
|
567
|
+
retries: DSL_EXTERNAL_RETRIES,
|
|
568
|
+
delayMs: DSL_EXTERNAL_RETRY_DELAY_MS,
|
|
569
|
+
label: "editPosition (SL sync)",
|
|
570
|
+
onRetry: (attempt, remaining, err) => logger.warn("[dsl] editPosition retry", { asset: state.asset, attempt, remaining, err }),
|
|
571
|
+
});
|
|
572
|
+
if (r.slOrderId != null)
|
|
573
|
+
slSpan.setAttribute("senpi.order.id", String(r.slOrderId));
|
|
574
|
+
return r;
|
|
619
575
|
});
|
|
620
|
-
slUpdateEmitted = true;
|
|
621
576
|
let syncedForEmit = null;
|
|
622
577
|
await setIfStillActive(stateManager, key, state.address, state.asset, (current) => {
|
|
623
578
|
const synced = {
|
|
@@ -651,30 +606,10 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
651
606
|
slOrderId: synced.slOrderId ?? 0,
|
|
652
607
|
triggerReason: synced.triggerReason,
|
|
653
608
|
__positionId: synced.positionId ?? synced.correlationId,
|
|
654
|
-
__correlationId: synced.correlationId,
|
|
655
609
|
timestamp: ts,
|
|
656
610
|
});
|
|
657
611
|
}
|
|
658
612
|
catch (e) {
|
|
659
|
-
// Telemetry-only fire-and-forget: the failed venue-call window (dsl.sl_update, error).
|
|
660
|
-
// Guarded: when the ok emit already fired, the venue call itself succeeded — a later
|
|
661
|
-
// state-write throw must not be misattributed to the venue.
|
|
662
|
-
if (!slUpdateEmitted) {
|
|
663
|
-
bus.emit("tracking.dsl_sl_update", {
|
|
664
|
-
tickId,
|
|
665
|
-
key,
|
|
666
|
-
asset: state.asset,
|
|
667
|
-
dex,
|
|
668
|
-
positionId: state.positionId ?? state.correlationId,
|
|
669
|
-
startedAt: slSyncStartedAt,
|
|
670
|
-
endedAt: Date.now(),
|
|
671
|
-
outcome: "error",
|
|
672
|
-
newSLPrice: exchangeTriggerPx,
|
|
673
|
-
syncReason,
|
|
674
|
-
error: String(e),
|
|
675
|
-
timestamp: isoNow(),
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
613
|
let syncFailureCount = null;
|
|
679
614
|
await setIfStillActive(stateManager, key, state.address, state.asset, (current) => {
|
|
680
615
|
syncFailureCount = (current.slSyncFailureCount ?? 0) + 1;
|
|
@@ -688,14 +623,8 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
688
623
|
}, { tickId, skipMessage: "[dsl] skip SL sync-failure write: state no longer active (concurrent close)" });
|
|
689
624
|
if (syncFailureCount == null)
|
|
690
625
|
return;
|
|
691
|
-
logger
|
|
692
|
-
|
|
693
|
-
asset: state.asset,
|
|
694
|
-
exchangeTriggerPx,
|
|
695
|
-
dslEffectiveFloor,
|
|
696
|
-
slSyncFailureCount: syncFailureCount,
|
|
697
|
-
err: e,
|
|
698
|
-
});
|
|
626
|
+
emitEvent(logger, () => buildSlSyncFailedEvent(failureContext(state), syncFailureCount ?? 0, e));
|
|
627
|
+
recordDslDegradation({ failure: "sl_sync", errorType: errorTypeOf(e) });
|
|
699
628
|
}
|
|
700
629
|
}
|
|
701
630
|
const hbState = await stateManager.getOrLoad(key);
|
|
@@ -728,7 +657,6 @@ export async function processOnePosition(ctx, key, state, price) {
|
|
|
728
657
|
elapsedMinutes: hbState.elapsedMinutes,
|
|
729
658
|
triggerReason: hbState.triggerReason,
|
|
730
659
|
__positionId: hbState.positionId ?? hbState.correlationId,
|
|
731
|
-
__correlationId: hbState.correlationId,
|
|
732
660
|
margin: hbState.leverage > 0
|
|
733
661
|
? (hbState.size * hbState.entryPrice) / hbState.leverage
|
|
734
662
|
: 0,
|
|
@@ -765,11 +693,11 @@ async function attemptHandoffRegistration(ctx, key, next, _original, strategy) {
|
|
|
765
693
|
// attempt succeeded but we never persisted "ok"), adopt it instead of
|
|
766
694
|
// sending another addRatchetStop that the backend turns into an EDIT.
|
|
767
695
|
try {
|
|
768
|
-
const existing = await strategy.queryRatchetStops({
|
|
696
|
+
const existing = await withSpan("dsl.handoff", { "senpi.dsl.handoff.op": "register_precheck" }, () => strategy.queryRatchetStops({
|
|
769
697
|
asset: next.asset,
|
|
770
698
|
dex: next.dex || undefined,
|
|
771
699
|
status: "ALL",
|
|
772
|
-
});
|
|
700
|
+
}));
|
|
773
701
|
const active = existing.filter((p) => !BACKEND_TERMINAL_STATUSES.has(p.status));
|
|
774
702
|
if (active.length > 0) {
|
|
775
703
|
const adopted = active[0];
|
|
@@ -802,18 +730,24 @@ async function attemptHandoffRegistration(ctx, key, next, _original, strategy) {
|
|
|
802
730
|
});
|
|
803
731
|
}
|
|
804
732
|
try {
|
|
805
|
-
const result = await
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
733
|
+
const result = await withSpan("dsl.handoff", { "senpi.dsl.handoff.op": "register" }, async (handoffSpan) => {
|
|
734
|
+
const r = await strategy.addRatchetStop({
|
|
735
|
+
asset: next.asset,
|
|
736
|
+
dex: next.dex || undefined,
|
|
737
|
+
direction: next.direction,
|
|
738
|
+
entryPrice: next.entryPrice,
|
|
739
|
+
size: next.size,
|
|
740
|
+
leverage: next.leverage,
|
|
741
|
+
ratchetStopConfig: {
|
|
742
|
+
tiered: {
|
|
743
|
+
tiers: mapTiersToEngineConfig(next.tiers),
|
|
744
|
+
},
|
|
815
745
|
},
|
|
816
|
-
}
|
|
746
|
+
});
|
|
747
|
+
if (r.success && r.position) {
|
|
748
|
+
handoffSpan.setAttribute("senpi.dsl.handoff.status", BACKEND_TERMINAL_STATUSES.has(r.position.status) ? "aborted" : "ok");
|
|
749
|
+
}
|
|
750
|
+
return r;
|
|
817
751
|
});
|
|
818
752
|
if (result.success && result.position) {
|
|
819
753
|
if (BACKEND_TERMINAL_STATUSES.has(result.position.status)) {
|
|
@@ -854,22 +788,19 @@ async function attemptHandoffRegistration(ctx, key, next, _original, strategy) {
|
|
|
854
788
|
});
|
|
855
789
|
}
|
|
856
790
|
else {
|
|
857
|
-
logger
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
});
|
|
791
|
+
emitEvent(logger, () => buildHandoffFailedEvent(failureContext(next), {
|
|
792
|
+
failure: "register",
|
|
793
|
+
redact: { result: JSON.stringify(result).slice(0, 800) },
|
|
794
|
+
}));
|
|
795
|
+
recordDslDegradation({ failure: "handoff", handoffFailure: "register" });
|
|
862
796
|
}
|
|
863
797
|
}
|
|
864
798
|
catch (e) {
|
|
865
|
-
logger
|
|
866
|
-
|
|
867
|
-
asset: next.asset,
|
|
868
|
-
err: e,
|
|
869
|
-
});
|
|
799
|
+
emitEvent(logger, () => buildHandoffFailedEvent(failureContext(next), { failure: "register", error: e }));
|
|
800
|
+
recordDslDegradation({ failure: "handoff", handoffFailure: "register", errorType: errorTypeOf(e) });
|
|
870
801
|
}
|
|
871
802
|
}
|
|
872
|
-
async function handleHandoffOk(ctx, key, next, original, strategy) {
|
|
803
|
+
async function handleHandoffOk(ctx, key, next, original, strategy, span) {
|
|
873
804
|
const { tickId, ts, stateManager, bus } = ctx;
|
|
874
805
|
let updated = { ...next };
|
|
875
806
|
// Snapshot pre-merge state so we can detect backend event echoes for tier/SL
|
|
@@ -877,24 +808,22 @@ async function handleHandoffOk(ctx, key, next, original, strategy) {
|
|
|
877
808
|
const prevTierIndex = updated.currentTierIndex;
|
|
878
809
|
const prevSlOrderId = updated.slOrderId;
|
|
879
810
|
try {
|
|
880
|
-
const positions = await strategy.queryRatchetStops({
|
|
811
|
+
const positions = await withSpan("dsl.handoff", { "senpi.dsl.handoff.op": "poll_positions" }, () => strategy.queryRatchetStops({
|
|
881
812
|
asset: original.asset,
|
|
882
813
|
dex: original.dex || undefined,
|
|
883
814
|
status: "ALL",
|
|
884
|
-
});
|
|
815
|
+
}));
|
|
885
816
|
const backendPos = next.backendDslPositionId
|
|
886
817
|
? positions.find((p) => p.id === next.backendDslPositionId) ?? null
|
|
887
818
|
: positions.filter((p) => !BACKEND_TERMINAL_STATUSES.has(p.status)).length === 1
|
|
888
819
|
? positions.filter((p) => !BACKEND_TERMINAL_STATUSES.has(p.status))[0]
|
|
889
820
|
: null;
|
|
890
821
|
if (!backendPos) {
|
|
891
|
-
logger
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
returnedIds: positions.map((p) => p.id),
|
|
897
|
-
});
|
|
822
|
+
emitEvent(logger, () => buildHandoffFailedEvent(failureContext(original), {
|
|
823
|
+
failure: "rollback",
|
|
824
|
+
backendPositionId: next.backendDslPositionId ?? undefined,
|
|
825
|
+
}));
|
|
826
|
+
recordDslDegradation({ failure: "handoff", handoffFailure: "rollback" });
|
|
898
827
|
const rolledBack = {
|
|
899
828
|
...updated,
|
|
900
829
|
handoffStatus: null,
|
|
@@ -906,12 +835,14 @@ async function handleHandoffOk(ctx, key, next, original, strategy) {
|
|
|
906
835
|
}
|
|
907
836
|
else {
|
|
908
837
|
if (BACKEND_TERMINAL_STATUSES.has(backendPos.status)) {
|
|
838
|
+
span.addEvent("external_close_detected", { source: "backend_terminal" });
|
|
909
839
|
logger.info("[dsl] backend reports terminal status, closing position locally", {
|
|
910
840
|
tickId,
|
|
911
841
|
asset: original.asset,
|
|
912
842
|
backendStatus: backendPos.status,
|
|
913
843
|
});
|
|
914
844
|
const closeReason = `backend_${backendPos.status.toLowerCase()}`;
|
|
845
|
+
span.setAttribute("senpi.dsl.close_reason", closeReason);
|
|
915
846
|
const closedState = {
|
|
916
847
|
...updated,
|
|
917
848
|
active: false,
|
|
@@ -943,20 +874,21 @@ async function handleHandoffOk(ctx, key, next, original, strategy) {
|
|
|
943
874
|
}
|
|
944
875
|
}
|
|
945
876
|
catch (e) {
|
|
946
|
-
logger
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
});
|
|
877
|
+
emitEvent(logger, () => buildHandoffFailedEvent(failureContext(original), {
|
|
878
|
+
failure: "poll",
|
|
879
|
+
backendPositionId: next.backendDslPositionId ?? undefined,
|
|
880
|
+
error: e,
|
|
881
|
+
}));
|
|
882
|
+
recordDslDegradation({ failure: "handoff", handoffFailure: "poll", errorType: errorTypeOf(e) });
|
|
951
883
|
}
|
|
952
884
|
try {
|
|
953
885
|
// ASC ordering is required: the cursor advances to the LAST element of the array
|
|
954
886
|
// below, which must be the newest event. Backend default is DESC.
|
|
955
|
-
const events = await strategy.queryRatchetStopEvents({
|
|
887
|
+
const events = await withSpan("dsl.handoff", { "senpi.dsl.handoff.op": "poll_events" }, () => strategy.queryRatchetStopEvents({
|
|
956
888
|
positionId: updated.backendDslPositionId ?? undefined,
|
|
957
889
|
since: updated.lastBackendDslTick ?? undefined,
|
|
958
890
|
sortOrder: "ASC",
|
|
959
|
-
});
|
|
891
|
+
}));
|
|
960
892
|
// Filter out events already seen on the previous poll (since may be inclusive)
|
|
961
893
|
const cursor = updated.lastBackendDslTick;
|
|
962
894
|
const freshEvents = cursor
|
|
@@ -1037,7 +969,9 @@ async function handleHandoffOk(ctx, key, next, original, strategy) {
|
|
|
1037
969
|
});
|
|
1038
970
|
// Archive local state when backend reports position closed via event stream
|
|
1039
971
|
if (backendClosed) {
|
|
972
|
+
span.addEvent("external_close_detected", { source: "backend_terminal" });
|
|
1040
973
|
const closeReason = backendCloseReason ?? "backend_closed";
|
|
974
|
+
span.setAttribute("senpi.dsl.close_reason", closeReason);
|
|
1041
975
|
logger.info("[dsl] backend CLOSED event received, archiving local state", {
|
|
1042
976
|
tickId,
|
|
1043
977
|
key,
|