@haaaiawd/second-nature 0.1.8 → 0.1.10
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 +281 -69
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -1
- package/runtime/cli/commands/index.d.ts +2 -0
- package/runtime/cli/commands/index.js +61 -6
- package/runtime/cli/explain/explain-surface-subject.d.ts +8 -0
- package/runtime/cli/explain/explain-surface-subject.js +9 -0
- package/runtime/cli/explain/format-explanation.d.ts +2 -0
- package/runtime/cli/explain/format-explanation.js +2 -0
- package/runtime/cli/explain/resolve-subject.js +15 -0
- package/runtime/cli/host-capability/classify-delivery.d.ts +14 -0
- package/runtime/cli/host-capability/classify-delivery.js +20 -0
- package/runtime/cli/host-capability/probe-host-capability.d.ts +2 -0
- package/runtime/cli/host-capability/probe-host-capability.js +58 -0
- package/runtime/cli/host-capability/record-host-capability.d.ts +6 -0
- package/runtime/cli/host-capability/record-host-capability.js +14 -0
- package/runtime/cli/host-capability/types.d.ts +71 -0
- package/runtime/cli/host-capability/types.js +6 -0
- package/runtime/cli/host-smoke/run-host-smoke.d.ts +2 -0
- package/runtime/cli/host-smoke/run-host-smoke.js +40 -0
- package/runtime/cli/host-smoke/types.d.ts +35 -0
- package/runtime/cli/host-smoke/types.js +6 -0
- package/runtime/cli/index.js +18 -0
- package/runtime/cli/ops/heartbeat-surface.d.ts +35 -0
- package/runtime/cli/ops/heartbeat-surface.js +71 -0
- package/runtime/cli/ops/ops-router.d.ts +16 -0
- package/runtime/cli/ops/ops-router.js +83 -0
- package/runtime/cli/ops/show-operator-fallback.d.ts +13 -0
- package/runtime/cli/ops/show-operator-fallback.js +22 -0
- package/runtime/cli/ops/workspace-heartbeat-runner.d.ts +10 -0
- package/runtime/cli/ops/workspace-heartbeat-runner.js +26 -0
- package/runtime/cli/read-models/index.d.ts +11 -2
- package/runtime/cli/read-models/index.js +50 -0
- package/runtime/cli/read-models/operator-explain-map.d.ts +6 -0
- package/runtime/cli/read-models/operator-explain-map.js +10 -0
- package/runtime/cli/read-models/types.d.ts +5 -1
- package/runtime/cli/runtime/runtime-artifact-boundary.d.ts +28 -0
- package/runtime/cli/runtime/runtime-artifact-boundary.js +94 -0
- package/runtime/connectors/base/contract.d.ts +6 -0
- package/runtime/connectors/base/execution-policy.d.ts +47 -0
- package/runtime/connectors/base/execution-policy.js +82 -0
- package/runtime/connectors/base/index.d.ts +2 -0
- package/runtime/connectors/base/index.js +2 -0
- package/runtime/connectors/base/manifest.d.ts +55 -2
- package/runtime/connectors/base/manifest.js +50 -0
- package/runtime/connectors/base/map-life-evidence.d.ts +16 -0
- package/runtime/connectors/base/map-life-evidence.js +79 -0
- package/runtime/connectors/base/policy-layer.d.ts +2 -0
- package/runtime/connectors/base/policy-layer.js +16 -0
- package/runtime/connectors/base/route-planner.js +1 -0
- package/runtime/connectors/index.d.ts +1 -0
- package/runtime/connectors/index.js +1 -0
- package/runtime/connectors/near-real/near-real-connector-smoke.d.ts +19 -0
- package/runtime/connectors/near-real/near-real-connector-smoke.js +152 -0
- package/runtime/core/second-nature/heartbeat/heartbeat-executor.js +2 -0
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.d.ts +37 -16
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +95 -29
- package/runtime/core/second-nature/heartbeat/index.d.ts +4 -1
- package/runtime/core/second-nature/heartbeat/index.js +4 -1
- package/runtime/core/second-nature/heartbeat/run-heartbeat-cycle.d.ts +21 -0
- package/runtime/core/second-nature/heartbeat/run-heartbeat-cycle.js +35 -0
- package/runtime/core/second-nature/heartbeat/runtime-snapshot.d.ts +28 -0
- package/runtime/core/second-nature/heartbeat/runtime-snapshot.js +35 -0
- package/runtime/core/second-nature/heartbeat/signal.d.ts +9 -2
- package/runtime/core/second-nature/heartbeat/snapshot-builder.d.ts +19 -1
- package/runtime/core/second-nature/index.d.ts +8 -0
- package/runtime/core/second-nature/index.js +8 -0
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.d.ts +1 -1
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.js +9 -4
- package/runtime/core/second-nature/orchestrator/guard-layer.d.ts +6 -0
- package/runtime/core/second-nature/orchestrator/guard-layer.js +76 -20
- package/runtime/core/second-nature/orchestrator/intent-planner.d.ts +10 -0
- package/runtime/core/second-nature/orchestrator/intent-planner.js +135 -28
- package/runtime/core/second-nature/orchestrator/lease-manager.d.ts +1 -1
- package/runtime/core/second-nature/orchestrator/lease-manager.js +1 -1
- package/runtime/core/second-nature/outreach/build-outreach-draft-request.d.ts +6 -0
- package/runtime/core/second-nature/outreach/build-outreach-draft-request.js +63 -0
- package/runtime/core/second-nature/outreach/delivery-target.d.ts +26 -0
- package/runtime/core/second-nature/outreach/delivery-target.js +70 -0
- package/runtime/core/second-nature/outreach/dispatch-user-outreach.d.ts +38 -0
- package/runtime/core/second-nature/outreach/dispatch-user-outreach.js +119 -0
- package/runtime/core/second-nature/outreach/judge-input-from-snapshot.d.ts +7 -0
- package/runtime/core/second-nature/outreach/judge-input-from-snapshot.js +45 -0
- package/runtime/core/second-nature/outreach/judge-outreach.d.ts +40 -0
- package/runtime/core/second-nature/outreach/judge-outreach.js +121 -0
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.d.ts +21 -0
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.js +123 -0
- package/runtime/core/second-nature/rhythm/planner-rhythm-window.d.ts +15 -0
- package/runtime/core/second-nature/rhythm/planner-rhythm-window.js +52 -0
- package/runtime/core/second-nature/rhythm/policy-bridge.d.ts +19 -0
- package/runtime/core/second-nature/rhythm/policy-bridge.js +34 -0
- package/runtime/core/second-nature/types.d.ts +16 -2
- package/runtime/guidance/draft-outreach-message.d.ts +7 -0
- package/runtime/guidance/draft-outreach-message.js +42 -0
- package/runtime/guidance/evidence-guidance.d.ts +40 -0
- package/runtime/guidance/evidence-guidance.js +52 -0
- package/runtime/guidance/index.d.ts +3 -0
- package/runtime/guidance/index.js +3 -0
- package/runtime/guidance/outreach-draft-schema.d.ts +228 -0
- package/runtime/guidance/outreach-draft-schema.js +80 -0
- package/runtime/observability/audit/append-only-audit-store.d.ts +14 -0
- package/runtime/observability/audit/append-only-audit-store.js +21 -0
- package/runtime/observability/audit/audit-envelope.d.ts +51 -0
- package/runtime/observability/audit/audit-envelope.js +130 -0
- package/runtime/observability/audit/verify-audit-hash-chain.d.ts +23 -0
- package/runtime/observability/audit/verify-audit-hash-chain.js +83 -0
- package/runtime/observability/db/index.js +11 -0
- package/runtime/observability/db/schema/host-capability-reports.d.ts +180 -0
- package/runtime/observability/db/schema/host-capability-reports.js +12 -0
- package/runtime/observability/db/schema/index.d.ts +1 -0
- package/runtime/observability/db/schema/index.js +1 -0
- package/runtime/observability/index.d.ts +7 -0
- package/runtime/observability/index.js +7 -0
- package/runtime/observability/query/explain-query.d.ts +48 -0
- package/runtime/observability/query/explain-query.js +114 -0
- package/runtime/observability/query/export-audit-bundle.d.ts +22 -0
- package/runtime/observability/query/export-audit-bundle.js +27 -0
- package/runtime/observability/services/decision-ledger.d.ts +1 -1
- package/runtime/observability/services/decision-ledger.js +4 -0
- package/runtime/observability/services/governance-audit.d.ts +14 -0
- package/runtime/observability/services/governance-audit.js +25 -1
- package/runtime/observability/services/governance-plane-recorder.d.ts +47 -0
- package/runtime/observability/services/governance-plane-recorder.js +55 -0
- package/runtime/observability/services/lived-experience-audit.d.ts +97 -0
- package/runtime/observability/services/lived-experience-audit.js +162 -0
- package/runtime/storage/bootstrap/native-sqlite-probe.d.ts +7 -0
- package/runtime/storage/bootstrap/native-sqlite-probe.js +28 -0
- package/runtime/storage/bootstrap/repair-gate.d.ts +17 -0
- package/runtime/storage/bootstrap/repair-gate.js +71 -0
- package/runtime/storage/bootstrap/storage-mode-smoke.d.ts +38 -0
- package/runtime/storage/bootstrap/storage-mode-smoke.js +85 -0
- package/runtime/storage/db/index.js +49 -0
- package/runtime/storage/db/schema/delivery-attempts.d.ts +199 -0
- package/runtime/storage/db/schema/delivery-attempts.js +13 -0
- package/runtime/storage/db/schema/index.d.ts +3 -0
- package/runtime/storage/db/schema/index.js +3 -0
- package/runtime/storage/db/schema/life-evidence-index.d.ts +161 -0
- package/runtime/storage/db/schema/life-evidence-index.js +11 -0
- package/runtime/storage/db/schema/operator-fallback-artifacts.d.ts +161 -0
- package/runtime/storage/db/schema/operator-fallback-artifacts.js +11 -0
- package/runtime/storage/db/schema/policies.d.ts +17 -0
- package/runtime/storage/db/schema/policies.js +1 -0
- package/runtime/storage/delivery/query-delivery-attempts.d.ts +3 -0
- package/runtime/storage/delivery/query-delivery-attempts.js +32 -0
- package/runtime/storage/delivery/types.d.ts +27 -0
- package/runtime/storage/delivery/types.js +1 -0
- package/runtime/storage/delivery/write-delivery-attempt.d.ts +6 -0
- package/runtime/storage/delivery/write-delivery-attempt.js +36 -0
- package/runtime/storage/fallback/load-operator-fallback.d.ts +14 -0
- package/runtime/storage/fallback/load-operator-fallback.js +47 -0
- package/runtime/storage/fallback/operator-fallback-types.d.ts +9 -0
- package/runtime/storage/fallback/operator-fallback-types.js +1 -0
- package/runtime/storage/fallback/operator-fallback-view.d.ts +11 -0
- package/runtime/storage/fallback/operator-fallback-view.js +1 -0
- package/runtime/storage/fallback/write-operator-fallback.d.ts +6 -0
- package/runtime/storage/fallback/write-operator-fallback.js +21 -0
- package/runtime/storage/index.d.ts +21 -0
- package/runtime/storage/index.js +14 -0
- package/runtime/storage/life-evidence/append-life-evidence.d.ts +7 -0
- package/runtime/storage/life-evidence/append-life-evidence.js +64 -0
- package/runtime/storage/life-evidence/types.d.ts +45 -0
- package/runtime/storage/life-evidence/types.js +6 -0
- package/runtime/storage/quiet/persist-quiet-artifact.d.ts +7 -0
- package/runtime/storage/quiet/persist-quiet-artifact.js +22 -0
- package/runtime/storage/quiet/quiet-artifact-types.d.ts +18 -0
- package/runtime/storage/quiet/quiet-artifact-types.js +1 -0
- package/runtime/storage/quiet/quiet-artifact-writer.d.ts +15 -0
- package/runtime/storage/quiet/quiet-artifact-writer.js +56 -0
- package/runtime/storage/repositories/credential-repository.js +12 -1
- package/runtime/storage/rhythm/rhythm-policy-snapshot.d.ts +10 -0
- package/runtime/storage/rhythm/rhythm-policy-snapshot.js +34 -0
- package/runtime/storage/services/credential-vault.d.ts +5 -0
- package/runtime/storage/services/credential-vault.js +47 -9
- package/runtime/storage/snapshots/continuity-snapshot.d.ts +9 -0
- package/runtime/storage/snapshots/continuity-snapshot.js +41 -0
- package/runtime/storage/snapshots/life-evidence-snapshot.d.ts +6 -0
- package/runtime/storage/snapshots/life-evidence-snapshot.js +114 -0
- package/runtime/storage/snapshots/types.d.ts +58 -0
- package/runtime/storage/snapshots/types.js +1 -0
- package/runtime/storage/state-api.js +11 -4
- package/runtime/storage/user-interest/load-user-interest-snapshot.d.ts +2 -0
- package/runtime/storage/user-interest/load-user-interest-snapshot.js +150 -0
- package/runtime/storage/user-interest/types.d.ts +25 -0
- package/runtime/storage/user-interest/types.js +1 -0
- package/workspace-ops-bridge.js +78 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { resolveExplainSubject } from "./resolve-subject.js";
|
|
2
|
+
export async function explainSurfaceSubject(subjectRaw, readModels) {
|
|
3
|
+
const trimmed = subjectRaw.trim();
|
|
4
|
+
if (!trimmed) {
|
|
5
|
+
throw new Error("explain_subject_requires_id");
|
|
6
|
+
}
|
|
7
|
+
const subject = resolveExplainSubject(trimmed);
|
|
8
|
+
return readModels.explain(subject);
|
|
9
|
+
}
|
|
@@ -6,5 +6,7 @@ export interface FormattedExplanation {
|
|
|
6
6
|
evidenceRefs: string[];
|
|
7
7
|
requiredUserInput?: string[];
|
|
8
8
|
nextStep?: string;
|
|
9
|
+
warnings?: string[];
|
|
10
|
+
relatedAuditEventIds?: string[];
|
|
9
11
|
}
|
|
10
12
|
export declare function formatExplanation(model: ExplainReadModel): FormattedExplanation;
|
|
@@ -22,5 +22,20 @@ export function resolveExplainSubject(raw) {
|
|
|
22
22
|
if (prefix === "soul") {
|
|
23
23
|
return { kind: "soul-change", id };
|
|
24
24
|
}
|
|
25
|
+
if (prefix === "fallback") {
|
|
26
|
+
return { kind: "fallback", id };
|
|
27
|
+
}
|
|
28
|
+
if (prefix === "probe") {
|
|
29
|
+
return { kind: "probe", id };
|
|
30
|
+
}
|
|
31
|
+
if (prefix === "report") {
|
|
32
|
+
return { kind: "report", id };
|
|
33
|
+
}
|
|
34
|
+
if (prefix === "delivery") {
|
|
35
|
+
return { kind: "delivery", id };
|
|
36
|
+
}
|
|
37
|
+
if (prefix === "source" || prefix === "source_ref") {
|
|
38
|
+
return { kind: "source_ref", id };
|
|
39
|
+
}
|
|
25
40
|
throw new Error("explain_subject_unsupported");
|
|
26
41
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes host-reported delivery signals into DeliveryCapabilityStatus (cli-system).
|
|
3
|
+
*/
|
|
4
|
+
import type { DeliveryCapabilityStatus } from "./types.js";
|
|
5
|
+
export interface ClassifyDeliveryCapabilityInput {
|
|
6
|
+
/** Host-reported delivery channel / target hint */
|
|
7
|
+
rawTarget?: string | null;
|
|
8
|
+
channel?: string | null;
|
|
9
|
+
/** When false, host API for delivery is not reachable */
|
|
10
|
+
apiAvailable?: boolean;
|
|
11
|
+
/** When true, host explicitly reports unsupported delivery surface */
|
|
12
|
+
hostUnsupported?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function classifyDeliveryCapability(input: ClassifyDeliveryCapabilityInput): DeliveryCapabilityStatus;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function classifyDeliveryCapability(input) {
|
|
2
|
+
if (input.hostUnsupported) {
|
|
3
|
+
return "host_unsupported";
|
|
4
|
+
}
|
|
5
|
+
if (input.apiAvailable === false) {
|
|
6
|
+
return "host_api_unavailable";
|
|
7
|
+
}
|
|
8
|
+
const target = (input.rawTarget ?? "").trim().toLowerCase();
|
|
9
|
+
if (target === "none" || target === "") {
|
|
10
|
+
return "target_none";
|
|
11
|
+
}
|
|
12
|
+
const ch = (input.channel ?? "").trim();
|
|
13
|
+
if (!ch) {
|
|
14
|
+
return "channel_missing";
|
|
15
|
+
}
|
|
16
|
+
if (target === "unknown" || target === "unspecified") {
|
|
17
|
+
return "unknown";
|
|
18
|
+
}
|
|
19
|
+
return "target_available";
|
|
20
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw host capability probe — aggregates adapter checks into HostCapabilityReport.
|
|
3
|
+
*/
|
|
4
|
+
import * as crypto from "node:crypto";
|
|
5
|
+
function mergeEvidenceRefs(...groups) {
|
|
6
|
+
const seen = new Set();
|
|
7
|
+
const out = [];
|
|
8
|
+
for (const group of groups) {
|
|
9
|
+
for (const ref of group) {
|
|
10
|
+
const key = `${ref.kind}:${ref.id}`;
|
|
11
|
+
if (!seen.has(key)) {
|
|
12
|
+
seen.add(key);
|
|
13
|
+
out.push(ref);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
export function probeHostCapability(options) {
|
|
20
|
+
const { adapter, docLinks, docCheckedAt, hostVersion, observedVersion } = options;
|
|
21
|
+
const generatedAt = new Date().toISOString();
|
|
22
|
+
const pluginLoad = adapter.checkPluginLoad();
|
|
23
|
+
const heartbeatBridge = adapter.checkHeartbeatBridge();
|
|
24
|
+
const heartbeatToolInvocation = adapter.checkHeartbeatToolInvocation();
|
|
25
|
+
const delivery = adapter.checkDeliveryTarget();
|
|
26
|
+
const deliveryTarget = delivery.status;
|
|
27
|
+
const ackDropBehavior = adapter.checkAckDropBehavior();
|
|
28
|
+
const hookSupport = adapter.checkHookSupport();
|
|
29
|
+
const conflictRecords = [];
|
|
30
|
+
if (delivery.reason === "docs_vs_observed_mismatch" && docLinks.length > 0) {
|
|
31
|
+
const doc = docLinks[0];
|
|
32
|
+
conflictRecords.push({
|
|
33
|
+
capability: "delivery_target",
|
|
34
|
+
documentedBehavior: doc.documentedBehavior,
|
|
35
|
+
observedBehavior: deliveryTarget,
|
|
36
|
+
hostVersion,
|
|
37
|
+
docUrl: doc.url,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const evidenceRefs = mergeEvidenceRefs(pluginLoad.evidenceRefs, heartbeatBridge.evidenceRefs, heartbeatToolInvocation.evidenceRefs, delivery.evidenceRefs, ackDropBehavior.evidenceRefs, ...hookSupport.map((h) => h.evidenceRefs));
|
|
41
|
+
return {
|
|
42
|
+
reportId: crypto.randomUUID(),
|
|
43
|
+
generatedAt,
|
|
44
|
+
hostVersion,
|
|
45
|
+
observedVersion,
|
|
46
|
+
docLinks,
|
|
47
|
+
docCheckedAt,
|
|
48
|
+
pluginLoad,
|
|
49
|
+
heartbeatBridge,
|
|
50
|
+
heartbeatToolInvocation,
|
|
51
|
+
deliveryTarget,
|
|
52
|
+
ackDropBehavior,
|
|
53
|
+
hookSupport,
|
|
54
|
+
evidenceRefs,
|
|
55
|
+
conflictRecords,
|
|
56
|
+
recommendedNextStep: conflictRecords.length > 0 ? "reconcile_docs_vs_observed" : undefined,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persist HostCapabilityReport into observability SQLite (T1.1.2).
|
|
3
|
+
*/
|
|
4
|
+
import type { ObservabilityDatabase } from "../../observability/db/index.js";
|
|
5
|
+
import type { HostCapabilityReport } from "./types.js";
|
|
6
|
+
export declare function recordHostCapability(db: ObservabilityDatabase, report: HostCapabilityReport): Promise<void>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { hostCapabilityReports } from "../../observability/db/schema/host-capability-reports.js";
|
|
2
|
+
export async function recordHostCapability(db, report) {
|
|
3
|
+
await db.db.insert(hostCapabilityReports).values({
|
|
4
|
+
reportId: report.reportId,
|
|
5
|
+
generatedAt: report.generatedAt,
|
|
6
|
+
hostVersion: report.hostVersion ?? null,
|
|
7
|
+
observedVersion: report.observedVersion ?? null,
|
|
8
|
+
docCheckedAt: report.docCheckedAt,
|
|
9
|
+
docLinksJson: JSON.stringify(report.docLinks),
|
|
10
|
+
deliveryTarget: report.deliveryTarget,
|
|
11
|
+
conflictRecordsJson: JSON.stringify(report.conflictRecords),
|
|
12
|
+
fullReportJson: JSON.stringify(report),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host capability probe contracts (cli-system v5 / ADR-007).
|
|
3
|
+
*
|
|
4
|
+
* Test coverage: tests/unit/cli/host-capability.test.ts, tests/integration/cli/host-capability-probe.test.ts
|
|
5
|
+
*/
|
|
6
|
+
export type DeliveryCapabilityStatus = "target_available" | "target_none" | "channel_missing" | "host_api_unavailable" | "host_unsupported" | "unknown";
|
|
7
|
+
export type CapabilityVerdict = "pass" | "fail" | "unknown" | "not_applicable";
|
|
8
|
+
export interface SourceRef {
|
|
9
|
+
id: string;
|
|
10
|
+
kind: "platform_item" | "workspace_artifact" | "decision_record" | "user_anchor" | "connector_result" | "host_report" | "fallback_artifact";
|
|
11
|
+
uri: string;
|
|
12
|
+
excerptHash?: string;
|
|
13
|
+
observedAt?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface HostCapabilityDocReference {
|
|
16
|
+
title: string;
|
|
17
|
+
url: string;
|
|
18
|
+
checkedAt: string;
|
|
19
|
+
documentedBehavior: string;
|
|
20
|
+
}
|
|
21
|
+
export interface HostCapabilityConflictRecord {
|
|
22
|
+
capability: string;
|
|
23
|
+
documentedBehavior: string;
|
|
24
|
+
observedBehavior: string;
|
|
25
|
+
hostVersion?: string;
|
|
26
|
+
docUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CapabilityCheckResult {
|
|
29
|
+
name: string;
|
|
30
|
+
verdict: CapabilityVerdict;
|
|
31
|
+
observedAt: string;
|
|
32
|
+
reason?: string;
|
|
33
|
+
evidenceRefs: SourceRef[];
|
|
34
|
+
}
|
|
35
|
+
export interface HostCapabilityReport {
|
|
36
|
+
reportId: string;
|
|
37
|
+
generatedAt: string;
|
|
38
|
+
hostVersion?: string;
|
|
39
|
+
observedVersion?: string;
|
|
40
|
+
docLinks: HostCapabilityDocReference[];
|
|
41
|
+
docCheckedAt: string;
|
|
42
|
+
pluginLoad: CapabilityCheckResult;
|
|
43
|
+
heartbeatBridge: CapabilityCheckResult;
|
|
44
|
+
heartbeatToolInvocation: CapabilityCheckResult;
|
|
45
|
+
deliveryTarget: DeliveryCapabilityStatus;
|
|
46
|
+
ackDropBehavior: CapabilityCheckResult;
|
|
47
|
+
hookSupport: CapabilityCheckResult[];
|
|
48
|
+
evidenceRefs: SourceRef[];
|
|
49
|
+
conflictRecords: HostCapabilityConflictRecord[];
|
|
50
|
+
recommendedNextStep?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface HostCapabilityProbeOptions {
|
|
53
|
+
adapter: HostCapabilityAdapter;
|
|
54
|
+
docLinks: HostCapabilityDocReference[];
|
|
55
|
+
docCheckedAt: string;
|
|
56
|
+
hostVersion?: string;
|
|
57
|
+
observedVersion?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface HostCapabilityAdapter {
|
|
60
|
+
checkPluginLoad(): CapabilityCheckResult;
|
|
61
|
+
checkHeartbeatBridge(): CapabilityCheckResult;
|
|
62
|
+
checkHeartbeatToolInvocation(): CapabilityCheckResult;
|
|
63
|
+
/** Return normalized delivery capability as observed on the host */
|
|
64
|
+
checkDeliveryTarget(): {
|
|
65
|
+
status: DeliveryCapabilityStatus;
|
|
66
|
+
evidenceRefs: SourceRef[];
|
|
67
|
+
reason?: string;
|
|
68
|
+
};
|
|
69
|
+
checkAckDropBehavior(): CapabilityCheckResult;
|
|
70
|
+
checkHookSupport(): CapabilityCheckResult[];
|
|
71
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reproducible host smoke runner (T1.3.1). Uses transcript fixtures — no live OpenClaw in unit/integration path.
|
|
3
|
+
*
|
|
4
|
+
* Core logic: evaluate `heartbeat_tool_invocation` by substring match for heartbeat_check / second_nature_ops heartbeat surface.
|
|
5
|
+
*/
|
|
6
|
+
import * as crypto from "node:crypto";
|
|
7
|
+
function evalHeartbeatToolInvocation(c) {
|
|
8
|
+
const hasHeartbeatCheck = c.toolInvocations.some((t) => /heartbeat_check|second_nature_ops\s*\(\s*\{[^}]*heartbeat_check|command\s*:\s*["']heartbeat_check["']/i.test(t));
|
|
9
|
+
if (hasHeartbeatCheck) {
|
|
10
|
+
return { caseType: c.type, status: "pass", reasons: [] };
|
|
11
|
+
}
|
|
12
|
+
return { caseType: c.type, status: "fail", reasons: ["heartbeat_tool_not_invoked"] };
|
|
13
|
+
}
|
|
14
|
+
function evalDocsConflict(c) {
|
|
15
|
+
if (c.observedBehavior.trim() === c.docExpectation.trim()) {
|
|
16
|
+
return { caseType: c.type, status: "pass", reasons: [] };
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
caseType: c.type,
|
|
20
|
+
status: "fail",
|
|
21
|
+
reasons: ["docs_vs_observed_conflict", `expected:${c.docExpectation}`, `observed:${c.observedBehavior}`],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function evalCase(c) {
|
|
25
|
+
if (c.type === "heartbeat_tool_invocation") {
|
|
26
|
+
return evalHeartbeatToolInvocation(c);
|
|
27
|
+
}
|
|
28
|
+
return evalDocsConflict(c);
|
|
29
|
+
}
|
|
30
|
+
export async function runHostSmoke(plan) {
|
|
31
|
+
const results = plan.cases.map((c) => evalCase(c));
|
|
32
|
+
return {
|
|
33
|
+
reportId: crypto.randomUUID(),
|
|
34
|
+
generatedAt: new Date().toISOString(),
|
|
35
|
+
results,
|
|
36
|
+
docLinks: plan.docLinks,
|
|
37
|
+
docCheckedAt: plan.docCheckedAt,
|
|
38
|
+
hostVersion: plan.hostVersion,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host smoke plan + report types (T1.3.1).
|
|
3
|
+
*
|
|
4
|
+
* `heartbeat_tool_invocation` verifies that a near-real transcript actually invoked heartbeat_check.
|
|
5
|
+
*/
|
|
6
|
+
export interface HeartbeatToolInvocationCase {
|
|
7
|
+
readonly type: "heartbeat_tool_invocation";
|
|
8
|
+
/** Tool names, ops strings, or host transcript fragments observed during the smoke turn */
|
|
9
|
+
toolInvocations: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface DocsVsObservedConflictCase {
|
|
12
|
+
readonly type: "docs_vs_observed_conflict";
|
|
13
|
+
docExpectation: string;
|
|
14
|
+
observedBehavior: string;
|
|
15
|
+
}
|
|
16
|
+
export type HostSmokeCase = HeartbeatToolInvocationCase | DocsVsObservedConflictCase;
|
|
17
|
+
export interface HostSmokePlan {
|
|
18
|
+
cases: HostSmokeCase[];
|
|
19
|
+
docLinks?: string[];
|
|
20
|
+
docCheckedAt?: string;
|
|
21
|
+
hostVersion?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface HostSmokeCaseResult {
|
|
24
|
+
caseType: HostSmokeCase["type"];
|
|
25
|
+
status: "pass" | "fail" | "unknown";
|
|
26
|
+
reasons: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface HostSmokeReport {
|
|
29
|
+
reportId: string;
|
|
30
|
+
generatedAt: string;
|
|
31
|
+
results: HostSmokeCaseResult[];
|
|
32
|
+
docLinks?: string[];
|
|
33
|
+
docCheckedAt?: string;
|
|
34
|
+
hostVersion?: string;
|
|
35
|
+
}
|
package/runtime/cli/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createObservabilityDatabase } from "../observability/db/index.js";
|
|
2
2
|
import { createStateAPI, createStateDatabase } from "../storage/index.js";
|
|
3
|
+
import path from "node:path";
|
|
3
4
|
import { createActionBridge } from "./action-bridge.js";
|
|
4
5
|
import { createCliCommands } from "./commands/index.js";
|
|
6
|
+
import { createOpsRouter } from "./ops/ops-router.js";
|
|
5
7
|
import { createCliReadModels } from "./read-models/index.js";
|
|
8
|
+
import { resolvePackagedRuntime } from "./runtime/runtime-artifact-boundary.js";
|
|
6
9
|
export function createCliRuntimeDeps(overrides = {}) {
|
|
7
10
|
const stateDb = overrides.stateDb ?? createStateDatabase();
|
|
8
11
|
const observabilityDb = overrides.observabilityDb ?? createObservabilityDatabase();
|
|
@@ -19,9 +22,15 @@ export function createCliRuntimeDeps(overrides = {}) {
|
|
|
19
22
|
}
|
|
20
23
|
export function createCommandRouter(options = {}) {
|
|
21
24
|
const runtime = createCliRuntimeDeps(options.deps);
|
|
25
|
+
const pluginRoot = path.join(process.cwd(), "plugin");
|
|
26
|
+
const opsRouter = createOpsRouter({
|
|
27
|
+
runtimeAvailable: resolvePackagedRuntime(pluginRoot).ok,
|
|
28
|
+
readModels: runtime.readModels,
|
|
29
|
+
});
|
|
22
30
|
const commands = createCliCommands({
|
|
23
31
|
readModels: runtime.readModels,
|
|
24
32
|
actionBridge: runtime.actionBridge,
|
|
33
|
+
opsRouter,
|
|
25
34
|
});
|
|
26
35
|
return {
|
|
27
36
|
commands,
|
|
@@ -34,3 +43,12 @@ export function closeCliRuntimeDeps(deps) {
|
|
|
34
43
|
deps.stateDb.close();
|
|
35
44
|
deps.observabilityDb.close();
|
|
36
45
|
}
|
|
46
|
+
export { createOpsRouter } from "./ops/ops-router.js";
|
|
47
|
+
export { heartbeatCheck, } from "./ops/heartbeat-surface.js";
|
|
48
|
+
export * from "./host-capability/types.js";
|
|
49
|
+
export { classifyDeliveryCapability } from "./host-capability/classify-delivery.js";
|
|
50
|
+
export { probeHostCapability } from "./host-capability/probe-host-capability.js";
|
|
51
|
+
export { recordHostCapability } from "./host-capability/record-host-capability.js";
|
|
52
|
+
export { runHostSmoke } from "./host-smoke/run-host-smoke.js";
|
|
53
|
+
export { explainSurfaceSubject } from "./explain/explain-surface-subject.js";
|
|
54
|
+
export { showOperatorFallback, OperatorFallbackNotFoundError } from "./ops/show-operator-fallback.js";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable HeartbeatSurfaceResult for second_nature_ops / CLI (T1.1.3, cli-system / ADR-005).
|
|
3
|
+
*
|
|
4
|
+
* S1 scope: carrier / probe / runtime-unavailable / fake control-plane passthrough only.
|
|
5
|
+
* Workspace full runtime: delegates to `runHeartbeatCycle` when read models are wired (US-001 / CH-09-02).
|
|
6
|
+
*/
|
|
7
|
+
import type { SurfaceMode } from "../runtime/runtime-artifact-boundary.js";
|
|
8
|
+
import type { HeartbeatSignal } from "../../core/second-nature/heartbeat/signal.js";
|
|
9
|
+
import type { CliReadModels } from "../read-models/index.js";
|
|
10
|
+
export type HeartbeatSurfaceStatus = "heartbeat_ok" | "intent_selected" | "denied" | "deferred" | "runtime_carrier_only" | "delivery_unavailable";
|
|
11
|
+
export interface HeartbeatSurfaceResult {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
status: HeartbeatSurfaceStatus;
|
|
14
|
+
surfaceMode: SurfaceMode;
|
|
15
|
+
decisionId?: string;
|
|
16
|
+
deliveryAttemptId?: string;
|
|
17
|
+
capabilityReportRef?: string;
|
|
18
|
+
fallbackRef?: string;
|
|
19
|
+
reasons: string[];
|
|
20
|
+
/** When false, callers must not treat the round as lived-experience loop completion */
|
|
21
|
+
livedExperienceLoopClaimed: boolean;
|
|
22
|
+
/** True when structured fields mirror a fake adapter for schema parity only */
|
|
23
|
+
schemaParityOnly?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface HeartbeatCheckInput {
|
|
26
|
+
probeOnly?: boolean;
|
|
27
|
+
runtimeAvailable: boolean;
|
|
28
|
+
fakeControlPlanePassthrough?: Record<string, unknown>;
|
|
29
|
+
/** When set, full-runtime heartbeat_check runs the control-plane decision loop (US-001). */
|
|
30
|
+
readModels?: CliReadModels;
|
|
31
|
+
timestamp?: string;
|
|
32
|
+
sessionContext?: string;
|
|
33
|
+
scopeHint?: HeartbeatSignal["scopeHint"];
|
|
34
|
+
}
|
|
35
|
+
export declare function heartbeatCheck(input: HeartbeatCheckInput): Promise<HeartbeatSurfaceResult>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createWorkspaceHeartbeatRunner } from "./workspace-heartbeat-runner.js";
|
|
2
|
+
function mapCycleToSurface(cycle, surfaceMode) {
|
|
3
|
+
const status = cycle.status === "runtime_carrier_only" ? "runtime_carrier_only" : cycle.status;
|
|
4
|
+
return {
|
|
5
|
+
ok: true,
|
|
6
|
+
status,
|
|
7
|
+
surfaceMode,
|
|
8
|
+
decisionId: cycle.decisionId,
|
|
9
|
+
deliveryAttemptId: cycle.deliveryAttemptId,
|
|
10
|
+
fallbackRef: cycle.fallbackRef,
|
|
11
|
+
reasons: cycle.reasons,
|
|
12
|
+
livedExperienceLoopClaimed: false,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export async function heartbeatCheck(input) {
|
|
16
|
+
if (!input.runtimeAvailable) {
|
|
17
|
+
return {
|
|
18
|
+
ok: true,
|
|
19
|
+
status: "runtime_carrier_only",
|
|
20
|
+
surfaceMode: "host_safe_carrier",
|
|
21
|
+
reasons: ["runtime_unavailable_packaged_carrier"],
|
|
22
|
+
livedExperienceLoopClaimed: false,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (input.probeOnly) {
|
|
26
|
+
return {
|
|
27
|
+
ok: true,
|
|
28
|
+
status: "heartbeat_ok",
|
|
29
|
+
surfaceMode: "capability_probe",
|
|
30
|
+
reasons: ["probe_only"],
|
|
31
|
+
livedExperienceLoopClaimed: false,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (input.fakeControlPlanePassthrough) {
|
|
35
|
+
const decisionId = typeof input.fakeControlPlanePassthrough.decisionId === "string"
|
|
36
|
+
? input.fakeControlPlanePassthrough.decisionId
|
|
37
|
+
: undefined;
|
|
38
|
+
return {
|
|
39
|
+
ok: true,
|
|
40
|
+
status: "intent_selected",
|
|
41
|
+
surfaceMode: "host_safe_carrier",
|
|
42
|
+
reasons: ["fake_control_plane_passthrough"],
|
|
43
|
+
decisionId,
|
|
44
|
+
livedExperienceLoopClaimed: false,
|
|
45
|
+
schemaParityOnly: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (!input.readModels) {
|
|
49
|
+
return {
|
|
50
|
+
ok: true,
|
|
51
|
+
status: "runtime_carrier_only",
|
|
52
|
+
surfaceMode: "host_safe_carrier",
|
|
53
|
+
reasons: ["heartbeat_read_models_unavailable"],
|
|
54
|
+
livedExperienceLoopClaimed: false,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const timestamp = typeof input.timestamp === "string" && input.timestamp.trim().length > 0
|
|
58
|
+
? input.timestamp.trim()
|
|
59
|
+
: new Date().toISOString();
|
|
60
|
+
const signal = {
|
|
61
|
+
trigger: "heartbeat_bridge",
|
|
62
|
+
scopeHint: input.scopeHint,
|
|
63
|
+
payload: {
|
|
64
|
+
timestamp,
|
|
65
|
+
sessionContext: typeof input.sessionContext === "string" ? input.sessionContext : undefined,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
const run = createWorkspaceHeartbeatRunner(input.readModels);
|
|
69
|
+
const cycle = await run(signal);
|
|
70
|
+
return mapCycleToSurface(cycle, "workspace_full_runtime");
|
|
71
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ops command dispatch for CLI + tool surfaces (T1.1.3, T1.2.2).
|
|
3
|
+
*/
|
|
4
|
+
import { type HeartbeatCheckInput, type HeartbeatSurfaceResult } from "./heartbeat-surface.js";
|
|
5
|
+
import type { CliReadModels } from "../read-models/index.js";
|
|
6
|
+
export interface OpsRouterDeps {
|
|
7
|
+
/** When true, packaged runtime artifacts resolved and full graph is loadable */
|
|
8
|
+
runtimeAvailable: boolean;
|
|
9
|
+
/** Workspace read models: fallback view + heartbeat decision loop inputs (T1.2.2 / US-001). */
|
|
10
|
+
readModels?: CliReadModels;
|
|
11
|
+
}
|
|
12
|
+
export interface OpsRouter {
|
|
13
|
+
heartbeatCheck(input: HeartbeatCheckInput): Promise<HeartbeatSurfaceResult>;
|
|
14
|
+
dispatch(command: string, input?: Record<string, unknown>): HeartbeatSurfaceResult | Record<string, unknown> | Promise<HeartbeatSurfaceResult> | Promise<Record<string, unknown>>;
|
|
15
|
+
}
|
|
16
|
+
export declare function createOpsRouter(deps: OpsRouterDeps): OpsRouter;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ops command dispatch for CLI + tool surfaces (T1.1.3, T1.2.2).
|
|
3
|
+
*/
|
|
4
|
+
import { heartbeatCheck } from "./heartbeat-surface.js";
|
|
5
|
+
import { showOperatorFallback, OperatorFallbackNotFoundError } from "./show-operator-fallback.js";
|
|
6
|
+
export function createOpsRouter(deps) {
|
|
7
|
+
return {
|
|
8
|
+
heartbeatCheck: (input) => heartbeatCheck({
|
|
9
|
+
...input,
|
|
10
|
+
runtimeAvailable: input.runtimeAvailable ?? deps.runtimeAvailable,
|
|
11
|
+
readModels: input.readModels ?? deps.readModels,
|
|
12
|
+
}),
|
|
13
|
+
dispatch(command, input) {
|
|
14
|
+
if (command === "heartbeat_check") {
|
|
15
|
+
const runtimeAvailable = typeof input?.runtimeAvailable === "boolean" ? input.runtimeAvailable : deps.runtimeAvailable;
|
|
16
|
+
return heartbeatCheck({
|
|
17
|
+
probeOnly: Boolean(input?.probeOnly),
|
|
18
|
+
runtimeAvailable,
|
|
19
|
+
fakeControlPlanePassthrough: input?.fakeControlPlanePassthrough && typeof input.fakeControlPlanePassthrough === "object"
|
|
20
|
+
? input.fakeControlPlanePassthrough
|
|
21
|
+
: undefined,
|
|
22
|
+
readModels: deps.readModels,
|
|
23
|
+
timestamp: typeof input?.timestamp === "string" ? input.timestamp : undefined,
|
|
24
|
+
sessionContext: typeof input?.sessionContext === "string" ? input.sessionContext : undefined,
|
|
25
|
+
scopeHint: input?.scopeHint,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (command === "fallback") {
|
|
29
|
+
const ref = typeof input?.ref === "string" ? input.ref.trim() : "";
|
|
30
|
+
if (!ref) {
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
error: {
|
|
34
|
+
code: "MISSING_FALLBACK_REF",
|
|
35
|
+
message: "fallback requires args.ref (e.g. fallback:…)",
|
|
36
|
+
requiredUserInput: ["ref"],
|
|
37
|
+
nextStep: "reinvoke_with_ref",
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
if (!deps.readModels?.loadFallbackView) {
|
|
42
|
+
return {
|
|
43
|
+
ok: false,
|
|
44
|
+
error: {
|
|
45
|
+
code: "FALLBACK_READ_MODEL_UNAVAILABLE",
|
|
46
|
+
message: "Operator fallback view requires workspace read models",
|
|
47
|
+
requiredUserInput: ["ref"],
|
|
48
|
+
nextStep: "wire_read_models_into_ops_router",
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return (async () => {
|
|
53
|
+
try {
|
|
54
|
+
const data = await showOperatorFallback(ref, deps.readModels);
|
|
55
|
+
return { ok: true, command: "fallback", data };
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (error instanceof OperatorFallbackNotFoundError) {
|
|
59
|
+
return {
|
|
60
|
+
ok: false,
|
|
61
|
+
command: "fallback",
|
|
62
|
+
error: {
|
|
63
|
+
code: error.code,
|
|
64
|
+
message: error.message,
|
|
65
|
+
requiredUserInput: ["ref"],
|
|
66
|
+
nextStep: "verify_fallback_ref_from_delivery_audit",
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
})();
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
ok: false,
|
|
76
|
+
error: {
|
|
77
|
+
code: "unknown_ops_command",
|
|
78
|
+
message: `Unknown ops command: ${command}`,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OperatorFallbackView } from "../../storage/fallback/operator-fallback-view.js";
|
|
2
|
+
export declare class OperatorFallbackNotFoundError extends Error {
|
|
3
|
+
readonly ref: string;
|
|
4
|
+
readonly code: "FALLBACK_NOT_FOUND";
|
|
5
|
+
constructor(ref: string);
|
|
6
|
+
}
|
|
7
|
+
export interface ShowOperatorFallbackReadModels {
|
|
8
|
+
loadFallbackView(ref: string): Promise<OperatorFallbackView | null>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* T1.2.2 — Operator-visible fallback: always `status: not_sent` (ADR-007), never sent/delivered.
|
|
12
|
+
*/
|
|
13
|
+
export declare function showOperatorFallback(ref: string, readModels: ShowOperatorFallbackReadModels): Promise<OperatorFallbackView>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class OperatorFallbackNotFoundError extends Error {
|
|
2
|
+
ref;
|
|
3
|
+
code = "FALLBACK_NOT_FOUND";
|
|
4
|
+
constructor(ref) {
|
|
5
|
+
super(`No operator fallback artifact for ref: ${ref}`);
|
|
6
|
+
this.ref = ref;
|
|
7
|
+
this.name = "OperatorFallbackNotFoundError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* T1.2.2 — Operator-visible fallback: always `status: not_sent` (ADR-007), never sent/delivered.
|
|
12
|
+
*/
|
|
13
|
+
export async function showOperatorFallback(ref, readModels) {
|
|
14
|
+
const view = await readModels.loadFallbackView(ref);
|
|
15
|
+
if (!view) {
|
|
16
|
+
throw new OperatorFallbackNotFoundError(ref.trim());
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
...view,
|
|
20
|
+
status: "not_sent",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wires CLI read models into control-plane `runHeartbeatCycle` for `heartbeat_check` (US-001 / CH-09-02).
|
|
3
|
+
*
|
|
4
|
+
* Snapshot inputs are derived from aggregated status; delivery defaults to none until host capability is modeled here.
|
|
5
|
+
*/
|
|
6
|
+
import type { HeartbeatSignal, HeartbeatCycleResult } from "../../core/second-nature/heartbeat/signal.js";
|
|
7
|
+
import type { SnapshotInputs } from "../../core/second-nature/heartbeat/snapshot-builder.js";
|
|
8
|
+
import type { CliReadModels } from "../read-models/index.js";
|
|
9
|
+
export declare function loadSnapshotInputsForWorkspaceHeartbeat(readModels: CliReadModels): Promise<SnapshotInputs>;
|
|
10
|
+
export declare function createWorkspaceHeartbeatRunner(readModels: CliReadModels): (signal: HeartbeatSignal) => Promise<HeartbeatCycleResult>;
|