@haaaiawd/second-nature 0.2.8 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/index.js +12 -3
  2. package/openclaw.plugin.json +3 -6
  3. package/package.json +1 -1
  4. package/runtime/cli/host-capability/probe-host-capability.js +1 -1
  5. package/runtime/cli/host-capability/types.d.ts +2 -7
  6. package/runtime/cli/host-capability/types.js +0 -5
  7. package/runtime/cli/ops/heartbeat-surface.d.ts +2 -0
  8. package/runtime/cli/ops/heartbeat-surface.js +32 -3
  9. package/runtime/cli/ops/manual-run-dispatcher.d.ts +10 -0
  10. package/runtime/cli/ops/manual-run-dispatcher.js +49 -0
  11. package/runtime/cli/ops/ops-router.js +5 -3
  12. package/runtime/cli/ops/workspace-heartbeat-runner.js +2 -5
  13. package/runtime/connectors/base/normalized-evidence-content.js +15 -2
  14. package/runtime/connectors/manifest/manifest-schema.d.ts +2 -2
  15. package/runtime/connectors/registry/dynamic-connector-registry.js +16 -1
  16. package/runtime/connectors/services/connector-executor-adapter.js +58 -35
  17. package/runtime/core/second-nature/action/action-closure-recorder.d.ts +2 -0
  18. package/runtime/core/second-nature/action/action-closure-recorder.js +2 -4
  19. package/runtime/core/second-nature/action/action-proposal-builder.js +5 -32
  20. package/runtime/core/second-nature/action/policy-bound-dispatch.js +4 -3
  21. package/runtime/core/second-nature/control-plane/accepted-projection-loader.js +1 -11
  22. package/runtime/core/second-nature/control-plane/heartbeat-orchestrator.d.ts +1 -0
  23. package/runtime/core/second-nature/control-plane/heartbeat-orchestrator.js +10 -6
  24. package/runtime/core/second-nature/control-plane/real-runtime-spine.d.ts +2 -0
  25. package/runtime/core/second-nature/control-plane/real-runtime-spine.js +1 -0
  26. package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +4 -3
  27. package/runtime/core/second-nature/heartbeat/runtime-snapshot.d.ts +3 -2
  28. package/runtime/core/second-nature/heartbeat/snapshot-builder.d.ts +3 -2
  29. package/runtime/core/second-nature/orchestrator/intent-planner.js +4 -2
  30. package/runtime/core/second-nature/orchestrator/narrative-update.js +1 -2
  31. package/runtime/core/second-nature/orchestrator/platform-capability-router.d.ts +2 -2
  32. package/runtime/core/second-nature/orchestrator/platform-capability-router.js +1 -1
  33. package/runtime/core/second-nature/outreach/build-outreach-draft-request.js +2 -3
  34. package/runtime/core/second-nature/outreach/dispatch-user-outreach.d.ts +2 -2
  35. package/runtime/core/second-nature/outreach/dispatch-user-outreach.js +6 -1
  36. package/runtime/core/second-nature/outreach/judge-input-from-snapshot.js +3 -14
  37. package/runtime/core/second-nature/outreach/judge-outreach.d.ts +6 -5
  38. package/runtime/core/second-nature/perception/judgment-engine.js +2 -12
  39. package/runtime/core/second-nature/perception/perception-builder.js +1 -9
  40. package/runtime/core/second-nature/quiet/run-source-backed-quiet.js +13 -15
  41. package/runtime/core/second-nature/quiet-dream/daily-rhythm-scheduler.js +10 -13
  42. package/runtime/core/second-nature/quiet-dream/dream-consolidation-runner.d.ts +1 -0
  43. package/runtime/core/second-nature/quiet-dream/dream-consolidation-runner.js +11 -19
  44. package/runtime/core/second-nature/quiet-dream/dream-scheduler.js +0 -2
  45. package/runtime/core/second-nature/quiet-dream/memory-projection-lifecycle.js +0 -12
  46. package/runtime/core/second-nature/quiet-dream/quiet-daily-review-builder.js +1 -11
  47. package/runtime/core/second-nature/types.d.ts +2 -9
  48. package/runtime/dream/dream-engine.js +11 -4
  49. package/runtime/guidance/outreach-draft-schema.d.ts +12 -12
  50. package/runtime/guidance/persona-selection.js +5 -0
  51. package/runtime/guidance/template-registry.js +6 -1
  52. package/runtime/guidance/types.d.ts +2 -2
  53. package/runtime/observability/living-loop-health-gate.js +2 -8
  54. package/runtime/observability/loop-stage-event-sink.js +0 -1
  55. package/runtime/observability/services/lived-experience-audit.d.ts +7 -7
  56. package/runtime/shared/serialization.d.ts +17 -0
  57. package/runtime/shared/serialization.js +27 -0
  58. package/runtime/shared/source-ref-compat.d.ts +26 -0
  59. package/runtime/shared/source-ref-compat.js +61 -0
  60. package/runtime/shared/types/goal.d.ts +4 -4
  61. package/runtime/shared/types/goal.js +1 -1
  62. package/runtime/shared/types/index.d.ts +1 -0
  63. package/runtime/shared/types/index.js +1 -3
  64. package/runtime/shared/types/source-ref.d.ts +2 -2
  65. package/runtime/shared/types/v7-entities.d.ts +5 -5
  66. package/runtime/shared/types/v7-entities.js +1 -1
  67. package/runtime/shared/types/v8-contracts.d.ts +1 -1
  68. package/runtime/storage/db/index.js +31 -26
  69. package/runtime/storage/db/migrations/index.js +4 -0
  70. package/runtime/storage/db/migrations/v8-004-schema-closure.d.ts +19 -0
  71. package/runtime/storage/db/migrations/v8-004-schema-closure.js +74 -0
  72. package/runtime/storage/db/migrations/v8-005-single-status-schema.d.ts +11 -0
  73. package/runtime/storage/db/migrations/v8-005-single-status-schema.js +16 -0
  74. package/runtime/storage/db/schema/v8-entities.d.ts +0 -95
  75. package/runtime/storage/db/schema/v8-entities.js +4 -7
  76. package/runtime/storage/delivery/types.d.ts +2 -2
  77. package/runtime/storage/fallback/load-operator-fallback.d.ts +2 -2
  78. package/runtime/storage/fallback/operator-fallback-types.d.ts +2 -2
  79. package/runtime/storage/fallback/operator-fallback-view.d.ts +2 -2
  80. package/runtime/storage/index.d.ts +1 -1
  81. package/runtime/storage/life-evidence/types.d.ts +5 -5
  82. package/runtime/storage/quiet/quiet-artifact-types.d.ts +4 -4
  83. package/runtime/storage/quiet/quiet-artifact-writer.d.ts +2 -2
  84. package/runtime/storage/services/write-validation-gate.d.ts +1 -1
  85. package/runtime/storage/services/write-validation-gate.js +16 -4
  86. package/runtime/storage/snapshots/types.d.ts +8 -8
  87. package/runtime/storage/user-interest/types.d.ts +3 -3
  88. package/runtime/storage/v8-state-stores.d.ts +8 -1
  89. package/runtime/storage/v8-state-stores.js +23 -20
  90. package/workspace-ops-bridge.js +29 -1
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export type LifeEvidenceType = "platform_browse" | "platform_interaction" | "work_progress" | "task_discovery" | "user_interaction" | "quiet_reflection" | "delivery_fallback";
7
7
  export type Sensitivity = "public" | "private" | "credential" | "sensitive";
8
- export interface SourceRef {
8
+ export interface LifeEvidenceSourceRef {
9
9
  id: string;
10
10
  kind: "platform_item" | "workspace_artifact" | "decision_record" | "user_anchor" | "connector_result" | "host_report" | "fallback_artifact";
11
11
  uri: string;
@@ -19,7 +19,7 @@ export interface LifeEvidenceCandidate {
19
19
  platformId?: string;
20
20
  summary: string;
21
21
  rawContentRef?: string;
22
- sourceRefs: SourceRef[];
22
+ sourceRefs: LifeEvidenceSourceRef[];
23
23
  sensitivity: Sensitivity;
24
24
  confidence?: number;
25
25
  tags?: string[];
@@ -32,14 +32,14 @@ export interface LifeEvidence {
32
32
  platformId?: string;
33
33
  summary: string;
34
34
  rawContentRef?: string;
35
- sourceRefs: SourceRef[];
35
+ sourceRefs: LifeEvidenceSourceRef[];
36
36
  sensitivity: Sensitivity;
37
37
  confidence: number;
38
38
  tags: string[];
39
39
  producer: string;
40
- artifactRef: SourceRef;
40
+ artifactRef: LifeEvidenceSourceRef;
41
41
  }
42
42
  export interface LifeEvidenceWriteAck {
43
43
  evidenceId: string;
44
- artifactRef: SourceRef;
44
+ artifactRef: LifeEvidenceSourceRef;
45
45
  }
@@ -1,10 +1,10 @@
1
- import type { SourceRef } from "../life-evidence/types.js";
1
+ import type { LifeEvidenceSourceRef } from "../life-evidence/types.js";
2
2
  export type QuietArtifactKind = "daily_report" | "narrative_reflection" | "curated_memory_candidate" | "empty_state";
3
3
  export type QuietClaimType = "fact" | "emotion" | "interpretation" | "next_step";
4
4
  export interface QuietClaim {
5
5
  id: string;
6
6
  text: string;
7
- sourceRefs: SourceRef[];
7
+ sourceRefs: LifeEvidenceSourceRef[];
8
8
  claimType: QuietClaimType;
9
9
  }
10
10
  export interface QuietArtifactWrite {
@@ -13,6 +13,6 @@ export interface QuietArtifactWrite {
13
13
  title: string;
14
14
  body: string;
15
15
  claims: QuietClaim[];
16
- sourceRefs: SourceRef[];
17
- memoryCandidateRefs?: SourceRef[];
16
+ sourceRefs: LifeEvidenceSourceRef[];
17
+ memoryCandidateRefs?: LifeEvidenceSourceRef[];
18
18
  }
@@ -1,4 +1,4 @@
1
- import type { SourceRef } from "../life-evidence/types.js";
1
+ import type { LifeEvidenceSourceRef } from "../life-evidence/types.js";
2
2
  import type { SourceCoverage } from "../snapshots/types.js";
3
3
  import type { QuietArtifactWrite } from "./quiet-artifact-types.js";
4
4
  import type { QuietClaim } from "./quiet-artifact-types.js";
@@ -7,7 +7,7 @@ export declare function calculateQuietSourceCoverage(claims: QuietClaim[]): Sour
7
7
  export declare function evidenceGroundingRatio(input: Pick<QuietArtifactWrite, "claims" | "sourceRefs">): number;
8
8
  export interface QuietArtifactAck {
9
9
  artifactId: string;
10
- artifactRef: SourceRef;
10
+ artifactRef: LifeEvidenceSourceRef;
11
11
  sourceCoverage: SourceCoverage;
12
12
  }
13
13
  export declare function writeQuietArtifact(input: QuietArtifactWrite, opts?: {
@@ -7,7 +7,7 @@
7
7
  * readable reason codes (DR-022).
8
8
  *
9
9
  * Dependencies:
10
- * - `SourceRef` type from `../../shared/types/source-ref.js`
10
+ * - `SourceRefTuple` type from `../../shared/types/source-ref.js`
11
11
  * - v7 entity types for shape awareness
12
12
  *
13
13
  * Boundary:
@@ -7,7 +7,7 @@
7
7
  * readable reason codes (DR-022).
8
8
  *
9
9
  * Dependencies:
10
- * - `SourceRef` type from `../../shared/types/source-ref.js`
10
+ * - `SourceRefTuple` type from `../../shared/types/source-ref.js`
11
11
  * - v7 entity types for shape awareness
12
12
  *
13
13
  * Boundary:
@@ -115,7 +115,7 @@ const IDENTIFIER_FIELD_NAMES = new Set([
115
115
  "id",
116
116
  "runId",
117
117
  "run_id",
118
- "sourceRef",
118
+ "SourceRefTuple",
119
119
  "source_ref",
120
120
  "sourceRefs",
121
121
  "source_refs_json",
@@ -127,6 +127,14 @@ const IDENTIFIER_FIELD_NAMES = new Set([
127
127
  "capability_id",
128
128
  "candidate_id",
129
129
  ]);
130
+ // Fields that describe where a secret is stored must still reject payloads
131
+ // that contain raw secret material, even if the value is URI-shaped.
132
+ const SECRET_LOCATION_FIELD_NAMES = new Set([
133
+ "locationRef",
134
+ "location_ref",
135
+ "rotationPolicyRef",
136
+ "rotation_policy_ref",
137
+ ]);
130
138
  function looksLikeUriPath(text) {
131
139
  return /^[a-z][a-z0-9+.-]*:\/\//i.test(text) || (text.includes("/") && !text.includes(" "));
132
140
  }
@@ -154,8 +162,12 @@ function sensitivityScan(value, fieldPath = "payload") {
154
162
  const matched = match[0];
155
163
  if (exempt && exempt(matched))
156
164
  continue;
157
- if (isIdentifierField || looksLikeUriPath(value))
158
- continue;
165
+ if (isIdentifierField || looksLikeUriPath(value)) {
166
+ const leafField = fieldPath.split(".").pop() ?? "";
167
+ if (!SECRET_LOCATION_FIELD_NAMES.has(leafField)) {
168
+ continue;
169
+ }
170
+ }
159
171
  return {
160
172
  reason: "write_validation_failed:sensitivity_scan_failed",
161
173
  field: fieldPath,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Read-model snapshots aligned with state-system v5 (subset for S1/S2).
3
3
  */
4
- import type { LifeEvidenceType, SourceRef } from "../life-evidence/types.js";
4
+ import type { LifeEvidenceSourceRef, LifeEvidenceType } from "../life-evidence/types.js";
5
5
  export interface LifeEvidenceQuery {
6
6
  windowStart?: string;
7
7
  windowEnd?: string;
@@ -14,7 +14,7 @@ export interface SourceCoverage {
14
14
  claimCoverage: Array<{
15
15
  claimId: string;
16
16
  backed: boolean;
17
- sourceRefs: SourceRef[];
17
+ sourceRefs: LifeEvidenceSourceRef[];
18
18
  }>;
19
19
  }
20
20
  export interface LifeEvidenceReadModel {
@@ -24,7 +24,7 @@ export interface LifeEvidenceReadModel {
24
24
  platformId?: string;
25
25
  summary: string;
26
26
  rawContentRef?: string;
27
- sourceRefs: SourceRef[];
27
+ sourceRefs: LifeEvidenceSourceRef[];
28
28
  sensitivity: import("../life-evidence/types.js").Sensitivity;
29
29
  confidence: number;
30
30
  tags: string[];
@@ -35,11 +35,11 @@ export interface LifeEvidenceSnapshot {
35
35
  generatedAt: string;
36
36
  windowStart: string;
37
37
  windowEnd: string;
38
- evidenceRefs: SourceRef[];
38
+ evidenceRefs: LifeEvidenceSourceRef[];
39
39
  platformEvents: LifeEvidenceReadModel[];
40
40
  workEvents: LifeEvidenceReadModel[];
41
41
  userInteractionEvents: LifeEvidenceReadModel[];
42
- quietArtifacts: SourceRef[];
42
+ quietArtifacts: LifeEvidenceSourceRef[];
43
43
  coverage: SourceCoverage;
44
44
  empty: boolean;
45
45
  }
@@ -47,12 +47,12 @@ export interface ContinuitySnapshot {
47
47
  snapshotId: string;
48
48
  generatedAt: string;
49
49
  lastHeartbeatAt?: string;
50
- recentDecisionRefs: SourceRef[];
51
- openObligations: SourceRef[];
50
+ recentDecisionRefs: LifeEvidenceSourceRef[];
51
+ openObligations: LifeEvidenceSourceRef[];
52
52
  quietDebt: {
53
53
  hasUnprocessedEvidence: boolean;
54
54
  oldestUnprocessedEvidenceAt?: string;
55
55
  pendingCount: number;
56
56
  };
57
- fallbackRefs: SourceRef[];
57
+ fallbackRefs: LifeEvidenceSourceRef[];
58
58
  }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Test coverage: tests/unit/storage/user-interest-snapshot.test.ts
5
5
  */
6
- import type { SourceRef } from "../life-evidence/types.js";
6
+ import type { LifeEvidenceSourceRef } from "../life-evidence/types.js";
7
7
  export type UserInterestStaleness = "fresh" | "stale" | "insufficient";
8
8
  export interface UserInterestSignal {
9
9
  id: string;
@@ -11,14 +11,14 @@ export interface UserInterestSignal {
11
11
  affinity: "positive" | "negative" | "watching" | "unknown";
12
12
  reason: string;
13
13
  confidence: number;
14
- sourceRefs: SourceRef[];
14
+ sourceRefs: LifeEvidenceSourceRef[];
15
15
  updatedAt: string;
16
16
  }
17
17
  export interface UserInterestSnapshot {
18
18
  snapshotId: string;
19
19
  generatedAt: string;
20
20
  signals: UserInterestSignal[];
21
- sourceRefs: SourceRef[];
21
+ sourceRefs: LifeEvidenceSourceRef[];
22
22
  confidence: number;
23
23
  staleness: UserInterestStaleness;
24
24
  missingReasons?: string[];
@@ -120,7 +120,6 @@ export declare function writeDreamConsolidationRun(db: StateDatabase, row: Omit<
120
120
  */
121
121
  export declare function updateDreamConsolidationRunStatus(db: StateDatabase, id: string, status: DreamConsolidationRunRecord["status"], options?: {
122
122
  reason?: DreamConsolidationRunRecord["reason"];
123
- lifecycleStatus?: DreamConsolidationRunRecord["lifecycleStatus"];
124
123
  payloadJson?: string;
125
124
  }): Promise<{
126
125
  id: string;
@@ -133,6 +132,14 @@ export declare function readDreamConsolidationRunsByQuietId(db: StateDatabase, q
133
132
  rows: DreamConsolidationRunRecord[];
134
133
  degraded?: DegradedOperationResult;
135
134
  }>;
135
+ /**
136
+ * Read the most recent DreamConsolidationRun globally, filtered by status.
137
+ * Used to enforce the 7-day Dream interval across Quiet review IDs.
138
+ */
139
+ export declare function readLatestDreamConsolidationRunByStatus(db: StateDatabase, statuses: DreamConsolidationRunRecord["status"][]): Promise<{
140
+ row?: DreamConsolidationRunRecord;
141
+ degraded?: DegradedOperationResult;
142
+ }>;
136
143
  export declare function writeLongTermMemoryProjection(db: StateDatabase, row: Omit<NewLongTermMemoryProjectionRecord, "sourceRefsJson"> & {
137
144
  sourceRefs: SourceRef[];
138
145
  }): Promise<{
@@ -21,27 +21,12 @@
21
21
  *
22
22
  * Test coverage: tests/unit/storage/v8-state-stores.test.ts
23
23
  */
24
- import { eq, and, desc, like, isNull } from "drizzle-orm";
24
+ import { eq, and, desc, like, isNull, inArray } from "drizzle-orm";
25
25
  import { evidenceItem, perceptionCard, judgmentVerdict, actionClosureRecord, quietDailyReview, dreamConsolidationRun, longTermMemoryProjection, heartbeatCycleTrace, loopStageEvent, impulseContextArtifact, dailyRhythmState, connectorCooldownState, } from "./db/schema/v8-entities.js";
26
+ import { serializeSourceRefs, parseSourceRefs, } from "../shared/serialization.js";
26
27
  // ───────────────────────────────────────────────────────────────
27
28
  // Shared helpers
28
29
  // ───────────────────────────────────────────────────────────────
29
- function serializeSourceRefs(refs) {
30
- return JSON.stringify(refs);
31
- }
32
- function parseSourceRefs(json) {
33
- if (!json)
34
- return [];
35
- try {
36
- const parsed = JSON.parse(json);
37
- if (Array.isArray(parsed))
38
- return parsed;
39
- return [];
40
- }
41
- catch {
42
- return [];
43
- }
44
- }
45
30
  function makeDegraded(reason, ownerStage, operatorNextAction, sourceRefs = []) {
46
31
  return {
47
32
  status: "degraded",
@@ -444,8 +429,6 @@ export async function updateDreamConsolidationRunStatus(db, id, status, options)
444
429
  const updateData = { status };
445
430
  if (options?.reason !== undefined)
446
431
  updateData.reason = options.reason;
447
- if (options?.lifecycleStatus !== undefined)
448
- updateData.lifecycleStatus = options.lifecycleStatus;
449
432
  if (options?.payloadJson !== undefined)
450
433
  updateData.payloadJson = options.payloadJson;
451
434
  await db.db.update(dreamConsolidationRun).set(updateData).where(eq(dreamConsolidationRun.id, id));
@@ -486,6 +469,26 @@ export async function readDreamConsolidationRunsByQuietId(db, quietReviewId) {
486
469
  };
487
470
  }
488
471
  }
472
+ /**
473
+ * Read the most recent DreamConsolidationRun globally, filtered by status.
474
+ * Used to enforce the 7-day Dream interval across Quiet review IDs.
475
+ */
476
+ export async function readLatestDreamConsolidationRunByStatus(db, statuses) {
477
+ try {
478
+ const rows = await db.db
479
+ .select()
480
+ .from(dreamConsolidationRun)
481
+ .where(inArray(dreamConsolidationRun.status, statuses))
482
+ .orderBy(desc(dreamConsolidationRun.createdAt))
483
+ .limit(1);
484
+ return { row: rows[0] };
485
+ }
486
+ catch {
487
+ return {
488
+ degraded: makeDegraded("state_unreadable", "dream", "Check state database connectivity"),
489
+ };
490
+ }
491
+ }
489
492
  // ───────────────────────────────────────────────────────────────
490
493
  // LongTermMemoryProjection store
491
494
  // ───────────────────────────────────────────────────────────────
@@ -511,7 +514,7 @@ export async function writeLongTermMemoryProjection(db, row) {
511
514
  */
512
515
  export async function updateLongTermMemoryProjectionStatus(db, id, status, payloadJson) {
513
516
  try {
514
- const updateData = { status, lifecycleStatus: status };
517
+ const updateData = { status };
515
518
  if (payloadJson !== undefined) {
516
519
  updateData.payloadJson = payloadJson;
517
520
  }
@@ -99,7 +99,35 @@ export async function openWorkspaceOpsBridge(workspaceRoot) {
99
99
  const prevCwd = process.cwd();
100
100
  try {
101
101
  process.chdir(resolvedRoot);
102
- return await def.execute(input);
102
+ const result = await def.execute(input);
103
+ // T-ROS.C.3-followup: ensure sql.js in-memory DB is persisted after each
104
+ // mutating tool call so subsequent calls (possibly in a new process) see
105
+ // the latest state. Flush failures are reported as warnings, never fatal.
106
+ try {
107
+ if (typeof stateDb.flush === "function") {
108
+ stateDb.flush();
109
+ }
110
+ }
111
+ catch (flushErr) {
112
+ const warning = flushErr instanceof Error ? flushErr.message : String(flushErr);
113
+ result.warnings = [
114
+ ...(result.warnings ?? []),
115
+ `state_flush_warning:${warning}`,
116
+ ];
117
+ }
118
+ try {
119
+ if (typeof observabilityDb.flush === "function") {
120
+ observabilityDb.flush();
121
+ }
122
+ }
123
+ catch (flushErr) {
124
+ const warning = flushErr instanceof Error ? flushErr.message : String(flushErr);
125
+ result.warnings = [
126
+ ...(result.warnings ?? []),
127
+ `observability_flush_warning:${warning}`,
128
+ ];
129
+ }
130
+ return result;
103
131
  }
104
132
  finally {
105
133
  process.chdir(prevCwd);