@haaaiawd/second-nature 0.1.16 → 0.1.18
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/index.js +855 -851
- package/openclaw.plugin.json +29 -29
- package/package.json +52 -52
- package/runtime/cli/commands/index.d.ts +14 -14
- package/runtime/cli/commands/index.js +193 -193
- package/runtime/cli/explain/explain-surface-subject.d.ts +8 -8
- package/runtime/cli/explain/explain-surface-subject.js +9 -9
- package/runtime/cli/explain/format-explanation.d.ts +12 -12
- package/runtime/cli/explain/format-explanation.js +12 -12
- package/runtime/cli/explain/resolve-subject.js +41 -41
- package/runtime/cli/host-capability/classify-delivery.d.ts +14 -14
- package/runtime/cli/host-capability/classify-delivery.js +20 -20
- package/runtime/cli/host-capability/probe-host-capability.d.ts +2 -2
- package/runtime/cli/host-capability/probe-host-capability.js +58 -58
- package/runtime/cli/host-capability/record-host-capability.d.ts +6 -6
- package/runtime/cli/host-capability/record-host-capability.js +14 -14
- package/runtime/cli/host-capability/types.d.ts +71 -71
- package/runtime/cli/host-capability/types.js +6 -6
- package/runtime/cli/host-smoke/run-host-smoke.d.ts +2 -2
- package/runtime/cli/host-smoke/run-host-smoke.js +40 -40
- package/runtime/cli/host-smoke/types.d.ts +35 -35
- package/runtime/cli/host-smoke/types.js +6 -6
- package/runtime/cli/index.js +58 -54
- package/runtime/cli/ops/heartbeat-surface.d.ts +38 -35
- package/runtime/cli/ops/heartbeat-surface.js +73 -71
- package/runtime/cli/ops/ops-router.d.ts +19 -16
- package/runtime/cli/ops/ops-router.js +89 -87
- package/runtime/cli/ops/show-operator-fallback.d.ts +13 -13
- package/runtime/cli/ops/show-operator-fallback.js +22 -22
- package/runtime/cli/ops/workspace-heartbeat-runner.d.ts +19 -10
- package/runtime/cli/ops/workspace-heartbeat-runner.js +39 -26
- package/runtime/cli/read-models/index.d.ts +29 -29
- package/runtime/cli/read-models/index.js +256 -256
- package/runtime/cli/read-models/operator-explain-map.d.ts +6 -6
- package/runtime/cli/read-models/operator-explain-map.js +10 -10
- package/runtime/cli/read-models/types.d.ts +79 -79
- package/runtime/cli/runtime/runtime-artifact-boundary.d.ts +28 -28
- package/runtime/cli/runtime/runtime-artifact-boundary.js +94 -94
- package/runtime/connectors/base/contract.d.ts +87 -87
- package/runtime/connectors/base/execution-policy.d.ts +47 -47
- package/runtime/connectors/base/execution-policy.js +82 -82
- package/runtime/connectors/base/index.d.ts +8 -8
- package/runtime/connectors/base/index.js +8 -8
- package/runtime/connectors/base/manifest.d.ts +64 -64
- package/runtime/connectors/base/manifest.js +86 -86
- package/runtime/connectors/base/map-life-evidence.d.ts +16 -16
- package/runtime/connectors/base/map-life-evidence.js +79 -79
- package/runtime/connectors/base/policy-layer.d.ts +29 -29
- package/runtime/connectors/base/policy-layer.js +198 -198
- package/runtime/connectors/base/route-planner.js +99 -99
- package/runtime/connectors/index.d.ts +5 -5
- package/runtime/connectors/index.js +5 -5
- package/runtime/connectors/near-real/near-real-connector-smoke.d.ts +19 -19
- package/runtime/connectors/near-real/near-real-connector-smoke.js +152 -152
- package/runtime/core/second-nature/heartbeat/heartbeat-executor.js +114 -114
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.d.ts +63 -63
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +139 -139
- package/runtime/core/second-nature/heartbeat/index.d.ts +8 -8
- package/runtime/core/second-nature/heartbeat/index.js +7 -7
- package/runtime/core/second-nature/heartbeat/run-heartbeat-cycle.d.ts +21 -21
- package/runtime/core/second-nature/heartbeat/run-heartbeat-cycle.js +35 -35
- package/runtime/core/second-nature/heartbeat/runtime-snapshot.d.ts +28 -28
- package/runtime/core/second-nature/heartbeat/runtime-snapshot.js +35 -35
- package/runtime/core/second-nature/heartbeat/signal.d.ts +42 -42
- package/runtime/core/second-nature/heartbeat/snapshot-builder.d.ts +51 -51
- package/runtime/core/second-nature/index.d.ts +22 -22
- package/runtime/core/second-nature/index.js +22 -22
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.d.ts +100 -100
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.js +144 -144
- package/runtime/core/second-nature/orchestrator/guard-layer.d.ts +8 -8
- package/runtime/core/second-nature/orchestrator/guard-layer.js +110 -110
- package/runtime/core/second-nature/orchestrator/intent-planner.d.ts +13 -13
- package/runtime/core/second-nature/orchestrator/intent-planner.js +199 -199
- package/runtime/core/second-nature/orchestrator/lease-manager.d.ts +14 -14
- package/runtime/core/second-nature/orchestrator/lease-manager.js +58 -58
- package/runtime/core/second-nature/outreach/build-outreach-draft-request.d.ts +6 -6
- package/runtime/core/second-nature/outreach/build-outreach-draft-request.js +63 -63
- package/runtime/core/second-nature/outreach/delivery-target.d.ts +26 -26
- package/runtime/core/second-nature/outreach/delivery-target.js +70 -70
- package/runtime/core/second-nature/outreach/dispatch-user-outreach.d.ts +38 -38
- package/runtime/core/second-nature/outreach/dispatch-user-outreach.js +119 -119
- package/runtime/core/second-nature/outreach/judge-input-from-snapshot.d.ts +7 -7
- package/runtime/core/second-nature/outreach/judge-input-from-snapshot.js +45 -45
- package/runtime/core/second-nature/outreach/judge-outreach.d.ts +40 -40
- package/runtime/core/second-nature/outreach/judge-outreach.js +121 -121
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.d.ts +21 -21
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.js +123 -123
- package/runtime/core/second-nature/rhythm/planner-rhythm-window.d.ts +15 -15
- package/runtime/core/second-nature/rhythm/planner-rhythm-window.js +52 -52
- package/runtime/core/second-nature/rhythm/policy-bridge.d.ts +19 -19
- package/runtime/core/second-nature/rhythm/policy-bridge.js +34 -34
- package/runtime/core/second-nature/runtime/service-entry.js +45 -45
- package/runtime/core/second-nature/types.d.ts +51 -51
- package/runtime/guidance/draft-outreach-message.d.ts +7 -7
- package/runtime/guidance/draft-outreach-message.js +42 -42
- package/runtime/guidance/evidence-guidance.d.ts +40 -40
- package/runtime/guidance/evidence-guidance.js +52 -52
- package/runtime/guidance/index.d.ts +11 -11
- package/runtime/guidance/index.js +11 -11
- package/runtime/guidance/outreach-draft-schema.d.ts +228 -228
- package/runtime/guidance/outreach-draft-schema.js +80 -80
- package/runtime/observability/audit/append-only-audit-store.d.ts +14 -14
- package/runtime/observability/audit/append-only-audit-store.js +21 -21
- package/runtime/observability/audit/audit-envelope.d.ts +51 -51
- package/runtime/observability/audit/audit-envelope.js +130 -130
- package/runtime/observability/audit/verify-audit-hash-chain.d.ts +23 -23
- package/runtime/observability/audit/verify-audit-hash-chain.js +83 -83
- package/runtime/observability/db/index.js +124 -124
- package/runtime/observability/db/schema/host-capability-reports.d.ts +180 -180
- package/runtime/observability/db/schema/host-capability-reports.js +12 -12
- package/runtime/observability/db/schema/index.d.ts +947 -947
- package/runtime/observability/db/schema/index.js +71 -71
- package/runtime/observability/index.d.ts +20 -19
- package/runtime/observability/index.js +19 -18
- package/runtime/observability/query/explain-query.d.ts +48 -48
- package/runtime/observability/query/explain-query.js +114 -114
- package/runtime/observability/query/export-audit-bundle.d.ts +22 -22
- package/runtime/observability/query/export-audit-bundle.js +27 -27
- package/runtime/observability/services/decision-ledger.d.ts +46 -46
- package/runtime/observability/services/decision-ledger.js +161 -161
- package/runtime/observability/services/governance-audit.d.ts +41 -41
- package/runtime/observability/services/governance-audit.js +163 -163
- package/runtime/observability/services/governance-plane-recorder.d.ts +47 -47
- package/runtime/observability/services/governance-plane-recorder.js +55 -55
- package/runtime/observability/services/lived-experience-audit.d.ts +97 -97
- package/runtime/observability/services/lived-experience-audit.js +162 -162
- package/runtime/observability/services/runtime-decision-recorder.d.ts +29 -0
- package/runtime/observability/services/runtime-decision-recorder.js +94 -0
- package/runtime/storage/bootstrap/native-sqlite-probe.d.ts +7 -7
- package/runtime/storage/bootstrap/native-sqlite-probe.js +28 -28
- package/runtime/storage/bootstrap/repair-gate.d.ts +17 -17
- package/runtime/storage/bootstrap/repair-gate.js +71 -71
- package/runtime/storage/bootstrap/storage-mode-smoke.d.ts +38 -38
- package/runtime/storage/bootstrap/storage-mode-smoke.js +85 -85
- package/runtime/storage/db/index.js +154 -154
- package/runtime/storage/db/schema/delivery-attempts.d.ts +199 -199
- package/runtime/storage/db/schema/delivery-attempts.js +13 -13
- package/runtime/storage/db/schema/index.d.ts +9 -9
- package/runtime/storage/db/schema/index.js +9 -9
- package/runtime/storage/db/schema/life-evidence-index.d.ts +161 -161
- package/runtime/storage/db/schema/life-evidence-index.js +11 -11
- package/runtime/storage/db/schema/operator-fallback-artifacts.d.ts +161 -161
- package/runtime/storage/db/schema/operator-fallback-artifacts.js +11 -11
- package/runtime/storage/db/schema/policies.d.ts +98 -98
- package/runtime/storage/db/schema/policies.js +8 -8
- package/runtime/storage/delivery/query-delivery-attempts.d.ts +3 -3
- package/runtime/storage/delivery/query-delivery-attempts.js +32 -32
- package/runtime/storage/delivery/types.d.ts +27 -27
- package/runtime/storage/delivery/types.js +1 -1
- package/runtime/storage/delivery/write-delivery-attempt.d.ts +6 -6
- package/runtime/storage/delivery/write-delivery-attempt.js +36 -36
- package/runtime/storage/fallback/load-operator-fallback.d.ts +14 -14
- package/runtime/storage/fallback/load-operator-fallback.js +47 -47
- package/runtime/storage/fallback/operator-fallback-types.d.ts +9 -9
- package/runtime/storage/fallback/operator-fallback-types.js +1 -1
- package/runtime/storage/fallback/operator-fallback-view.d.ts +11 -11
- package/runtime/storage/fallback/operator-fallback-view.js +1 -1
- package/runtime/storage/fallback/write-operator-fallback.d.ts +6 -6
- package/runtime/storage/fallback/write-operator-fallback.js +21 -21
- package/runtime/storage/index.d.ts +37 -37
- package/runtime/storage/index.js +30 -30
- package/runtime/storage/life-evidence/append-life-evidence.d.ts +7 -7
- package/runtime/storage/life-evidence/append-life-evidence.js +64 -64
- package/runtime/storage/life-evidence/types.d.ts +45 -45
- package/runtime/storage/life-evidence/types.js +6 -6
- package/runtime/storage/quiet/persist-quiet-artifact.d.ts +7 -7
- package/runtime/storage/quiet/persist-quiet-artifact.js +22 -22
- package/runtime/storage/quiet/quiet-artifact-types.d.ts +18 -18
- package/runtime/storage/quiet/quiet-artifact-types.js +1 -1
- package/runtime/storage/quiet/quiet-artifact-writer.d.ts +15 -15
- package/runtime/storage/quiet/quiet-artifact-writer.js +56 -56
- package/runtime/storage/repositories/credential-repository.js +30 -30
- package/runtime/storage/rhythm/rhythm-policy-snapshot.d.ts +10 -10
- package/runtime/storage/rhythm/rhythm-policy-snapshot.js +34 -34
- package/runtime/storage/services/credential-vault.d.ts +13 -13
- package/runtime/storage/services/credential-vault.js +116 -116
- package/runtime/storage/snapshots/continuity-snapshot.d.ts +9 -9
- package/runtime/storage/snapshots/continuity-snapshot.js +41 -41
- package/runtime/storage/snapshots/life-evidence-snapshot.d.ts +6 -6
- package/runtime/storage/snapshots/life-evidence-snapshot.js +114 -114
- package/runtime/storage/snapshots/types.d.ts +58 -58
- package/runtime/storage/snapshots/types.js +1 -1
- package/runtime/storage/state-api.js +104 -104
- package/runtime/storage/user-interest/load-user-interest-snapshot.d.ts +2 -2
- package/runtime/storage/user-interest/load-user-interest-snapshot.js +150 -150
- package/runtime/storage/user-interest/types.d.ts +25 -25
- package/runtime/storage/user-interest/types.js +1 -1
- package/workspace-ops-bridge.js +81 -80
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
import { AppendOnlyAuditStore } from "../audit/append-only-audit-store.js";
|
|
2
|
-
import type { SourceRef } from "../../storage/life-evidence/types.js";
|
|
3
|
-
export type RuntimeScope = "rhythm" | "user_task" | "user_reply";
|
|
4
|
-
export type HeartbeatOutcome = "heartbeat_ok" | "intent_selected" | "denied" | "deferred" | "runtime_carrier_only" | "delivery_unavailable";
|
|
5
|
-
export type DeliveryAuditStatus = "not_requested" | "target_available" | "target_none" | "channel_missing" | "host_unsupported" | "ack_dropped" | "sent" | "failed" | "not_sent_fallback";
|
|
6
|
-
export type GroundingStatus = "pass" | "degraded" | "blocked";
|
|
7
|
-
export interface DecisionTracePayload {
|
|
8
|
-
decisionId: string;
|
|
9
|
-
traceId: string;
|
|
10
|
-
heartbeatId?: string;
|
|
11
|
-
runtimeScope: RuntimeScope;
|
|
12
|
-
outcome: HeartbeatOutcome;
|
|
13
|
-
selectedIntentId?: string;
|
|
14
|
-
candidateId?: string;
|
|
15
|
-
rhythmWindowKind?: string;
|
|
16
|
-
hardGuardVerdict?: "allow" | "deny" | "defer" | "silent";
|
|
17
|
-
outreachVerdict?: "allow" | "deny" | "defer";
|
|
18
|
-
deliveryAuditId?: string;
|
|
19
|
-
reasonCodes: string[];
|
|
20
|
-
sourceRefs: SourceRef[];
|
|
21
|
-
snapshotRef?: SourceRef;
|
|
22
|
-
createdAt: string;
|
|
23
|
-
}
|
|
24
|
-
export interface DeliveryAuditPayload {
|
|
25
|
-
auditId: string;
|
|
26
|
-
decisionId: string;
|
|
27
|
-
traceId: string;
|
|
28
|
-
target?: "none" | "last" | "explicit";
|
|
29
|
-
channel?: string;
|
|
30
|
-
recipientRef?: string;
|
|
31
|
-
status: DeliveryAuditStatus;
|
|
32
|
-
messageId?: string;
|
|
33
|
-
hostProofRef?: SourceRef;
|
|
34
|
-
fallbackRef?: string;
|
|
35
|
-
ackDropMatched?: boolean;
|
|
36
|
-
hostVersion?: string;
|
|
37
|
-
reasonCodes: string[];
|
|
38
|
-
createdAt: string;
|
|
39
|
-
}
|
|
40
|
-
export interface SourceCoverageAuditPayload {
|
|
41
|
-
auditId: string;
|
|
42
|
-
traceId: string;
|
|
43
|
-
/** When set, explain index links this audit to the decision timeline. */
|
|
44
|
-
decisionId?: string;
|
|
45
|
-
subjectType: "quiet_artifact" | "outreach_draft" | "guidance_payload" | "decision_trace" | "host_report";
|
|
46
|
-
subjectRef: string;
|
|
47
|
-
usedSourceRefs: SourceRef[];
|
|
48
|
-
unresolvedRefs: SourceRef[];
|
|
49
|
-
coverageRatio: number;
|
|
50
|
-
unsupportedClaims: string[];
|
|
51
|
-
status: GroundingStatus;
|
|
52
|
-
reasonCodes: string[];
|
|
53
|
-
createdAt: string;
|
|
54
|
-
}
|
|
55
|
-
export interface GuidanceGroundingAuditPayload {
|
|
56
|
-
auditId: string;
|
|
57
|
-
traceId: string;
|
|
58
|
-
decisionId?: string;
|
|
59
|
-
requestId: string;
|
|
60
|
-
draftId?: string;
|
|
61
|
-
sceneType: "outreach" | "quiet_reflection" | "social" | "explain" | "user_reply_continuity" | "fallback_candidate";
|
|
62
|
-
groundingStatus: GroundingStatus;
|
|
63
|
-
usedSourceRefs: SourceRef[];
|
|
64
|
-
unsupportedClaims: string[];
|
|
65
|
-
guardViolations: string[];
|
|
66
|
-
deliveryWording?: "sendable" | "not_sent_fallback_candidate";
|
|
67
|
-
createdAt: string;
|
|
68
|
-
}
|
|
69
|
-
export interface ExplainLinkageSummary {
|
|
70
|
-
decisionId: string;
|
|
71
|
-
summary: string;
|
|
72
|
-
warnings: string[];
|
|
73
|
-
deliveryStatus?: DeliveryAuditStatus;
|
|
74
|
-
relatedEventIds: string[];
|
|
75
|
-
}
|
|
76
|
-
export declare class LivedExperienceAuditRecorder {
|
|
77
|
-
private readonly store;
|
|
78
|
-
private seq;
|
|
79
|
-
private readonly explainIndex;
|
|
80
|
-
constructor(store: AppendOnlyAuditStore);
|
|
81
|
-
private bumpSequence;
|
|
82
|
-
private touchDecision;
|
|
83
|
-
recordDecisionTrace(payload: DecisionTracePayload): {
|
|
84
|
-
eventId: string;
|
|
85
|
-
};
|
|
86
|
-
recordDeliveryAudit(payload: DeliveryAuditPayload): {
|
|
87
|
-
eventId: string;
|
|
88
|
-
};
|
|
89
|
-
recordSourceCoverage(payload: SourceCoverageAuditPayload): {
|
|
90
|
-
eventId: string;
|
|
91
|
-
};
|
|
92
|
-
recordGuidanceGrounding(payload: GuidanceGroundingAuditPayload): {
|
|
93
|
-
eventId: string;
|
|
94
|
-
};
|
|
95
|
-
explainLinkageForDecision(decisionId: string): ExplainLinkageSummary;
|
|
96
|
-
}
|
|
97
|
-
export declare function createLivedExperienceAuditRecorder(store?: AppendOnlyAuditStore): LivedExperienceAuditRecorder;
|
|
1
|
+
import { AppendOnlyAuditStore } from "../audit/append-only-audit-store.js";
|
|
2
|
+
import type { SourceRef } from "../../storage/life-evidence/types.js";
|
|
3
|
+
export type RuntimeScope = "rhythm" | "user_task" | "user_reply";
|
|
4
|
+
export type HeartbeatOutcome = "heartbeat_ok" | "intent_selected" | "denied" | "deferred" | "runtime_carrier_only" | "delivery_unavailable";
|
|
5
|
+
export type DeliveryAuditStatus = "not_requested" | "target_available" | "target_none" | "channel_missing" | "host_unsupported" | "ack_dropped" | "sent" | "failed" | "not_sent_fallback";
|
|
6
|
+
export type GroundingStatus = "pass" | "degraded" | "blocked";
|
|
7
|
+
export interface DecisionTracePayload {
|
|
8
|
+
decisionId: string;
|
|
9
|
+
traceId: string;
|
|
10
|
+
heartbeatId?: string;
|
|
11
|
+
runtimeScope: RuntimeScope;
|
|
12
|
+
outcome: HeartbeatOutcome;
|
|
13
|
+
selectedIntentId?: string;
|
|
14
|
+
candidateId?: string;
|
|
15
|
+
rhythmWindowKind?: string;
|
|
16
|
+
hardGuardVerdict?: "allow" | "deny" | "defer" | "silent";
|
|
17
|
+
outreachVerdict?: "allow" | "deny" | "defer";
|
|
18
|
+
deliveryAuditId?: string;
|
|
19
|
+
reasonCodes: string[];
|
|
20
|
+
sourceRefs: SourceRef[];
|
|
21
|
+
snapshotRef?: SourceRef;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
}
|
|
24
|
+
export interface DeliveryAuditPayload {
|
|
25
|
+
auditId: string;
|
|
26
|
+
decisionId: string;
|
|
27
|
+
traceId: string;
|
|
28
|
+
target?: "none" | "last" | "explicit";
|
|
29
|
+
channel?: string;
|
|
30
|
+
recipientRef?: string;
|
|
31
|
+
status: DeliveryAuditStatus;
|
|
32
|
+
messageId?: string;
|
|
33
|
+
hostProofRef?: SourceRef;
|
|
34
|
+
fallbackRef?: string;
|
|
35
|
+
ackDropMatched?: boolean;
|
|
36
|
+
hostVersion?: string;
|
|
37
|
+
reasonCodes: string[];
|
|
38
|
+
createdAt: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SourceCoverageAuditPayload {
|
|
41
|
+
auditId: string;
|
|
42
|
+
traceId: string;
|
|
43
|
+
/** When set, explain index links this audit to the decision timeline. */
|
|
44
|
+
decisionId?: string;
|
|
45
|
+
subjectType: "quiet_artifact" | "outreach_draft" | "guidance_payload" | "decision_trace" | "host_report";
|
|
46
|
+
subjectRef: string;
|
|
47
|
+
usedSourceRefs: SourceRef[];
|
|
48
|
+
unresolvedRefs: SourceRef[];
|
|
49
|
+
coverageRatio: number;
|
|
50
|
+
unsupportedClaims: string[];
|
|
51
|
+
status: GroundingStatus;
|
|
52
|
+
reasonCodes: string[];
|
|
53
|
+
createdAt: string;
|
|
54
|
+
}
|
|
55
|
+
export interface GuidanceGroundingAuditPayload {
|
|
56
|
+
auditId: string;
|
|
57
|
+
traceId: string;
|
|
58
|
+
decisionId?: string;
|
|
59
|
+
requestId: string;
|
|
60
|
+
draftId?: string;
|
|
61
|
+
sceneType: "outreach" | "quiet_reflection" | "social" | "explain" | "user_reply_continuity" | "fallback_candidate";
|
|
62
|
+
groundingStatus: GroundingStatus;
|
|
63
|
+
usedSourceRefs: SourceRef[];
|
|
64
|
+
unsupportedClaims: string[];
|
|
65
|
+
guardViolations: string[];
|
|
66
|
+
deliveryWording?: "sendable" | "not_sent_fallback_candidate";
|
|
67
|
+
createdAt: string;
|
|
68
|
+
}
|
|
69
|
+
export interface ExplainLinkageSummary {
|
|
70
|
+
decisionId: string;
|
|
71
|
+
summary: string;
|
|
72
|
+
warnings: string[];
|
|
73
|
+
deliveryStatus?: DeliveryAuditStatus;
|
|
74
|
+
relatedEventIds: string[];
|
|
75
|
+
}
|
|
76
|
+
export declare class LivedExperienceAuditRecorder {
|
|
77
|
+
private readonly store;
|
|
78
|
+
private seq;
|
|
79
|
+
private readonly explainIndex;
|
|
80
|
+
constructor(store: AppendOnlyAuditStore);
|
|
81
|
+
private bumpSequence;
|
|
82
|
+
private touchDecision;
|
|
83
|
+
recordDecisionTrace(payload: DecisionTracePayload): {
|
|
84
|
+
eventId: string;
|
|
85
|
+
};
|
|
86
|
+
recordDeliveryAudit(payload: DeliveryAuditPayload): {
|
|
87
|
+
eventId: string;
|
|
88
|
+
};
|
|
89
|
+
recordSourceCoverage(payload: SourceCoverageAuditPayload): {
|
|
90
|
+
eventId: string;
|
|
91
|
+
};
|
|
92
|
+
recordGuidanceGrounding(payload: GuidanceGroundingAuditPayload): {
|
|
93
|
+
eventId: string;
|
|
94
|
+
};
|
|
95
|
+
explainLinkageForDecision(decisionId: string): ExplainLinkageSummary;
|
|
96
|
+
}
|
|
97
|
+
export declare function createLivedExperienceAuditRecorder(store?: AppendOnlyAuditStore): LivedExperienceAuditRecorder;
|
|
@@ -1,162 +1,162 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Decision trace, delivery audit, source coverage, guidance grounding + explain index (T5.2.1).
|
|
3
|
-
*
|
|
4
|
-
* Core logic: append-only envelopes with hash chain; explain index links decisionId to events and
|
|
5
|
-
* flags when delivery audit indicates no user-visible contact (target_none / not_sent_fallback).
|
|
6
|
-
* Test coverage: tests/unit/observability/lived-experience-audit.test.ts
|
|
7
|
-
*/
|
|
8
|
-
import * as crypto from "node:crypto";
|
|
9
|
-
import { AppendOnlyAuditStore } from "../audit/append-only-audit-store.js";
|
|
10
|
-
import { buildAuditEnvelope } from "../audit/audit-envelope.js";
|
|
11
|
-
function validateDecisionTrace(t) {
|
|
12
|
-
if (!t.decisionId?.trim())
|
|
13
|
-
throw new Error("decision_trace_requires_decision_id");
|
|
14
|
-
if (!t.traceId?.trim())
|
|
15
|
-
throw new Error("decision_trace_requires_trace_id");
|
|
16
|
-
if (!t.outcome)
|
|
17
|
-
throw new Error("decision_trace_requires_outcome");
|
|
18
|
-
}
|
|
19
|
-
function validateDeliveryAudit(a) {
|
|
20
|
-
if (!a.auditId?.trim())
|
|
21
|
-
throw new Error("delivery_audit_requires_audit_id");
|
|
22
|
-
if (!a.decisionId?.trim())
|
|
23
|
-
throw new Error("delivery_audit_requires_decision_id");
|
|
24
|
-
if (a.status === "sent") {
|
|
25
|
-
const ok = Boolean(a.messageId?.trim()) || Boolean(a.hostProofRef);
|
|
26
|
-
if (!ok)
|
|
27
|
-
throw new Error("delivery_audit_sent_requires_message_id_or_host_proof_ref");
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
export class LivedExperienceAuditRecorder {
|
|
31
|
-
store;
|
|
32
|
-
seq = 0;
|
|
33
|
-
explainIndex = new Map();
|
|
34
|
-
constructor(store) {
|
|
35
|
-
this.store = store;
|
|
36
|
-
}
|
|
37
|
-
bumpSequence() {
|
|
38
|
-
this.seq += 1;
|
|
39
|
-
return this.seq;
|
|
40
|
-
}
|
|
41
|
-
touchDecision(decisionId, traceId, eventId) {
|
|
42
|
-
let e = this.explainIndex.get(decisionId);
|
|
43
|
-
if (!e) {
|
|
44
|
-
e = { traceIds: new Set(), eventIds: [], deliveryStatuses: [], fallbackRefs: [], noUserVisibleContact: false };
|
|
45
|
-
this.explainIndex.set(decisionId, e);
|
|
46
|
-
}
|
|
47
|
-
e.traceIds.add(traceId);
|
|
48
|
-
e.eventIds.push(eventId);
|
|
49
|
-
return e;
|
|
50
|
-
}
|
|
51
|
-
recordDecisionTrace(payload) {
|
|
52
|
-
validateDecisionTrace(payload);
|
|
53
|
-
const seq = this.bumpSequence();
|
|
54
|
-
const envelope = buildAuditEnvelope({
|
|
55
|
-
family: "heartbeat.decision",
|
|
56
|
-
plane: "decision",
|
|
57
|
-
traceId: payload.traceId,
|
|
58
|
-
sequence: seq,
|
|
59
|
-
payload,
|
|
60
|
-
previousHash: this.store.lastRecordHash(),
|
|
61
|
-
eventId: crypto.randomUUID(),
|
|
62
|
-
createdAt: payload.createdAt,
|
|
63
|
-
});
|
|
64
|
-
this.store.append(envelope);
|
|
65
|
-
const entry = this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
66
|
-
if (payload.outcome === "heartbeat_ok" &&
|
|
67
|
-
payload.reasonCodes.some((c) => c.includes("target_none") || c === "target_none")) {
|
|
68
|
-
entry.noUserVisibleContact = true;
|
|
69
|
-
}
|
|
70
|
-
return { eventId: envelope.eventId };
|
|
71
|
-
}
|
|
72
|
-
recordDeliveryAudit(payload) {
|
|
73
|
-
validateDeliveryAudit(payload);
|
|
74
|
-
const seq = this.bumpSequence();
|
|
75
|
-
const envelope = buildAuditEnvelope({
|
|
76
|
-
family: "delivery",
|
|
77
|
-
plane: "delivery",
|
|
78
|
-
traceId: payload.traceId,
|
|
79
|
-
sequence: seq,
|
|
80
|
-
payload,
|
|
81
|
-
previousHash: this.store.lastRecordHash(),
|
|
82
|
-
eventId: payload.auditId,
|
|
83
|
-
createdAt: payload.createdAt,
|
|
84
|
-
});
|
|
85
|
-
this.store.append(envelope);
|
|
86
|
-
const entry = this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
87
|
-
entry.deliveryStatuses.push(payload.status);
|
|
88
|
-
if (payload.fallbackRef)
|
|
89
|
-
entry.fallbackRefs.push(payload.fallbackRef);
|
|
90
|
-
if (payload.status === "target_none" ||
|
|
91
|
-
payload.status === "not_sent_fallback" ||
|
|
92
|
-
payload.status === "channel_missing" ||
|
|
93
|
-
payload.status === "host_unsupported" ||
|
|
94
|
-
payload.status === "failed" ||
|
|
95
|
-
payload.status === "ack_dropped") {
|
|
96
|
-
entry.noUserVisibleContact = true;
|
|
97
|
-
}
|
|
98
|
-
return { eventId: envelope.eventId };
|
|
99
|
-
}
|
|
100
|
-
recordSourceCoverage(payload) {
|
|
101
|
-
const seq = this.bumpSequence();
|
|
102
|
-
const envelope = buildAuditEnvelope({
|
|
103
|
-
family: "source_coverage",
|
|
104
|
-
plane: "source_coverage",
|
|
105
|
-
traceId: payload.traceId,
|
|
106
|
-
sequence: seq,
|
|
107
|
-
payload,
|
|
108
|
-
previousHash: this.store.lastRecordHash(),
|
|
109
|
-
eventId: payload.auditId,
|
|
110
|
-
createdAt: payload.createdAt,
|
|
111
|
-
});
|
|
112
|
-
this.store.append(envelope);
|
|
113
|
-
if (payload.decisionId) {
|
|
114
|
-
this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
115
|
-
}
|
|
116
|
-
return { eventId: envelope.eventId };
|
|
117
|
-
}
|
|
118
|
-
recordGuidanceGrounding(payload) {
|
|
119
|
-
const seq = this.bumpSequence();
|
|
120
|
-
const envelope = buildAuditEnvelope({
|
|
121
|
-
family: "guidance.grounding",
|
|
122
|
-
plane: "source_coverage",
|
|
123
|
-
traceId: payload.traceId,
|
|
124
|
-
sequence: seq,
|
|
125
|
-
payload,
|
|
126
|
-
previousHash: this.store.lastRecordHash(),
|
|
127
|
-
eventId: payload.auditId,
|
|
128
|
-
createdAt: payload.createdAt,
|
|
129
|
-
});
|
|
130
|
-
this.store.append(envelope);
|
|
131
|
-
if (payload.decisionId) {
|
|
132
|
-
this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
133
|
-
}
|
|
134
|
-
return { eventId: envelope.eventId };
|
|
135
|
-
}
|
|
136
|
-
explainLinkageForDecision(decisionId) {
|
|
137
|
-
const entry = this.explainIndex.get(decisionId);
|
|
138
|
-
const warnings = [];
|
|
139
|
-
if (!entry) {
|
|
140
|
-
return {
|
|
141
|
-
decisionId,
|
|
142
|
-
summary: "no_audit_events_indexed_for_decision",
|
|
143
|
-
warnings: ["no_indexed_events"],
|
|
144
|
-
relatedEventIds: [],
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
if (entry.noUserVisibleContact) {
|
|
148
|
-
warnings.push("no_user_visible_contact_claim_prohibited");
|
|
149
|
-
}
|
|
150
|
-
const lastDelivery = entry.deliveryStatuses[entry.deliveryStatuses.length - 1];
|
|
151
|
-
return {
|
|
152
|
-
decisionId,
|
|
153
|
-
summary: `indexed_events=${entry.eventIds.length};delivery=${lastDelivery ?? "unknown"}`,
|
|
154
|
-
warnings,
|
|
155
|
-
deliveryStatus: lastDelivery,
|
|
156
|
-
relatedEventIds: [...entry.eventIds],
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
export function createLivedExperienceAuditRecorder(store) {
|
|
161
|
-
return new LivedExperienceAuditRecorder(store ?? new AppendOnlyAuditStore());
|
|
162
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Decision trace, delivery audit, source coverage, guidance grounding + explain index (T5.2.1).
|
|
3
|
+
*
|
|
4
|
+
* Core logic: append-only envelopes with hash chain; explain index links decisionId to events and
|
|
5
|
+
* flags when delivery audit indicates no user-visible contact (target_none / not_sent_fallback).
|
|
6
|
+
* Test coverage: tests/unit/observability/lived-experience-audit.test.ts
|
|
7
|
+
*/
|
|
8
|
+
import * as crypto from "node:crypto";
|
|
9
|
+
import { AppendOnlyAuditStore } from "../audit/append-only-audit-store.js";
|
|
10
|
+
import { buildAuditEnvelope } from "../audit/audit-envelope.js";
|
|
11
|
+
function validateDecisionTrace(t) {
|
|
12
|
+
if (!t.decisionId?.trim())
|
|
13
|
+
throw new Error("decision_trace_requires_decision_id");
|
|
14
|
+
if (!t.traceId?.trim())
|
|
15
|
+
throw new Error("decision_trace_requires_trace_id");
|
|
16
|
+
if (!t.outcome)
|
|
17
|
+
throw new Error("decision_trace_requires_outcome");
|
|
18
|
+
}
|
|
19
|
+
function validateDeliveryAudit(a) {
|
|
20
|
+
if (!a.auditId?.trim())
|
|
21
|
+
throw new Error("delivery_audit_requires_audit_id");
|
|
22
|
+
if (!a.decisionId?.trim())
|
|
23
|
+
throw new Error("delivery_audit_requires_decision_id");
|
|
24
|
+
if (a.status === "sent") {
|
|
25
|
+
const ok = Boolean(a.messageId?.trim()) || Boolean(a.hostProofRef);
|
|
26
|
+
if (!ok)
|
|
27
|
+
throw new Error("delivery_audit_sent_requires_message_id_or_host_proof_ref");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class LivedExperienceAuditRecorder {
|
|
31
|
+
store;
|
|
32
|
+
seq = 0;
|
|
33
|
+
explainIndex = new Map();
|
|
34
|
+
constructor(store) {
|
|
35
|
+
this.store = store;
|
|
36
|
+
}
|
|
37
|
+
bumpSequence() {
|
|
38
|
+
this.seq += 1;
|
|
39
|
+
return this.seq;
|
|
40
|
+
}
|
|
41
|
+
touchDecision(decisionId, traceId, eventId) {
|
|
42
|
+
let e = this.explainIndex.get(decisionId);
|
|
43
|
+
if (!e) {
|
|
44
|
+
e = { traceIds: new Set(), eventIds: [], deliveryStatuses: [], fallbackRefs: [], noUserVisibleContact: false };
|
|
45
|
+
this.explainIndex.set(decisionId, e);
|
|
46
|
+
}
|
|
47
|
+
e.traceIds.add(traceId);
|
|
48
|
+
e.eventIds.push(eventId);
|
|
49
|
+
return e;
|
|
50
|
+
}
|
|
51
|
+
recordDecisionTrace(payload) {
|
|
52
|
+
validateDecisionTrace(payload);
|
|
53
|
+
const seq = this.bumpSequence();
|
|
54
|
+
const envelope = buildAuditEnvelope({
|
|
55
|
+
family: "heartbeat.decision",
|
|
56
|
+
plane: "decision",
|
|
57
|
+
traceId: payload.traceId,
|
|
58
|
+
sequence: seq,
|
|
59
|
+
payload,
|
|
60
|
+
previousHash: this.store.lastRecordHash(),
|
|
61
|
+
eventId: crypto.randomUUID(),
|
|
62
|
+
createdAt: payload.createdAt,
|
|
63
|
+
});
|
|
64
|
+
this.store.append(envelope);
|
|
65
|
+
const entry = this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
66
|
+
if (payload.outcome === "heartbeat_ok" &&
|
|
67
|
+
payload.reasonCodes.some((c) => c.includes("target_none") || c === "target_none")) {
|
|
68
|
+
entry.noUserVisibleContact = true;
|
|
69
|
+
}
|
|
70
|
+
return { eventId: envelope.eventId };
|
|
71
|
+
}
|
|
72
|
+
recordDeliveryAudit(payload) {
|
|
73
|
+
validateDeliveryAudit(payload);
|
|
74
|
+
const seq = this.bumpSequence();
|
|
75
|
+
const envelope = buildAuditEnvelope({
|
|
76
|
+
family: "delivery",
|
|
77
|
+
plane: "delivery",
|
|
78
|
+
traceId: payload.traceId,
|
|
79
|
+
sequence: seq,
|
|
80
|
+
payload,
|
|
81
|
+
previousHash: this.store.lastRecordHash(),
|
|
82
|
+
eventId: payload.auditId,
|
|
83
|
+
createdAt: payload.createdAt,
|
|
84
|
+
});
|
|
85
|
+
this.store.append(envelope);
|
|
86
|
+
const entry = this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
87
|
+
entry.deliveryStatuses.push(payload.status);
|
|
88
|
+
if (payload.fallbackRef)
|
|
89
|
+
entry.fallbackRefs.push(payload.fallbackRef);
|
|
90
|
+
if (payload.status === "target_none" ||
|
|
91
|
+
payload.status === "not_sent_fallback" ||
|
|
92
|
+
payload.status === "channel_missing" ||
|
|
93
|
+
payload.status === "host_unsupported" ||
|
|
94
|
+
payload.status === "failed" ||
|
|
95
|
+
payload.status === "ack_dropped") {
|
|
96
|
+
entry.noUserVisibleContact = true;
|
|
97
|
+
}
|
|
98
|
+
return { eventId: envelope.eventId };
|
|
99
|
+
}
|
|
100
|
+
recordSourceCoverage(payload) {
|
|
101
|
+
const seq = this.bumpSequence();
|
|
102
|
+
const envelope = buildAuditEnvelope({
|
|
103
|
+
family: "source_coverage",
|
|
104
|
+
plane: "source_coverage",
|
|
105
|
+
traceId: payload.traceId,
|
|
106
|
+
sequence: seq,
|
|
107
|
+
payload,
|
|
108
|
+
previousHash: this.store.lastRecordHash(),
|
|
109
|
+
eventId: payload.auditId,
|
|
110
|
+
createdAt: payload.createdAt,
|
|
111
|
+
});
|
|
112
|
+
this.store.append(envelope);
|
|
113
|
+
if (payload.decisionId) {
|
|
114
|
+
this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
115
|
+
}
|
|
116
|
+
return { eventId: envelope.eventId };
|
|
117
|
+
}
|
|
118
|
+
recordGuidanceGrounding(payload) {
|
|
119
|
+
const seq = this.bumpSequence();
|
|
120
|
+
const envelope = buildAuditEnvelope({
|
|
121
|
+
family: "guidance.grounding",
|
|
122
|
+
plane: "source_coverage",
|
|
123
|
+
traceId: payload.traceId,
|
|
124
|
+
sequence: seq,
|
|
125
|
+
payload,
|
|
126
|
+
previousHash: this.store.lastRecordHash(),
|
|
127
|
+
eventId: payload.auditId,
|
|
128
|
+
createdAt: payload.createdAt,
|
|
129
|
+
});
|
|
130
|
+
this.store.append(envelope);
|
|
131
|
+
if (payload.decisionId) {
|
|
132
|
+
this.touchDecision(payload.decisionId, payload.traceId, envelope.eventId);
|
|
133
|
+
}
|
|
134
|
+
return { eventId: envelope.eventId };
|
|
135
|
+
}
|
|
136
|
+
explainLinkageForDecision(decisionId) {
|
|
137
|
+
const entry = this.explainIndex.get(decisionId);
|
|
138
|
+
const warnings = [];
|
|
139
|
+
if (!entry) {
|
|
140
|
+
return {
|
|
141
|
+
decisionId,
|
|
142
|
+
summary: "no_audit_events_indexed_for_decision",
|
|
143
|
+
warnings: ["no_indexed_events"],
|
|
144
|
+
relatedEventIds: [],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (entry.noUserVisibleContact) {
|
|
148
|
+
warnings.push("no_user_visible_contact_claim_prohibited");
|
|
149
|
+
}
|
|
150
|
+
const lastDelivery = entry.deliveryStatuses[entry.deliveryStatuses.length - 1];
|
|
151
|
+
return {
|
|
152
|
+
decisionId,
|
|
153
|
+
summary: `indexed_events=${entry.eventIds.length};delivery=${lastDelivery ?? "unknown"}`,
|
|
154
|
+
warnings,
|
|
155
|
+
deliveryStatus: lastDelivery,
|
|
156
|
+
relatedEventIds: [...entry.eventIds],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
export function createLivedExperienceAuditRecorder(store) {
|
|
161
|
+
return new LivedExperienceAuditRecorder(store ?? new AppendOnlyAuditStore());
|
|
162
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ObservabilityDatabase } from "../db/index.js";
|
|
2
|
+
import { DecisionLedger, type HeartbeatDecisionEvent } from "./decision-ledger.js";
|
|
3
|
+
import { ExecutionTelemetry } from "./execution-telemetry.js";
|
|
4
|
+
import type { HeartbeatCycleResult, HeartbeatSignal } from "../../core/second-nature/heartbeat/signal.js";
|
|
5
|
+
export declare const RUNTIME_DECISION_TRACE_PREFIX = "sn-runtime-";
|
|
6
|
+
export declare const RUNTIME_INTERNAL_PLATFORM_ID = "second-nature-runtime";
|
|
7
|
+
export interface RecordHeartbeatCycleInput {
|
|
8
|
+
cycle: HeartbeatCycleResult;
|
|
9
|
+
signal: HeartbeatSignal;
|
|
10
|
+
/**
|
|
11
|
+
* Override rhythm `mode` written to the ledger row. When omitted, falls back
|
|
12
|
+
* to `"active"`; downstream loadStatus only treats `quiet` /
|
|
13
|
+
* `maintenance_only` / `paused_for_interrupt` as Quiet-aware values.
|
|
14
|
+
*/
|
|
15
|
+
rhythmMode?: HeartbeatDecisionEvent["mode"];
|
|
16
|
+
}
|
|
17
|
+
export interface RecordHeartbeatCycleOutput {
|
|
18
|
+
traceId: string;
|
|
19
|
+
decisionId: string;
|
|
20
|
+
attemptId: string;
|
|
21
|
+
}
|
|
22
|
+
export interface RuntimeDecisionRecorder {
|
|
23
|
+
recordHeartbeatCycle(input: RecordHeartbeatCycleInput): Promise<RecordHeartbeatCycleOutput>;
|
|
24
|
+
}
|
|
25
|
+
export interface CreateRuntimeDecisionRecorderDeps {
|
|
26
|
+
ledger?: DecisionLedger;
|
|
27
|
+
telemetry?: ExecutionTelemetry;
|
|
28
|
+
}
|
|
29
|
+
export declare function createRuntimeDecisionRecorder(observabilityDb: ObservabilityDatabase, overrides?: CreateRuntimeDecisionRecorderDeps): RuntimeDecisionRecorder;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Decision Recorder (T1.2.3).
|
|
3
|
+
*
|
|
4
|
+
* Core logic: after a workspace `runHeartbeatCycle` completes, persist two rows that
|
|
5
|
+
* `loadStatus` already filters on, so operator status stops returning `unknown` for
|
|
6
|
+
* `rhythm.mode` / `runtime.serviceStatus` once the runtime has executed at least once.
|
|
7
|
+
* - `decision_ledger` row via `DecisionLedger.recordHeartbeatDecision()` with
|
|
8
|
+
* `traceId` prefix `sn-runtime-` (matches `INTERNAL_RUNTIME_TRACE_PREFIX`).
|
|
9
|
+
* - `execution_attempts` row via `ExecutionTelemetry.startAttempt` +
|
|
10
|
+
* `completeAttempt` with `platformId === "second-nature-runtime"` (matches
|
|
11
|
+
* `INTERNAL_RUNTIME_PLATFORM_ID`).
|
|
12
|
+
*
|
|
13
|
+
* Boundaries:
|
|
14
|
+
* - Recorder failure must NOT break the heartbeat surface response — caller wraps with try/catch.
|
|
15
|
+
* - Carrier-only / probe-only / runtime-unavailable paths do NOT invoke this recorder
|
|
16
|
+
* (their semantics intentionally remain "unknown" until a full-runtime turn happens).
|
|
17
|
+
* - This is a derived observability writer; it is not the canonical decision producer
|
|
18
|
+
* (control-plane keeps that contract). It exists to close the read-side aggregation gap.
|
|
19
|
+
*/
|
|
20
|
+
import { randomUUID } from "node:crypto";
|
|
21
|
+
import { DecisionLedger } from "./decision-ledger.js";
|
|
22
|
+
import { ExecutionTelemetry } from "./execution-telemetry.js";
|
|
23
|
+
export const RUNTIME_DECISION_TRACE_PREFIX = "sn-runtime-";
|
|
24
|
+
export const RUNTIME_INTERNAL_PLATFORM_ID = "second-nature-runtime";
|
|
25
|
+
const RUNTIME_INTERNAL_CAPABILITY = "runtime.heartbeat";
|
|
26
|
+
const RUNTIME_INTERNAL_CHANNEL = "internal";
|
|
27
|
+
export function createRuntimeDecisionRecorder(observabilityDb, overrides = {}) {
|
|
28
|
+
const ledger = overrides.ledger ?? new DecisionLedger(observabilityDb);
|
|
29
|
+
const telemetry = overrides.telemetry ?? new ExecutionTelemetry(observabilityDb);
|
|
30
|
+
return {
|
|
31
|
+
async recordHeartbeatCycle({ cycle, signal, rhythmMode }) {
|
|
32
|
+
const timestamp = typeof signal.payload.timestamp === "string" && signal.payload.timestamp.trim().length > 0
|
|
33
|
+
? signal.payload.timestamp
|
|
34
|
+
: new Date().toISOString();
|
|
35
|
+
const uniqueId = randomUUID();
|
|
36
|
+
const traceId = `${RUNTIME_DECISION_TRACE_PREFIX}${cycle.scope}-${cycle.status}-${uniqueId}`;
|
|
37
|
+
const decisionId = `decision-runtime-${uniqueId}`;
|
|
38
|
+
const tickId = `tick-runtime-${uniqueId}`;
|
|
39
|
+
const event = {
|
|
40
|
+
id: decisionId,
|
|
41
|
+
tickId,
|
|
42
|
+
traceId,
|
|
43
|
+
runtimeScope: cycle.scope,
|
|
44
|
+
triggerSource: signal.trigger,
|
|
45
|
+
decisionStatus: mapCycleStatus(cycle.status),
|
|
46
|
+
reasons: cycle.reasons,
|
|
47
|
+
intentId: cycle.selectedIntentId,
|
|
48
|
+
mode: rhythmMode ?? "active",
|
|
49
|
+
createdAt: timestamp,
|
|
50
|
+
};
|
|
51
|
+
await ledger.recordHeartbeatDecision(event);
|
|
52
|
+
const attemptId = await telemetry.startAttempt({
|
|
53
|
+
traceId,
|
|
54
|
+
decisionId,
|
|
55
|
+
intentId: cycle.selectedIntentId ?? `${RUNTIME_INTERNAL_PLATFORM_ID}-tick`,
|
|
56
|
+
platformId: RUNTIME_INTERNAL_PLATFORM_ID,
|
|
57
|
+
capability: RUNTIME_INTERNAL_CAPABILITY,
|
|
58
|
+
channel: RUNTIME_INTERNAL_CHANNEL,
|
|
59
|
+
startedAt: timestamp,
|
|
60
|
+
});
|
|
61
|
+
const status = isFailureCycle(cycle.status) ? "failed" : "succeeded";
|
|
62
|
+
const failureClass = status === "failed" ? cycleStatusFailureClass(cycle.status) : undefined;
|
|
63
|
+
await telemetry.completeAttempt(traceId, status, undefined, failureClass);
|
|
64
|
+
return { traceId, decisionId, attemptId };
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function mapCycleStatus(status) {
|
|
69
|
+
switch (status) {
|
|
70
|
+
case "intent_selected":
|
|
71
|
+
return "intent_selected";
|
|
72
|
+
case "denied":
|
|
73
|
+
return "denied";
|
|
74
|
+
case "deferred":
|
|
75
|
+
return "deferred";
|
|
76
|
+
case "delivery_unavailable":
|
|
77
|
+
return "delivery_unavailable";
|
|
78
|
+
case "runtime_carrier_only":
|
|
79
|
+
return "runtime_carrier_only";
|
|
80
|
+
case "heartbeat_ok":
|
|
81
|
+
default:
|
|
82
|
+
return "heartbeat_ok";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function isFailureCycle(status) {
|
|
86
|
+
return status === "delivery_unavailable" || status === "denied";
|
|
87
|
+
}
|
|
88
|
+
function cycleStatusFailureClass(status) {
|
|
89
|
+
if (status === "delivery_unavailable")
|
|
90
|
+
return "delivery_unavailable";
|
|
91
|
+
if (status === "denied")
|
|
92
|
+
return "decision_denied";
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export interface NativeSqliteProbeResult {
|
|
2
|
-
moduleLoadOk: boolean;
|
|
3
|
-
/** package version when load succeeds */
|
|
4
|
-
version?: string;
|
|
5
|
-
errorMessage?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function probeNativeSqliteLoad(): NativeSqliteProbeResult;
|
|
1
|
+
export interface NativeSqliteProbeResult {
|
|
2
|
+
moduleLoadOk: boolean;
|
|
3
|
+
/** package version when load succeeds */
|
|
4
|
+
version?: string;
|
|
5
|
+
errorMessage?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function probeNativeSqliteLoad(): NativeSqliteProbeResult;
|