@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,144 +1,144 @@
|
|
|
1
|
-
import * as crypto from "crypto";
|
|
2
|
-
function needsLease(effectClass) {
|
|
3
|
-
return effectClass === "external_platform_action" || effectClass === "connector_action" || effectClass === "user_outreach";
|
|
4
|
-
}
|
|
5
|
-
function needsCheckpoint(effectClass) {
|
|
6
|
-
return effectClass !== "maintenance" && effectClass !== "no_effect";
|
|
7
|
-
}
|
|
8
|
-
function isConnectorEffect(effectClass) {
|
|
9
|
-
return effectClass === "external_platform_action" || effectClass === "connector_action";
|
|
10
|
-
}
|
|
11
|
-
function toCapabilityIntent(intent) {
|
|
12
|
-
if (intent.kind === "work")
|
|
13
|
-
return "work.discover";
|
|
14
|
-
if (intent.kind === "exploration")
|
|
15
|
-
return "feed.read";
|
|
16
|
-
if (intent.kind === "social")
|
|
17
|
-
return "comment.reply";
|
|
18
|
-
if (intent.kind === "outreach")
|
|
19
|
-
return "message.send";
|
|
20
|
-
if (intent.kind === "quiet")
|
|
21
|
-
return "feed.read";
|
|
22
|
-
return "feed.read";
|
|
23
|
-
}
|
|
24
|
-
export class EffectDispatcher {
|
|
25
|
-
leaseManager;
|
|
26
|
-
commitPort;
|
|
27
|
-
connectorExecutor;
|
|
28
|
-
checkpointPort;
|
|
29
|
-
memoryPort;
|
|
30
|
-
reflectionPort;
|
|
31
|
-
constructor(leaseManager, commitPort, connectorExecutor, checkpointPort, memoryPort, reflectionPort) {
|
|
32
|
-
this.leaseManager = leaseManager;
|
|
33
|
-
this.commitPort = commitPort;
|
|
34
|
-
this.connectorExecutor = connectorExecutor;
|
|
35
|
-
this.checkpointPort = checkpointPort;
|
|
36
|
-
this.memoryPort = memoryPort;
|
|
37
|
-
this.reflectionPort = reflectionPort;
|
|
38
|
-
}
|
|
39
|
-
async dispatchEffect(intent, decision) {
|
|
40
|
-
const lease = needsLease(intent.effectClass)
|
|
41
|
-
? await this.leaseManager.acquire(intent.effectClass, intent.platformId ?? intent.id)
|
|
42
|
-
: await this.leaseManager.acquire("maintenance");
|
|
43
|
-
if (!lease.granted) {
|
|
44
|
-
return { status: "deferred", reason: "lease_unavailable" };
|
|
45
|
-
}
|
|
46
|
-
if (needsCheckpoint(intent.effectClass)) {
|
|
47
|
-
await this.checkpointPort.saveCheckpoint({
|
|
48
|
-
id: decision.checkpointId,
|
|
49
|
-
tickId: decision.tickId,
|
|
50
|
-
intentId: decision.intentId,
|
|
51
|
-
phase: isConnectorEffect(intent.effectClass) ? "before_effect" : "before_quiet_write",
|
|
52
|
-
snapshotRef: decision.traceId,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
const commit = await this.commitPort.createIntentCommitRecord({
|
|
56
|
-
intentId: decision.intentId,
|
|
57
|
-
decisionId: decision.decisionId,
|
|
58
|
-
checkpointId: decision.checkpointId,
|
|
59
|
-
state: "planned",
|
|
60
|
-
});
|
|
61
|
-
try {
|
|
62
|
-
if (isConnectorEffect(intent.effectClass)) {
|
|
63
|
-
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
64
|
-
const result = await this.connectorExecutor.executeEffect({
|
|
65
|
-
platformId: intent.platformId ?? "unknown",
|
|
66
|
-
intent: toCapabilityIntent(intent),
|
|
67
|
-
payload: intent.payload ?? {},
|
|
68
|
-
decisionId: decision.decisionId,
|
|
69
|
-
intentId: decision.intentId,
|
|
70
|
-
idempotencyKey: `idem:${decision.decisionId}:${decision.intentId}`,
|
|
71
|
-
});
|
|
72
|
-
if (result.status === "success") {
|
|
73
|
-
await this.commitPort.advanceIntentCommitState(commit.id, "externally_acknowledged", {
|
|
74
|
-
outcomeRef: result.metadata.platformId,
|
|
75
|
-
});
|
|
76
|
-
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
77
|
-
traceId: decision.traceId,
|
|
78
|
-
outcomeRef: result.metadata.platformId,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
if (result.status === "retryable_failure") {
|
|
83
|
-
await this.commitPort.advanceIntentCommitState(commit.id, "reconcile", {
|
|
84
|
-
failureClass: result.failureClass,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
await this.commitPort.abortIntentCommit(commit.id, result.failureClass ?? "external_effect_failed");
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return { status: "effect_executed", result, commitId: commit.id };
|
|
92
|
-
}
|
|
93
|
-
if (intent.effectClass === "memory_curation") {
|
|
94
|
-
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
95
|
-
await this.memoryPort.persistCurationResult({
|
|
96
|
-
summary: intent.summary,
|
|
97
|
-
sourceRefs: [decision.traceId],
|
|
98
|
-
traceId: decision.traceId,
|
|
99
|
-
});
|
|
100
|
-
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
101
|
-
traceId: decision.traceId,
|
|
102
|
-
outcomeRef: "memory_curation",
|
|
103
|
-
});
|
|
104
|
-
return { status: "curated", commitId: commit.id };
|
|
105
|
-
}
|
|
106
|
-
if (intent.effectClass === "narrative_reflection") {
|
|
107
|
-
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
108
|
-
const reflection = await this.reflectionPort.runNarrativeReflection({
|
|
109
|
-
decisionId: decision.decisionId,
|
|
110
|
-
intentId: decision.intentId,
|
|
111
|
-
traceId: decision.traceId,
|
|
112
|
-
});
|
|
113
|
-
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
114
|
-
traceId: decision.traceId,
|
|
115
|
-
outcomeRef: reflection.outcomeRef,
|
|
116
|
-
});
|
|
117
|
-
return { status: "reflected", commitId: commit.id };
|
|
118
|
-
}
|
|
119
|
-
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
120
|
-
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
121
|
-
traceId: decision.traceId,
|
|
122
|
-
outcomeRef: "maintenance",
|
|
123
|
-
});
|
|
124
|
-
return { status: "maintenance_done", commitId: commit.id };
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
await this.commitPort.abortIntentCommit(commit.id, String(error));
|
|
128
|
-
throw error;
|
|
129
|
-
}
|
|
130
|
-
finally {
|
|
131
|
-
await lease.release();
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
export function buildDecisionContext(input) {
|
|
136
|
-
const decisionId = input.decisionId ?? crypto.randomUUID();
|
|
137
|
-
return {
|
|
138
|
-
decisionId,
|
|
139
|
-
intentId: input.intentId,
|
|
140
|
-
tickId: input.tickId,
|
|
141
|
-
checkpointId: `checkpoint:${input.intentId}:${Date.now()}`,
|
|
142
|
-
traceId: `trace:${decisionId}`,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
1
|
+
import * as crypto from "crypto";
|
|
2
|
+
function needsLease(effectClass) {
|
|
3
|
+
return effectClass === "external_platform_action" || effectClass === "connector_action" || effectClass === "user_outreach";
|
|
4
|
+
}
|
|
5
|
+
function needsCheckpoint(effectClass) {
|
|
6
|
+
return effectClass !== "maintenance" && effectClass !== "no_effect";
|
|
7
|
+
}
|
|
8
|
+
function isConnectorEffect(effectClass) {
|
|
9
|
+
return effectClass === "external_platform_action" || effectClass === "connector_action";
|
|
10
|
+
}
|
|
11
|
+
function toCapabilityIntent(intent) {
|
|
12
|
+
if (intent.kind === "work")
|
|
13
|
+
return "work.discover";
|
|
14
|
+
if (intent.kind === "exploration")
|
|
15
|
+
return "feed.read";
|
|
16
|
+
if (intent.kind === "social")
|
|
17
|
+
return "comment.reply";
|
|
18
|
+
if (intent.kind === "outreach")
|
|
19
|
+
return "message.send";
|
|
20
|
+
if (intent.kind === "quiet")
|
|
21
|
+
return "feed.read";
|
|
22
|
+
return "feed.read";
|
|
23
|
+
}
|
|
24
|
+
export class EffectDispatcher {
|
|
25
|
+
leaseManager;
|
|
26
|
+
commitPort;
|
|
27
|
+
connectorExecutor;
|
|
28
|
+
checkpointPort;
|
|
29
|
+
memoryPort;
|
|
30
|
+
reflectionPort;
|
|
31
|
+
constructor(leaseManager, commitPort, connectorExecutor, checkpointPort, memoryPort, reflectionPort) {
|
|
32
|
+
this.leaseManager = leaseManager;
|
|
33
|
+
this.commitPort = commitPort;
|
|
34
|
+
this.connectorExecutor = connectorExecutor;
|
|
35
|
+
this.checkpointPort = checkpointPort;
|
|
36
|
+
this.memoryPort = memoryPort;
|
|
37
|
+
this.reflectionPort = reflectionPort;
|
|
38
|
+
}
|
|
39
|
+
async dispatchEffect(intent, decision) {
|
|
40
|
+
const lease = needsLease(intent.effectClass)
|
|
41
|
+
? await this.leaseManager.acquire(intent.effectClass, intent.platformId ?? intent.id)
|
|
42
|
+
: await this.leaseManager.acquire("maintenance");
|
|
43
|
+
if (!lease.granted) {
|
|
44
|
+
return { status: "deferred", reason: "lease_unavailable" };
|
|
45
|
+
}
|
|
46
|
+
if (needsCheckpoint(intent.effectClass)) {
|
|
47
|
+
await this.checkpointPort.saveCheckpoint({
|
|
48
|
+
id: decision.checkpointId,
|
|
49
|
+
tickId: decision.tickId,
|
|
50
|
+
intentId: decision.intentId,
|
|
51
|
+
phase: isConnectorEffect(intent.effectClass) ? "before_effect" : "before_quiet_write",
|
|
52
|
+
snapshotRef: decision.traceId,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const commit = await this.commitPort.createIntentCommitRecord({
|
|
56
|
+
intentId: decision.intentId,
|
|
57
|
+
decisionId: decision.decisionId,
|
|
58
|
+
checkpointId: decision.checkpointId,
|
|
59
|
+
state: "planned",
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
if (isConnectorEffect(intent.effectClass)) {
|
|
63
|
+
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
64
|
+
const result = await this.connectorExecutor.executeEffect({
|
|
65
|
+
platformId: intent.platformId ?? "unknown",
|
|
66
|
+
intent: toCapabilityIntent(intent),
|
|
67
|
+
payload: intent.payload ?? {},
|
|
68
|
+
decisionId: decision.decisionId,
|
|
69
|
+
intentId: decision.intentId,
|
|
70
|
+
idempotencyKey: `idem:${decision.decisionId}:${decision.intentId}`,
|
|
71
|
+
});
|
|
72
|
+
if (result.status === "success") {
|
|
73
|
+
await this.commitPort.advanceIntentCommitState(commit.id, "externally_acknowledged", {
|
|
74
|
+
outcomeRef: result.metadata.platformId,
|
|
75
|
+
});
|
|
76
|
+
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
77
|
+
traceId: decision.traceId,
|
|
78
|
+
outcomeRef: result.metadata.platformId,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
if (result.status === "retryable_failure") {
|
|
83
|
+
await this.commitPort.advanceIntentCommitState(commit.id, "reconcile", {
|
|
84
|
+
failureClass: result.failureClass,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
await this.commitPort.abortIntentCommit(commit.id, result.failureClass ?? "external_effect_failed");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { status: "effect_executed", result, commitId: commit.id };
|
|
92
|
+
}
|
|
93
|
+
if (intent.effectClass === "memory_curation") {
|
|
94
|
+
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
95
|
+
await this.memoryPort.persistCurationResult({
|
|
96
|
+
summary: intent.summary,
|
|
97
|
+
sourceRefs: [decision.traceId],
|
|
98
|
+
traceId: decision.traceId,
|
|
99
|
+
});
|
|
100
|
+
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
101
|
+
traceId: decision.traceId,
|
|
102
|
+
outcomeRef: "memory_curation",
|
|
103
|
+
});
|
|
104
|
+
return { status: "curated", commitId: commit.id };
|
|
105
|
+
}
|
|
106
|
+
if (intent.effectClass === "narrative_reflection") {
|
|
107
|
+
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
108
|
+
const reflection = await this.reflectionPort.runNarrativeReflection({
|
|
109
|
+
decisionId: decision.decisionId,
|
|
110
|
+
intentId: decision.intentId,
|
|
111
|
+
traceId: decision.traceId,
|
|
112
|
+
});
|
|
113
|
+
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
114
|
+
traceId: decision.traceId,
|
|
115
|
+
outcomeRef: reflection.outcomeRef,
|
|
116
|
+
});
|
|
117
|
+
return { status: "reflected", commitId: commit.id };
|
|
118
|
+
}
|
|
119
|
+
await this.commitPort.advanceIntentCommitState(commit.id, "dispatched");
|
|
120
|
+
await this.commitPort.commitIntentOutcome(commit.id, {
|
|
121
|
+
traceId: decision.traceId,
|
|
122
|
+
outcomeRef: "maintenance",
|
|
123
|
+
});
|
|
124
|
+
return { status: "maintenance_done", commitId: commit.id };
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
await this.commitPort.abortIntentCommit(commit.id, String(error));
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
await lease.release();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export function buildDecisionContext(input) {
|
|
136
|
+
const decisionId = input.decisionId ?? crypto.randomUUID();
|
|
137
|
+
return {
|
|
138
|
+
decisionId,
|
|
139
|
+
intentId: input.intentId,
|
|
140
|
+
tickId: input.tickId,
|
|
141
|
+
checkpointId: `checkpoint:${input.intentId}:${Date.now()}`,
|
|
142
|
+
traceId: `trace:${decisionId}`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { CandidateIntent, ContinuitySnapshot, GuardEvaluation } from "../types.js";
|
|
2
|
-
import type { HeartbeatRuntimeSnapshot } from "../heartbeat/runtime-snapshot.js";
|
|
3
|
-
/**
|
|
4
|
-
* Hard guard evaluation (T2.1.3): source, dedupe, cooldown, quiet bias, budget, risk, awaiting user.
|
|
5
|
-
*/
|
|
6
|
-
export declare function evaluateHardGuards(intent: CandidateIntent, runtime: HeartbeatRuntimeSnapshot): GuardEvaluation;
|
|
7
|
-
/** Continuity-only guard path for legacy call sites; builds a minimal runtime snapshot. */
|
|
8
|
-
export declare function evaluateGuards(intent: CandidateIntent, snapshot: ContinuitySnapshot): GuardEvaluation;
|
|
1
|
+
import type { CandidateIntent, ContinuitySnapshot, GuardEvaluation } from "../types.js";
|
|
2
|
+
import type { HeartbeatRuntimeSnapshot } from "../heartbeat/runtime-snapshot.js";
|
|
3
|
+
/**
|
|
4
|
+
* Hard guard evaluation (T2.1.3): source, dedupe, cooldown, quiet bias, budget, risk, awaiting user.
|
|
5
|
+
*/
|
|
6
|
+
export declare function evaluateHardGuards(intent: CandidateIntent, runtime: HeartbeatRuntimeSnapshot): GuardEvaluation;
|
|
7
|
+
/** Continuity-only guard path for legacy call sites; builds a minimal runtime snapshot. */
|
|
8
|
+
export declare function evaluateGuards(intent: CandidateIntent, snapshot: ContinuitySnapshot): GuardEvaluation;
|
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
import { buildHeartbeatRuntimeSnapshot } from "../heartbeat/runtime-snapshot.js";
|
|
2
|
-
const QUIET_DENY_KINDS = ["outreach", "social"];
|
|
3
|
-
function intentFingerprint(intent) {
|
|
4
|
-
return intent.idempotencyKey ?? `${intent.kind}:${intent.summary}`;
|
|
5
|
-
}
|
|
6
|
-
function isBudgetExceeded(intent, snapshot) {
|
|
7
|
-
if (intent.kind !== "social")
|
|
8
|
-
return false;
|
|
9
|
-
if (!snapshot.budgets)
|
|
10
|
-
return false;
|
|
11
|
-
return snapshot.budgets.socialUsed >= snapshot.budgets.socialLimit;
|
|
12
|
-
}
|
|
13
|
-
function isQuietSuppressed(intent, runtime) {
|
|
14
|
-
if (!runtime.rhythmWindow.quietBias)
|
|
15
|
-
return false;
|
|
16
|
-
if (QUIET_DENY_KINDS.includes(intent.kind)) {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
if (intent.effectClass === "connector_action" || intent.effectClass === "external_platform_action") {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
function isSourceBacked(intent) {
|
|
25
|
-
if (intent.sourceRefs.length > 0)
|
|
26
|
-
return true;
|
|
27
|
-
if (intent.effectClass === "maintenance" || intent.effectClass === "no_effect")
|
|
28
|
-
return true;
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
function isRiskBlocked(intent, snapshot) {
|
|
32
|
-
if (!snapshot.riskSuppressed)
|
|
33
|
-
return false;
|
|
34
|
-
return intent.kind === "exploration" || intent.kind === "social" || intent.kind === "outreach";
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Hard guard evaluation (T2.1.3): source, dedupe, cooldown, quiet bias, budget, risk, awaiting user.
|
|
38
|
-
*/
|
|
39
|
-
export function evaluateHardGuards(intent, runtime) {
|
|
40
|
-
const snapshot = runtime.continuity;
|
|
41
|
-
const reasons = [];
|
|
42
|
-
if (!isSourceBacked(intent)) {
|
|
43
|
-
reasons.push("missing_source_refs");
|
|
44
|
-
}
|
|
45
|
-
const key = intentFingerprint(intent);
|
|
46
|
-
if (runtime.hardGuards.hasDuplicateIntent(key)) {
|
|
47
|
-
reasons.push("duplicate_intent");
|
|
48
|
-
}
|
|
49
|
-
if (intent.effectClass === "user_outreach" && !runtime.hardGuards.isOutreachCooldownClear(key)) {
|
|
50
|
-
reasons.push("outreach_cooldown");
|
|
51
|
-
}
|
|
52
|
-
if (isQuietSuppressed(intent, runtime)) {
|
|
53
|
-
reasons.push("quiet_window_suppression");
|
|
54
|
-
}
|
|
55
|
-
if (isBudgetExceeded(intent, snapshot)) {
|
|
56
|
-
reasons.push("budget_exceeded");
|
|
57
|
-
}
|
|
58
|
-
if (snapshot.awaitingUserInput) {
|
|
59
|
-
reasons.push("awaiting_user");
|
|
60
|
-
}
|
|
61
|
-
if (isRiskBlocked(intent, snapshot)) {
|
|
62
|
-
reasons.push("risk_suppressed");
|
|
63
|
-
}
|
|
64
|
-
if (reasons.length === 0) {
|
|
65
|
-
return {
|
|
66
|
-
verdict: "allow",
|
|
67
|
-
reasons: [],
|
|
68
|
-
quietSuppressed: false,
|
|
69
|
-
leaseRequired: intent.effectClass === "external_platform_action" ||
|
|
70
|
-
intent.effectClass === "connector_action" ||
|
|
71
|
-
intent.effectClass === "user_outreach",
|
|
72
|
-
requiresCheckpoint: intent.effectClass !== "maintenance" && intent.effectClass !== "no_effect",
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
const duplicate = reasons.includes("duplicate_intent");
|
|
76
|
-
const cooldown = reasons.includes("outreach_cooldown");
|
|
77
|
-
if (duplicate || cooldown) {
|
|
78
|
-
return {
|
|
79
|
-
verdict: "defer",
|
|
80
|
-
reasons,
|
|
81
|
-
quietSuppressed: reasons.includes("quiet_window_suppression"),
|
|
82
|
-
leaseRequired: false,
|
|
83
|
-
requiresCheckpoint: false,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
const escalated = reasons.includes("awaiting_user") && intent.kind === "outreach";
|
|
87
|
-
return {
|
|
88
|
-
verdict: escalated ? "escalate" : "deny",
|
|
89
|
-
reasons,
|
|
90
|
-
quietSuppressed: reasons.includes("quiet_window_suppression"),
|
|
91
|
-
leaseRequired: false,
|
|
92
|
-
requiresCheckpoint: false,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
/** Continuity-only guard path for legacy call sites; builds a minimal runtime snapshot. */
|
|
96
|
-
export function evaluateGuards(intent, snapshot) {
|
|
97
|
-
const inputs = {
|
|
98
|
-
mode: snapshot.mode,
|
|
99
|
-
currentWindowId: snapshot.currentWindowId,
|
|
100
|
-
pendingObligations: snapshot.pendingObligations,
|
|
101
|
-
recentOutreachHashes: snapshot.recentOutreachHashes,
|
|
102
|
-
deniedIntents: snapshot.deniedIntents,
|
|
103
|
-
budgets: snapshot.budgets,
|
|
104
|
-
awaitingUserInput: snapshot.awaitingUserInput,
|
|
105
|
-
riskSuppressed: snapshot.riskSuppressed,
|
|
106
|
-
quietEnabledBridge: snapshot.mode === "quiet",
|
|
107
|
-
};
|
|
108
|
-
const runtime = buildHeartbeatRuntimeSnapshot("2026-03-25T12:00:00.000Z", inputs, snapshot);
|
|
109
|
-
return evaluateHardGuards(intent, runtime);
|
|
110
|
-
}
|
|
1
|
+
import { buildHeartbeatRuntimeSnapshot } from "../heartbeat/runtime-snapshot.js";
|
|
2
|
+
const QUIET_DENY_KINDS = ["outreach", "social"];
|
|
3
|
+
function intentFingerprint(intent) {
|
|
4
|
+
return intent.idempotencyKey ?? `${intent.kind}:${intent.summary}`;
|
|
5
|
+
}
|
|
6
|
+
function isBudgetExceeded(intent, snapshot) {
|
|
7
|
+
if (intent.kind !== "social")
|
|
8
|
+
return false;
|
|
9
|
+
if (!snapshot.budgets)
|
|
10
|
+
return false;
|
|
11
|
+
return snapshot.budgets.socialUsed >= snapshot.budgets.socialLimit;
|
|
12
|
+
}
|
|
13
|
+
function isQuietSuppressed(intent, runtime) {
|
|
14
|
+
if (!runtime.rhythmWindow.quietBias)
|
|
15
|
+
return false;
|
|
16
|
+
if (QUIET_DENY_KINDS.includes(intent.kind)) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (intent.effectClass === "connector_action" || intent.effectClass === "external_platform_action") {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
function isSourceBacked(intent) {
|
|
25
|
+
if (intent.sourceRefs.length > 0)
|
|
26
|
+
return true;
|
|
27
|
+
if (intent.effectClass === "maintenance" || intent.effectClass === "no_effect")
|
|
28
|
+
return true;
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
function isRiskBlocked(intent, snapshot) {
|
|
32
|
+
if (!snapshot.riskSuppressed)
|
|
33
|
+
return false;
|
|
34
|
+
return intent.kind === "exploration" || intent.kind === "social" || intent.kind === "outreach";
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Hard guard evaluation (T2.1.3): source, dedupe, cooldown, quiet bias, budget, risk, awaiting user.
|
|
38
|
+
*/
|
|
39
|
+
export function evaluateHardGuards(intent, runtime) {
|
|
40
|
+
const snapshot = runtime.continuity;
|
|
41
|
+
const reasons = [];
|
|
42
|
+
if (!isSourceBacked(intent)) {
|
|
43
|
+
reasons.push("missing_source_refs");
|
|
44
|
+
}
|
|
45
|
+
const key = intentFingerprint(intent);
|
|
46
|
+
if (runtime.hardGuards.hasDuplicateIntent(key)) {
|
|
47
|
+
reasons.push("duplicate_intent");
|
|
48
|
+
}
|
|
49
|
+
if (intent.effectClass === "user_outreach" && !runtime.hardGuards.isOutreachCooldownClear(key)) {
|
|
50
|
+
reasons.push("outreach_cooldown");
|
|
51
|
+
}
|
|
52
|
+
if (isQuietSuppressed(intent, runtime)) {
|
|
53
|
+
reasons.push("quiet_window_suppression");
|
|
54
|
+
}
|
|
55
|
+
if (isBudgetExceeded(intent, snapshot)) {
|
|
56
|
+
reasons.push("budget_exceeded");
|
|
57
|
+
}
|
|
58
|
+
if (snapshot.awaitingUserInput) {
|
|
59
|
+
reasons.push("awaiting_user");
|
|
60
|
+
}
|
|
61
|
+
if (isRiskBlocked(intent, snapshot)) {
|
|
62
|
+
reasons.push("risk_suppressed");
|
|
63
|
+
}
|
|
64
|
+
if (reasons.length === 0) {
|
|
65
|
+
return {
|
|
66
|
+
verdict: "allow",
|
|
67
|
+
reasons: [],
|
|
68
|
+
quietSuppressed: false,
|
|
69
|
+
leaseRequired: intent.effectClass === "external_platform_action" ||
|
|
70
|
+
intent.effectClass === "connector_action" ||
|
|
71
|
+
intent.effectClass === "user_outreach",
|
|
72
|
+
requiresCheckpoint: intent.effectClass !== "maintenance" && intent.effectClass !== "no_effect",
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const duplicate = reasons.includes("duplicate_intent");
|
|
76
|
+
const cooldown = reasons.includes("outreach_cooldown");
|
|
77
|
+
if (duplicate || cooldown) {
|
|
78
|
+
return {
|
|
79
|
+
verdict: "defer",
|
|
80
|
+
reasons,
|
|
81
|
+
quietSuppressed: reasons.includes("quiet_window_suppression"),
|
|
82
|
+
leaseRequired: false,
|
|
83
|
+
requiresCheckpoint: false,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const escalated = reasons.includes("awaiting_user") && intent.kind === "outreach";
|
|
87
|
+
return {
|
|
88
|
+
verdict: escalated ? "escalate" : "deny",
|
|
89
|
+
reasons,
|
|
90
|
+
quietSuppressed: reasons.includes("quiet_window_suppression"),
|
|
91
|
+
leaseRequired: false,
|
|
92
|
+
requiresCheckpoint: false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/** Continuity-only guard path for legacy call sites; builds a minimal runtime snapshot. */
|
|
96
|
+
export function evaluateGuards(intent, snapshot) {
|
|
97
|
+
const inputs = {
|
|
98
|
+
mode: snapshot.mode,
|
|
99
|
+
currentWindowId: snapshot.currentWindowId,
|
|
100
|
+
pendingObligations: snapshot.pendingObligations,
|
|
101
|
+
recentOutreachHashes: snapshot.recentOutreachHashes,
|
|
102
|
+
deniedIntents: snapshot.deniedIntents,
|
|
103
|
+
budgets: snapshot.budgets,
|
|
104
|
+
awaitingUserInput: snapshot.awaitingUserInput,
|
|
105
|
+
riskSuppressed: snapshot.riskSuppressed,
|
|
106
|
+
quietEnabledBridge: snapshot.mode === "quiet",
|
|
107
|
+
};
|
|
108
|
+
const runtime = buildHeartbeatRuntimeSnapshot("2026-03-25T12:00:00.000Z", inputs, snapshot);
|
|
109
|
+
return evaluateHardGuards(intent, runtime);
|
|
110
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Candidate intent planner (T2.1.3): window-biased planning + priority cap.
|
|
3
|
-
* `planCandidateIntents` is the contract name; `planIntent` bridges legacy continuity-only tests.
|
|
4
|
-
*/
|
|
5
|
-
import type { CandidateIntent, ContinuitySnapshot, DecisionBasis } from "../types.js";
|
|
6
|
-
import type { HeartbeatRuntimeSnapshot } from "../heartbeat/runtime-snapshot.js";
|
|
7
|
-
/**
|
|
8
|
-
* Plan ordered candidates for one heartbeat turn using rhythm window + life evidence slice.
|
|
9
|
-
*/
|
|
10
|
-
export declare function planCandidateIntents(runtime: HeartbeatRuntimeSnapshot): CandidateIntent[];
|
|
11
|
-
/** @deprecated Continuity-only helper for tests; prefer `planCandidateIntents` + `buildHeartbeatRuntimeSnapshot`. */
|
|
12
|
-
export declare function planIntent(snapshot: ContinuitySnapshot): CandidateIntent[];
|
|
13
|
-
export declare function decideDecisionBasis(intent: CandidateIntent): DecisionBasis;
|
|
1
|
+
/**
|
|
2
|
+
* Candidate intent planner (T2.1.3): window-biased planning + priority cap.
|
|
3
|
+
* `planCandidateIntents` is the contract name; `planIntent` bridges legacy continuity-only tests.
|
|
4
|
+
*/
|
|
5
|
+
import type { CandidateIntent, ContinuitySnapshot, DecisionBasis } from "../types.js";
|
|
6
|
+
import type { HeartbeatRuntimeSnapshot } from "../heartbeat/runtime-snapshot.js";
|
|
7
|
+
/**
|
|
8
|
+
* Plan ordered candidates for one heartbeat turn using rhythm window + life evidence slice.
|
|
9
|
+
*/
|
|
10
|
+
export declare function planCandidateIntents(runtime: HeartbeatRuntimeSnapshot): CandidateIntent[];
|
|
11
|
+
/** @deprecated Continuity-only helper for tests; prefer `planCandidateIntents` + `buildHeartbeatRuntimeSnapshot`. */
|
|
12
|
+
export declare function planIntent(snapshot: ContinuitySnapshot): CandidateIntent[];
|
|
13
|
+
export declare function decideDecisionBasis(intent: CandidateIntent): DecisionBasis;
|