@haaaiawd/second-nature 0.1.17 → 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.
Files changed (188) hide show
  1. package/index.js +855 -855
  2. package/openclaw.plugin.json +29 -29
  3. package/package.json +52 -52
  4. package/runtime/cli/commands/index.d.ts +14 -14
  5. package/runtime/cli/commands/index.js +193 -193
  6. package/runtime/cli/explain/explain-surface-subject.d.ts +8 -8
  7. package/runtime/cli/explain/explain-surface-subject.js +9 -9
  8. package/runtime/cli/explain/format-explanation.d.ts +12 -12
  9. package/runtime/cli/explain/format-explanation.js +12 -12
  10. package/runtime/cli/explain/resolve-subject.js +41 -41
  11. package/runtime/cli/host-capability/classify-delivery.d.ts +14 -14
  12. package/runtime/cli/host-capability/classify-delivery.js +20 -20
  13. package/runtime/cli/host-capability/probe-host-capability.d.ts +2 -2
  14. package/runtime/cli/host-capability/probe-host-capability.js +58 -58
  15. package/runtime/cli/host-capability/record-host-capability.d.ts +6 -6
  16. package/runtime/cli/host-capability/record-host-capability.js +14 -14
  17. package/runtime/cli/host-capability/types.d.ts +71 -71
  18. package/runtime/cli/host-capability/types.js +6 -6
  19. package/runtime/cli/host-smoke/run-host-smoke.d.ts +2 -2
  20. package/runtime/cli/host-smoke/run-host-smoke.js +40 -40
  21. package/runtime/cli/host-smoke/types.d.ts +35 -35
  22. package/runtime/cli/host-smoke/types.js +6 -6
  23. package/runtime/cli/index.js +58 -54
  24. package/runtime/cli/ops/heartbeat-surface.d.ts +38 -35
  25. package/runtime/cli/ops/heartbeat-surface.js +73 -71
  26. package/runtime/cli/ops/ops-router.d.ts +19 -16
  27. package/runtime/cli/ops/ops-router.js +89 -87
  28. package/runtime/cli/ops/show-operator-fallback.d.ts +13 -13
  29. package/runtime/cli/ops/show-operator-fallback.js +22 -22
  30. package/runtime/cli/ops/workspace-heartbeat-runner.d.ts +19 -10
  31. package/runtime/cli/ops/workspace-heartbeat-runner.js +39 -26
  32. package/runtime/cli/read-models/index.d.ts +29 -29
  33. package/runtime/cli/read-models/index.js +256 -256
  34. package/runtime/cli/read-models/operator-explain-map.d.ts +6 -6
  35. package/runtime/cli/read-models/operator-explain-map.js +10 -10
  36. package/runtime/cli/read-models/types.d.ts +79 -79
  37. package/runtime/cli/runtime/runtime-artifact-boundary.d.ts +28 -28
  38. package/runtime/cli/runtime/runtime-artifact-boundary.js +94 -94
  39. package/runtime/connectors/base/contract.d.ts +87 -87
  40. package/runtime/connectors/base/execution-policy.d.ts +47 -47
  41. package/runtime/connectors/base/execution-policy.js +82 -82
  42. package/runtime/connectors/base/index.d.ts +8 -8
  43. package/runtime/connectors/base/index.js +8 -8
  44. package/runtime/connectors/base/manifest.d.ts +64 -64
  45. package/runtime/connectors/base/manifest.js +86 -86
  46. package/runtime/connectors/base/map-life-evidence.d.ts +16 -16
  47. package/runtime/connectors/base/map-life-evidence.js +79 -79
  48. package/runtime/connectors/base/policy-layer.d.ts +29 -29
  49. package/runtime/connectors/base/policy-layer.js +198 -198
  50. package/runtime/connectors/base/route-planner.js +99 -99
  51. package/runtime/connectors/index.d.ts +5 -5
  52. package/runtime/connectors/index.js +5 -5
  53. package/runtime/connectors/near-real/near-real-connector-smoke.d.ts +19 -19
  54. package/runtime/connectors/near-real/near-real-connector-smoke.js +152 -152
  55. package/runtime/core/second-nature/heartbeat/heartbeat-executor.js +114 -114
  56. package/runtime/core/second-nature/heartbeat/heartbeat-loop.d.ts +63 -63
  57. package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +139 -139
  58. package/runtime/core/second-nature/heartbeat/index.d.ts +8 -8
  59. package/runtime/core/second-nature/heartbeat/index.js +7 -7
  60. package/runtime/core/second-nature/heartbeat/run-heartbeat-cycle.d.ts +21 -21
  61. package/runtime/core/second-nature/heartbeat/run-heartbeat-cycle.js +35 -35
  62. package/runtime/core/second-nature/heartbeat/runtime-snapshot.d.ts +28 -28
  63. package/runtime/core/second-nature/heartbeat/runtime-snapshot.js +35 -35
  64. package/runtime/core/second-nature/heartbeat/signal.d.ts +42 -42
  65. package/runtime/core/second-nature/heartbeat/snapshot-builder.d.ts +51 -51
  66. package/runtime/core/second-nature/index.d.ts +22 -22
  67. package/runtime/core/second-nature/index.js +22 -22
  68. package/runtime/core/second-nature/orchestrator/effect-dispatcher.d.ts +100 -100
  69. package/runtime/core/second-nature/orchestrator/effect-dispatcher.js +144 -144
  70. package/runtime/core/second-nature/orchestrator/guard-layer.d.ts +8 -8
  71. package/runtime/core/second-nature/orchestrator/guard-layer.js +110 -110
  72. package/runtime/core/second-nature/orchestrator/intent-planner.d.ts +13 -13
  73. package/runtime/core/second-nature/orchestrator/intent-planner.js +199 -199
  74. package/runtime/core/second-nature/orchestrator/lease-manager.d.ts +14 -14
  75. package/runtime/core/second-nature/orchestrator/lease-manager.js +58 -58
  76. package/runtime/core/second-nature/outreach/build-outreach-draft-request.d.ts +6 -6
  77. package/runtime/core/second-nature/outreach/build-outreach-draft-request.js +63 -63
  78. package/runtime/core/second-nature/outreach/delivery-target.d.ts +26 -26
  79. package/runtime/core/second-nature/outreach/delivery-target.js +70 -70
  80. package/runtime/core/second-nature/outreach/dispatch-user-outreach.d.ts +38 -38
  81. package/runtime/core/second-nature/outreach/dispatch-user-outreach.js +119 -119
  82. package/runtime/core/second-nature/outreach/judge-input-from-snapshot.d.ts +7 -7
  83. package/runtime/core/second-nature/outreach/judge-input-from-snapshot.js +45 -45
  84. package/runtime/core/second-nature/outreach/judge-outreach.d.ts +40 -40
  85. package/runtime/core/second-nature/outreach/judge-outreach.js +121 -121
  86. package/runtime/core/second-nature/quiet/run-source-backed-quiet.d.ts +21 -21
  87. package/runtime/core/second-nature/quiet/run-source-backed-quiet.js +123 -123
  88. package/runtime/core/second-nature/rhythm/planner-rhythm-window.d.ts +15 -15
  89. package/runtime/core/second-nature/rhythm/planner-rhythm-window.js +52 -52
  90. package/runtime/core/second-nature/rhythm/policy-bridge.d.ts +19 -19
  91. package/runtime/core/second-nature/rhythm/policy-bridge.js +34 -34
  92. package/runtime/core/second-nature/runtime/service-entry.js +45 -45
  93. package/runtime/core/second-nature/types.d.ts +51 -51
  94. package/runtime/guidance/draft-outreach-message.d.ts +7 -7
  95. package/runtime/guidance/draft-outreach-message.js +42 -42
  96. package/runtime/guidance/evidence-guidance.d.ts +40 -40
  97. package/runtime/guidance/evidence-guidance.js +52 -52
  98. package/runtime/guidance/index.d.ts +11 -11
  99. package/runtime/guidance/index.js +11 -11
  100. package/runtime/guidance/outreach-draft-schema.d.ts +228 -228
  101. package/runtime/guidance/outreach-draft-schema.js +80 -80
  102. package/runtime/observability/audit/append-only-audit-store.d.ts +14 -14
  103. package/runtime/observability/audit/append-only-audit-store.js +21 -21
  104. package/runtime/observability/audit/audit-envelope.d.ts +51 -51
  105. package/runtime/observability/audit/audit-envelope.js +130 -130
  106. package/runtime/observability/audit/verify-audit-hash-chain.d.ts +23 -23
  107. package/runtime/observability/audit/verify-audit-hash-chain.js +83 -83
  108. package/runtime/observability/db/index.js +124 -124
  109. package/runtime/observability/db/schema/host-capability-reports.d.ts +180 -180
  110. package/runtime/observability/db/schema/host-capability-reports.js +12 -12
  111. package/runtime/observability/db/schema/index.d.ts +947 -947
  112. package/runtime/observability/db/schema/index.js +71 -71
  113. package/runtime/observability/index.d.ts +20 -19
  114. package/runtime/observability/index.js +19 -18
  115. package/runtime/observability/query/explain-query.d.ts +48 -48
  116. package/runtime/observability/query/explain-query.js +114 -114
  117. package/runtime/observability/query/export-audit-bundle.d.ts +22 -22
  118. package/runtime/observability/query/export-audit-bundle.js +27 -27
  119. package/runtime/observability/services/decision-ledger.d.ts +46 -46
  120. package/runtime/observability/services/decision-ledger.js +161 -161
  121. package/runtime/observability/services/governance-audit.d.ts +41 -41
  122. package/runtime/observability/services/governance-audit.js +163 -163
  123. package/runtime/observability/services/governance-plane-recorder.d.ts +47 -47
  124. package/runtime/observability/services/governance-plane-recorder.js +55 -55
  125. package/runtime/observability/services/lived-experience-audit.d.ts +97 -97
  126. package/runtime/observability/services/lived-experience-audit.js +162 -162
  127. package/runtime/observability/services/runtime-decision-recorder.d.ts +29 -0
  128. package/runtime/observability/services/runtime-decision-recorder.js +94 -0
  129. package/runtime/storage/bootstrap/native-sqlite-probe.d.ts +7 -7
  130. package/runtime/storage/bootstrap/native-sqlite-probe.js +28 -28
  131. package/runtime/storage/bootstrap/repair-gate.d.ts +17 -17
  132. package/runtime/storage/bootstrap/repair-gate.js +71 -71
  133. package/runtime/storage/bootstrap/storage-mode-smoke.d.ts +38 -38
  134. package/runtime/storage/bootstrap/storage-mode-smoke.js +85 -85
  135. package/runtime/storage/db/index.js +154 -154
  136. package/runtime/storage/db/schema/delivery-attempts.d.ts +199 -199
  137. package/runtime/storage/db/schema/delivery-attempts.js +13 -13
  138. package/runtime/storage/db/schema/index.d.ts +9 -9
  139. package/runtime/storage/db/schema/index.js +9 -9
  140. package/runtime/storage/db/schema/life-evidence-index.d.ts +161 -161
  141. package/runtime/storage/db/schema/life-evidence-index.js +11 -11
  142. package/runtime/storage/db/schema/operator-fallback-artifacts.d.ts +161 -161
  143. package/runtime/storage/db/schema/operator-fallback-artifacts.js +11 -11
  144. package/runtime/storage/db/schema/policies.d.ts +98 -98
  145. package/runtime/storage/db/schema/policies.js +8 -8
  146. package/runtime/storage/delivery/query-delivery-attempts.d.ts +3 -3
  147. package/runtime/storage/delivery/query-delivery-attempts.js +32 -32
  148. package/runtime/storage/delivery/types.d.ts +27 -27
  149. package/runtime/storage/delivery/types.js +1 -1
  150. package/runtime/storage/delivery/write-delivery-attempt.d.ts +6 -6
  151. package/runtime/storage/delivery/write-delivery-attempt.js +36 -36
  152. package/runtime/storage/fallback/load-operator-fallback.d.ts +14 -14
  153. package/runtime/storage/fallback/load-operator-fallback.js +47 -47
  154. package/runtime/storage/fallback/operator-fallback-types.d.ts +9 -9
  155. package/runtime/storage/fallback/operator-fallback-types.js +1 -1
  156. package/runtime/storage/fallback/operator-fallback-view.d.ts +11 -11
  157. package/runtime/storage/fallback/operator-fallback-view.js +1 -1
  158. package/runtime/storage/fallback/write-operator-fallback.d.ts +6 -6
  159. package/runtime/storage/fallback/write-operator-fallback.js +21 -21
  160. package/runtime/storage/index.d.ts +37 -37
  161. package/runtime/storage/index.js +30 -30
  162. package/runtime/storage/life-evidence/append-life-evidence.d.ts +7 -7
  163. package/runtime/storage/life-evidence/append-life-evidence.js +64 -64
  164. package/runtime/storage/life-evidence/types.d.ts +45 -45
  165. package/runtime/storage/life-evidence/types.js +6 -6
  166. package/runtime/storage/quiet/persist-quiet-artifact.d.ts +7 -7
  167. package/runtime/storage/quiet/persist-quiet-artifact.js +22 -22
  168. package/runtime/storage/quiet/quiet-artifact-types.d.ts +18 -18
  169. package/runtime/storage/quiet/quiet-artifact-types.js +1 -1
  170. package/runtime/storage/quiet/quiet-artifact-writer.d.ts +15 -15
  171. package/runtime/storage/quiet/quiet-artifact-writer.js +56 -56
  172. package/runtime/storage/repositories/credential-repository.js +30 -30
  173. package/runtime/storage/rhythm/rhythm-policy-snapshot.d.ts +10 -10
  174. package/runtime/storage/rhythm/rhythm-policy-snapshot.js +34 -34
  175. package/runtime/storage/services/credential-vault.d.ts +13 -13
  176. package/runtime/storage/services/credential-vault.js +116 -116
  177. package/runtime/storage/snapshots/continuity-snapshot.d.ts +9 -9
  178. package/runtime/storage/snapshots/continuity-snapshot.js +41 -41
  179. package/runtime/storage/snapshots/life-evidence-snapshot.d.ts +6 -6
  180. package/runtime/storage/snapshots/life-evidence-snapshot.js +114 -114
  181. package/runtime/storage/snapshots/types.d.ts +58 -58
  182. package/runtime/storage/snapshots/types.js +1 -1
  183. package/runtime/storage/state-api.js +104 -104
  184. package/runtime/storage/user-interest/load-user-interest-snapshot.d.ts +2 -2
  185. package/runtime/storage/user-interest/load-user-interest-snapshot.js +150 -150
  186. package/runtime/storage/user-interest/types.d.ts +25 -25
  187. package/runtime/storage/user-interest/types.js +1 -1
  188. package/workspace-ops-bridge.js +81 -80
@@ -1,256 +1,256 @@
1
- import { desc } from "drizzle-orm";
2
- import { createQuietInputLoader } from "../../storage/services/quiet-input-loader.js";
3
- import { AssetRepository } from "../../storage/repositories/asset-repository.js";
4
- import { CredentialRepository } from "../../storage/repositories/credential-repository.js";
5
- import { EvidenceQueryEngine } from "../../observability/query/evidence-query-engine.js";
6
- import { decisionLedger, executionAttempts } from "../../observability/db/schema/index.js";
7
- import { queryExplain } from "../../observability/query/explain-query.js";
8
- import { mapOperatorExplainToReadModel } from "./operator-explain-map.js";
9
- import { loadOperatorFallbackRow, toOperatorFallbackView } from "../../storage/fallback/load-operator-fallback.js";
10
- const INTERNAL_RUNTIME_PLATFORM_ID = "second-nature-runtime";
11
- const INTERNAL_RUNTIME_TRACE_PREFIX = "sn-runtime-";
12
- function toExplainQuery(subject) {
13
- switch (subject.kind) {
14
- case "decision":
15
- return { kind: "decision", decisionId: subject.id };
16
- case "fallback": {
17
- const ref = subject.id.startsWith("fallback:") ? subject.id : `fallback:${subject.id}`;
18
- return { kind: "fallback", fallbackRef: ref };
19
- }
20
- case "probe":
21
- case "report":
22
- return { kind: "report", reportId: subject.id };
23
- case "delivery":
24
- return { kind: "delivery", auditId: subject.id };
25
- case "source_ref":
26
- return { kind: "source_ref", sourceRefId: subject.id };
27
- default:
28
- return undefined;
29
- }
30
- }
31
- function isAuditOnlySubjectKind(kind) {
32
- return kind === "fallback" || kind === "probe" || kind === "report" || kind === "delivery" || kind === "source_ref";
33
- }
34
- function buildCredentialNextStep(status) {
35
- if (status === "pending_verification")
36
- return "submit_verification_answer";
37
- if (status === "expired" || status === "revoked" || status === "failed")
38
- return "refresh_credential_context";
39
- return undefined;
40
- }
41
- function mapRuntimeStatus(attempt) {
42
- if (!attempt) {
43
- return "unknown";
44
- }
45
- if (attempt.failureClass || attempt.status === "failed") {
46
- return "degraded";
47
- }
48
- return "running";
49
- }
50
- function mapConnectorStatus(attempt) {
51
- if (!attempt) {
52
- return "unknown";
53
- }
54
- if (attempt.failureClass || attempt.status === "failed") {
55
- return "degraded";
56
- }
57
- return "healthy";
58
- }
59
- export function createCliReadModels(deps) {
60
- const assetRepository = new AssetRepository(deps.stateDb);
61
- const credentialRepository = new CredentialRepository(deps.stateDb);
62
- const quietLoader = createQuietInputLoader(assetRepository);
63
- const evidenceQuery = new EvidenceQueryEngine(deps.observabilityDb);
64
- const auditStore = deps.livedExperienceAuditStore;
65
- return {
66
- async loadStatus(_scope) {
67
- let recentAttempts = [];
68
- let recentDecisions = [];
69
- let credentials = [];
70
- try {
71
- recentAttempts = await deps.observabilityDb.db
72
- .select()
73
- .from(executionAttempts)
74
- .orderBy(desc(executionAttempts.startedAt), desc(executionAttempts.finishedAt))
75
- .limit(50);
76
- }
77
- catch {
78
- recentAttempts = [];
79
- }
80
- try {
81
- recentDecisions = await deps.observabilityDb.db
82
- .select()
83
- .from(decisionLedger)
84
- .orderBy(desc(decisionLedger.createdAt))
85
- .limit(50);
86
- }
87
- catch {
88
- recentDecisions = [];
89
- }
90
- try {
91
- credentials = await deps.stateDb.db.query.credentialRecords.findMany();
92
- }
93
- catch {
94
- credentials = [];
95
- }
96
- const latestRuntimeAttempt = recentAttempts.find((attempt) => attempt.platformId === INTERNAL_RUNTIME_PLATFORM_ID);
97
- const latestConnectorAttempt = recentAttempts.find((attempt) => attempt.platformId !== INTERNAL_RUNTIME_PLATFORM_ID);
98
- const latestRuntimeDecision = recentDecisions.find((decision) => decision.traceId.startsWith(INTERNAL_RUNTIME_TRACE_PREFIX));
99
- const runtimeUpdatedAt = latestRuntimeAttempt?.finishedAt ?? latestRuntimeAttempt?.startedAt ?? latestRuntimeDecision?.createdAt ?? "";
100
- const quietMode = latestRuntimeDecision?.mode === "quiet" ||
101
- latestRuntimeDecision?.mode === "maintenance_only" ||
102
- latestRuntimeDecision?.mode === "paused_for_interrupt"
103
- ? latestRuntimeDecision.mode
104
- : "unknown";
105
- const riskFlags = [latestRuntimeAttempt?.failureClass, latestConnectorAttempt?.failureClass].filter((value) => Boolean(value));
106
- const connectorSummary = latestConnectorAttempt
107
- ? [
108
- {
109
- platformId: latestConnectorAttempt.platformId,
110
- status: mapConnectorStatus(latestConnectorAttempt),
111
- channel: latestConnectorAttempt.channel,
112
- failureClass: latestConnectorAttempt.failureClass ?? undefined,
113
- },
114
- ]
115
- : [];
116
- return {
117
- runtime: {
118
- host: "openclaw-plugin",
119
- serviceStatus: mapRuntimeStatus(latestRuntimeAttempt),
120
- updatedAt: runtimeUpdatedAt,
121
- },
122
- rhythm: {
123
- mode: latestRuntimeDecision?.mode ?? "unknown",
124
- windowId: undefined,
125
- },
126
- quiet: {
127
- mode: quietMode,
128
- lastEvent: latestRuntimeDecision?.traceId,
129
- interrupted: latestRuntimeDecision?.mode === "paused_for_interrupt" ? true : undefined,
130
- },
131
- connectors: connectorSummary,
132
- credentials: credentials.map((item) => ({
133
- platformId: item.platformId ?? item.platform_id,
134
- status: item.status,
135
- nextStep: buildCredentialNextStep(item.status),
136
- })),
137
- risk: {
138
- level: riskFlags.length > 0 ? "medium" : "low",
139
- flags: riskFlags,
140
- },
141
- };
142
- },
143
- async loadDailyReport(day) {
144
- let bundle;
145
- try {
146
- bundle = await quietLoader.loadQuietInputs({
147
- dateRange: { start: `${day}T00:00:00.000Z`, end: `${day}T23:59:59.999Z` },
148
- assetFilters: { includeJournal: false, includeReports: true, includeCurated: false },
149
- });
150
- }
151
- catch {
152
- bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
153
- }
154
- const report = bundle.dailyReports[0];
155
- return {
156
- day,
157
- summary: report?.summary ?? "",
158
- highlights: report?.highlights ?? [],
159
- sourceRefs: report?.sources ?? [],
160
- };
161
- },
162
- async loadQuiet(scope) {
163
- const now = new Date();
164
- const start = new Date(now);
165
- start.setDate(now.getDate() - 1);
166
- let bundle;
167
- try {
168
- bundle = await quietLoader.loadQuietInputs({
169
- dateRange: { start: start.toISOString(), end: now.toISOString() },
170
- });
171
- }
172
- catch {
173
- bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
174
- }
175
- return {
176
- scope,
177
- mode: bundle.sourceCount > 0 ? "quiet" : "unknown",
178
- sourceCount: bundle.sourceCount,
179
- reportCount: bundle.dailyReports.length,
180
- recentJournalCount: bundle.journalEntries.length,
181
- };
182
- },
183
- async loadSession(sessionId) {
184
- const traceId = sessionId;
185
- const bundle = await evidenceQuery.queryEvidence({ traceId });
186
- return {
187
- requestedSessionId: sessionId,
188
- traceId,
189
- decisionCount: bundle.decisions.length,
190
- attemptCount: bundle.attempts.length,
191
- governanceCount: bundle.governance.length,
192
- keyFactors: bundle.explanation.keyFactors,
193
- evidenceRefs: bundle.explanation.evidenceRefs,
194
- };
195
- },
196
- async loadCredential(platformId) {
197
- let record;
198
- try {
199
- record = await credentialRepository.findByPlatformId(platformId);
200
- }
201
- catch {
202
- record = undefined;
203
- }
204
- if (!record) {
205
- return {
206
- platformId,
207
- status: "missing",
208
- nextStep: "provide_credential_context",
209
- };
210
- }
211
- return {
212
- platformId: record.platformId ?? record.platform_id,
213
- status: record.status,
214
- verificationDeadline: record.expiresAt ?? undefined,
215
- attemptsRemaining: record.attemptsRemaining ?? undefined,
216
- nextStep: buildCredentialNextStep(record.status),
217
- };
218
- },
219
- async loadFallbackView(ref) {
220
- const row = await loadOperatorFallbackRow(deps.stateDb, ref);
221
- if (!row)
222
- return null;
223
- return toOperatorFallbackView(row);
224
- },
225
- async explain(subject) {
226
- const q = toExplainQuery(subject);
227
- if (auditStore && q) {
228
- const op = queryExplain(q, auditStore);
229
- if (isAuditOnlySubjectKind(subject.kind)) {
230
- return mapOperatorExplainToReadModel(op, subject.kind);
231
- }
232
- if (op.relatedEventIds.length > 0) {
233
- return mapOperatorExplainToReadModel(op, subject.kind);
234
- }
235
- }
236
- if (isAuditOnlySubjectKind(subject.kind)) {
237
- return {
238
- subjectType: subject.kind,
239
- conclusion: auditStore ? "no_matching_audit_events" : "lived_experience_audit_store_unavailable",
240
- keyFactors: auditStore ? [] : ["configure_lived_experience_audit_store_for_operator_explain"],
241
- evidenceRefs: [],
242
- };
243
- }
244
- const query = subject.kind === "decision" || subject.kind === "platform-selection" || subject.kind === "outreach"
245
- ? { decisionId: subject.id }
246
- : { assetId: subject.id };
247
- const bundle = await evidenceQuery.queryEvidence(query);
248
- return {
249
- subjectType: subject.kind,
250
- conclusion: bundle.explanation.conclusion,
251
- keyFactors: bundle.explanation.keyFactors,
252
- evidenceRefs: bundle.explanation.evidenceRefs,
253
- };
254
- },
255
- };
256
- }
1
+ import { desc } from "drizzle-orm";
2
+ import { createQuietInputLoader } from "../../storage/services/quiet-input-loader.js";
3
+ import { AssetRepository } from "../../storage/repositories/asset-repository.js";
4
+ import { CredentialRepository } from "../../storage/repositories/credential-repository.js";
5
+ import { EvidenceQueryEngine } from "../../observability/query/evidence-query-engine.js";
6
+ import { decisionLedger, executionAttempts } from "../../observability/db/schema/index.js";
7
+ import { queryExplain } from "../../observability/query/explain-query.js";
8
+ import { mapOperatorExplainToReadModel } from "./operator-explain-map.js";
9
+ import { loadOperatorFallbackRow, toOperatorFallbackView } from "../../storage/fallback/load-operator-fallback.js";
10
+ const INTERNAL_RUNTIME_PLATFORM_ID = "second-nature-runtime";
11
+ const INTERNAL_RUNTIME_TRACE_PREFIX = "sn-runtime-";
12
+ function toExplainQuery(subject) {
13
+ switch (subject.kind) {
14
+ case "decision":
15
+ return { kind: "decision", decisionId: subject.id };
16
+ case "fallback": {
17
+ const ref = subject.id.startsWith("fallback:") ? subject.id : `fallback:${subject.id}`;
18
+ return { kind: "fallback", fallbackRef: ref };
19
+ }
20
+ case "probe":
21
+ case "report":
22
+ return { kind: "report", reportId: subject.id };
23
+ case "delivery":
24
+ return { kind: "delivery", auditId: subject.id };
25
+ case "source_ref":
26
+ return { kind: "source_ref", sourceRefId: subject.id };
27
+ default:
28
+ return undefined;
29
+ }
30
+ }
31
+ function isAuditOnlySubjectKind(kind) {
32
+ return kind === "fallback" || kind === "probe" || kind === "report" || kind === "delivery" || kind === "source_ref";
33
+ }
34
+ function buildCredentialNextStep(status) {
35
+ if (status === "pending_verification")
36
+ return "submit_verification_answer";
37
+ if (status === "expired" || status === "revoked" || status === "failed")
38
+ return "refresh_credential_context";
39
+ return undefined;
40
+ }
41
+ function mapRuntimeStatus(attempt) {
42
+ if (!attempt) {
43
+ return "unknown";
44
+ }
45
+ if (attempt.failureClass || attempt.status === "failed") {
46
+ return "degraded";
47
+ }
48
+ return "running";
49
+ }
50
+ function mapConnectorStatus(attempt) {
51
+ if (!attempt) {
52
+ return "unknown";
53
+ }
54
+ if (attempt.failureClass || attempt.status === "failed") {
55
+ return "degraded";
56
+ }
57
+ return "healthy";
58
+ }
59
+ export function createCliReadModels(deps) {
60
+ const assetRepository = new AssetRepository(deps.stateDb);
61
+ const credentialRepository = new CredentialRepository(deps.stateDb);
62
+ const quietLoader = createQuietInputLoader(assetRepository);
63
+ const evidenceQuery = new EvidenceQueryEngine(deps.observabilityDb);
64
+ const auditStore = deps.livedExperienceAuditStore;
65
+ return {
66
+ async loadStatus(_scope) {
67
+ let recentAttempts = [];
68
+ let recentDecisions = [];
69
+ let credentials = [];
70
+ try {
71
+ recentAttempts = await deps.observabilityDb.db
72
+ .select()
73
+ .from(executionAttempts)
74
+ .orderBy(desc(executionAttempts.startedAt), desc(executionAttempts.finishedAt))
75
+ .limit(50);
76
+ }
77
+ catch {
78
+ recentAttempts = [];
79
+ }
80
+ try {
81
+ recentDecisions = await deps.observabilityDb.db
82
+ .select()
83
+ .from(decisionLedger)
84
+ .orderBy(desc(decisionLedger.createdAt))
85
+ .limit(50);
86
+ }
87
+ catch {
88
+ recentDecisions = [];
89
+ }
90
+ try {
91
+ credentials = await deps.stateDb.db.query.credentialRecords.findMany();
92
+ }
93
+ catch {
94
+ credentials = [];
95
+ }
96
+ const latestRuntimeAttempt = recentAttempts.find((attempt) => attempt.platformId === INTERNAL_RUNTIME_PLATFORM_ID);
97
+ const latestConnectorAttempt = recentAttempts.find((attempt) => attempt.platformId !== INTERNAL_RUNTIME_PLATFORM_ID);
98
+ const latestRuntimeDecision = recentDecisions.find((decision) => decision.traceId.startsWith(INTERNAL_RUNTIME_TRACE_PREFIX));
99
+ const runtimeUpdatedAt = latestRuntimeAttempt?.finishedAt ?? latestRuntimeAttempt?.startedAt ?? latestRuntimeDecision?.createdAt ?? "";
100
+ const quietMode = latestRuntimeDecision?.mode === "quiet" ||
101
+ latestRuntimeDecision?.mode === "maintenance_only" ||
102
+ latestRuntimeDecision?.mode === "paused_for_interrupt"
103
+ ? latestRuntimeDecision.mode
104
+ : "unknown";
105
+ const riskFlags = [latestRuntimeAttempt?.failureClass, latestConnectorAttempt?.failureClass].filter((value) => Boolean(value));
106
+ const connectorSummary = latestConnectorAttempt
107
+ ? [
108
+ {
109
+ platformId: latestConnectorAttempt.platformId,
110
+ status: mapConnectorStatus(latestConnectorAttempt),
111
+ channel: latestConnectorAttempt.channel,
112
+ failureClass: latestConnectorAttempt.failureClass ?? undefined,
113
+ },
114
+ ]
115
+ : [];
116
+ return {
117
+ runtime: {
118
+ host: "openclaw-plugin",
119
+ serviceStatus: mapRuntimeStatus(latestRuntimeAttempt),
120
+ updatedAt: runtimeUpdatedAt,
121
+ },
122
+ rhythm: {
123
+ mode: latestRuntimeDecision?.mode ?? "unknown",
124
+ windowId: undefined,
125
+ },
126
+ quiet: {
127
+ mode: quietMode,
128
+ lastEvent: latestRuntimeDecision?.traceId,
129
+ interrupted: latestRuntimeDecision?.mode === "paused_for_interrupt" ? true : undefined,
130
+ },
131
+ connectors: connectorSummary,
132
+ credentials: credentials.map((item) => ({
133
+ platformId: item.platformId ?? item.platform_id,
134
+ status: item.status,
135
+ nextStep: buildCredentialNextStep(item.status),
136
+ })),
137
+ risk: {
138
+ level: riskFlags.length > 0 ? "medium" : "low",
139
+ flags: riskFlags,
140
+ },
141
+ };
142
+ },
143
+ async loadDailyReport(day) {
144
+ let bundle;
145
+ try {
146
+ bundle = await quietLoader.loadQuietInputs({
147
+ dateRange: { start: `${day}T00:00:00.000Z`, end: `${day}T23:59:59.999Z` },
148
+ assetFilters: { includeJournal: false, includeReports: true, includeCurated: false },
149
+ });
150
+ }
151
+ catch {
152
+ bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
153
+ }
154
+ const report = bundle.dailyReports[0];
155
+ return {
156
+ day,
157
+ summary: report?.summary ?? "",
158
+ highlights: report?.highlights ?? [],
159
+ sourceRefs: report?.sources ?? [],
160
+ };
161
+ },
162
+ async loadQuiet(scope) {
163
+ const now = new Date();
164
+ const start = new Date(now);
165
+ start.setDate(now.getDate() - 1);
166
+ let bundle;
167
+ try {
168
+ bundle = await quietLoader.loadQuietInputs({
169
+ dateRange: { start: start.toISOString(), end: now.toISOString() },
170
+ });
171
+ }
172
+ catch {
173
+ bundle = { dailyReports: [], journalEntries: [], sourceCount: 0 };
174
+ }
175
+ return {
176
+ scope,
177
+ mode: bundle.sourceCount > 0 ? "quiet" : "unknown",
178
+ sourceCount: bundle.sourceCount,
179
+ reportCount: bundle.dailyReports.length,
180
+ recentJournalCount: bundle.journalEntries.length,
181
+ };
182
+ },
183
+ async loadSession(sessionId) {
184
+ const traceId = sessionId;
185
+ const bundle = await evidenceQuery.queryEvidence({ traceId });
186
+ return {
187
+ requestedSessionId: sessionId,
188
+ traceId,
189
+ decisionCount: bundle.decisions.length,
190
+ attemptCount: bundle.attempts.length,
191
+ governanceCount: bundle.governance.length,
192
+ keyFactors: bundle.explanation.keyFactors,
193
+ evidenceRefs: bundle.explanation.evidenceRefs,
194
+ };
195
+ },
196
+ async loadCredential(platformId) {
197
+ let record;
198
+ try {
199
+ record = await credentialRepository.findByPlatformId(platformId);
200
+ }
201
+ catch {
202
+ record = undefined;
203
+ }
204
+ if (!record) {
205
+ return {
206
+ platformId,
207
+ status: "missing",
208
+ nextStep: "provide_credential_context",
209
+ };
210
+ }
211
+ return {
212
+ platformId: record.platformId ?? record.platform_id,
213
+ status: record.status,
214
+ verificationDeadline: record.expiresAt ?? undefined,
215
+ attemptsRemaining: record.attemptsRemaining ?? undefined,
216
+ nextStep: buildCredentialNextStep(record.status),
217
+ };
218
+ },
219
+ async loadFallbackView(ref) {
220
+ const row = await loadOperatorFallbackRow(deps.stateDb, ref);
221
+ if (!row)
222
+ return null;
223
+ return toOperatorFallbackView(row);
224
+ },
225
+ async explain(subject) {
226
+ const q = toExplainQuery(subject);
227
+ if (auditStore && q) {
228
+ const op = queryExplain(q, auditStore);
229
+ if (isAuditOnlySubjectKind(subject.kind)) {
230
+ return mapOperatorExplainToReadModel(op, subject.kind);
231
+ }
232
+ if (op.relatedEventIds.length > 0) {
233
+ return mapOperatorExplainToReadModel(op, subject.kind);
234
+ }
235
+ }
236
+ if (isAuditOnlySubjectKind(subject.kind)) {
237
+ return {
238
+ subjectType: subject.kind,
239
+ conclusion: auditStore ? "no_matching_audit_events" : "lived_experience_audit_store_unavailable",
240
+ keyFactors: auditStore ? [] : ["configure_lived_experience_audit_store_for_operator_explain"],
241
+ evidenceRefs: [],
242
+ };
243
+ }
244
+ const query = subject.kind === "decision" || subject.kind === "platform-selection" || subject.kind === "outreach"
245
+ ? { decisionId: subject.id }
246
+ : { assetId: subject.id };
247
+ const bundle = await evidenceQuery.queryEvidence(query);
248
+ return {
249
+ subjectType: subject.kind,
250
+ conclusion: bundle.explanation.conclusion,
251
+ keyFactors: bundle.explanation.keyFactors,
252
+ evidenceRefs: bundle.explanation.evidenceRefs,
253
+ };
254
+ },
255
+ };
256
+ }
@@ -1,6 +1,6 @@
1
- /**
2
- * Maps T5.3.1 operator explain query results into CLI ExplainReadModel (T1.2.1).
3
- */
4
- import type { OperatorExplainReadModel } from "../../observability/query/explain-query.js";
5
- import type { ExplainReadModel, ExplainSubjectKind } from "./types.js";
6
- export declare function mapOperatorExplainToReadModel(op: OperatorExplainReadModel, subjectKind: ExplainSubjectKind): ExplainReadModel;
1
+ /**
2
+ * Maps T5.3.1 operator explain query results into CLI ExplainReadModel (T1.2.1).
3
+ */
4
+ import type { OperatorExplainReadModel } from "../../observability/query/explain-query.js";
5
+ import type { ExplainReadModel, ExplainSubjectKind } from "./types.js";
6
+ export declare function mapOperatorExplainToReadModel(op: OperatorExplainReadModel, subjectKind: ExplainSubjectKind): ExplainReadModel;
@@ -1,10 +1,10 @@
1
- export function mapOperatorExplainToReadModel(op, subjectKind) {
2
- return {
3
- subjectType: subjectKind,
4
- conclusion: op.summary,
5
- keyFactors: op.events.map((e) => `${e.eventId}:${e.summary}`),
6
- evidenceRefs: op.relatedEventIds.map((id) => `audit_event:${id}`),
7
- warnings: op.warnings.length ? op.warnings : undefined,
8
- relatedAuditEventIds: op.relatedEventIds.length ? op.relatedEventIds : undefined,
9
- };
10
- }
1
+ export function mapOperatorExplainToReadModel(op, subjectKind) {
2
+ return {
3
+ subjectType: subjectKind,
4
+ conclusion: op.summary,
5
+ keyFactors: op.events.map((e) => `${e.eventId}:${e.summary}`),
6
+ evidenceRefs: op.relatedEventIds.map((id) => `audit_event:${id}`),
7
+ warnings: op.warnings.length ? op.warnings : undefined,
8
+ relatedAuditEventIds: op.relatedEventIds.length ? op.relatedEventIds : undefined,
9
+ };
10
+ }