@haaaiawd/second-nature 0.2.1 → 0.2.4
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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/runtime/cli/index.js +5 -1
- package/runtime/cli/ops/heartbeat-surface.d.ts +23 -0
- package/runtime/cli/ops/heartbeat-surface.js +73 -1
- package/runtime/cli/ops/manual-run-dispatcher.d.ts +2 -0
- package/runtime/cli/ops/manual-run-dispatcher.js +10 -0
- package/runtime/cli/ops/ops-router.js +117 -31
- package/runtime/cli/ops/workspace-heartbeat-runner.d.ts +3 -0
- package/runtime/cli/ops/workspace-heartbeat-runner.js +2 -0
- package/runtime/connectors/base/contract.d.ts +10 -0
- package/runtime/connectors/base/policy-bound-write-dispatch.d.ts +29 -0
- package/runtime/connectors/base/policy-bound-write-dispatch.js +127 -0
- package/runtime/core/second-nature/control-plane/heartbeat-orchestrator.js +336 -25
- package/runtime/core/second-nature/control-plane/real-runtime-spine.d.ts +33 -0
- package/runtime/core/second-nature/control-plane/real-runtime-spine.js +41 -0
- package/runtime/core/second-nature/guidance/impulse-context-reader.d.ts +44 -0
- package/runtime/core/second-nature/guidance/impulse-context-reader.js +84 -0
- package/runtime/core/second-nature/guidance/impulse-context-writer.d.ts +39 -0
- package/runtime/core/second-nature/guidance/impulse-context-writer.js +70 -0
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.d.ts +6 -1
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +11 -0
- package/runtime/core/second-nature/perception/judgment-engine.d.ts +2 -0
- package/runtime/core/second-nature/perception/judgment-engine.js +11 -1
- package/runtime/core/second-nature/perception/perception-builder.d.ts +6 -2
- package/runtime/core/second-nature/perception/perception-builder.js +18 -7
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.d.ts +3 -0
- package/runtime/core/second-nature/quiet/run-source-backed-quiet.js +42 -1
- package/runtime/core/second-nature/quiet-dream/daily-rhythm-scheduler.d.ts +43 -0
- package/runtime/core/second-nature/quiet-dream/daily-rhythm-scheduler.js +157 -0
- package/runtime/core/second-nature/quiet-dream/memory-projection-lifecycle.js +17 -16
- package/runtime/core/second-nature/quiet-dream/quiet-daily-review-builder.d.ts +3 -0
- package/runtime/core/second-nature/quiet-dream/quiet-daily-review-builder.js +4 -0
- package/runtime/observability/living-loop-health-gate.d.ts +45 -0
- package/runtime/observability/living-loop-health-gate.js +94 -0
- package/runtime/observability/loop-status.d.ts +11 -0
- package/runtime/observability/loop-status.js +49 -3
- package/runtime/observability/services/audit-closure-recorders.d.ts +31 -0
- package/runtime/observability/services/audit-closure-recorders.js +87 -0
- package/runtime/observability/services/heartbeat-digest-assembler.d.ts +12 -0
- package/runtime/observability/services/heartbeat-digest-assembler.js +22 -3
- package/runtime/shared/types/v8-contracts.d.ts +2 -2
- package/runtime/storage/db/index.js +34 -0
- package/runtime/storage/db/migrations/index.js +4 -0
- package/runtime/storage/db/migrations/v8-001-living-perception-loop.js +119 -119
- package/runtime/storage/db/migrations/v8-002-perception-contract-alignment.d.ts +12 -0
- package/runtime/storage/db/migrations/v8-002-perception-contract-alignment.js +14 -0
- package/runtime/storage/db/migrations/v8-003-quiet-closure-refs.d.ts +10 -0
- package/runtime/storage/db/migrations/v8-003-quiet-closure-refs.js +12 -0
- package/runtime/storage/db/schema/v8-entities.d.ts +586 -0
- package/runtime/storage/db/schema/v8-entities.js +39 -0
- package/runtime/storage/v8-state-stores.d.ts +32 -2
- package/runtime/storage/v8-state-stores.js +121 -2
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* Test coverage: tests/unit/storage/v8-state-stores.test.ts
|
|
23
23
|
*/
|
|
24
24
|
import type { StateDatabase } from "./db/index.js";
|
|
25
|
-
import { type EvidenceItemRecord, type NewEvidenceItemRecord, type PerceptionCardRecord, type NewPerceptionCardRecord, type JudgmentVerdictRecord, type NewJudgmentVerdictRecord, type ActionClosureRecordSelect, type ActionClosureRecordInsert, type QuietDailyReviewRecord, type NewQuietDailyReviewRecord, type DreamConsolidationRunRecord, type NewDreamConsolidationRunRecord, type LongTermMemoryProjectionRecord, type NewLongTermMemoryProjectionRecord, type HeartbeatCycleTraceRecord, type NewHeartbeatCycleTraceRecord, type LoopStageEventRecord, type NewLoopStageEventRecord } from "./db/schema/v8-entities.js";
|
|
25
|
+
import { type EvidenceItemRecord, type NewEvidenceItemRecord, type PerceptionCardRecord, type NewPerceptionCardRecord, type JudgmentVerdictRecord, type NewJudgmentVerdictRecord, type ActionClosureRecordSelect, type ActionClosureRecordInsert, type QuietDailyReviewRecord, type NewQuietDailyReviewRecord, type DreamConsolidationRunRecord, type NewDreamConsolidationRunRecord, type LongTermMemoryProjectionRecord, type NewLongTermMemoryProjectionRecord, type HeartbeatCycleTraceRecord, type NewHeartbeatCycleTraceRecord, type LoopStageEventRecord, type NewLoopStageEventRecord, type ImpulseContextArtifactRecord, type NewImpulseContextArtifactRecord, type DailyRhythmStateRecord, type NewDailyRhythmStateRecord } from "./db/schema/v8-entities.js";
|
|
26
26
|
import type { SourceRef, DegradedOperationResult } from "../shared/types/v8-contracts.js";
|
|
27
27
|
export interface WriteValidationError {
|
|
28
28
|
ok: false;
|
|
@@ -81,8 +81,9 @@ export declare function readActionClosuresByDay(db: StateDatabase, day: string):
|
|
|
81
81
|
rows: ActionClosureRecordSelect[];
|
|
82
82
|
degraded?: DegradedOperationResult;
|
|
83
83
|
}>;
|
|
84
|
-
export declare function writeQuietDailyReview(db: StateDatabase, row: Omit<NewQuietDailyReviewRecord, "sourceRefsJson"> & {
|
|
84
|
+
export declare function writeQuietDailyReview(db: StateDatabase, row: Omit<NewQuietDailyReviewRecord, "sourceRefsJson" | "closureRefsJson"> & {
|
|
85
85
|
sourceRefs: SourceRef[];
|
|
86
|
+
closureRefs?: SourceRef[];
|
|
86
87
|
}): Promise<{
|
|
87
88
|
id: string;
|
|
88
89
|
} | DegradedOperationResult>;
|
|
@@ -112,6 +113,13 @@ export declare function writeLongTermMemoryProjection(db: StateDatabase, row: Om
|
|
|
112
113
|
}): Promise<{
|
|
113
114
|
id: string;
|
|
114
115
|
} | DegradedOperationResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Update an existing projection's status — required for supersession lifecycle.
|
|
118
|
+
* Uses UPDATE instead of INSERT to avoid primary-key conflict.
|
|
119
|
+
*/
|
|
120
|
+
export declare function updateLongTermMemoryProjectionStatus(db: StateDatabase, id: string, status: LongTermMemoryProjectionRecord["status"], payloadJson?: string): Promise<{
|
|
121
|
+
id: string;
|
|
122
|
+
} | DegradedOperationResult>;
|
|
115
123
|
export declare function readMemoryProjectionsByStatus(db: StateDatabase, status: LongTermMemoryProjectionRecord["status"]): Promise<{
|
|
116
124
|
rows: LongTermMemoryProjectionRecord[];
|
|
117
125
|
degraded?: DegradedOperationResult;
|
|
@@ -120,6 +128,10 @@ export declare function readMemoryProjectionsByTopic(db: StateDatabase, topicKey
|
|
|
120
128
|
rows: LongTermMemoryProjectionRecord[];
|
|
121
129
|
degraded?: DegradedOperationResult;
|
|
122
130
|
}>;
|
|
131
|
+
export declare function readLongTermMemoryProjectionById(db: StateDatabase, id: string): Promise<{
|
|
132
|
+
row?: LongTermMemoryProjectionRecord;
|
|
133
|
+
degraded?: DegradedOperationResult;
|
|
134
|
+
}>;
|
|
123
135
|
export declare function writeHeartbeatCycleTrace(db: StateDatabase, row: Omit<NewHeartbeatCycleTraceRecord, "sourceRefsJson"> & {
|
|
124
136
|
sourceRefs?: SourceRef[];
|
|
125
137
|
}): Promise<{
|
|
@@ -142,6 +154,24 @@ export declare function readLoopStageEventsByStage(db: StateDatabase, stage: Loo
|
|
|
142
154
|
rows: LoopStageEventRecord[];
|
|
143
155
|
degraded?: DegradedOperationResult;
|
|
144
156
|
}>;
|
|
157
|
+
export declare function writeImpulseContextArtifact(db: StateDatabase, row: Omit<NewImpulseContextArtifactRecord, "sourceRefsJson"> & {
|
|
158
|
+
sourceRefs: SourceRef[];
|
|
159
|
+
}): Promise<{
|
|
160
|
+
id: string;
|
|
161
|
+
} | DegradedOperationResult>;
|
|
162
|
+
export declare function readImpulseContextArtifact(db: StateDatabase, sceneType: string, capabilityIntent?: string, platformId?: string): Promise<{
|
|
163
|
+
row?: ImpulseContextArtifactRecord;
|
|
164
|
+
degraded?: DegradedOperationResult;
|
|
165
|
+
}>;
|
|
166
|
+
export declare function writeDailyRhythmState(db: StateDatabase, row: Omit<NewDailyRhythmStateRecord, "sourceRefsJson"> & {
|
|
167
|
+
sourceRefs: SourceRef[];
|
|
168
|
+
}): Promise<{
|
|
169
|
+
id: string;
|
|
170
|
+
} | DegradedOperationResult>;
|
|
171
|
+
export declare function readDailyRhythmStateByDay(db: StateDatabase, day: string): Promise<{
|
|
172
|
+
row?: DailyRhythmStateRecord;
|
|
173
|
+
degraded?: DegradedOperationResult;
|
|
174
|
+
}>;
|
|
145
175
|
export declare function extractSourceRefs(row: {
|
|
146
176
|
sourceRefsJson: string | null;
|
|
147
177
|
}): SourceRef[];
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
*
|
|
22
22
|
* Test coverage: tests/unit/storage/v8-state-stores.test.ts
|
|
23
23
|
*/
|
|
24
|
-
import { eq, desc, like } from "drizzle-orm";
|
|
25
|
-
import { evidenceItem, perceptionCard, judgmentVerdict, actionClosureRecord, quietDailyReview, dreamConsolidationRun, longTermMemoryProjection, heartbeatCycleTrace, loopStageEvent, } from "./db/schema/v8-entities.js";
|
|
24
|
+
import { eq, and, desc, like, isNull } from "drizzle-orm";
|
|
25
|
+
import { evidenceItem, perceptionCard, judgmentVerdict, actionClosureRecord, quietDailyReview, dreamConsolidationRun, longTermMemoryProjection, heartbeatCycleTrace, loopStageEvent, impulseContextArtifact, dailyRhythmState, } from "./db/schema/v8-entities.js";
|
|
26
26
|
// ───────────────────────────────────────────────────────────────
|
|
27
27
|
// Shared helpers
|
|
28
28
|
// ───────────────────────────────────────────────────────────────
|
|
@@ -258,6 +258,7 @@ export async function writeQuietDailyReview(db, row) {
|
|
|
258
258
|
const record = {
|
|
259
259
|
...row,
|
|
260
260
|
sourceRefsJson: serializeSourceRefs(validated.record),
|
|
261
|
+
closureRefsJson: row.closureRefs ? serializeSourceRefs(row.closureRefs) : null,
|
|
261
262
|
};
|
|
262
263
|
await db.db.insert(quietDailyReview).values(record);
|
|
263
264
|
return { id: row.id };
|
|
@@ -366,6 +367,23 @@ export async function writeLongTermMemoryProjection(db, row) {
|
|
|
366
367
|
return makeDegraded("state_unreadable", "projection", "Retry projection write after DB recovery", validated.record);
|
|
367
368
|
}
|
|
368
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Update an existing projection's status — required for supersession lifecycle.
|
|
372
|
+
* Uses UPDATE instead of INSERT to avoid primary-key conflict.
|
|
373
|
+
*/
|
|
374
|
+
export async function updateLongTermMemoryProjectionStatus(db, id, status, payloadJson) {
|
|
375
|
+
try {
|
|
376
|
+
const updateData = { status, lifecycleStatus: status };
|
|
377
|
+
if (payloadJson !== undefined) {
|
|
378
|
+
updateData.payloadJson = payloadJson;
|
|
379
|
+
}
|
|
380
|
+
await db.db.update(longTermMemoryProjection).set(updateData).where(eq(longTermMemoryProjection.id, id));
|
|
381
|
+
return { id };
|
|
382
|
+
}
|
|
383
|
+
catch {
|
|
384
|
+
return makeDegraded("state_unreadable", "projection", `Retry projection status update for ${id} after DB recovery`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
369
387
|
export async function readMemoryProjectionsByStatus(db, status) {
|
|
370
388
|
try {
|
|
371
389
|
const rows = await db.db
|
|
@@ -398,6 +416,21 @@ export async function readMemoryProjectionsByTopic(db, topicKey) {
|
|
|
398
416
|
};
|
|
399
417
|
}
|
|
400
418
|
}
|
|
419
|
+
export async function readLongTermMemoryProjectionById(db, id) {
|
|
420
|
+
try {
|
|
421
|
+
const rows = await db.db
|
|
422
|
+
.select()
|
|
423
|
+
.from(longTermMemoryProjection)
|
|
424
|
+
.where(eq(longTermMemoryProjection.id, id))
|
|
425
|
+
.limit(1);
|
|
426
|
+
return { row: rows[0] };
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
return {
|
|
430
|
+
degraded: makeDegraded("state_unreadable", "projection", `Check state database connectivity for projection ${id}`),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
}
|
|
401
434
|
// ───────────────────────────────────────────────────────────────
|
|
402
435
|
// HeartbeatCycleTrace store
|
|
403
436
|
// ───────────────────────────────────────────────────────────────
|
|
@@ -484,6 +517,92 @@ export async function readLoopStageEventsByStage(db, stage, limit = 100) {
|
|
|
484
517
|
}
|
|
485
518
|
}
|
|
486
519
|
// ───────────────────────────────────────────────────────────────
|
|
520
|
+
// ImpulseContextArtifact store
|
|
521
|
+
// ───────────────────────────────────────────────────────────────
|
|
522
|
+
export async function writeImpulseContextArtifact(db, row) {
|
|
523
|
+
const validated = validateSourceRefs(row.sourceRefs, "projection");
|
|
524
|
+
if (!validated.ok)
|
|
525
|
+
return validated.degraded;
|
|
526
|
+
try {
|
|
527
|
+
const record = {
|
|
528
|
+
...row,
|
|
529
|
+
sourceRefsJson: serializeSourceRefs(validated.record),
|
|
530
|
+
};
|
|
531
|
+
// Upsert: delete existing then insert (SQLite primary-key conflict)
|
|
532
|
+
await db.db.delete(impulseContextArtifact).where(eq(impulseContextArtifact.id, row.id));
|
|
533
|
+
await db.db.insert(impulseContextArtifact).values(record);
|
|
534
|
+
return { id: row.id };
|
|
535
|
+
}
|
|
536
|
+
catch {
|
|
537
|
+
return makeDegraded("state_unreadable", "projection", "Retry impulse context write after DB recovery", validated.record);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
export async function readImpulseContextArtifact(db, sceneType, capabilityIntent, platformId) {
|
|
541
|
+
try {
|
|
542
|
+
const conditions = [eq(impulseContextArtifact.sceneType, sceneType)];
|
|
543
|
+
if (capabilityIntent) {
|
|
544
|
+
conditions.push(eq(impulseContextArtifact.capabilityIntent, capabilityIntent));
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
conditions.push(isNull(impulseContextArtifact.capabilityIntent));
|
|
548
|
+
}
|
|
549
|
+
if (platformId) {
|
|
550
|
+
conditions.push(eq(impulseContextArtifact.platformId, platformId));
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
conditions.push(isNull(impulseContextArtifact.platformId));
|
|
554
|
+
}
|
|
555
|
+
const rows = await db.db
|
|
556
|
+
.select()
|
|
557
|
+
.from(impulseContextArtifact)
|
|
558
|
+
.where(and(...conditions))
|
|
559
|
+
.orderBy(desc(impulseContextArtifact.updatedAt))
|
|
560
|
+
.limit(1);
|
|
561
|
+
return { row: rows[0] };
|
|
562
|
+
}
|
|
563
|
+
catch {
|
|
564
|
+
return {
|
|
565
|
+
degraded: makeDegraded("state_unreadable", "projection", "Check state database connectivity"),
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
// ───────────────────────────────────────────────────────────────
|
|
570
|
+
// DailyRhythmState store
|
|
571
|
+
// ───────────────────────────────────────────────────────────────
|
|
572
|
+
export async function writeDailyRhythmState(db, row) {
|
|
573
|
+
const validated = validateSourceRefs(row.sourceRefs, "dream");
|
|
574
|
+
if (!validated.ok)
|
|
575
|
+
return validated.degraded;
|
|
576
|
+
try {
|
|
577
|
+
const record = {
|
|
578
|
+
...row,
|
|
579
|
+
sourceRefsJson: serializeSourceRefs(validated.record),
|
|
580
|
+
};
|
|
581
|
+
await db.db.delete(dailyRhythmState).where(eq(dailyRhythmState.id, row.id));
|
|
582
|
+
await db.db.insert(dailyRhythmState).values(record);
|
|
583
|
+
return { id: row.id };
|
|
584
|
+
}
|
|
585
|
+
catch {
|
|
586
|
+
return makeDegraded("state_unreadable", "dream", "Retry daily rhythm state write after DB recovery", validated.record);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
export async function readDailyRhythmStateByDay(db, day) {
|
|
590
|
+
try {
|
|
591
|
+
const rows = await db.db
|
|
592
|
+
.select()
|
|
593
|
+
.from(dailyRhythmState)
|
|
594
|
+
.where(eq(dailyRhythmState.day, day))
|
|
595
|
+
.orderBy(desc(dailyRhythmState.updatedAt))
|
|
596
|
+
.limit(1);
|
|
597
|
+
return { row: rows[0] };
|
|
598
|
+
}
|
|
599
|
+
catch {
|
|
600
|
+
return {
|
|
601
|
+
degraded: makeDegraded("state_unreadable", "dream", `Check state database connectivity for day=${day}`),
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// ───────────────────────────────────────────────────────────────
|
|
487
606
|
// SourceRef round-trip helper (for tests and consumers)
|
|
488
607
|
// ───────────────────────────────────────────────────────────────
|
|
489
608
|
export function extractSourceRefs(row) {
|