@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
@@ -7,7 +7,7 @@
7
7
  * - `status` supports full v7 lifecycle including paused → expired/replaced.
8
8
  *
9
9
  * Dependencies:
10
- * - `SourceRef` from `./source-ref.js` for grounding.
10
+ * - `SourceRefTuple` from `./source-ref.js` for grounding.
11
11
  *
12
12
  * Boundary:
13
13
  * - Used by state-memory (GoalLifecycleStore), control-plane
@@ -17,7 +17,7 @@
17
17
  * Test coverage: tests/unit/shared/v7-entities.test.ts (invalid kind
18
18
  * `@ts-expect-error` compile guard).
19
19
  */
20
- import type { SourceRef } from "./source-ref.js";
20
+ import type { SourceRefTuple } from "./source-ref.js";
21
21
  export type AgentGoalKind = "short_term" | "long_term" | "habit" | "maintenance" | "passive_sensing" | "outreach" | "exploration";
22
22
  export type AgentGoalStatus = "proposal" | "accepted" | "rejected" | "completed" | "paused" | "expired" | "replaced";
23
23
  export type AgentGoalOrigin = "owner_set" | "agent_proposed" | "policy_seeded";
@@ -32,7 +32,7 @@ export interface AgentGoal {
32
32
  completionCriteria: string;
33
33
  risk: "low" | "medium" | "high";
34
34
  priorityHint: number;
35
- sourceRefs: SourceRef;
35
+ sourceRefs: SourceRefTuple;
36
36
  acceptedBy?: "owner" | "policy_allowlist";
37
37
  expiresAt?: string;
38
38
  createdAt: string;
@@ -48,7 +48,7 @@ export interface AgentGoalWrite {
48
48
  completionCriteria: string;
49
49
  risk: "low" | "medium" | "high";
50
50
  priorityHint: number;
51
- sourceRefs: SourceRef;
51
+ sourceRefs: SourceRefTuple;
52
52
  acceptedBy?: "owner" | "policy_allowlist";
53
53
  expiresAt?: string;
54
54
  createdAt: string;
@@ -7,7 +7,7 @@
7
7
  * - `status` supports full v7 lifecycle including paused → expired/replaced.
8
8
  *
9
9
  * Dependencies:
10
- * - `SourceRef` from `./source-ref.js` for grounding.
10
+ * - `SourceRefTuple` from `./source-ref.js` for grounding.
11
11
  *
12
12
  * Boundary:
13
13
  * - Used by state-memory (GoalLifecycleStore), control-plane
@@ -4,3 +4,4 @@ export * from "./outreach.js";
4
4
  export * from "./source-ref.js";
5
5
  export * from "./goal.js";
6
6
  export * from "./v7-entities.js";
7
+ export * from "./v8-contracts.js";
@@ -4,6 +4,4 @@ export * from "./outreach.js";
4
4
  export * from "./source-ref.js";
5
5
  export * from "./goal.js";
6
6
  export * from "./v7-entities.js";
7
- // v8-contracts intentionally NOT re-exported from index to avoid SourceRef
8
- // name collision with v7 tuple type. v8 consumers import directly from
9
- // `./v8-contracts.js`.
7
+ export * from "./v8-contracts.js";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * SourceRef — v7 non-empty tuple for source grounding.
2
+ * SourceRefTuple — v7 non-empty tuple for source grounding.
3
3
  *
4
4
  * Core logic: Every fact claim must carry at least one source reference.
5
5
  * DR-025 enforces non-empty at compile time. Empty array assignments are
@@ -11,4 +11,4 @@
11
11
  * Test coverage: tests/unit/shared/v7-entities.test.ts (compile-time
12
12
  * `@ts-expect-error` guard for empty tuple).
13
13
  */
14
- export type SourceRef = readonly [string, ...string[]];
14
+ export type SourceRefTuple = readonly [string, ...string[]];
@@ -12,7 +12,7 @@
12
12
  * - ADR-002/003/007/008 — entity semantics
13
13
  *
14
14
  * Dependencies:
15
- * - `SourceRef` from `./source-ref.js`
15
+ * - `SourceRefTuple` from `./source-ref.js`
16
16
  * - `AgentGoal` from `./goal.js`
17
17
  *
18
18
  * Boundary:
@@ -24,7 +24,7 @@
24
24
  *
25
25
  * Test coverage: tests/unit/shared/v7-entities.test.ts
26
26
  */
27
- import type { SourceRef } from "./source-ref.js";
27
+ import type { SourceRefTuple } from "./source-ref.js";
28
28
  import type { AgentGoal } from "./goal.js";
29
29
  export interface PlatformHandle {
30
30
  platformId: string;
@@ -60,7 +60,7 @@ export interface ToolExperience {
60
60
  failureClass?: string;
61
61
  latencyMs: number;
62
62
  evidenceQuality: number;
63
- sourceRefs: SourceRef;
63
+ sourceRefs: SourceRefTuple;
64
64
  triggerSource: ToolExperienceTriggerSource;
65
65
  createdAt: string;
66
66
  }
@@ -97,7 +97,7 @@ export interface QuietClaim {
97
97
  claimId: string;
98
98
  kind: QuietClaimKind;
99
99
  text: string;
100
- sourceRefs: SourceRef;
100
+ sourceRefs: SourceRefTuple;
101
101
  confidence: number;
102
102
  createdAt: string;
103
103
  }
@@ -107,7 +107,7 @@ export interface DailyDiary {
107
107
  observedToday: string[];
108
108
  notableSignals: string[];
109
109
  tomorrowDirection: string;
110
- sourceRefs: SourceRef;
110
+ sourceRefs: SourceRefTuple;
111
111
  createdAt: string;
112
112
  }
113
113
  export type DreamOutputStatus = "candidate" | "accepted" | "archived" | "partial";
@@ -12,7 +12,7 @@
12
12
  * - ADR-002/003/007/008 — entity semantics
13
13
  *
14
14
  * Dependencies:
15
- * - `SourceRef` from `./source-ref.js`
15
+ * - `SourceRefTuple` from `./source-ref.js`
16
16
  * - `AgentGoal` from `./goal.js`
17
17
  *
18
18
  * Boundary:
@@ -82,5 +82,5 @@ export interface DegradedOperationResult {
82
82
  operatorNextAction: string;
83
83
  retryable: boolean;
84
84
  }
85
- export type V8ReasonCode = "quiet_completed" | "quiet_empty_input" | "quiet_state_unreadable" | "quiet_validation_failed" | "quiet_redaction_blocked" | "dream_scheduled" | "dream_scheduled_stalled" | "dream_scheduler_unavailable" | "dream_started" | "dream_completed" | "dream_failed" | "dream_blocked_redaction" | "dream_rules_only" | "dream_model_timeout" | "projection_candidate_created" | "projection_accepted" | "projection_rejected" | "projection_superseded" | "projection_topic_matched" | "proposal_created" | "proposal_no_action" | "proposal_missing_source_refs" | "proposal_risk_blocked" | "policy_allowed" | "policy_deferred_owner_confirmation" | "policy_downgraded_to_draft" | "policy_denied_missing_permission" | "policy_denied_high_risk" | "policy_denied_breaker_open" | "guidance_unavailable" | "closure_completed" | "closure_no_action" | "closure_denied" | "closure_deferred" | "closure_downgraded" | "closure_downgraded_without_draft" | "closure_failed" | "perception_rules_only" | "perception_contract_drift" | "evidence_batch_empty" | "evidence_batch_truncated" | "evidence_content_missing" | "judgment_low_confidence" | "judgment_missing_source_refs" | "source_refs_unresolved" | "state_unreadable" | "stage_event_missing" | "ingestion_no_data" | "ingestion_empty" | "ingestion_state_unreadable" | "ingestion_connector_failed" | "execution_completed" | "execution_failed" | "execution_timeout" | "execution_unavailable";
85
+ export type V8ReasonCode = "quiet_completed" | "quiet_empty_input" | "quiet_state_unreadable" | "quiet_validation_failed" | "quiet_redaction_blocked" | "dream_scheduled" | "dream_scheduled_stalled" | "dream_scheduler_unavailable" | "dream_started" | "dream_completed" | "dream_failed" | "dream_blocked_redaction" | "dream_interval_active" | "dream_rules_only" | "dream_model_timeout" | "projection_candidate_created" | "projection_accepted" | "projection_rejected" | "projection_superseded" | "projection_topic_matched" | "proposal_created" | "proposal_no_action" | "proposal_missing_source_refs" | "proposal_risk_blocked" | "policy_allowed" | "policy_deferred_owner_confirmation" | "policy_downgraded_to_draft" | "policy_denied_missing_permission" | "policy_denied_high_risk" | "policy_denied_breaker_open" | "guidance_unavailable" | "closure_completed" | "closure_no_action" | "closure_denied" | "closure_deferred" | "closure_downgraded" | "closure_downgraded_without_draft" | "closure_failed" | "perception_rules_only" | "perception_contract_drift" | "evidence_batch_empty" | "evidence_batch_truncated" | "evidence_content_missing" | "judgment_low_confidence" | "judgment_missing_source_refs" | "source_refs_unresolved" | "state_unreadable" | "stage_event_missing" | "ingestion_no_data" | "ingestion_empty" | "ingestion_state_unreadable" | "ingestion_connector_failed" | "execution_completed" | "execution_failed" | "execution_timeout" | "execution_unavailable";
86
86
  export declare const ACTION_KIND_REGISTRY: Readonly<Record<PlatformNeutralActionKind, ActionKindMetadata>>;
@@ -232,11 +232,10 @@ const STATE_SCHEMA_SQL = `
232
232
  status TEXT NOT NULL,
233
233
  reason TEXT,
234
234
  next_state TEXT,
235
- source_refs_json TEXT NOT NULL,
236
- redaction_class TEXT NOT NULL DEFAULT 'none',
237
- payload_json TEXT,
238
- lifecycle_status TEXT NOT NULL DEFAULT 'closed'
239
- );
235
+ source_refs_json TEXT NOT NULL,
236
+ redaction_class TEXT NOT NULL DEFAULT 'none',
237
+ payload_json TEXT
238
+ );
240
239
  CREATE TABLE IF NOT EXISTS quiet_daily_review (
241
240
  id TEXT PRIMARY KEY,
242
241
  created_at TEXT NOT NULL,
@@ -255,22 +254,20 @@ const STATE_SCHEMA_SQL = `
255
254
  quiet_review_id TEXT NOT NULL,
256
255
  status TEXT NOT NULL,
257
256
  reason TEXT,
258
- source_refs_json TEXT NOT NULL,
259
- redaction_class TEXT NOT NULL DEFAULT 'none',
260
- payload_json TEXT,
261
- lifecycle_status TEXT NOT NULL DEFAULT 'pending'
262
- );
257
+ source_refs_json TEXT NOT NULL,
258
+ redaction_class TEXT NOT NULL DEFAULT 'none',
259
+ payload_json TEXT
260
+ );
263
261
  CREATE TABLE IF NOT EXISTS long_term_memory_projection (
264
262
  id TEXT PRIMARY KEY,
265
263
  created_at TEXT NOT NULL,
266
264
  candidate_id TEXT NOT NULL,
267
265
  topic_key TEXT NOT NULL,
268
266
  status TEXT NOT NULL DEFAULT 'candidate',
269
- source_refs_json TEXT NOT NULL,
270
- redaction_class TEXT NOT NULL DEFAULT 'none',
271
- payload_json TEXT,
272
- lifecycle_status TEXT NOT NULL DEFAULT 'candidate'
273
- );
267
+ source_refs_json TEXT NOT NULL,
268
+ redaction_class TEXT NOT NULL DEFAULT 'none',
269
+ payload_json TEXT
270
+ );
274
271
  CREATE TABLE IF NOT EXISTS heartbeat_cycle_trace (
275
272
  id TEXT PRIMARY KEY,
276
273
  cycle_sequence INTEGER NOT NULL,
@@ -279,12 +276,11 @@ const STATE_SCHEMA_SQL = `
279
276
  input_count INTEGER NOT NULL DEFAULT 0,
280
277
  output_count INTEGER NOT NULL DEFAULT 0,
281
278
  expected_downstream_by_cycle INTEGER,
282
- status TEXT NOT NULL,
283
- source_refs_json TEXT,
284
- redaction_class TEXT NOT NULL DEFAULT 'none',
285
- payload_json TEXT,
286
- lifecycle_status TEXT NOT NULL DEFAULT 'started'
287
- );
279
+ status TEXT NOT NULL,
280
+ source_refs_json TEXT,
281
+ redaction_class TEXT NOT NULL DEFAULT 'none',
282
+ payload_json TEXT
283
+ );
288
284
  CREATE TABLE IF NOT EXISTS loop_stage_event (
289
285
  id TEXT PRIMARY KEY,
290
286
  cycle_id TEXT NOT NULL,
@@ -294,11 +290,10 @@ const STATE_SCHEMA_SQL = `
294
290
  reason TEXT,
295
291
  source_refs_json TEXT NOT NULL,
296
292
  redaction_class TEXT NOT NULL DEFAULT 'none',
297
- occurred_at TEXT NOT NULL,
298
- expected_downstream_by_cycle INTEGER,
299
- payload_json TEXT,
300
- lifecycle_status TEXT NOT NULL DEFAULT 'started'
301
- );
293
+ occurred_at TEXT NOT NULL,
294
+ expected_downstream_by_cycle INTEGER,
295
+ payload_json TEXT
296
+ );
302
297
  CREATE TABLE IF NOT EXISTS impulse_context_artifact (
303
298
  id TEXT PRIMARY KEY,
304
299
  created_at TEXT NOT NULL,
@@ -366,12 +361,22 @@ function bootstrapStateSchema(sqlite) {
366
361
  runMigrations(sqlite, ALL_MIGRATIONS);
367
362
  }
368
363
  function applyStateSchemaMigrations(sqlite) {
364
+ // Defensive column/index additions for DBs that were initialized before
365
+ // v8-004-schema-closure. Fresh DBs already have these from bootstrap SQL.
366
+ // Each statement is wrapped individually so duplicate-column errors are
367
+ // harmless and do not block startup.
369
368
  const migrations = [
370
369
  "ALTER TABLE policy_records ADD COLUMN outreach_daily_budget INTEGER NOT NULL DEFAULT 2",
371
370
  "ALTER TABLE action_closure_record ADD COLUMN platform_id TEXT",
372
371
  "ALTER TABLE action_closure_record ADD COLUMN capability_id TEXT",
372
+ "ALTER TABLE quiet_daily_review ADD COLUMN closure_refs_json TEXT",
373
373
  "ALTER TABLE connector_cooldown_state ADD COLUMN terminal_count INTEGER NOT NULL DEFAULT 0",
374
374
  "CREATE INDEX IF NOT EXISTS connector_cooldown_state_platform_capability_idx ON connector_cooldown_state(platform_id, capability_id)",
375
+ "ALTER TABLE action_closure_record DROP COLUMN lifecycle_status",
376
+ "ALTER TABLE dream_consolidation_run DROP COLUMN lifecycle_status",
377
+ "ALTER TABLE long_term_memory_projection DROP COLUMN lifecycle_status",
378
+ "ALTER TABLE heartbeat_cycle_trace DROP COLUMN lifecycle_status",
379
+ "ALTER TABLE loop_stage_event DROP COLUMN lifecycle_status",
375
380
  ];
376
381
  for (const sql of migrations) {
377
382
  try {
@@ -8,6 +8,8 @@ import { V7_004_BEHAVIOR_PROMOTION } from "./v7-004-behavior-promotion.js";
8
8
  import { V8_001_LIVING_PERCEPTION_LOOP } from "./v8-001-living-perception-loop.js";
9
9
  import { V8_002_PERCEPTION_CONTRACT_ALIGNMENT } from "./v8-002-perception-contract-alignment.js";
10
10
  import { V8_003_QUIET_CLOSURE_REFS } from "./v8-003-quiet-closure-refs.js";
11
+ import { V8_004_SCHEMA_CLOSURE } from "./v8-004-schema-closure.js";
12
+ import { V8_005_SINGLE_STATUS_SCHEMA } from "./v8-005-single-status-schema.js";
11
13
  export const ALL_MIGRATIONS = [
12
14
  V7_001_FOUNDATION,
13
15
  V7_002_EFFECT_COMMIT_LEDGER,
@@ -16,4 +18,6 @@ export const ALL_MIGRATIONS = [
16
18
  V8_001_LIVING_PERCEPTION_LOOP,
17
19
  V8_002_PERCEPTION_CONTRACT_ALIGNMENT,
18
20
  V8_003_QUIET_CLOSURE_REFS,
21
+ V8_004_SCHEMA_CLOSURE,
22
+ V8_005_SINGLE_STATUS_SCHEMA,
19
23
  ];
@@ -0,0 +1,19 @@
1
+ /**
2
+ * v8-004 Schema Closure — brings pre-existing v8 DBs up to the current bootstrap schema.
3
+ *
4
+ * Problem: v8-001 created the first v8 tables, but daily_rhythm_state,
5
+ * impulse_context_artifact, connector_cooldown_state, and several columns
6
+ * (action_closure_record.platform_id/capability_id,
7
+ * quiet_daily_review.closure_refs_json, connector_cooldown_state.terminal_count)
8
+ * were added later only in the bootstrap SQL. DBs initialized before those
9
+ * bootstrap changes would miss tables/columns and break at runtime.
10
+ *
11
+ * Strategy:
12
+ * - CREATE TABLE IF NOT EXISTS for the three tables (idempotent on fresh DBs).
13
+ * - Column-level fixes are handled by the defensive applyStateSchemaMigrations
14
+ * helper in db/index.ts, because SQLite cannot conditionally ADD COLUMN.
15
+ *
16
+ * Resolves T-SMS.R.2.
17
+ */
18
+ import type { Migration } from "../migration-runner.js";
19
+ export declare const V8_004_SCHEMA_CLOSURE: Migration;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * v8-004 Schema Closure — brings pre-existing v8 DBs up to the current bootstrap schema.
3
+ *
4
+ * Problem: v8-001 created the first v8 tables, but daily_rhythm_state,
5
+ * impulse_context_artifact, connector_cooldown_state, and several columns
6
+ * (action_closure_record.platform_id/capability_id,
7
+ * quiet_daily_review.closure_refs_json, connector_cooldown_state.terminal_count)
8
+ * were added later only in the bootstrap SQL. DBs initialized before those
9
+ * bootstrap changes would miss tables/columns and break at runtime.
10
+ *
11
+ * Strategy:
12
+ * - CREATE TABLE IF NOT EXISTS for the three tables (idempotent on fresh DBs).
13
+ * - Column-level fixes are handled by the defensive applyStateSchemaMigrations
14
+ * helper in db/index.ts, because SQLite cannot conditionally ADD COLUMN.
15
+ *
16
+ * Resolves T-SMS.R.2.
17
+ */
18
+ export const V8_004_SCHEMA_CLOSURE = {
19
+ version: 8,
20
+ label: "v8-schema-closure",
21
+ sql: `
22
+ CREATE TABLE IF NOT EXISTS daily_rhythm_state (
23
+ id TEXT PRIMARY KEY,
24
+ day TEXT NOT NULL,
25
+ quiet_status TEXT NOT NULL DEFAULT 'not_due',
26
+ dream_status TEXT NOT NULL DEFAULT 'not_due',
27
+ quiet_reason TEXT,
28
+ dream_reason TEXT,
29
+ quiet_completed_at TEXT,
30
+ dream_completed_at TEXT,
31
+ source_refs_json TEXT NOT NULL,
32
+ payload_json TEXT,
33
+ updated_at TEXT NOT NULL
34
+ );
35
+
36
+ CREATE TABLE IF NOT EXISTS impulse_context_artifact (
37
+ id TEXT PRIMARY KEY,
38
+ created_at TEXT NOT NULL,
39
+ updated_at TEXT NOT NULL,
40
+ scene_type TEXT NOT NULL,
41
+ capability_intent TEXT,
42
+ platform_id TEXT,
43
+ capability_class TEXT,
44
+ impulse_source TEXT NOT NULL,
45
+ impulse_text TEXT,
46
+ atmosphere_text TEXT,
47
+ expression_boundary_constraints_json TEXT,
48
+ expression_boundary_style TEXT,
49
+ freshness_version INTEGER NOT NULL DEFAULT 1,
50
+ source_refs_json TEXT NOT NULL,
51
+ redaction_class TEXT NOT NULL DEFAULT 'none',
52
+ payload_json TEXT,
53
+ lifecycle_status TEXT NOT NULL DEFAULT 'active'
54
+ );
55
+
56
+ CREATE TABLE IF NOT EXISTS connector_cooldown_state (
57
+ id TEXT PRIMARY KEY,
58
+ platform_id TEXT NOT NULL,
59
+ capability_id TEXT NOT NULL,
60
+ failure_class TEXT NOT NULL,
61
+ retry_after_ms INTEGER,
62
+ blocked_until TEXT NOT NULL,
63
+ failure_count INTEGER NOT NULL DEFAULT 1,
64
+ terminal_count INTEGER NOT NULL DEFAULT 0,
65
+ source_refs_json TEXT NOT NULL,
66
+ redaction_class TEXT NOT NULL DEFAULT 'none',
67
+ payload_json TEXT,
68
+ created_at TEXT NOT NULL,
69
+ updated_at TEXT NOT NULL
70
+ );
71
+ CREATE INDEX IF NOT EXISTS connector_cooldown_state_platform_capability_idx
72
+ ON connector_cooldown_state(platform_id, capability_id);
73
+ `,
74
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * v8-005 Single Status Schema — records Wave 114 status-column cleanup.
3
+ *
4
+ * SQLite cannot safely run `DROP COLUMN IF EXISTS`; the actual idempotent
5
+ * column removal lives in applyStateSchemaMigrations where each statement is
6
+ * isolated. This migration marks the schema version after that defensive pass.
7
+ *
8
+ * Resolves T-SMS.R.4.
9
+ */
10
+ import type { Migration } from "../migration-runner.js";
11
+ export declare const V8_005_SINGLE_STATUS_SCHEMA: Migration;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * v8-005 Single Status Schema — records Wave 114 status-column cleanup.
3
+ *
4
+ * SQLite cannot safely run `DROP COLUMN IF EXISTS`; the actual idempotent
5
+ * column removal lives in applyStateSchemaMigrations where each statement is
6
+ * isolated. This migration marks the schema version after that defensive pass.
7
+ *
8
+ * Resolves T-SMS.R.4.
9
+ */
10
+ export const V8_005_SINGLE_STATUS_SCHEMA = {
11
+ version: 9,
12
+ label: "v8-single-status-schema",
13
+ sql: `
14
+ SELECT 1;
15
+ `,
16
+ };
@@ -1006,25 +1006,6 @@ export declare const actionClosureRecord: import("drizzle-orm/sqlite-core").SQLi
1006
1006
  }, {}, {
1007
1007
  length: number | undefined;
1008
1008
  }>;
1009
- lifecycleStatus: import("drizzle-orm/sqlite-core").SQLiteColumn<{
1010
- name: "lifecycle_status";
1011
- tableName: "action_closure_record";
1012
- dataType: "string";
1013
- columnType: "SQLiteText";
1014
- data: string;
1015
- driverParam: string;
1016
- notNull: true;
1017
- hasDefault: true;
1018
- isPrimaryKey: false;
1019
- isAutoincrement: false;
1020
- hasRuntimeDefault: false;
1021
- enumValues: [string, ...string[]];
1022
- baseColumn: never;
1023
- identity: undefined;
1024
- generated: undefined;
1025
- }, {}, {
1026
- length: number | undefined;
1027
- }>;
1028
1009
  };
1029
1010
  dialect: "sqlite";
1030
1011
  }>;
@@ -1381,25 +1362,6 @@ export declare const dreamConsolidationRun: import("drizzle-orm/sqlite-core").SQ
1381
1362
  }, {}, {
1382
1363
  length: number | undefined;
1383
1364
  }>;
1384
- lifecycleStatus: import("drizzle-orm/sqlite-core").SQLiteColumn<{
1385
- name: "lifecycle_status";
1386
- tableName: "dream_consolidation_run";
1387
- dataType: "string";
1388
- columnType: "SQLiteText";
1389
- data: string;
1390
- driverParam: string;
1391
- notNull: true;
1392
- hasDefault: true;
1393
- isPrimaryKey: false;
1394
- isAutoincrement: false;
1395
- hasRuntimeDefault: false;
1396
- enumValues: [string, ...string[]];
1397
- baseColumn: never;
1398
- identity: undefined;
1399
- generated: undefined;
1400
- }, {}, {
1401
- length: number | undefined;
1402
- }>;
1403
1365
  };
1404
1366
  dialect: "sqlite";
1405
1367
  }>;
@@ -1561,25 +1523,6 @@ export declare const longTermMemoryProjection: import("drizzle-orm/sqlite-core")
1561
1523
  }, {}, {
1562
1524
  length: number | undefined;
1563
1525
  }>;
1564
- lifecycleStatus: import("drizzle-orm/sqlite-core").SQLiteColumn<{
1565
- name: "lifecycle_status";
1566
- tableName: "long_term_memory_projection";
1567
- dataType: "string";
1568
- columnType: "SQLiteText";
1569
- data: string;
1570
- driverParam: string;
1571
- notNull: true;
1572
- hasDefault: true;
1573
- isPrimaryKey: false;
1574
- isAutoincrement: false;
1575
- hasRuntimeDefault: false;
1576
- enumValues: [string, ...string[]];
1577
- baseColumn: never;
1578
- identity: undefined;
1579
- generated: undefined;
1580
- }, {}, {
1581
- length: number | undefined;
1582
- }>;
1583
1526
  };
1584
1527
  dialect: "sqlite";
1585
1528
  }>;
@@ -1790,25 +1733,6 @@ export declare const heartbeatCycleTrace: import("drizzle-orm/sqlite-core").SQLi
1790
1733
  }, {}, {
1791
1734
  length: number | undefined;
1792
1735
  }>;
1793
- lifecycleStatus: import("drizzle-orm/sqlite-core").SQLiteColumn<{
1794
- name: "lifecycle_status";
1795
- tableName: "heartbeat_cycle_trace";
1796
- dataType: "string";
1797
- columnType: "SQLiteText";
1798
- data: string;
1799
- driverParam: string;
1800
- notNull: true;
1801
- hasDefault: true;
1802
- isPrimaryKey: false;
1803
- isAutoincrement: false;
1804
- hasRuntimeDefault: false;
1805
- enumValues: [string, ...string[]];
1806
- baseColumn: never;
1807
- identity: undefined;
1808
- generated: undefined;
1809
- }, {}, {
1810
- length: number | undefined;
1811
- }>;
1812
1736
  };
1813
1737
  dialect: "sqlite";
1814
1738
  }>;
@@ -2023,25 +1947,6 @@ export declare const loopStageEvent: import("drizzle-orm/sqlite-core").SQLiteTab
2023
1947
  }, {}, {
2024
1948
  length: number | undefined;
2025
1949
  }>;
2026
- lifecycleStatus: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2027
- name: "lifecycle_status";
2028
- tableName: "loop_stage_event";
2029
- dataType: "string";
2030
- columnType: "SQLiteText";
2031
- data: string;
2032
- driverParam: string;
2033
- notNull: true;
2034
- hasDefault: true;
2035
- isPrimaryKey: false;
2036
- isAutoincrement: false;
2037
- hasRuntimeDefault: false;
2038
- enumValues: [string, ...string[]];
2039
- baseColumn: never;
2040
- identity: undefined;
2041
- generated: undefined;
2042
- }, {}, {
2043
- length: number | undefined;
2044
- }>;
2045
1950
  };
2046
1951
  dialect: "sqlite";
2047
1952
  }>;
@@ -12,7 +12,7 @@
12
12
  * Dependencies: drizzle-orm/sqlite-core
13
13
  * Boundary: Schema definitions only; no runtime logic.
14
14
  */
15
- import { sqliteTable, text, integer, real, index } from "drizzle-orm/sqlite-core";
15
+ import { sqliteTable, text, integer, real, index, uniqueIndex } from "drizzle-orm/sqlite-core";
16
16
  // ───────────────────────────────────────────────────────────────
17
17
  // 1. EvidenceItem
18
18
  // ───────────────────────────────────────────────────────────────
@@ -27,7 +27,9 @@ export const evidenceItem = sqliteTable("evidence_item", {
27
27
  redactionClass: text("redaction_class").notNull().default("none"),
28
28
  payloadJson: text("payload_json"),
29
29
  lifecycleStatus: text("lifecycle_status").notNull().default("pending"),
30
- });
30
+ }, (table) => ({
31
+ platformContentHashIdx: uniqueIndex("evidence_item_platform_content_hash_idx").on(table.platformId, table.contentHash),
32
+ }));
31
33
  // ───────────────────────────────────────────────────────────────
32
34
  // 2. PerceptionCard
33
35
  // ───────────────────────────────────────────────────────────────
@@ -83,7 +85,6 @@ export const actionClosureRecord = sqliteTable("action_closure_record", {
83
85
  sourceRefsJson: text("source_refs_json").notNull(),
84
86
  redactionClass: text("redaction_class").notNull().default("none"),
85
87
  payloadJson: text("payload_json"),
86
- lifecycleStatus: text("lifecycle_status").notNull().default("closed"),
87
88
  });
88
89
  // ───────────────────────────────────────────────────────────────
89
90
  // 5. QuietDailyReview
@@ -112,7 +113,6 @@ export const dreamConsolidationRun = sqliteTable("dream_consolidation_run", {
112
113
  sourceRefsJson: text("source_refs_json").notNull(),
113
114
  redactionClass: text("redaction_class").notNull().default("none"),
114
115
  payloadJson: text("payload_json"),
115
- lifecycleStatus: text("lifecycle_status").notNull().default("pending"),
116
116
  });
117
117
  // ───────────────────────────────────────────────────────────────
118
118
  // 7. LongTermMemoryProjection
@@ -126,7 +126,6 @@ export const longTermMemoryProjection = sqliteTable("long_term_memory_projection
126
126
  sourceRefsJson: text("source_refs_json").notNull(),
127
127
  redactionClass: text("redaction_class").notNull().default("none"),
128
128
  payloadJson: text("payload_json"),
129
- lifecycleStatus: text("lifecycle_status").notNull().default("candidate"),
130
129
  });
131
130
  // ───────────────────────────────────────────────────────────────
132
131
  // 8. HeartbeatCycleTrace
@@ -143,7 +142,6 @@ export const heartbeatCycleTrace = sqliteTable("heartbeat_cycle_trace", {
143
142
  sourceRefsJson: text("source_refs_json"),
144
143
  redactionClass: text("redaction_class").notNull().default("none"),
145
144
  payloadJson: text("payload_json"),
146
- lifecycleStatus: text("lifecycle_status").notNull().default("started"),
147
145
  });
148
146
  // ───────────────────────────────────────────────────────────────
149
147
  // 9. LoopStageEvent
@@ -160,7 +158,6 @@ export const loopStageEvent = sqliteTable("loop_stage_event", {
160
158
  occurredAt: text("occurred_at").notNull(),
161
159
  expectedDownstreamByCycle: integer("expected_downstream_by_cycle"),
162
160
  payloadJson: text("payload_json"),
163
- lifecycleStatus: text("lifecycle_status").notNull().default("started"),
164
161
  });
165
162
  // ───────────────────────────────────────────────────────────────
166
163
  // 10. ImpulseContextArtifact
@@ -4,7 +4,7 @@
4
4
  * Boundaries: validates proof fields before index write; hostProofRef uses SourceRef JSON.
5
5
  * Test coverage: tests/unit/storage/delivery-attempt.test.ts
6
6
  */
7
- import type { SourceRef } from "../life-evidence/types.js";
7
+ import type { LifeEvidenceSourceRef } from "../life-evidence/types.js";
8
8
  export type DeliveryAttemptStatus = "sent" | "failed" | "dropped_by_host_policy";
9
9
  export interface DeliveryAttemptWrite {
10
10
  attemptId: string;
@@ -13,7 +13,7 @@ export interface DeliveryAttemptWrite {
13
13
  channel?: string;
14
14
  status: DeliveryAttemptStatus;
15
15
  messageId?: string;
16
- hostProofRef?: SourceRef;
16
+ hostProofRef?: LifeEvidenceSourceRef;
17
17
  errorClass?: string;
18
18
  fallbackRef?: string;
19
19
  }
@@ -1,5 +1,5 @@
1
1
  import type { StateDatabase } from "../db/index.js";
2
- import type { SourceRef } from "../life-evidence/types.js";
2
+ import type { LifeEvidenceSourceRef } from "../life-evidence/types.js";
3
3
  import type { OperatorFallbackView } from "./operator-fallback-view.js";
4
4
  export declare function normalizeFallbackRef(ref: string): string;
5
5
  /** Loads persisted operator fallback row; does not coerce status (use `toOperatorFallbackView`). */
@@ -7,7 +7,7 @@ export declare function loadOperatorFallbackRow(state: StateDatabase, fallbackRe
7
7
  fallbackRef: string;
8
8
  reason: string;
9
9
  status: string;
10
- sourceRefs: SourceRef[];
10
+ sourceRefs: LifeEvidenceSourceRef[];
11
11
  candidateMessage?: string;
12
12
  nextStep: string;
13
13
  } | null>;
@@ -1,9 +1,9 @@
1
- import type { SourceRef } from "../life-evidence/types.js";
1
+ import type { LifeEvidenceSourceRef } from "../life-evidence/types.js";
2
2
  export type OperatorFallbackReason = "target_none" | "channel_missing" | "host_unsupported" | "delivery_failed";
3
3
  export interface OperatorFallbackWrite {
4
4
  reason: OperatorFallbackReason;
5
5
  decisionId: string;
6
- sourceRefs: SourceRef[];
6
+ sourceRefs: LifeEvidenceSourceRef[];
7
7
  candidateMessage?: string;
8
8
  nextStep: string;
9
9
  }
@@ -1,11 +1,11 @@
1
- import type { SourceRef } from "../life-evidence/types.js";
1
+ import type { LifeEvidenceSourceRef } from "../life-evidence/types.js";
2
2
  import type { OperatorFallbackReason } from "./operator-fallback-types.js";
3
3
  /** Operator-facing delivery fallback (T1.2.2 / cli-system v5). Status is always not_sent — never sent/delivered. */
4
4
  export interface OperatorFallbackView {
5
5
  fallbackRef: string;
6
6
  reason: OperatorFallbackReason | string;
7
7
  status: "not_sent";
8
- sourceRefs: SourceRef[];
8
+ sourceRefs: LifeEvidenceSourceRef[];
9
9
  candidateMessage?: string;
10
10
  nextStep: string;
11
11
  }
@@ -22,7 +22,7 @@ export { createNarrativeStateStore, type NarrativeStateStore, type NarrativeStat
22
22
  export { createRelationshipMemoryStore, type RelationshipMemoryStore, type RelationshipMemory, type RelationshipMemoryUpdate, type RelationshipMemoryWriteAck, type TopicAffinity, } from "./relationship/relationship-memory-store.js";
23
23
  export { createAgentGoalStore, type AgentGoalStore, type AgentGoal, type AgentGoalWrite, type AgentGoalStatusTransition, type AgentGoalQuery, type AgentGoalWriteAck, } from "./goal/agent-goal-store.js";
24
24
  export { createMemoryStoreLifecycle, type MemoryStorePort, type MemoryStore, type MemoryStoreWrite, type MemoryStoreLifecycleTransition, type MemoryStoreAck, type CanonicalMemoryEntry, type DreamInsight, type MemoryStoreValidation, } from "./memory-store/memory-store-lifecycle.js";
25
- export type { LifeEvidence, LifeEvidenceCandidate, LifeEvidenceType, LifeEvidenceWriteAck, Sensitivity, SourceRef, } from "./life-evidence/types.js";
25
+ export type { LifeEvidence, LifeEvidenceCandidate, LifeEvidenceSourceRef, LifeEvidenceType, LifeEvidenceWriteAck, Sensitivity, } from "./life-evidence/types.js";
26
26
  export { appendLifeEvidence, type AppendLifeEvidenceOptions } from "./life-evidence/append-life-evidence.js";
27
27
  export { loadRhythmPolicySnapshot, type RhythmPolicySnapshot } from "./rhythm/rhythm-policy-snapshot.js";
28
28
  export type { LifeEvidenceQuery, LifeEvidenceSnapshot, LifeEvidenceReadModel, ContinuitySnapshot, SourceCoverage, } from "./snapshots/types.js";