@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,139 +1,162 @@
|
|
|
1
|
-
import { buildContinuitySnapshot } from "./snapshot-builder.js";
|
|
2
|
-
import { buildHeartbeatRuntimeSnapshot } from "./runtime-snapshot.js";
|
|
3
|
-
import { planCandidateIntents } from "../orchestrator/intent-planner.js";
|
|
4
|
-
import { evaluateHardGuards } from "../orchestrator/guard-layer.js";
|
|
5
|
-
import { dispatchUserOutreachIntent } from "../outreach/dispatch-user-outreach.js";
|
|
6
|
-
import { buildJudgeOutreachInputFromSnapshot } from "../outreach/judge-input-from-snapshot.js";
|
|
7
|
-
import { runSourceBackedQuiet } from "../quiet/run-source-backed-quiet.js";
|
|
8
|
-
/**
|
|
9
|
-
* Resolves the heartbeat outcome for a guard-allowed intent (outreach dispatch, quiet orchestration, or default).
|
|
10
|
-
* Exported for unit tests (CR-M1 wiring).
|
|
11
|
-
*/
|
|
12
|
-
export async function resolveAllowedIntentResult(intent, runtime, inputs, signal, deps) {
|
|
13
|
-
const day = typeof signal.payload.timestamp === "string"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
1
|
+
import { buildContinuitySnapshot, } from "./snapshot-builder.js";
|
|
2
|
+
import { buildHeartbeatRuntimeSnapshot, } from "./runtime-snapshot.js";
|
|
3
|
+
import { planCandidateIntents } from "../orchestrator/intent-planner.js";
|
|
4
|
+
import { evaluateHardGuards } from "../orchestrator/guard-layer.js";
|
|
5
|
+
import { dispatchUserOutreachIntent, } from "../outreach/dispatch-user-outreach.js";
|
|
6
|
+
import { buildJudgeOutreachInputFromSnapshot } from "../outreach/judge-input-from-snapshot.js";
|
|
7
|
+
import { runSourceBackedQuiet } from "../quiet/run-source-backed-quiet.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolves the heartbeat outcome for a guard-allowed intent (outreach dispatch, quiet orchestration, or default).
|
|
10
|
+
* Exported for unit tests (CR-M1 wiring).
|
|
11
|
+
*/
|
|
12
|
+
export async function resolveAllowedIntentResult(intent, runtime, inputs, signal, deps) {
|
|
13
|
+
const day = typeof signal.payload.timestamp === "string"
|
|
14
|
+
? signal.payload.timestamp.slice(0, 10)
|
|
15
|
+
: "1970-01-01";
|
|
16
|
+
if (intent.effectClass === "user_outreach" && deps.outreachDispatch) {
|
|
17
|
+
return dispatchUserOutreachIntent({
|
|
18
|
+
candidate: intent,
|
|
19
|
+
snapshot: runtime,
|
|
20
|
+
judgeInput: buildJudgeOutreachInputFromSnapshot(intent, runtime, inputs),
|
|
21
|
+
guidance: deps.outreachDispatch.guidance,
|
|
22
|
+
delivery: deps.outreachDispatch.delivery,
|
|
23
|
+
state: deps.outreachDispatch.state,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (deps.quietWorkflow &&
|
|
27
|
+
(intent.kind === "quiet" ||
|
|
28
|
+
(intent.kind === "reflection" &&
|
|
29
|
+
intent.effectClass === "narrative_reflection"))) {
|
|
30
|
+
const quietRun = await runSourceBackedQuiet({
|
|
31
|
+
candidate: intent,
|
|
32
|
+
runtime,
|
|
33
|
+
day,
|
|
34
|
+
userInterestSnapshot: inputs.userInterestSnapshot,
|
|
35
|
+
workspaceRoot: deps.quietWorkflow.workspaceRoot,
|
|
36
|
+
});
|
|
37
|
+
return quietRun.result;
|
|
38
|
+
}
|
|
39
|
+
// T2.2.3 (CH-14-02/03 / CH-15-01): all intent_selected results must carry at least one
|
|
40
|
+
// machine-readable reason so operators can distinguish between effect classes:
|
|
41
|
+
// - maintenance / no_effect → "internal_tick" (no external side-effects)
|
|
42
|
+
// - connector_action without dispatch wired → "connector_dispatch_unwired"
|
|
43
|
+
// - external_platform_action / memory_curation → not generated by intent-planner today;
|
|
44
|
+
// if a future path produces them, they will reach the fallback [] branch below and
|
|
45
|
+
// should have dedicated reason codes added (e.g. "external_platform_action_unwired").
|
|
46
|
+
// - other (outreach / quiet) → caught by the early-return branches above
|
|
47
|
+
const noExternalEffect = intent.effectClass === "maintenance" ||
|
|
48
|
+
intent.effectClass === "no_effect" ||
|
|
49
|
+
intent.kind === "maintenance";
|
|
50
|
+
const connectorUnwired = intent.effectClass === "connector_action";
|
|
51
|
+
const reasons = noExternalEffect
|
|
52
|
+
? ["internal_tick"]
|
|
53
|
+
: connectorUnwired
|
|
54
|
+
? ["connector_dispatch_unwired"]
|
|
55
|
+
: [];
|
|
56
|
+
return {
|
|
57
|
+
scope: "rhythm",
|
|
58
|
+
status: "intent_selected",
|
|
59
|
+
selectedIntentId: intent.id,
|
|
60
|
+
reasons,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Ingest a heartbeat rhythm signal and drive one full decision round.
|
|
65
|
+
*/
|
|
66
|
+
export async function ingestRhythmSignal(signal, deps) {
|
|
67
|
+
const inputs = await deps.loadSnapshotInputs();
|
|
68
|
+
const snapshot = buildContinuitySnapshot(inputs);
|
|
69
|
+
const timestamp = signal.payload.timestamp;
|
|
70
|
+
const runtime = buildHeartbeatRuntimeSnapshot(timestamp, inputs, snapshot);
|
|
71
|
+
const candidates = planCandidateIntents(runtime);
|
|
72
|
+
const emitTrace = async (result) => {
|
|
73
|
+
if (!deps.recordDecisionTrace)
|
|
74
|
+
return;
|
|
75
|
+
await deps.recordDecisionTrace({
|
|
76
|
+
scope: result.scope,
|
|
77
|
+
status: result.status,
|
|
78
|
+
reasons: result.reasons,
|
|
79
|
+
selectedIntentId: result.selectedIntentId,
|
|
80
|
+
rhythmWindowId: runtime.rhythmWindow.windowId,
|
|
81
|
+
allowedIntentKinds: [...runtime.rhythmWindow.allowedIntentKinds],
|
|
82
|
+
candidateCount: candidates.length,
|
|
83
|
+
lifeEvidenceEmpty: runtime.lifeEvidence.evidenceRefs.length === 0 &&
|
|
84
|
+
runtime.lifeEvidence.platformEventCount === 0 &&
|
|
85
|
+
runtime.lifeEvidence.workEventCount === 0,
|
|
86
|
+
trigger: signal.trigger,
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
let hasCandidates = false;
|
|
90
|
+
let anyAllow = false;
|
|
91
|
+
let anyDefer = false;
|
|
92
|
+
let anyDeny = false;
|
|
93
|
+
const denyReasons = [];
|
|
94
|
+
for (const intent of candidates) {
|
|
95
|
+
hasCandidates = true;
|
|
96
|
+
const evaluation = evaluateHardGuards(intent, runtime);
|
|
97
|
+
if (evaluation.verdict === "allow") {
|
|
98
|
+
anyAllow = true;
|
|
99
|
+
const base = {
|
|
100
|
+
scope: "rhythm",
|
|
101
|
+
status: "intent_selected",
|
|
102
|
+
selectedIntentId: intent.id,
|
|
103
|
+
reasons: evaluation.reasons,
|
|
104
|
+
};
|
|
105
|
+
const resolved = await resolveAllowedIntentResult(intent, runtime, inputs, signal, deps);
|
|
106
|
+
const result = resolved.status === "intent_selected" &&
|
|
107
|
+
resolved.reasons.length === 0 &&
|
|
108
|
+
evaluation.reasons.length > 0
|
|
109
|
+
? { ...resolved, reasons: evaluation.reasons }
|
|
110
|
+
: resolved;
|
|
111
|
+
await emitTrace(result);
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
if (evaluation.verdict === "defer") {
|
|
115
|
+
anyDefer = true;
|
|
116
|
+
denyReasons.push(`${intent.id}:${evaluation.verdict}(${evaluation.reasons.join(",")})`);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
anyDeny = true;
|
|
120
|
+
denyReasons.push(`${intent.id}:${evaluation.verdict}(${evaluation.reasons.join(",")})`);
|
|
121
|
+
}
|
|
122
|
+
if (!hasCandidates) {
|
|
123
|
+
const result = {
|
|
124
|
+
scope: "rhythm",
|
|
125
|
+
status: "heartbeat_ok",
|
|
126
|
+
reasons: ["silent_no_candidates"],
|
|
127
|
+
};
|
|
128
|
+
await emitTrace(result);
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
if (!anyAllow && anyDefer && !anyDeny) {
|
|
132
|
+
const result = {
|
|
133
|
+
scope: "rhythm",
|
|
134
|
+
status: "deferred",
|
|
135
|
+
reasons: denyReasons.length > 0 ? denyReasons : ["all_candidates_deferred"],
|
|
136
|
+
};
|
|
137
|
+
await emitTrace(result);
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
if (!anyAllow && denyReasons.length > 0) {
|
|
141
|
+
const result = {
|
|
142
|
+
scope: "rhythm",
|
|
143
|
+
status: "denied",
|
|
144
|
+
reasons: denyReasons,
|
|
145
|
+
};
|
|
146
|
+
await emitTrace(result);
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
const result = {
|
|
150
|
+
scope: "rhythm",
|
|
151
|
+
status: "heartbeat_ok",
|
|
152
|
+
reasons: ["no_allow_verdict"],
|
|
153
|
+
};
|
|
154
|
+
await emitTrace(result);
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Build a snapshot directly from inputs (for testing or when state-system is unavailable).
|
|
159
|
+
*/
|
|
160
|
+
export function buildSnapshotFromInputs(inputs) {
|
|
161
|
+
return buildContinuitySnapshot(inputs);
|
|
162
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { type RuntimeScope, type RuntimeTrigger, type HeartbeatCycleStatus, type HeartbeatSignal, type ScopedRuntimeInput, type HeartbeatCycleResult, type ScopeRouteResult, } from "./signal.js";
|
|
2
|
-
export { buildContinuitySnapshot, type SnapshotInputs, } from "./snapshot-builder.js";
|
|
3
|
-
export { ingestRhythmSignal, resolveAllowedIntentResult, type HeartbeatDeps, type HeartbeatOutreachDispatchDeps, type HeartbeatQuietWorkflowDeps, type HeartbeatDecisionTracePayload, buildSnapshotFromInputs, } from "./heartbeat-loop.js";
|
|
4
|
-
export { buildHeartbeatRuntimeSnapshot, buildLifeEvidenceSliceFromInputs, buildHardGuardDeps, resolveRhythmPolicyForHeartbeat, isLifeEvidenceSliceEmpty, type HeartbeatRuntimeSnapshot, type PlannerLifeEvidenceSlice, type HardGuardDeps, } from "./runtime-snapshot.js";
|
|
5
|
-
export { buildPlannerRhythmWindow, type PlannerRhythmWindowSlice } from "../rhythm/planner-rhythm-window.js";
|
|
6
|
-
export { runHeartbeatCycle, type RunHeartbeatCycleInput } from "./run-heartbeat-cycle.js";
|
|
7
|
-
export { routeScopedInput, type ScopeRouterDeps, } from "./scope-router.js";
|
|
8
|
-
export { requestGuidanceForIntent, dispatchAllowedEffect, executeHeartbeatCycle, type GuidanceBridgeDeps, type EffectDispatchDeps, type HeartbeatExecutorDeps, type GuidanceBridgeResult, type HeartbeatExecutionResult, } from "./heartbeat-executor.js";
|
|
1
|
+
export { type RuntimeScope, type RuntimeTrigger, type HeartbeatCycleStatus, type HeartbeatSignal, type ScopedRuntimeInput, type HeartbeatCycleResult, type ScopeRouteResult, } from "./signal.js";
|
|
2
|
+
export { buildContinuitySnapshot, type SnapshotInputs, } from "./snapshot-builder.js";
|
|
3
|
+
export { ingestRhythmSignal, resolveAllowedIntentResult, type HeartbeatDeps, type HeartbeatOutreachDispatchDeps, type HeartbeatQuietWorkflowDeps, type HeartbeatDecisionTracePayload, buildSnapshotFromInputs, } from "./heartbeat-loop.js";
|
|
4
|
+
export { buildHeartbeatRuntimeSnapshot, buildLifeEvidenceSliceFromInputs, buildHardGuardDeps, resolveRhythmPolicyForHeartbeat, isLifeEvidenceSliceEmpty, type HeartbeatRuntimeSnapshot, type PlannerLifeEvidenceSlice, type HardGuardDeps, } from "./runtime-snapshot.js";
|
|
5
|
+
export { buildPlannerRhythmWindow, type PlannerRhythmWindowSlice } from "../rhythm/planner-rhythm-window.js";
|
|
6
|
+
export { runHeartbeatCycle, type RunHeartbeatCycleInput } from "./run-heartbeat-cycle.js";
|
|
7
|
+
export { routeScopedInput, type ScopeRouterDeps, } from "./scope-router.js";
|
|
8
|
+
export { requestGuidanceForIntent, dispatchAllowedEffect, executeHeartbeatCycle, type GuidanceBridgeDeps, type EffectDispatchDeps, type HeartbeatExecutorDeps, type GuidanceBridgeResult, type HeartbeatExecutionResult, } from "./heartbeat-executor.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { buildContinuitySnapshot, } from "./snapshot-builder.js";
|
|
2
|
-
export { ingestRhythmSignal, resolveAllowedIntentResult, buildSnapshotFromInputs, } from "./heartbeat-loop.js";
|
|
3
|
-
export { buildHeartbeatRuntimeSnapshot, buildLifeEvidenceSliceFromInputs, buildHardGuardDeps, resolveRhythmPolicyForHeartbeat, isLifeEvidenceSliceEmpty, } from "./runtime-snapshot.js";
|
|
4
|
-
export { buildPlannerRhythmWindow } from "../rhythm/planner-rhythm-window.js";
|
|
5
|
-
export { runHeartbeatCycle } from "./run-heartbeat-cycle.js";
|
|
6
|
-
export { routeScopedInput, } from "./scope-router.js";
|
|
7
|
-
export { requestGuidanceForIntent, dispatchAllowedEffect, executeHeartbeatCycle, } from "./heartbeat-executor.js";
|
|
1
|
+
export { buildContinuitySnapshot, } from "./snapshot-builder.js";
|
|
2
|
+
export { ingestRhythmSignal, resolveAllowedIntentResult, buildSnapshotFromInputs, } from "./heartbeat-loop.js";
|
|
3
|
+
export { buildHeartbeatRuntimeSnapshot, buildLifeEvidenceSliceFromInputs, buildHardGuardDeps, resolveRhythmPolicyForHeartbeat, isLifeEvidenceSliceEmpty, } from "./runtime-snapshot.js";
|
|
4
|
+
export { buildPlannerRhythmWindow } from "../rhythm/planner-rhythm-window.js";
|
|
5
|
+
export { runHeartbeatCycle } from "./run-heartbeat-cycle.js";
|
|
6
|
+
export { routeScopedInput, } from "./scope-router.js";
|
|
7
|
+
export { requestGuidanceForIntent, dispatchAllowedEffect, executeHeartbeatCycle, } from "./heartbeat-executor.js";
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Control-plane heartbeat cycle entry (T2.1.1).
|
|
3
|
-
*
|
|
4
|
-
* Core logic: runtime availability gate → scope routing (user_task bypasses rhythm) →
|
|
5
|
-
* rhythm path delegates to ingestRhythmSignal. Mirrors L0 control-plane-system §4.3.
|
|
6
|
-
*
|
|
7
|
-
* Boundaries: does not claim lived-experience completion when runtime is unavailable;
|
|
8
|
-
* user_task / user_reply do not enter the rhythm candidate planner.
|
|
9
|
-
*/
|
|
10
|
-
import type { HeartbeatSignal, HeartbeatCycleResult } from "./signal.js";
|
|
11
|
-
import type { HeartbeatDeps } from "./heartbeat-loop.js";
|
|
12
|
-
export interface RunHeartbeatCycleInput {
|
|
13
|
-
signal: HeartbeatSignal;
|
|
14
|
-
/** When false, return runtime_carrier_only without loading snapshots (host-safe carrier). */
|
|
15
|
-
runtimeAvailable: boolean;
|
|
16
|
-
deps: HeartbeatDeps;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Single entry for one heartbeat turn: scope routing, runtime gate, then rhythm loop if applicable.
|
|
20
|
-
*/
|
|
21
|
-
export declare function runHeartbeatCycle(input: RunHeartbeatCycleInput): Promise<HeartbeatCycleResult>;
|
|
1
|
+
/**
|
|
2
|
+
* Control-plane heartbeat cycle entry (T2.1.1).
|
|
3
|
+
*
|
|
4
|
+
* Core logic: runtime availability gate → scope routing (user_task bypasses rhythm) →
|
|
5
|
+
* rhythm path delegates to ingestRhythmSignal. Mirrors L0 control-plane-system §4.3.
|
|
6
|
+
*
|
|
7
|
+
* Boundaries: does not claim lived-experience completion when runtime is unavailable;
|
|
8
|
+
* user_task / user_reply do not enter the rhythm candidate planner.
|
|
9
|
+
*/
|
|
10
|
+
import type { HeartbeatSignal, HeartbeatCycleResult } from "./signal.js";
|
|
11
|
+
import type { HeartbeatDeps } from "./heartbeat-loop.js";
|
|
12
|
+
export interface RunHeartbeatCycleInput {
|
|
13
|
+
signal: HeartbeatSignal;
|
|
14
|
+
/** When false, return runtime_carrier_only without loading snapshots (host-safe carrier). */
|
|
15
|
+
runtimeAvailable: boolean;
|
|
16
|
+
deps: HeartbeatDeps;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Single entry for one heartbeat turn: scope routing, runtime gate, then rhythm loop if applicable.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runHeartbeatCycle(input: RunHeartbeatCycleInput): Promise<HeartbeatCycleResult>;
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { ingestRhythmSignal } from "./heartbeat-loop.js";
|
|
2
|
-
import { routeScopedInput } from "./scope-router.js";
|
|
3
|
-
/**
|
|
4
|
-
* Single entry for one heartbeat turn: scope routing, runtime gate, then rhythm loop if applicable.
|
|
5
|
-
*/
|
|
6
|
-
export async function runHeartbeatCycle(input) {
|
|
7
|
-
const scoped = {
|
|
8
|
-
trigger: input.signal.trigger,
|
|
9
|
-
scopeHint: input.signal.scopeHint,
|
|
10
|
-
payload: input.signal.payload,
|
|
11
|
-
};
|
|
12
|
-
const route = routeScopedInput(scoped);
|
|
13
|
-
if (!input.runtimeAvailable) {
|
|
14
|
-
return {
|
|
15
|
-
scope: route.scope,
|
|
16
|
-
status: "runtime_carrier_only",
|
|
17
|
-
reasons: ["runtime_unavailable_no_lived_experience_loop"],
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
if (route.scope === "user_task") {
|
|
21
|
-
return {
|
|
22
|
-
scope: "user_task",
|
|
23
|
-
status: "heartbeat_ok",
|
|
24
|
-
reasons: ["rhythm_gate_bypass_user_task"],
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
if (route.scope === "user_reply") {
|
|
28
|
-
return {
|
|
29
|
-
scope: "user_reply",
|
|
30
|
-
status: "heartbeat_ok",
|
|
31
|
-
reasons: ["user_reply_light_continuity_skeleton"],
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
return ingestRhythmSignal(input.signal, input.deps);
|
|
35
|
-
}
|
|
1
|
+
import { ingestRhythmSignal } from "./heartbeat-loop.js";
|
|
2
|
+
import { routeScopedInput } from "./scope-router.js";
|
|
3
|
+
/**
|
|
4
|
+
* Single entry for one heartbeat turn: scope routing, runtime gate, then rhythm loop if applicable.
|
|
5
|
+
*/
|
|
6
|
+
export async function runHeartbeatCycle(input) {
|
|
7
|
+
const scoped = {
|
|
8
|
+
trigger: input.signal.trigger,
|
|
9
|
+
scopeHint: input.signal.scopeHint,
|
|
10
|
+
payload: input.signal.payload,
|
|
11
|
+
};
|
|
12
|
+
const route = routeScopedInput(scoped);
|
|
13
|
+
if (!input.runtimeAvailable) {
|
|
14
|
+
return {
|
|
15
|
+
scope: route.scope,
|
|
16
|
+
status: "runtime_carrier_only",
|
|
17
|
+
reasons: ["runtime_unavailable_no_lived_experience_loop"],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (route.scope === "user_task") {
|
|
21
|
+
return {
|
|
22
|
+
scope: "user_task",
|
|
23
|
+
status: "heartbeat_ok",
|
|
24
|
+
reasons: ["rhythm_gate_bypass_user_task"],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (route.scope === "user_reply") {
|
|
28
|
+
return {
|
|
29
|
+
scope: "user_reply",
|
|
30
|
+
status: "heartbeat_ok",
|
|
31
|
+
reasons: ["user_reply_light_continuity_skeleton"],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return ingestRhythmSignal(input.signal, input.deps);
|
|
35
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HeartbeatRuntimeSnapshot assembly for candidate planner + hard guards (T2.1.3, T2.2.1).
|
|
3
|
-
*/
|
|
4
|
-
import type { ContinuitySnapshot, ControlPlaneSourceRef } from "../types.js";
|
|
5
|
-
import type { RhythmPolicy } from "../rhythm/rhythm-policy.js";
|
|
6
|
-
import { type PlannerRhythmWindowSlice } from "../rhythm/planner-rhythm-window.js";
|
|
7
|
-
import type { SnapshotInputs } from "./snapshot-builder.js";
|
|
8
|
-
export interface PlannerLifeEvidenceSlice {
|
|
9
|
-
evidenceRefs: ControlPlaneSourceRef[];
|
|
10
|
-
platformEventCount: number;
|
|
11
|
-
workEventCount: number;
|
|
12
|
-
emptyReason?: "no_sources" | "state_unavailable" | "redacted_only";
|
|
13
|
-
}
|
|
14
|
-
export declare function isLifeEvidenceSliceEmpty(slice: PlannerLifeEvidenceSlice): boolean;
|
|
15
|
-
export interface HardGuardDeps {
|
|
16
|
-
hasDuplicateIntent: (idempotencyKey: string) => boolean;
|
|
17
|
-
isOutreachCooldownClear: (idempotencyKey: string) => boolean;
|
|
18
|
-
}
|
|
19
|
-
export interface HeartbeatRuntimeSnapshot {
|
|
20
|
-
continuity: ContinuitySnapshot;
|
|
21
|
-
lifeEvidence: PlannerLifeEvidenceSlice;
|
|
22
|
-
rhythmWindow: PlannerRhythmWindowSlice;
|
|
23
|
-
hardGuards: HardGuardDeps;
|
|
24
|
-
}
|
|
25
|
-
export declare function buildLifeEvidenceSliceFromInputs(inputs: SnapshotInputs): PlannerLifeEvidenceSlice;
|
|
26
|
-
export declare function buildHardGuardDeps(continuity: ContinuitySnapshot, inputs: SnapshotInputs): HardGuardDeps;
|
|
27
|
-
export declare function resolveRhythmPolicyForHeartbeat(inputs: SnapshotInputs): RhythmPolicy;
|
|
28
|
-
export declare function buildHeartbeatRuntimeSnapshot(timestamp: string, inputs: SnapshotInputs, continuity: ContinuitySnapshot): HeartbeatRuntimeSnapshot;
|
|
1
|
+
/**
|
|
2
|
+
* HeartbeatRuntimeSnapshot assembly for candidate planner + hard guards (T2.1.3, T2.2.1).
|
|
3
|
+
*/
|
|
4
|
+
import type { ContinuitySnapshot, ControlPlaneSourceRef } from "../types.js";
|
|
5
|
+
import type { RhythmPolicy } from "../rhythm/rhythm-policy.js";
|
|
6
|
+
import { type PlannerRhythmWindowSlice } from "../rhythm/planner-rhythm-window.js";
|
|
7
|
+
import type { SnapshotInputs } from "./snapshot-builder.js";
|
|
8
|
+
export interface PlannerLifeEvidenceSlice {
|
|
9
|
+
evidenceRefs: ControlPlaneSourceRef[];
|
|
10
|
+
platformEventCount: number;
|
|
11
|
+
workEventCount: number;
|
|
12
|
+
emptyReason?: "no_sources" | "state_unavailable" | "redacted_only";
|
|
13
|
+
}
|
|
14
|
+
export declare function isLifeEvidenceSliceEmpty(slice: PlannerLifeEvidenceSlice): boolean;
|
|
15
|
+
export interface HardGuardDeps {
|
|
16
|
+
hasDuplicateIntent: (idempotencyKey: string) => boolean;
|
|
17
|
+
isOutreachCooldownClear: (idempotencyKey: string) => boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface HeartbeatRuntimeSnapshot {
|
|
20
|
+
continuity: ContinuitySnapshot;
|
|
21
|
+
lifeEvidence: PlannerLifeEvidenceSlice;
|
|
22
|
+
rhythmWindow: PlannerRhythmWindowSlice;
|
|
23
|
+
hardGuards: HardGuardDeps;
|
|
24
|
+
}
|
|
25
|
+
export declare function buildLifeEvidenceSliceFromInputs(inputs: SnapshotInputs): PlannerLifeEvidenceSlice;
|
|
26
|
+
export declare function buildHardGuardDeps(continuity: ContinuitySnapshot, inputs: SnapshotInputs): HardGuardDeps;
|
|
27
|
+
export declare function resolveRhythmPolicyForHeartbeat(inputs: SnapshotInputs): RhythmPolicy;
|
|
28
|
+
export declare function buildHeartbeatRuntimeSnapshot(timestamp: string, inputs: SnapshotInputs, continuity: ContinuitySnapshot): HeartbeatRuntimeSnapshot;
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { rhythmPolicySnapshotToRhythmPolicy } from "../rhythm/policy-bridge.js";
|
|
2
|
-
import { buildPlannerRhythmWindow } from "../rhythm/planner-rhythm-window.js";
|
|
3
|
-
export function isLifeEvidenceSliceEmpty(slice) {
|
|
4
|
-
return slice.evidenceRefs.length === 0 && slice.platformEventCount === 0 && slice.workEventCount === 0;
|
|
5
|
-
}
|
|
6
|
-
export function buildLifeEvidenceSliceFromInputs(inputs) {
|
|
7
|
-
return {
|
|
8
|
-
evidenceRefs: inputs.lifeEvidenceRefs ?? [],
|
|
9
|
-
platformEventCount: inputs.platformEventCount ?? 0,
|
|
10
|
-
workEventCount: inputs.workEventCount ?? 0,
|
|
11
|
-
emptyReason: inputs.lifeEvidenceEmptyReason,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export function buildHardGuardDeps(continuity, inputs) {
|
|
15
|
-
return {
|
|
16
|
-
hasDuplicateIntent: (key) => (inputs.duplicateIntentKeys?.includes(key) ?? false) ||
|
|
17
|
-
continuity.deniedIntents.some((d) => d.reason === "duplicate_intent" && d.intentHash === key),
|
|
18
|
-
isOutreachCooldownClear: (key) => !(inputs.outreachCooldownKeys?.includes(key) ?? false),
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
export function resolveRhythmPolicyForHeartbeat(inputs) {
|
|
22
|
-
if (inputs.rhythmPolicy) {
|
|
23
|
-
return inputs.rhythmPolicy;
|
|
24
|
-
}
|
|
25
|
-
return rhythmPolicySnapshotToRhythmPolicy({
|
|
26
|
-
quietEnabled: inputs.quietEnabledBridge ?? false,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
export function buildHeartbeatRuntimeSnapshot(timestamp, inputs, continuity) {
|
|
30
|
-
const policy = resolveRhythmPolicyForHeartbeat(inputs);
|
|
31
|
-
const rhythmWindow = buildPlannerRhythmWindow(timestamp, continuity, policy);
|
|
32
|
-
const lifeEvidence = buildLifeEvidenceSliceFromInputs(inputs);
|
|
33
|
-
const hardGuards = buildHardGuardDeps(continuity, inputs);
|
|
34
|
-
return { continuity, lifeEvidence, rhythmWindow, hardGuards };
|
|
35
|
-
}
|
|
1
|
+
import { rhythmPolicySnapshotToRhythmPolicy } from "../rhythm/policy-bridge.js";
|
|
2
|
+
import { buildPlannerRhythmWindow } from "../rhythm/planner-rhythm-window.js";
|
|
3
|
+
export function isLifeEvidenceSliceEmpty(slice) {
|
|
4
|
+
return slice.evidenceRefs.length === 0 && slice.platformEventCount === 0 && slice.workEventCount === 0;
|
|
5
|
+
}
|
|
6
|
+
export function buildLifeEvidenceSliceFromInputs(inputs) {
|
|
7
|
+
return {
|
|
8
|
+
evidenceRefs: inputs.lifeEvidenceRefs ?? [],
|
|
9
|
+
platformEventCount: inputs.platformEventCount ?? 0,
|
|
10
|
+
workEventCount: inputs.workEventCount ?? 0,
|
|
11
|
+
emptyReason: inputs.lifeEvidenceEmptyReason,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function buildHardGuardDeps(continuity, inputs) {
|
|
15
|
+
return {
|
|
16
|
+
hasDuplicateIntent: (key) => (inputs.duplicateIntentKeys?.includes(key) ?? false) ||
|
|
17
|
+
continuity.deniedIntents.some((d) => d.reason === "duplicate_intent" && d.intentHash === key),
|
|
18
|
+
isOutreachCooldownClear: (key) => !(inputs.outreachCooldownKeys?.includes(key) ?? false),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function resolveRhythmPolicyForHeartbeat(inputs) {
|
|
22
|
+
if (inputs.rhythmPolicy) {
|
|
23
|
+
return inputs.rhythmPolicy;
|
|
24
|
+
}
|
|
25
|
+
return rhythmPolicySnapshotToRhythmPolicy({
|
|
26
|
+
quietEnabled: inputs.quietEnabledBridge ?? false,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export function buildHeartbeatRuntimeSnapshot(timestamp, inputs, continuity) {
|
|
30
|
+
const policy = resolveRhythmPolicyForHeartbeat(inputs);
|
|
31
|
+
const rhythmWindow = buildPlannerRhythmWindow(timestamp, continuity, policy);
|
|
32
|
+
const lifeEvidence = buildLifeEvidenceSliceFromInputs(inputs);
|
|
33
|
+
const hardGuards = buildHardGuardDeps(continuity, inputs);
|
|
34
|
+
return { continuity, lifeEvidence, rhythmWindow, hardGuards };
|
|
35
|
+
}
|