@haaaiawd/second-nature 0.1.18 → 0.1.19
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 -855
- 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 +65 -58
- package/runtime/cli/ops/heartbeat-surface.d.ts +45 -38
- package/runtime/cli/ops/heartbeat-surface.js +79 -73
- package/runtime/cli/ops/ops-router.d.ts +26 -19
- package/runtime/cli/ops/ops-router.js +102 -89
- 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 +40 -19
- package/runtime/cli/ops/workspace-heartbeat-runner.js +93 -39
- package/runtime/cli/read-models/index.d.ts +35 -29
- package/runtime/cli/read-models/index.js +365 -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 +112 -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 +162 -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 +47 -47
- 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 -20
- package/runtime/observability/index.js +19 -19
- 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 -29
- package/runtime/observability/services/runtime-decision-recorder.js +94 -94
- 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 +61 -61
- 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 -81
|
@@ -1,256 +1,365 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return { kind: "
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
case "
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
};
|
|
218
|
-
},
|
|
219
|
-
async
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { desc } from "drizzle-orm";
|
|
4
|
+
import { createQuietInputLoader } from "../../storage/services/quiet-input-loader.js";
|
|
5
|
+
import { AssetRepository } from "../../storage/repositories/asset-repository.js";
|
|
6
|
+
import { CredentialRepository } from "../../storage/repositories/credential-repository.js";
|
|
7
|
+
import { EvidenceQueryEngine } from "../../observability/query/evidence-query-engine.js";
|
|
8
|
+
import { decisionLedger, executionAttempts, } from "../../observability/db/schema/index.js";
|
|
9
|
+
import { AppendOnlyAuditStore } from "../../observability/audit/append-only-audit-store.js";
|
|
10
|
+
import { queryExplain, } from "../../observability/query/explain-query.js";
|
|
11
|
+
import { mapOperatorExplainToReadModel } from "./operator-explain-map.js";
|
|
12
|
+
import { loadOperatorFallbackRow, toOperatorFallbackView, } from "../../storage/fallback/load-operator-fallback.js";
|
|
13
|
+
const INTERNAL_RUNTIME_PLATFORM_ID = "second-nature-runtime";
|
|
14
|
+
const INTERNAL_RUNTIME_TRACE_PREFIX = "sn-runtime-";
|
|
15
|
+
function toExplainQuery(subject) {
|
|
16
|
+
switch (subject.kind) {
|
|
17
|
+
case "decision":
|
|
18
|
+
return { kind: "decision", decisionId: subject.id };
|
|
19
|
+
case "fallback": {
|
|
20
|
+
const ref = subject.id.startsWith("fallback:")
|
|
21
|
+
? subject.id
|
|
22
|
+
: `fallback:${subject.id}`;
|
|
23
|
+
return { kind: "fallback", fallbackRef: ref };
|
|
24
|
+
}
|
|
25
|
+
case "probe":
|
|
26
|
+
case "report":
|
|
27
|
+
return { kind: "report", reportId: subject.id };
|
|
28
|
+
case "delivery":
|
|
29
|
+
return { kind: "delivery", auditId: subject.id };
|
|
30
|
+
case "source_ref":
|
|
31
|
+
return { kind: "source_ref", sourceRefId: subject.id };
|
|
32
|
+
default:
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function isAuditOnlySubjectKind(kind) {
|
|
37
|
+
return (kind === "fallback" ||
|
|
38
|
+
kind === "probe" ||
|
|
39
|
+
kind === "report" ||
|
|
40
|
+
kind === "delivery" ||
|
|
41
|
+
kind === "source_ref");
|
|
42
|
+
}
|
|
43
|
+
function buildCredentialNextStep(status) {
|
|
44
|
+
if (status === "pending_verification")
|
|
45
|
+
return "submit_verification_answer";
|
|
46
|
+
if (status === "expired" || status === "revoked" || status === "failed")
|
|
47
|
+
return "refresh_credential_context";
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* T1.2.4: count persisted Quiet artifact JSON files under `.second-nature/quiet/{day}/`
|
|
52
|
+
* so `loadQuiet` / `loadDailyReport` can reflect Quiet artifacts in the read model.
|
|
53
|
+
*/
|
|
54
|
+
function countQuietArtifactsForDay(workspaceRoot, day) {
|
|
55
|
+
try {
|
|
56
|
+
const dir = path.join(workspaceRoot, ".second-nature", "quiet", day);
|
|
57
|
+
if (!fs.existsSync(dir))
|
|
58
|
+
return 0;
|
|
59
|
+
return fs.readdirSync(dir).filter((f) => f.endsWith(".json")).length;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* T1.2.4: scan the last N days under `.second-nature/quiet/` and count total JSON artifacts.
|
|
67
|
+
* Returns { totalArtifacts, recentDays } for merging into QuietReadModel.
|
|
68
|
+
*/
|
|
69
|
+
function countRecentQuietArtifacts(workspaceRoot, windowDays = 2) {
|
|
70
|
+
try {
|
|
71
|
+
const quietRoot = path.join(workspaceRoot, ".second-nature", "quiet");
|
|
72
|
+
if (!fs.existsSync(quietRoot))
|
|
73
|
+
return { totalArtifacts: 0, recentDays: [] };
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
const recentDays = [];
|
|
76
|
+
let total = 0;
|
|
77
|
+
for (let i = 0; i < windowDays; i++) {
|
|
78
|
+
const d = new Date(now - i * 86400000).toISOString().slice(0, 10);
|
|
79
|
+
const count = countQuietArtifactsForDay(workspaceRoot, d);
|
|
80
|
+
if (count > 0) {
|
|
81
|
+
recentDays.push(d);
|
|
82
|
+
total += count;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { totalArtifacts: total, recentDays };
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return { totalArtifacts: 0, recentDays: [] };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function mapRuntimeStatus(attempt) {
|
|
92
|
+
if (!attempt) {
|
|
93
|
+
return "unknown";
|
|
94
|
+
}
|
|
95
|
+
if (attempt.failureClass || attempt.status === "failed") {
|
|
96
|
+
return "degraded";
|
|
97
|
+
}
|
|
98
|
+
return "running";
|
|
99
|
+
}
|
|
100
|
+
function mapConnectorStatus(attempt) {
|
|
101
|
+
if (!attempt) {
|
|
102
|
+
return "unknown";
|
|
103
|
+
}
|
|
104
|
+
if (attempt.failureClass || attempt.status === "failed") {
|
|
105
|
+
return "degraded";
|
|
106
|
+
}
|
|
107
|
+
return "healthy";
|
|
108
|
+
}
|
|
109
|
+
export function createCliReadModels(deps) {
|
|
110
|
+
const assetRepository = new AssetRepository(deps.stateDb);
|
|
111
|
+
const credentialRepository = new CredentialRepository(deps.stateDb);
|
|
112
|
+
const quietLoader = createQuietInputLoader(assetRepository);
|
|
113
|
+
const evidenceQuery = new EvidenceQueryEngine(deps.observabilityDb);
|
|
114
|
+
// T1.2.5 (CH-14-05): default-inject an empty AppendOnlyAuditStore so `explain` does not
|
|
115
|
+
// immediately return `lived_experience_audit_store_unavailable` for callers that don't supply
|
|
116
|
+
// an explicit store. The empty store means audit-only subjects return `no_matching_audit_events`
|
|
117
|
+
// instead of a configuration error — which is more accurate and less alarming to operators.
|
|
118
|
+
const auditStore = deps.livedExperienceAuditStore ?? new AppendOnlyAuditStore();
|
|
119
|
+
return {
|
|
120
|
+
async loadStatus(_scope) {
|
|
121
|
+
let recentAttempts = [];
|
|
122
|
+
let recentDecisions = [];
|
|
123
|
+
let credentials = [];
|
|
124
|
+
try {
|
|
125
|
+
recentAttempts = await deps.observabilityDb.db
|
|
126
|
+
.select()
|
|
127
|
+
.from(executionAttempts)
|
|
128
|
+
.orderBy(desc(executionAttempts.startedAt), desc(executionAttempts.finishedAt))
|
|
129
|
+
.limit(50);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
recentAttempts = [];
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
recentDecisions = await deps.observabilityDb.db
|
|
136
|
+
.select()
|
|
137
|
+
.from(decisionLedger)
|
|
138
|
+
.orderBy(desc(decisionLedger.createdAt))
|
|
139
|
+
.limit(50);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
recentDecisions = [];
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
credentials = await deps.stateDb.db.query.credentialRecords.findMany();
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
credentials = [];
|
|
149
|
+
}
|
|
150
|
+
const latestRuntimeAttempt = recentAttempts.find((attempt) => attempt.platformId === INTERNAL_RUNTIME_PLATFORM_ID);
|
|
151
|
+
// CH-15-04 (CH-14-03): latestConnectorAttempt is the most recent execution attempt whose
|
|
152
|
+
// platformId is NOT the internal sn-runtime sentinel — i.e. a real connector platform
|
|
153
|
+
// (Moltbook, EvoMap, etc.). The `connectors` array in StatusReadModel reflects this single
|
|
154
|
+
// most-recent non-runtime attempt, NOT the full connector manifest. An empty array means
|
|
155
|
+
// no connector attempt has been recorded yet, not that connectors are misconfigured.
|
|
156
|
+
const latestConnectorAttempt = recentAttempts.find((attempt) => attempt.platformId !== INTERNAL_RUNTIME_PLATFORM_ID);
|
|
157
|
+
const latestRuntimeDecision = recentDecisions.find((decision) => decision.traceId.startsWith(INTERNAL_RUNTIME_TRACE_PREFIX));
|
|
158
|
+
const runtimeUpdatedAt = latestRuntimeAttempt?.finishedAt ??
|
|
159
|
+
latestRuntimeAttempt?.startedAt ??
|
|
160
|
+
latestRuntimeDecision?.createdAt ??
|
|
161
|
+
"";
|
|
162
|
+
const quietMode = latestRuntimeDecision?.mode === "quiet" ||
|
|
163
|
+
latestRuntimeDecision?.mode === "maintenance_only" ||
|
|
164
|
+
latestRuntimeDecision?.mode === "paused_for_interrupt"
|
|
165
|
+
? latestRuntimeDecision.mode
|
|
166
|
+
: "unknown";
|
|
167
|
+
const riskFlags = [
|
|
168
|
+
latestRuntimeAttempt?.failureClass,
|
|
169
|
+
latestConnectorAttempt?.failureClass,
|
|
170
|
+
].filter((value) => Boolean(value));
|
|
171
|
+
const connectorSummary = latestConnectorAttempt
|
|
172
|
+
? [
|
|
173
|
+
{
|
|
174
|
+
platformId: latestConnectorAttempt.platformId,
|
|
175
|
+
status: mapConnectorStatus(latestConnectorAttempt),
|
|
176
|
+
channel: latestConnectorAttempt.channel,
|
|
177
|
+
failureClass: latestConnectorAttempt.failureClass ?? undefined,
|
|
178
|
+
},
|
|
179
|
+
]
|
|
180
|
+
: [];
|
|
181
|
+
return {
|
|
182
|
+
runtime: {
|
|
183
|
+
host: "openclaw-plugin",
|
|
184
|
+
serviceStatus: mapRuntimeStatus(latestRuntimeAttempt),
|
|
185
|
+
updatedAt: runtimeUpdatedAt,
|
|
186
|
+
},
|
|
187
|
+
rhythm: {
|
|
188
|
+
mode: latestRuntimeDecision?.mode ?? "unknown",
|
|
189
|
+
windowId: undefined,
|
|
190
|
+
},
|
|
191
|
+
quiet: {
|
|
192
|
+
mode: quietMode,
|
|
193
|
+
lastEvent: latestRuntimeDecision?.traceId,
|
|
194
|
+
interrupted: latestRuntimeDecision?.mode === "paused_for_interrupt"
|
|
195
|
+
? true
|
|
196
|
+
: undefined,
|
|
197
|
+
},
|
|
198
|
+
connectors: connectorSummary,
|
|
199
|
+
credentials: credentials.map((item) => ({
|
|
200
|
+
platformId: item.platformId ??
|
|
201
|
+
item.platform_id,
|
|
202
|
+
status: item.status,
|
|
203
|
+
nextStep: buildCredentialNextStep(item.status),
|
|
204
|
+
})),
|
|
205
|
+
risk: {
|
|
206
|
+
level: riskFlags.length > 0 ? "medium" : "low",
|
|
207
|
+
flags: riskFlags,
|
|
208
|
+
},
|
|
209
|
+
// T1.2.5 (CH-14-04): default delivery posture is workspace_default_none because the
|
|
210
|
+
// workspace heartbeat hardcodes `deliveryCapability: { target: "none" }` until a host
|
|
211
|
+
// capability probe explicitly sets a valid target.
|
|
212
|
+
deliveryPosture: {
|
|
213
|
+
verdict: "none",
|
|
214
|
+
source: "workspace_default_none",
|
|
215
|
+
reasonCode: "delivery_target_none",
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
async loadDailyReport(day) {
|
|
220
|
+
let bundle;
|
|
221
|
+
try {
|
|
222
|
+
bundle = await quietLoader.loadQuietInputs({
|
|
223
|
+
dateRange: {
|
|
224
|
+
start: `${day}T00:00:00.000Z`,
|
|
225
|
+
end: `${day}T23:59:59.999Z`,
|
|
226
|
+
},
|
|
227
|
+
assetFilters: {
|
|
228
|
+
includeJournal: false,
|
|
229
|
+
includeReports: true,
|
|
230
|
+
includeCurated: false,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
|
|
236
|
+
}
|
|
237
|
+
// T1.2.4: merge persisted Quiet artifact JSON files from `.second-nature/quiet/{day}/`
|
|
238
|
+
// into the daily report sourceRefs so the read model reflects artifacts written by
|
|
239
|
+
// `persistQuietArtifactToWorkspace` (closes the canonical read/write gap for loadDailyReport).
|
|
240
|
+
const fsArtifactCount = deps.workspaceRoot
|
|
241
|
+
? countQuietArtifactsForDay(deps.workspaceRoot, day)
|
|
242
|
+
: 0;
|
|
243
|
+
const report = bundle.dailyReports[0];
|
|
244
|
+
const existingSources = report?.sources ?? [];
|
|
245
|
+
// Append synthetic source refs for each FS artifact not already in the list.
|
|
246
|
+
const fsSourceRefs = Array.from({ length: fsArtifactCount }, (_, i) => `quiet_artifact:${day}:${i}`).filter((ref) => !existingSources.includes(ref));
|
|
247
|
+
return {
|
|
248
|
+
day,
|
|
249
|
+
summary: report?.summary ?? "",
|
|
250
|
+
highlights: report?.highlights ?? [],
|
|
251
|
+
sourceRefs: [...existingSources, ...fsSourceRefs],
|
|
252
|
+
};
|
|
253
|
+
},
|
|
254
|
+
async loadQuiet(scope) {
|
|
255
|
+
const now = new Date();
|
|
256
|
+
const start = new Date(now);
|
|
257
|
+
start.setDate(now.getDate() - 1);
|
|
258
|
+
let bundle;
|
|
259
|
+
try {
|
|
260
|
+
bundle = await quietLoader.loadQuietInputs({
|
|
261
|
+
dateRange: { start: start.toISOString(), end: now.toISOString() },
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
|
|
266
|
+
}
|
|
267
|
+
// T1.2.4 (CH-14-07): also count persisted Quiet artifact JSON files under
|
|
268
|
+
// `.second-nature/quiet/` so that once `runSourceBackedQuiet` has written
|
|
269
|
+
// artifacts to disk, the read model is non-zero even if the legacy memory/
|
|
270
|
+
// journal path is empty.
|
|
271
|
+
const quietArtifacts = deps.workspaceRoot
|
|
272
|
+
? countRecentQuietArtifacts(deps.workspaceRoot, 2)
|
|
273
|
+
: { totalArtifacts: 0, recentDays: [] };
|
|
274
|
+
const totalSourceCount = bundle.sourceCount + quietArtifacts.totalArtifacts;
|
|
275
|
+
const totalReportCount = bundle.dailyReports.length + quietArtifacts.totalArtifacts;
|
|
276
|
+
return {
|
|
277
|
+
scope,
|
|
278
|
+
mode: totalSourceCount > 0 ? "quiet" : "unknown",
|
|
279
|
+
sourceCount: totalSourceCount,
|
|
280
|
+
reportCount: totalReportCount,
|
|
281
|
+
recentJournalCount: bundle.journalEntries.length,
|
|
282
|
+
};
|
|
283
|
+
},
|
|
284
|
+
async loadSession(sessionId) {
|
|
285
|
+
const traceId = sessionId;
|
|
286
|
+
const bundle = await evidenceQuery.queryEvidence({ traceId });
|
|
287
|
+
return {
|
|
288
|
+
requestedSessionId: sessionId,
|
|
289
|
+
traceId,
|
|
290
|
+
decisionCount: bundle.decisions.length,
|
|
291
|
+
attemptCount: bundle.attempts.length,
|
|
292
|
+
governanceCount: bundle.governance.length,
|
|
293
|
+
keyFactors: bundle.explanation.keyFactors,
|
|
294
|
+
evidenceRefs: bundle.explanation.evidenceRefs,
|
|
295
|
+
};
|
|
296
|
+
},
|
|
297
|
+
async loadCredential(platformId) {
|
|
298
|
+
let record;
|
|
299
|
+
try {
|
|
300
|
+
record = await credentialRepository.findByPlatformId(platformId);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
record = undefined;
|
|
304
|
+
}
|
|
305
|
+
if (!record) {
|
|
306
|
+
return {
|
|
307
|
+
platformId,
|
|
308
|
+
status: "missing",
|
|
309
|
+
nextStep: "provide_credential_context",
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
return {
|
|
313
|
+
platformId: record.platformId ??
|
|
314
|
+
record.platform_id,
|
|
315
|
+
status: record.status,
|
|
316
|
+
verificationDeadline: record.expiresAt ?? undefined,
|
|
317
|
+
attemptsRemaining: record.attemptsRemaining ?? undefined,
|
|
318
|
+
nextStep: buildCredentialNextStep(record.status),
|
|
319
|
+
};
|
|
320
|
+
},
|
|
321
|
+
async loadFallbackView(ref) {
|
|
322
|
+
const row = await loadOperatorFallbackRow(deps.stateDb, ref);
|
|
323
|
+
if (!row)
|
|
324
|
+
return null;
|
|
325
|
+
return toOperatorFallbackView(row);
|
|
326
|
+
},
|
|
327
|
+
async explain(subject) {
|
|
328
|
+
const q = toExplainQuery(subject);
|
|
329
|
+
// T1.2.5: auditStore is always non-null (default-injected), so the explain path always
|
|
330
|
+
// has a store available. For audit-only subjects with no matching events the summary
|
|
331
|
+
// from queryExplain will be "no_matching_audit_events" — accurate and non-alarming.
|
|
332
|
+
if (auditStore && q) {
|
|
333
|
+
const op = queryExplain(q, auditStore);
|
|
334
|
+
if (isAuditOnlySubjectKind(subject.kind)) {
|
|
335
|
+
return mapOperatorExplainToReadModel(op, subject.kind);
|
|
336
|
+
}
|
|
337
|
+
if (op.relatedEventIds.length > 0) {
|
|
338
|
+
return mapOperatorExplainToReadModel(op, subject.kind);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (isAuditOnlySubjectKind(subject.kind)) {
|
|
342
|
+
return {
|
|
343
|
+
subjectType: subject.kind,
|
|
344
|
+
// auditStore is always present (default-injected by T1.2.5), so this branch is
|
|
345
|
+
// only reached when q is undefined (unresolvable subject kind).
|
|
346
|
+
conclusion: "no_matching_audit_events",
|
|
347
|
+
keyFactors: [],
|
|
348
|
+
evidenceRefs: [],
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
const query = subject.kind === "decision" ||
|
|
352
|
+
subject.kind === "platform-selection" ||
|
|
353
|
+
subject.kind === "outreach"
|
|
354
|
+
? { decisionId: subject.id }
|
|
355
|
+
: { assetId: subject.id };
|
|
356
|
+
const bundle = await evidenceQuery.queryEvidence(query);
|
|
357
|
+
return {
|
|
358
|
+
subjectType: subject.kind,
|
|
359
|
+
conclusion: bundle.explanation.conclusion,
|
|
360
|
+
keyFactors: bundle.explanation.keyFactors,
|
|
361
|
+
evidenceRefs: bundle.explanation.evidenceRefs,
|
|
362
|
+
};
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|