@haaaiawd/second-nature 0.1.18 → 0.1.20

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 (190) hide show
  1. package/index.js +911 -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 +224 -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 +67 -58
  24. package/runtime/cli/ops/heartbeat-surface.d.ts +45 -38
  25. package/runtime/cli/ops/heartbeat-surface.js +79 -73
  26. package/runtime/cli/ops/ops-router.d.ts +32 -19
  27. package/runtime/cli/ops/ops-router.js +188 -89
  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 +40 -19
  31. package/runtime/cli/ops/workspace-heartbeat-runner.js +93 -39
  32. package/runtime/cli/read-models/index.d.ts +46 -29
  33. package/runtime/cli/read-models/index.js +391 -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 +129 -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 +162 -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 +47 -47
  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 -20
  114. package/runtime/observability/index.js +19 -19
  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/observability-retention.d.ts +10 -0
  128. package/runtime/observability/services/observability-retention.js +37 -0
  129. package/runtime/observability/services/runtime-decision-recorder.d.ts +29 -29
  130. package/runtime/observability/services/runtime-decision-recorder.js +94 -94
  131. package/runtime/storage/bootstrap/native-sqlite-probe.d.ts +7 -7
  132. package/runtime/storage/bootstrap/native-sqlite-probe.js +28 -28
  133. package/runtime/storage/bootstrap/repair-gate.d.ts +17 -17
  134. package/runtime/storage/bootstrap/repair-gate.js +71 -71
  135. package/runtime/storage/bootstrap/storage-mode-smoke.d.ts +38 -38
  136. package/runtime/storage/bootstrap/storage-mode-smoke.js +85 -85
  137. package/runtime/storage/db/index.js +61 -61
  138. package/runtime/storage/db/schema/delivery-attempts.d.ts +199 -199
  139. package/runtime/storage/db/schema/delivery-attempts.js +13 -13
  140. package/runtime/storage/db/schema/index.d.ts +9 -9
  141. package/runtime/storage/db/schema/index.js +9 -9
  142. package/runtime/storage/db/schema/life-evidence-index.d.ts +161 -161
  143. package/runtime/storage/db/schema/life-evidence-index.js +11 -11
  144. package/runtime/storage/db/schema/operator-fallback-artifacts.d.ts +161 -161
  145. package/runtime/storage/db/schema/operator-fallback-artifacts.js +11 -11
  146. package/runtime/storage/db/schema/policies.d.ts +98 -98
  147. package/runtime/storage/db/schema/policies.js +8 -8
  148. package/runtime/storage/delivery/query-delivery-attempts.d.ts +3 -3
  149. package/runtime/storage/delivery/query-delivery-attempts.js +32 -32
  150. package/runtime/storage/delivery/types.d.ts +27 -27
  151. package/runtime/storage/delivery/types.js +1 -1
  152. package/runtime/storage/delivery/write-delivery-attempt.d.ts +6 -6
  153. package/runtime/storage/delivery/write-delivery-attempt.js +36 -36
  154. package/runtime/storage/fallback/load-operator-fallback.d.ts +14 -14
  155. package/runtime/storage/fallback/load-operator-fallback.js +47 -47
  156. package/runtime/storage/fallback/operator-fallback-types.d.ts +9 -9
  157. package/runtime/storage/fallback/operator-fallback-types.js +1 -1
  158. package/runtime/storage/fallback/operator-fallback-view.d.ts +11 -11
  159. package/runtime/storage/fallback/operator-fallback-view.js +1 -1
  160. package/runtime/storage/fallback/write-operator-fallback.d.ts +6 -6
  161. package/runtime/storage/fallback/write-operator-fallback.js +21 -21
  162. package/runtime/storage/index.d.ts +37 -37
  163. package/runtime/storage/index.js +30 -30
  164. package/runtime/storage/life-evidence/append-life-evidence.d.ts +7 -7
  165. package/runtime/storage/life-evidence/append-life-evidence.js +64 -64
  166. package/runtime/storage/life-evidence/types.d.ts +45 -45
  167. package/runtime/storage/life-evidence/types.js +6 -6
  168. package/runtime/storage/quiet/persist-quiet-artifact.d.ts +7 -7
  169. package/runtime/storage/quiet/persist-quiet-artifact.js +22 -22
  170. package/runtime/storage/quiet/quiet-artifact-types.d.ts +18 -18
  171. package/runtime/storage/quiet/quiet-artifact-types.js +1 -1
  172. package/runtime/storage/quiet/quiet-artifact-writer.d.ts +15 -15
  173. package/runtime/storage/quiet/quiet-artifact-writer.js +56 -56
  174. package/runtime/storage/repositories/credential-repository.js +30 -30
  175. package/runtime/storage/rhythm/rhythm-policy-snapshot.d.ts +10 -10
  176. package/runtime/storage/rhythm/rhythm-policy-snapshot.js +34 -34
  177. package/runtime/storage/services/credential-vault.d.ts +13 -13
  178. package/runtime/storage/services/credential-vault.js +116 -116
  179. package/runtime/storage/snapshots/continuity-snapshot.d.ts +9 -9
  180. package/runtime/storage/snapshots/continuity-snapshot.js +41 -41
  181. package/runtime/storage/snapshots/life-evidence-snapshot.d.ts +6 -6
  182. package/runtime/storage/snapshots/life-evidence-snapshot.js +114 -114
  183. package/runtime/storage/snapshots/types.d.ts +58 -58
  184. package/runtime/storage/snapshots/types.js +1 -1
  185. package/runtime/storage/state-api.js +104 -104
  186. package/runtime/storage/user-interest/load-user-interest-snapshot.d.ts +2 -2
  187. package/runtime/storage/user-interest/load-user-interest-snapshot.js +150 -150
  188. package/runtime/storage/user-interest/types.d.ts +25 -25
  189. package/runtime/storage/user-interest/types.js +1 -1
  190. package/workspace-ops-bridge.js +90 -81
@@ -1,198 +1,198 @@
1
- import { classifyFailure } from "./failure-taxonomy.js";
2
- import { enforceExecutionPolicy } from "./execution-policy.js";
3
- const DEFAULT_RETRY_MAX = 3;
4
- const DEFAULT_BASE_DELAY_MS = 1000;
5
- const DEFAULT_MAX_DELAY_MS = 30000;
6
- function resolveRetryPolicy(input) {
7
- return {
8
- maxRetries: input?.maxRetries ?? DEFAULT_RETRY_MAX,
9
- baseDelayMs: input?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,
10
- maxDelayMs: input?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,
11
- jitter: input?.jitter ?? true,
12
- };
13
- }
14
- function computeRetryDelayMs(attempt, policy, retryAfterMs) {
15
- if (typeof retryAfterMs === "number" && retryAfterMs > 0) {
16
- return retryAfterMs;
17
- }
18
- const base = Math.min(policy.baseDelayMs * 2 ** Math.max(0, attempt - 1), policy.maxDelayMs);
19
- if (!policy.jitter)
20
- return base;
21
- return Math.floor(base * 0.8 + Math.random() * base * 0.4);
22
- }
23
- async function sleep(ms) {
24
- if (ms <= 0)
25
- return;
26
- await new Promise((resolve) => setTimeout(resolve, ms));
27
- }
28
- function makeTraceId(request, plan) {
29
- return `${request.platformId}:${request.intent}:${plan.channel}:${Date.now()}`;
30
- }
31
- function resolveIdentity(request) {
32
- if (!request.decisionId || !request.intentId) {
33
- throw new Error("connector_policy_missing_decision_or_intent_identity");
34
- }
35
- return {
36
- decisionId: request.decisionId,
37
- intentId: request.intentId,
38
- };
39
- }
40
- function isDegradedChannel(channel) {
41
- return channel === "cli" || channel === "skill" || channel === "browser";
42
- }
43
- function adaptProtocolErrors(error) {
44
- if (!error || typeof error !== "object") {
45
- return error;
46
- }
47
- const record = error;
48
- const detail = typeof record.detail === "string" ? record.detail : "";
49
- if (detail === "node_secret_required") {
50
- return { code: "verification_required", detail };
51
- }
52
- if (detail === "bundle_required") {
53
- return { code: "protocol_mismatch", detail };
54
- }
55
- if (detail === "asset_id mismatch") {
56
- return { code: "protocol_mismatch", detail };
57
- }
58
- return error;
59
- }
60
- export function createConnectorPolicyLayer(ctx) {
61
- const retryPolicy = resolveRetryPolicy(ctx.retryPolicy);
62
- const allowDegradedFallback = ctx.allowDegradedFallback ?? (() => true);
63
- return {
64
- async executeWithPolicy(intent, request) {
65
- if (ctx.cooldownPort) {
66
- const cooldown = await ctx.cooldownPort.isBlocked(request.platformId, intent);
67
- if (cooldown.blocked) {
68
- return {
69
- status: "terminal_failure",
70
- failureClass: "cooldown_blocked",
71
- retryAfterMs: cooldown.retryAfterMs,
72
- metadata: {
73
- platformId: request.platformId,
74
- channel: request.preferredChannel ?? "api_rest",
75
- latencyMs: 0,
76
- },
77
- };
78
- }
79
- }
80
- const identity = resolveIdentity(request);
81
- let plan;
82
- try {
83
- plan = await ctx.routePlanner.planRoute(intent, request);
84
- }
85
- catch (error) {
86
- const failure = classifyFailure(error);
87
- return {
88
- status: "terminal_failure",
89
- failureClass: failure.class,
90
- retryAfterMs: failure.retryAfterMs,
91
- metadata: {
92
- platformId: request.platformId,
93
- channel: request.preferredChannel ?? "api_rest",
94
- latencyMs: 0,
95
- },
96
- };
97
- }
98
- if (isDegradedChannel(plan.channel) && !allowDegradedFallback(plan, request)) {
99
- return {
100
- status: "terminal_failure",
101
- failureClass: "protocol_mismatch",
102
- metadata: {
103
- platformId: request.platformId,
104
- channel: plan.channel,
105
- latencyMs: 0,
106
- degraded: true,
107
- },
108
- };
109
- }
110
- const policyGate = await enforceExecutionPolicy(plan, intent, request, {
111
- effectCommitLedger: ctx.effectCommitLedger,
112
- });
113
- if (policyGate.skipAdapter && policyGate.existingOutcomeRef) {
114
- return {
115
- status: "success",
116
- data: { replayedCommit: true, outcomeRef: policyGate.existingOutcomeRef },
117
- metadata: {
118
- platformId: request.platformId,
119
- channel: plan.channel,
120
- latencyMs: 0,
121
- degraded: plan.degraded,
122
- },
123
- };
124
- }
125
- let lastFailure;
126
- for (let attempt = 1; attempt <= retryPolicy.maxRetries; attempt += 1) {
127
- const traceId = `${makeTraceId(request, plan)}:${attempt}`;
128
- if (ctx.telemetry) {
129
- await ctx.telemetry.startAttempt({
130
- traceId,
131
- decisionId: identity.decisionId,
132
- intentId: identity.intentId,
133
- platformId: request.platformId,
134
- capability: request.intent,
135
- channel: plan.channel,
136
- retryPolicy: JSON.stringify(retryPolicy),
137
- idempotencyKey: request.idempotencyKey,
138
- });
139
- }
140
- const raw = await ctx.executionRunner.run(plan, request);
141
- if (raw.success) {
142
- if (ctx.telemetry) {
143
- await ctx.telemetry.completeAttempt(traceId, "succeeded");
144
- }
145
- return {
146
- status: "success",
147
- data: raw.payload,
148
- metadata: {
149
- platformId: raw.platformId,
150
- channel: raw.channel,
151
- latencyMs: raw.latencyMs,
152
- degraded: raw.degraded,
153
- },
154
- };
155
- }
156
- const classified = classifyFailure(adaptProtocolErrors(raw.error));
157
- lastFailure = {
158
- failureClass: classified.class,
159
- retryAfterMs: classified.retryAfterMs,
160
- channel: raw.channel,
161
- };
162
- if (ctx.telemetry) {
163
- await ctx.telemetry.completeAttempt(traceId, "failed", undefined, classified.class);
164
- }
165
- if (ctx.cooldownPort) {
166
- await ctx.cooldownPort.markFailure(request.platformId, intent, classified.class, classified.retryAfterMs);
167
- }
168
- const isRetryable = classified.retryable;
169
- if (!isRetryable || attempt >= retryPolicy.maxRetries) {
170
- return {
171
- status: "terminal_failure",
172
- failureClass: classified.class,
173
- retryAfterMs: classified.retryAfterMs,
174
- metadata: {
175
- platformId: raw.platformId,
176
- channel: raw.channel,
177
- latencyMs: raw.latencyMs,
178
- degraded: raw.degraded,
179
- },
180
- };
181
- }
182
- const delay = computeRetryDelayMs(attempt, retryPolicy, classified.retryAfterMs);
183
- await sleep(delay);
184
- }
185
- return {
186
- status: "terminal_failure",
187
- failureClass: lastFailure?.failureClass ?? "unknown_platform_change",
188
- retryAfterMs: lastFailure?.retryAfterMs,
189
- metadata: {
190
- platformId: request.platformId,
191
- channel: lastFailure?.channel ?? plan.channel,
192
- latencyMs: 0,
193
- degraded: isDegradedChannel(lastFailure?.channel ?? plan.channel),
194
- },
195
- };
196
- },
197
- };
198
- }
1
+ import { classifyFailure } from "./failure-taxonomy.js";
2
+ import { enforceExecutionPolicy } from "./execution-policy.js";
3
+ const DEFAULT_RETRY_MAX = 3;
4
+ const DEFAULT_BASE_DELAY_MS = 1000;
5
+ const DEFAULT_MAX_DELAY_MS = 30000;
6
+ function resolveRetryPolicy(input) {
7
+ return {
8
+ maxRetries: input?.maxRetries ?? DEFAULT_RETRY_MAX,
9
+ baseDelayMs: input?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,
10
+ maxDelayMs: input?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,
11
+ jitter: input?.jitter ?? true,
12
+ };
13
+ }
14
+ function computeRetryDelayMs(attempt, policy, retryAfterMs) {
15
+ if (typeof retryAfterMs === "number" && retryAfterMs > 0) {
16
+ return retryAfterMs;
17
+ }
18
+ const base = Math.min(policy.baseDelayMs * 2 ** Math.max(0, attempt - 1), policy.maxDelayMs);
19
+ if (!policy.jitter)
20
+ return base;
21
+ return Math.floor(base * 0.8 + Math.random() * base * 0.4);
22
+ }
23
+ async function sleep(ms) {
24
+ if (ms <= 0)
25
+ return;
26
+ await new Promise((resolve) => setTimeout(resolve, ms));
27
+ }
28
+ function makeTraceId(request, plan) {
29
+ return `${request.platformId}:${request.intent}:${plan.channel}:${Date.now()}`;
30
+ }
31
+ function resolveIdentity(request) {
32
+ if (!request.decisionId || !request.intentId) {
33
+ throw new Error("connector_policy_missing_decision_or_intent_identity");
34
+ }
35
+ return {
36
+ decisionId: request.decisionId,
37
+ intentId: request.intentId,
38
+ };
39
+ }
40
+ function isDegradedChannel(channel) {
41
+ return channel === "cli" || channel === "skill" || channel === "browser";
42
+ }
43
+ function adaptProtocolErrors(error) {
44
+ if (!error || typeof error !== "object") {
45
+ return error;
46
+ }
47
+ const record = error;
48
+ const detail = typeof record.detail === "string" ? record.detail : "";
49
+ if (detail === "node_secret_required") {
50
+ return { code: "verification_required", detail };
51
+ }
52
+ if (detail === "bundle_required") {
53
+ return { code: "protocol_mismatch", detail };
54
+ }
55
+ if (detail === "asset_id mismatch") {
56
+ return { code: "protocol_mismatch", detail };
57
+ }
58
+ return error;
59
+ }
60
+ export function createConnectorPolicyLayer(ctx) {
61
+ const retryPolicy = resolveRetryPolicy(ctx.retryPolicy);
62
+ const allowDegradedFallback = ctx.allowDegradedFallback ?? (() => true);
63
+ return {
64
+ async executeWithPolicy(intent, request) {
65
+ if (ctx.cooldownPort) {
66
+ const cooldown = await ctx.cooldownPort.isBlocked(request.platformId, intent);
67
+ if (cooldown.blocked) {
68
+ return {
69
+ status: "terminal_failure",
70
+ failureClass: "cooldown_blocked",
71
+ retryAfterMs: cooldown.retryAfterMs,
72
+ metadata: {
73
+ platformId: request.platformId,
74
+ channel: request.preferredChannel ?? "api_rest",
75
+ latencyMs: 0,
76
+ },
77
+ };
78
+ }
79
+ }
80
+ const identity = resolveIdentity(request);
81
+ let plan;
82
+ try {
83
+ plan = await ctx.routePlanner.planRoute(intent, request);
84
+ }
85
+ catch (error) {
86
+ const failure = classifyFailure(error);
87
+ return {
88
+ status: "terminal_failure",
89
+ failureClass: failure.class,
90
+ retryAfterMs: failure.retryAfterMs,
91
+ metadata: {
92
+ platformId: request.platformId,
93
+ channel: request.preferredChannel ?? "api_rest",
94
+ latencyMs: 0,
95
+ },
96
+ };
97
+ }
98
+ if (isDegradedChannel(plan.channel) && !allowDegradedFallback(plan, request)) {
99
+ return {
100
+ status: "terminal_failure",
101
+ failureClass: "protocol_mismatch",
102
+ metadata: {
103
+ platformId: request.platformId,
104
+ channel: plan.channel,
105
+ latencyMs: 0,
106
+ degraded: true,
107
+ },
108
+ };
109
+ }
110
+ const policyGate = await enforceExecutionPolicy(plan, intent, request, {
111
+ effectCommitLedger: ctx.effectCommitLedger,
112
+ });
113
+ if (policyGate.skipAdapter && policyGate.existingOutcomeRef) {
114
+ return {
115
+ status: "success",
116
+ data: { replayedCommit: true, outcomeRef: policyGate.existingOutcomeRef },
117
+ metadata: {
118
+ platformId: request.platformId,
119
+ channel: plan.channel,
120
+ latencyMs: 0,
121
+ degraded: plan.degraded,
122
+ },
123
+ };
124
+ }
125
+ let lastFailure;
126
+ for (let attempt = 1; attempt <= retryPolicy.maxRetries; attempt += 1) {
127
+ const traceId = `${makeTraceId(request, plan)}:${attempt}`;
128
+ if (ctx.telemetry) {
129
+ await ctx.telemetry.startAttempt({
130
+ traceId,
131
+ decisionId: identity.decisionId,
132
+ intentId: identity.intentId,
133
+ platformId: request.platformId,
134
+ capability: request.intent,
135
+ channel: plan.channel,
136
+ retryPolicy: JSON.stringify(retryPolicy),
137
+ idempotencyKey: request.idempotencyKey,
138
+ });
139
+ }
140
+ const raw = await ctx.executionRunner.run(plan, request);
141
+ if (raw.success) {
142
+ if (ctx.telemetry) {
143
+ await ctx.telemetry.completeAttempt(traceId, "succeeded");
144
+ }
145
+ return {
146
+ status: "success",
147
+ data: raw.payload,
148
+ metadata: {
149
+ platformId: raw.platformId,
150
+ channel: raw.channel,
151
+ latencyMs: raw.latencyMs,
152
+ degraded: raw.degraded,
153
+ },
154
+ };
155
+ }
156
+ const classified = classifyFailure(adaptProtocolErrors(raw.error));
157
+ lastFailure = {
158
+ failureClass: classified.class,
159
+ retryAfterMs: classified.retryAfterMs,
160
+ channel: raw.channel,
161
+ };
162
+ if (ctx.telemetry) {
163
+ await ctx.telemetry.completeAttempt(traceId, "failed", undefined, classified.class);
164
+ }
165
+ if (ctx.cooldownPort) {
166
+ await ctx.cooldownPort.markFailure(request.platformId, intent, classified.class, classified.retryAfterMs);
167
+ }
168
+ const isRetryable = classified.retryable;
169
+ if (!isRetryable || attempt >= retryPolicy.maxRetries) {
170
+ return {
171
+ status: "terminal_failure",
172
+ failureClass: classified.class,
173
+ retryAfterMs: classified.retryAfterMs,
174
+ metadata: {
175
+ platformId: raw.platformId,
176
+ channel: raw.channel,
177
+ latencyMs: raw.latencyMs,
178
+ degraded: raw.degraded,
179
+ },
180
+ };
181
+ }
182
+ const delay = computeRetryDelayMs(attempt, retryPolicy, classified.retryAfterMs);
183
+ await sleep(delay);
184
+ }
185
+ return {
186
+ status: "terminal_failure",
187
+ failureClass: lastFailure?.failureClass ?? "unknown_platform_change",
188
+ retryAfterMs: lastFailure?.retryAfterMs,
189
+ metadata: {
190
+ platformId: request.platformId,
191
+ channel: lastFailure?.channel ?? plan.channel,
192
+ latencyMs: 0,
193
+ degraded: isDegradedChannel(lastFailure?.channel ?? plan.channel),
194
+ },
195
+ };
196
+ },
197
+ };
198
+ }
@@ -1,99 +1,99 @@
1
- import { ConnectorPolicyError } from "./failure-taxonomy.js";
2
- const HIGH_RISK_SIDE_EFFECTS = new Set([
3
- "post.publish",
4
- "comment.reply",
5
- "message.send",
6
- "task.claim",
7
- ]);
8
- function endpointModeFor(channel) {
9
- if (channel === "a2a")
10
- return "a2a_envelope";
11
- if (channel === "cli")
12
- return "cli_stdout";
13
- if (channel === "skill" || channel === "browser")
14
- return "skill_call";
15
- return "rest_json";
16
- }
17
- const DEFAULT_DEGRADED_CHANNELS = ["cli", "skill", "browser"];
18
- function isDegradedChannel(channel, degradedChannels) {
19
- const policy = degradedChannels && degradedChannels.length > 0 ? degradedChannels : DEFAULT_DEGRADED_CHANNELS;
20
- return policy.includes(channel);
21
- }
22
- function chooseByCredentialState(channels, credential) {
23
- if (credential.status === "pending_verification") {
24
- if (channels.includes("skill"))
25
- return "skill";
26
- if (channels.includes("browser"))
27
- return "browser";
28
- throw new ConnectorPolicyError("verification_required", "verification_recovery_channel_missing");
29
- }
30
- return undefined;
31
- }
32
- function choosePreferred(channels, preferred) {
33
- if (preferred && channels.includes(preferred))
34
- return preferred;
35
- return undefined;
36
- }
37
- function chooseHealthy(channels, platformId, health) {
38
- for (const channel of channels) {
39
- const snapshot = health.get(platformId, channel);
40
- if (!snapshot)
41
- return channel;
42
- if (snapshot.healthy && !snapshot.degraded)
43
- return channel;
44
- if (snapshot.healthy)
45
- return channel;
46
- }
47
- return channels[0];
48
- }
49
- function enforceSideEffectSafety(intent, channel, degradedChannels) {
50
- if (!HIGH_RISK_SIDE_EFFECTS.has(intent)) {
51
- return;
52
- }
53
- if (isDegradedChannel(channel, degradedChannels)) {
54
- throw new ConnectorPolicyError("protocol_mismatch", "degraded_channel_not_allowed_for_side_effect");
55
- }
56
- }
57
- export class ConnectorRoutePlanner {
58
- registry;
59
- statePort;
60
- channelHealth;
61
- constructor(registry, statePort, channelHealth) {
62
- this.registry = registry;
63
- this.statePort = statePort;
64
- this.channelHealth = channelHealth;
65
- }
66
- async planRoute(intent, request) {
67
- const manifest = this.registry.loadManifest(request.platformId);
68
- if (!manifest.supportedCapabilities.includes(intent)) {
69
- throw new ConnectorPolicyError("protocol_mismatch", "capability_not_supported_by_manifest");
70
- }
71
- const cooldown = await this.statePort.loadCooldownState(request.platformId, intent);
72
- if (cooldown.blocked) {
73
- throw new ConnectorPolicyError("cooldown_blocked", "platform_or_intent_cooldown_blocked", cooldown.retryAfterMs);
74
- }
75
- const credential = await this.statePort.loadCredentialState(request.platformId);
76
- if (credential.status === "missing" || credential.status === "revoked" || credential.status === "failed") {
77
- throw new ConnectorPolicyError("auth_failure", "credential_unavailable_for_route");
78
- }
79
- if (credential.status === "expired") {
80
- throw new ConnectorPolicyError("credential_expired", "credential_expired_for_route");
81
- }
82
- const channels = [...manifest.channelPriority];
83
- const byCredential = chooseByCredentialState(channels, credential);
84
- const preferred = choosePreferred(channels, request.preferredChannel);
85
- const selected = byCredential ?? preferred ?? chooseHealthy(channels, request.platformId, this.channelHealth);
86
- if (!selected) {
87
- throw new ConnectorPolicyError("protocol_mismatch", "no_available_channel");
88
- }
89
- enforceSideEffectSafety(intent, selected, manifest.degradedChannels);
90
- return {
91
- platformId: request.platformId,
92
- intent,
93
- channel: selected,
94
- endpointMode: endpointModeFor(selected),
95
- idempotencyKey: request.idempotencyKey,
96
- degraded: isDegradedChannel(selected, manifest.degradedChannels),
97
- };
98
- }
99
- }
1
+ import { ConnectorPolicyError } from "./failure-taxonomy.js";
2
+ const HIGH_RISK_SIDE_EFFECTS = new Set([
3
+ "post.publish",
4
+ "comment.reply",
5
+ "message.send",
6
+ "task.claim",
7
+ ]);
8
+ function endpointModeFor(channel) {
9
+ if (channel === "a2a")
10
+ return "a2a_envelope";
11
+ if (channel === "cli")
12
+ return "cli_stdout";
13
+ if (channel === "skill" || channel === "browser")
14
+ return "skill_call";
15
+ return "rest_json";
16
+ }
17
+ const DEFAULT_DEGRADED_CHANNELS = ["cli", "skill", "browser"];
18
+ function isDegradedChannel(channel, degradedChannels) {
19
+ const policy = degradedChannels && degradedChannels.length > 0 ? degradedChannels : DEFAULT_DEGRADED_CHANNELS;
20
+ return policy.includes(channel);
21
+ }
22
+ function chooseByCredentialState(channels, credential) {
23
+ if (credential.status === "pending_verification") {
24
+ if (channels.includes("skill"))
25
+ return "skill";
26
+ if (channels.includes("browser"))
27
+ return "browser";
28
+ throw new ConnectorPolicyError("verification_required", "verification_recovery_channel_missing");
29
+ }
30
+ return undefined;
31
+ }
32
+ function choosePreferred(channels, preferred) {
33
+ if (preferred && channels.includes(preferred))
34
+ return preferred;
35
+ return undefined;
36
+ }
37
+ function chooseHealthy(channels, platformId, health) {
38
+ for (const channel of channels) {
39
+ const snapshot = health.get(platformId, channel);
40
+ if (!snapshot)
41
+ return channel;
42
+ if (snapshot.healthy && !snapshot.degraded)
43
+ return channel;
44
+ if (snapshot.healthy)
45
+ return channel;
46
+ }
47
+ return channels[0];
48
+ }
49
+ function enforceSideEffectSafety(intent, channel, degradedChannels) {
50
+ if (!HIGH_RISK_SIDE_EFFECTS.has(intent)) {
51
+ return;
52
+ }
53
+ if (isDegradedChannel(channel, degradedChannels)) {
54
+ throw new ConnectorPolicyError("protocol_mismatch", "degraded_channel_not_allowed_for_side_effect");
55
+ }
56
+ }
57
+ export class ConnectorRoutePlanner {
58
+ registry;
59
+ statePort;
60
+ channelHealth;
61
+ constructor(registry, statePort, channelHealth) {
62
+ this.registry = registry;
63
+ this.statePort = statePort;
64
+ this.channelHealth = channelHealth;
65
+ }
66
+ async planRoute(intent, request) {
67
+ const manifest = this.registry.loadManifest(request.platformId);
68
+ if (!manifest.supportedCapabilities.includes(intent)) {
69
+ throw new ConnectorPolicyError("protocol_mismatch", "capability_not_supported_by_manifest");
70
+ }
71
+ const cooldown = await this.statePort.loadCooldownState(request.platformId, intent);
72
+ if (cooldown.blocked) {
73
+ throw new ConnectorPolicyError("cooldown_blocked", "platform_or_intent_cooldown_blocked", cooldown.retryAfterMs);
74
+ }
75
+ const credential = await this.statePort.loadCredentialState(request.platformId);
76
+ if (credential.status === "missing" || credential.status === "revoked" || credential.status === "failed") {
77
+ throw new ConnectorPolicyError("auth_failure", "credential_unavailable_for_route");
78
+ }
79
+ if (credential.status === "expired") {
80
+ throw new ConnectorPolicyError("credential_expired", "credential_expired_for_route");
81
+ }
82
+ const channels = [...manifest.channelPriority];
83
+ const byCredential = chooseByCredentialState(channels, credential);
84
+ const preferred = choosePreferred(channels, request.preferredChannel);
85
+ const selected = byCredential ?? preferred ?? chooseHealthy(channels, request.platformId, this.channelHealth);
86
+ if (!selected) {
87
+ throw new ConnectorPolicyError("protocol_mismatch", "no_available_channel");
88
+ }
89
+ enforceSideEffectSafety(intent, selected, manifest.degradedChannels);
90
+ return {
91
+ platformId: request.platformId,
92
+ intent,
93
+ channel: selected,
94
+ endpointMode: endpointModeFor(selected),
95
+ idempotencyKey: request.idempotencyKey,
96
+ degraded: isDegradedChannel(selected, manifest.degradedChannels),
97
+ };
98
+ }
99
+ }
@@ -1,5 +1,5 @@
1
- export * from "./base/index.js";
2
- export * from "./social-community/moltbook/index.js";
3
- export * from "./social-community/instreet/index.js";
4
- export * from "./agent-network/evomap/index.js";
5
- export * from "./near-real/near-real-connector-smoke.js";
1
+ export * from "./base/index.js";
2
+ export * from "./social-community/moltbook/index.js";
3
+ export * from "./social-community/instreet/index.js";
4
+ export * from "./agent-network/evomap/index.js";
5
+ export * from "./near-real/near-real-connector-smoke.js";
@@ -1,5 +1,5 @@
1
- export * from "./base/index.js";
2
- export * from "./social-community/moltbook/index.js";
3
- export * from "./social-community/instreet/index.js";
4
- export * from "./agent-network/evomap/index.js";
5
- export * from "./near-real/near-real-connector-smoke.js";
1
+ export * from "./base/index.js";
2
+ export * from "./social-community/moltbook/index.js";
3
+ export * from "./social-community/instreet/index.js";
4
+ export * from "./agent-network/evomap/index.js";
5
+ export * from "./near-real/near-real-connector-smoke.js";
@@ -1,19 +1,19 @@
1
- import type { ObservabilityDatabase } from "../../observability/db/index.js";
2
- import type { StateDatabase } from "../../storage/db/index.js";
3
- export interface NearRealConnectorSmokeResult {
4
- generatedAt: string;
5
- platforms: {
6
- social: "moltbook";
7
- agentNetwork: "evomap";
8
- };
9
- feedReadEvidenceId?: string;
10
- workDiscoverEvidenceId?: string;
11
- taskClaimDryRunOk: boolean;
12
- executionAttemptRowsForDecision: number;
13
- }
14
- export interface RunNearRealConnectorSmokeInput {
15
- state: StateDatabase;
16
- observabilityDb: ObservabilityDatabase;
17
- workspaceRoot: string;
18
- }
19
- export declare function runNearRealConnectorSmoke(input: RunNearRealConnectorSmokeInput): Promise<NearRealConnectorSmokeResult>;
1
+ import type { ObservabilityDatabase } from "../../observability/db/index.js";
2
+ import type { StateDatabase } from "../../storage/db/index.js";
3
+ export interface NearRealConnectorSmokeResult {
4
+ generatedAt: string;
5
+ platforms: {
6
+ social: "moltbook";
7
+ agentNetwork: "evomap";
8
+ };
9
+ feedReadEvidenceId?: string;
10
+ workDiscoverEvidenceId?: string;
11
+ taskClaimDryRunOk: boolean;
12
+ executionAttemptRowsForDecision: number;
13
+ }
14
+ export interface RunNearRealConnectorSmokeInput {
15
+ state: StateDatabase;
16
+ observabilityDb: ObservabilityDatabase;
17
+ workspaceRoot: string;
18
+ }
19
+ export declare function runNearRealConnectorSmoke(input: RunNearRealConnectorSmokeInput): Promise<NearRealConnectorSmokeResult>;