@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.
- package/index.js +911 -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 +224 -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 +67 -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 +32 -19
- package/runtime/cli/ops/ops-router.js +188 -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 +46 -29
- package/runtime/cli/read-models/index.js +391 -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 +129 -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/observability-retention.d.ts +10 -0
- package/runtime/observability/services/observability-retention.js +37 -0
- 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 +90 -81
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Heartbeat Decision Loop
|
|
3
|
-
*
|
|
4
|
-
* Main entry point for the heartbeat runtime. Accepts a HeartbeatSignal,
|
|
5
|
-
* builds runtime snapshot, plans candidate intents, evaluates hard guards,
|
|
6
|
-
* and returns a HeartbeatCycleResult.
|
|
7
|
-
*
|
|
8
|
-
* Per design doc §4.3: heartbeat round follows the sequence:
|
|
9
|
-
* signal → snapshot → plan → guard → result (HEARTBEAT_OK or intent_selected)
|
|
10
|
-
*
|
|
11
|
-
* Per ADR-005: heartbeat is the free-rhythm main entry; this loop
|
|
12
|
-
* implements the default conservative path where HEARTBEAT_OK is
|
|
13
|
-
* the first-class result when no action is warranted.
|
|
14
|
-
*/
|
|
15
|
-
import type { HeartbeatSignal, HeartbeatCycleResult, HeartbeatCycleStatus, RuntimeScope, RuntimeTrigger } from "./signal.js";
|
|
16
|
-
import type { CandidateIntent, ContinuitySnapshot, IntentKind } from "../types.js";
|
|
17
|
-
import { type SnapshotInputs } from "./snapshot-builder.js";
|
|
18
|
-
import { type HeartbeatRuntimeSnapshot } from "./runtime-snapshot.js";
|
|
19
|
-
import type { GuidanceDraftPort } from "../../../guidance/outreach-draft-schema.js";
|
|
20
|
-
import type { StateDatabase } from "../../../storage/db/index.js";
|
|
21
|
-
import { type OpenClawDeliveryPort } from "../outreach/dispatch-user-outreach.js";
|
|
22
|
-
export interface HeartbeatDecisionTracePayload {
|
|
23
|
-
scope: RuntimeScope;
|
|
24
|
-
status: HeartbeatCycleStatus;
|
|
25
|
-
reasons: string[];
|
|
26
|
-
selectedIntentId?: string;
|
|
27
|
-
rhythmWindowId: string;
|
|
28
|
-
allowedIntentKinds: IntentKind[];
|
|
29
|
-
candidateCount: number;
|
|
30
|
-
lifeEvidenceEmpty: boolean;
|
|
31
|
-
trigger: RuntimeTrigger;
|
|
32
|
-
}
|
|
33
|
-
/** Optional outreach delivery chain: when set, first allowed `user_outreach` runs dispatch (CR-M1). */
|
|
34
|
-
export interface HeartbeatOutreachDispatchDeps {
|
|
35
|
-
state: StateDatabase;
|
|
36
|
-
guidance: GuidanceDraftPort;
|
|
37
|
-
delivery: OpenClawDeliveryPort;
|
|
38
|
-
}
|
|
39
|
-
/** Optional Quiet orchestration: when set, quiet/reflection allows run source-backed Quiet writer (T2.3.3). */
|
|
40
|
-
export interface HeartbeatQuietWorkflowDeps {
|
|
41
|
-
workspaceRoot: string;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Resolves the heartbeat outcome for a guard-allowed intent (outreach dispatch, quiet orchestration, or default).
|
|
45
|
-
* Exported for unit tests (CR-M1 wiring).
|
|
46
|
-
*/
|
|
47
|
-
export declare function resolveAllowedIntentResult(intent: CandidateIntent, runtime: HeartbeatRuntimeSnapshot, inputs: SnapshotInputs, signal: HeartbeatSignal, deps: Pick<HeartbeatDeps, "outreachDispatch" | "quietWorkflow">): Promise<HeartbeatCycleResult>;
|
|
48
|
-
export interface HeartbeatDeps {
|
|
49
|
-
/** Load snapshot inputs from state-system */
|
|
50
|
-
loadSnapshotInputs: () => Promise<SnapshotInputs>;
|
|
51
|
-
/** Optional observability hook (T2.2.1): one record per completed cycle. */
|
|
52
|
-
recordDecisionTrace?: (payload: HeartbeatDecisionTracePayload) => Promise<void>;
|
|
53
|
-
outreachDispatch?: HeartbeatOutreachDispatchDeps;
|
|
54
|
-
quietWorkflow?: HeartbeatQuietWorkflowDeps;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Ingest a heartbeat rhythm signal and drive one full decision round.
|
|
58
|
-
*/
|
|
59
|
-
export declare function ingestRhythmSignal(signal: HeartbeatSignal, deps: HeartbeatDeps): Promise<HeartbeatCycleResult>;
|
|
60
|
-
/**
|
|
61
|
-
* Build a snapshot directly from inputs (for testing or when state-system is unavailable).
|
|
62
|
-
*/
|
|
63
|
-
export declare function buildSnapshotFromInputs(inputs: SnapshotInputs): ContinuitySnapshot;
|
|
1
|
+
/**
|
|
2
|
+
* Heartbeat Decision Loop
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for the heartbeat runtime. Accepts a HeartbeatSignal,
|
|
5
|
+
* builds runtime snapshot, plans candidate intents, evaluates hard guards,
|
|
6
|
+
* and returns a HeartbeatCycleResult.
|
|
7
|
+
*
|
|
8
|
+
* Per design doc §4.3: heartbeat round follows the sequence:
|
|
9
|
+
* signal → snapshot → plan → guard → result (HEARTBEAT_OK or intent_selected)
|
|
10
|
+
*
|
|
11
|
+
* Per ADR-005: heartbeat is the free-rhythm main entry; this loop
|
|
12
|
+
* implements the default conservative path where HEARTBEAT_OK is
|
|
13
|
+
* the first-class result when no action is warranted.
|
|
14
|
+
*/
|
|
15
|
+
import type { HeartbeatSignal, HeartbeatCycleResult, HeartbeatCycleStatus, RuntimeScope, RuntimeTrigger } from "./signal.js";
|
|
16
|
+
import type { CandidateIntent, ContinuitySnapshot, IntentKind } from "../types.js";
|
|
17
|
+
import { type SnapshotInputs } from "./snapshot-builder.js";
|
|
18
|
+
import { type HeartbeatRuntimeSnapshot } from "./runtime-snapshot.js";
|
|
19
|
+
import type { GuidanceDraftPort } from "../../../guidance/outreach-draft-schema.js";
|
|
20
|
+
import type { StateDatabase } from "../../../storage/db/index.js";
|
|
21
|
+
import { type OpenClawDeliveryPort } from "../outreach/dispatch-user-outreach.js";
|
|
22
|
+
export interface HeartbeatDecisionTracePayload {
|
|
23
|
+
scope: RuntimeScope;
|
|
24
|
+
status: HeartbeatCycleStatus;
|
|
25
|
+
reasons: string[];
|
|
26
|
+
selectedIntentId?: string;
|
|
27
|
+
rhythmWindowId: string;
|
|
28
|
+
allowedIntentKinds: IntentKind[];
|
|
29
|
+
candidateCount: number;
|
|
30
|
+
lifeEvidenceEmpty: boolean;
|
|
31
|
+
trigger: RuntimeTrigger;
|
|
32
|
+
}
|
|
33
|
+
/** Optional outreach delivery chain: when set, first allowed `user_outreach` runs dispatch (CR-M1). */
|
|
34
|
+
export interface HeartbeatOutreachDispatchDeps {
|
|
35
|
+
state: StateDatabase;
|
|
36
|
+
guidance: GuidanceDraftPort;
|
|
37
|
+
delivery: OpenClawDeliveryPort;
|
|
38
|
+
}
|
|
39
|
+
/** Optional Quiet orchestration: when set, quiet/reflection allows run source-backed Quiet writer (T2.3.3). */
|
|
40
|
+
export interface HeartbeatQuietWorkflowDeps {
|
|
41
|
+
workspaceRoot: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolves the heartbeat outcome for a guard-allowed intent (outreach dispatch, quiet orchestration, or default).
|
|
45
|
+
* Exported for unit tests (CR-M1 wiring).
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveAllowedIntentResult(intent: CandidateIntent, runtime: HeartbeatRuntimeSnapshot, inputs: SnapshotInputs, signal: HeartbeatSignal, deps: Pick<HeartbeatDeps, "outreachDispatch" | "quietWorkflow">): Promise<HeartbeatCycleResult>;
|
|
48
|
+
export interface HeartbeatDeps {
|
|
49
|
+
/** Load snapshot inputs from state-system */
|
|
50
|
+
loadSnapshotInputs: () => Promise<SnapshotInputs>;
|
|
51
|
+
/** Optional observability hook (T2.2.1): one record per completed cycle. */
|
|
52
|
+
recordDecisionTrace?: (payload: HeartbeatDecisionTracePayload) => Promise<void>;
|
|
53
|
+
outreachDispatch?: HeartbeatOutreachDispatchDeps;
|
|
54
|
+
quietWorkflow?: HeartbeatQuietWorkflowDeps;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Ingest a heartbeat rhythm signal and drive one full decision round.
|
|
58
|
+
*/
|
|
59
|
+
export declare function ingestRhythmSignal(signal: HeartbeatSignal, deps: HeartbeatDeps): Promise<HeartbeatCycleResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Build a snapshot directly from inputs (for testing or when state-system is unavailable).
|
|
62
|
+
*/
|
|
63
|
+
export declare function buildSnapshotFromInputs(inputs: SnapshotInputs): ContinuitySnapshot;
|
|
@@ -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
|
+
}
|