forge-openclaw-plugin 0.2.26 → 0.2.28

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 (109) hide show
  1. package/README.md +60 -3
  2. package/dist/assets/{board-ta0rUHOf.js → board-DPFvZf-D.js} +2 -2
  3. package/dist/assets/{board-ta0rUHOf.js.map → board-DPFvZf-D.js.map} +1 -1
  4. package/dist/assets/index-Auw3JrdE.css +1 -0
  5. package/dist/assets/index-D1H7myQH.js +85 -0
  6. package/dist/assets/index-D1H7myQH.js.map +1 -0
  7. package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js +2 -0
  8. package/dist/assets/knowledge-graph-layout.worker-DRvzPxhP.js.map +1 -0
  9. package/dist/assets/{motion-fBKPB6yw.js → motion-Bvwc85ch.js} +2 -2
  10. package/dist/assets/{motion-fBKPB6yw.js.map → motion-Bvwc85ch.js.map} +1 -1
  11. package/dist/assets/{table-C-IGTQni.js → table-FJQTJvUR.js} +2 -2
  12. package/dist/assets/{table-C-IGTQni.js.map → table-FJQTJvUR.js.map} +1 -1
  13. package/dist/assets/{ui-DInOpaYF.js → ui-GXFcgvSw.js} +2 -2
  14. package/dist/assets/{ui-DInOpaYF.js.map → ui-GXFcgvSw.js.map} +1 -1
  15. package/dist/assets/vendor-Cwf49UMz.js +1247 -0
  16. package/dist/assets/vendor-Cwf49UMz.js.map +1 -0
  17. package/dist/index.html +7 -7
  18. package/dist/openclaw/local-runtime.js +16 -0
  19. package/dist/openclaw/routes.d.ts +27 -0
  20. package/dist/openclaw/routes.js +16 -12
  21. package/dist/server/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
  22. package/dist/server/server/migrations/038_data_management_settings.sql +11 -0
  23. package/dist/server/server/migrations/039_life_force_and_action_points.sql +114 -0
  24. package/dist/server/server/migrations/040_screen_time_domain.sql +89 -0
  25. package/dist/server/server/migrations/041_companion_source_states.sql +21 -0
  26. package/dist/server/server/migrations/042_movement_boxes.sql +47 -0
  27. package/dist/server/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
  28. package/dist/server/server/src/app.js +1900 -91
  29. package/dist/server/server/src/connectors/box-registry.js +44 -9
  30. package/dist/server/server/src/data-management-types.js +107 -0
  31. package/dist/server/server/src/db.js +68 -4
  32. package/dist/server/server/src/demo-data.js +2 -2
  33. package/dist/server/server/src/health.js +702 -18
  34. package/dist/server/server/src/managers/platform/llm-manager.js +7 -4
  35. package/dist/server/server/src/managers/platform/mock-workbench-provider.js +149 -0
  36. package/dist/server/server/src/managers/platform/secrets-manager.js +18 -1
  37. package/dist/server/server/src/managers/runtime.js +9 -0
  38. package/dist/server/server/src/movement.js +1971 -112
  39. package/dist/server/server/src/openapi.js +1390 -105
  40. package/dist/server/server/src/psyche-types.js +9 -1
  41. package/dist/server/server/src/repositories/activity-events.js +8 -0
  42. package/dist/server/server/src/repositories/ai-connectors.js +522 -74
  43. package/dist/server/server/src/repositories/calendar.js +151 -0
  44. package/dist/server/server/src/repositories/habits.js +37 -1
  45. package/dist/server/server/src/repositories/model-settings.js +13 -3
  46. package/dist/server/server/src/repositories/notes.js +3 -0
  47. package/dist/server/server/src/repositories/settings.js +380 -18
  48. package/dist/server/server/src/repositories/tasks.js +170 -10
  49. package/dist/server/server/src/runtime-data-root.js +82 -0
  50. package/dist/server/server/src/screen-time.js +802 -0
  51. package/dist/server/server/src/services/data-management.js +788 -0
  52. package/dist/server/server/src/services/entity-crud.js +205 -2
  53. package/dist/server/server/src/services/knowledge-graph.js +1455 -0
  54. package/dist/server/server/src/services/life-force-model.js +217 -0
  55. package/dist/server/server/src/services/life-force.js +2506 -0
  56. package/dist/server/server/src/services/psyche-observation-calendar.js +383 -16
  57. package/dist/server/server/src/types.js +307 -14
  58. package/dist/server/server/src/web.js +228 -13
  59. package/dist/server/src/components/customization/utility-widgets.js +136 -27
  60. package/dist/server/src/components/ui/info-tooltip.js +25 -0
  61. package/dist/server/src/components/workbench-boxes/calendar/calendar-boxes.js +78 -0
  62. package/dist/server/src/components/workbench-boxes/goals/goals-boxes.js +62 -0
  63. package/dist/server/src/components/workbench-boxes/habits/habits-boxes.js +62 -0
  64. package/dist/server/src/components/workbench-boxes/health/health-boxes.js +63 -8
  65. package/dist/server/src/components/workbench-boxes/insights/insights-boxes.js +50 -0
  66. package/dist/server/src/components/workbench-boxes/kanban/kanban-boxes.js +62 -54
  67. package/dist/server/src/components/workbench-boxes/movement/movement-boxes.js +18 -8
  68. package/dist/server/src/components/workbench-boxes/notes/notes-boxes.js +56 -38
  69. package/dist/server/src/components/workbench-boxes/overview/overview-boxes.js +65 -0
  70. package/dist/server/src/components/workbench-boxes/preferences/preferences-boxes.js +78 -0
  71. package/dist/server/src/components/workbench-boxes/projects/projects-boxes.js +35 -30
  72. package/dist/server/src/components/workbench-boxes/psyche/psyche-boxes.js +88 -0
  73. package/dist/server/src/components/workbench-boxes/questionnaires/questionnaires-boxes.js +61 -0
  74. package/dist/server/src/components/workbench-boxes/review/review-boxes.js +53 -0
  75. package/dist/server/src/components/workbench-boxes/shared/define-workbench-box.js +3 -1
  76. package/dist/server/src/components/workbench-boxes/shared/generic-node-view.js +39 -3
  77. package/dist/server/src/components/workbench-boxes/strategies/strategies-boxes.js +62 -0
  78. package/dist/server/src/components/workbench-boxes/tasks/tasks-boxes.js +76 -0
  79. package/dist/server/src/components/workbench-boxes/today/today-boxes.js +47 -32
  80. package/dist/server/src/components/workbench-boxes/wiki/wiki-boxes.js +60 -0
  81. package/dist/server/src/lib/api.js +280 -21
  82. package/dist/server/src/lib/data-management-types.js +1 -0
  83. package/dist/server/src/lib/entity-visuals.js +279 -0
  84. package/dist/server/src/lib/knowledge-graph-types.js +276 -0
  85. package/dist/server/src/lib/knowledge-graph.js +470 -0
  86. package/dist/server/src/lib/schemas.js +4 -0
  87. package/dist/server/src/lib/snapshot-normalizer.js +45 -1
  88. package/dist/server/src/lib/workbench/contracts.js +229 -0
  89. package/dist/server/src/lib/workbench/nodes.js +200 -0
  90. package/dist/server/src/lib/workbench/registry.js +52 -5
  91. package/dist/server/src/lib/workbench/runtime.js +254 -38
  92. package/dist/server/src/lib/workbench/tool-catalog.js +68 -0
  93. package/openclaw.plugin.json +1 -1
  94. package/package.json +1 -1
  95. package/server/migrations/037_workbench_public_inputs_and_run_inputs.sql +5 -0
  96. package/server/migrations/038_data_management_settings.sql +11 -0
  97. package/server/migrations/039_life_force_and_action_points.sql +114 -0
  98. package/server/migrations/040_screen_time_domain.sql +89 -0
  99. package/server/migrations/041_companion_source_states.sql +21 -0
  100. package/server/migrations/042_movement_boxes.sql +47 -0
  101. package/server/migrations/043_movement_box_overlap_overrides.sql +26 -0
  102. package/skills/forge-openclaw/SKILL.md +41 -11
  103. package/skills/forge-openclaw/entity_conversation_playbooks.md +448 -34
  104. package/skills/forge-openclaw/psyche_entity_playbooks.md +170 -17
  105. package/dist/assets/index-Ro0ZF_az.css +0 -1
  106. package/dist/assets/index-ytlpSj23.js +0 -79
  107. package/dist/assets/index-ytlpSj23.js.map +0 -1
  108. package/dist/assets/vendor-lE3tZJcC.js +0 -876
  109. package/dist/assets/vendor-lE3tZJcC.js.map +0 -1
@@ -0,0 +1,47 @@
1
+ CREATE TABLE IF NOT EXISTS movement_boxes (
2
+ id TEXT PRIMARY KEY,
3
+ user_id TEXT NOT NULL,
4
+ kind TEXT NOT NULL CHECK (kind IN ('stay', 'trip', 'missing')),
5
+ source_kind TEXT NOT NULL CHECK (source_kind IN ('automatic', 'user_defined')),
6
+ origin TEXT NOT NULL CHECK (
7
+ origin IN (
8
+ 'recorded',
9
+ 'continued_stay',
10
+ 'repaired_gap',
11
+ 'missing',
12
+ 'user_defined',
13
+ 'user_invalidated'
14
+ )
15
+ ),
16
+ started_at TEXT NOT NULL,
17
+ ended_at TEXT NOT NULL,
18
+ title TEXT NOT NULL DEFAULT '',
19
+ subtitle TEXT NOT NULL DEFAULT '',
20
+ place_label TEXT,
21
+ anchor_external_uid TEXT,
22
+ tags_json TEXT NOT NULL DEFAULT '[]',
23
+ distance_meters REAL,
24
+ average_speed_mps REAL,
25
+ editable INTEGER NOT NULL DEFAULT 0,
26
+ override_count INTEGER NOT NULL DEFAULT 0,
27
+ overridden_automatic_box_ids_json TEXT NOT NULL DEFAULT '[]',
28
+ raw_stay_ids_json TEXT NOT NULL DEFAULT '[]',
29
+ raw_trip_ids_json TEXT NOT NULL DEFAULT '[]',
30
+ raw_point_count INTEGER NOT NULL DEFAULT 0,
31
+ has_legacy_corrections INTEGER NOT NULL DEFAULT 0,
32
+ legacy_origin_key TEXT,
33
+ metadata_json TEXT NOT NULL DEFAULT '{}',
34
+ deleted_at TEXT,
35
+ created_at TEXT NOT NULL,
36
+ updated_at TEXT NOT NULL
37
+ );
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_movement_boxes_user_time
40
+ ON movement_boxes(user_id, started_at, ended_at);
41
+
42
+ CREATE INDEX IF NOT EXISTS idx_movement_boxes_user_source
43
+ ON movement_boxes(user_id, source_kind, deleted_at, started_at);
44
+
45
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_movement_boxes_legacy_origin
46
+ ON movement_boxes(user_id, legacy_origin_key)
47
+ WHERE legacy_origin_key IS NOT NULL;
@@ -0,0 +1,26 @@
1
+ ALTER TABLE movement_boxes
2
+ ADD COLUMN true_started_at TEXT;
3
+
4
+ ALTER TABLE movement_boxes
5
+ ADD COLUMN true_ended_at TEXT;
6
+
7
+ ALTER TABLE movement_boxes
8
+ ADD COLUMN overridden_started_at TEXT;
9
+
10
+ ALTER TABLE movement_boxes
11
+ ADD COLUMN overridden_ended_at TEXT;
12
+
13
+ ALTER TABLE movement_boxes
14
+ ADD COLUMN overridden_by_box_id TEXT;
15
+
16
+ ALTER TABLE movement_boxes
17
+ ADD COLUMN overridden_user_box_ids_json TEXT NOT NULL DEFAULT '[]';
18
+
19
+ ALTER TABLE movement_boxes
20
+ ADD COLUMN override_ranges_json TEXT NOT NULL DEFAULT '[]';
21
+
22
+ ALTER TABLE movement_boxes
23
+ ADD COLUMN is_overridden INTEGER NOT NULL DEFAULT 0;
24
+
25
+ ALTER TABLE movement_boxes
26
+ ADD COLUMN is_fully_hidden INTEGER NOT NULL DEFAULT 0;
@@ -41,8 +41,9 @@ Wiki navigation and search rule:
41
41
  Health rule:
42
42
 
43
43
  - Sleep and sports records are first-class health surfaces, not generic notes or tasks.
44
- - Use `forge_get_sleep_overview` and `forge_get_sports_overview` for review.
45
- - Use `forge_update_sleep_session` and `forge_update_workout_session` when the user wants to attach reflective context, tags, or Forge links to an existing health record.
44
+ - Use `forge_get_sleep_overview` and `forge_get_sports_overview` for review and trend reading.
45
+ - Use the shared batch entity tools for ordinary `sleep_session` and `workout_session` create, update, delete, and search work. Do not force agents into a large one-route-per-entity mental model when the batch routes already cover the record cleanly.
46
+ - Use `forge_update_sleep_session` and `forge_update_workout_session` only when the job is reflective enrichment on one existing health record after review, such as attaching notes, tags, mood, meaning, or Forge links.
46
47
  - Habit-generated workouts and imported HealthKit workouts belong to the same workout record model, so do not invent a separate storage path for sport sessions.
47
48
 
48
49
  Write to Forge only with clear user consent. If the user is just thinking aloud, helping first is usually better than writing immediately. After helping, you may offer one short Forge prompt if the match is strong. If the user agrees, ask only for the missing fields and only one to three focused questions at a time. Do not offer Forge again after a decline unless the user reopens it.
@@ -55,6 +56,7 @@ Entity conversation rule:
55
56
  - Before you ask, decide the exact missing thing you need and how that answer will help you name, place, or save the record.
56
57
  - Prefer a progression of:
57
58
  concrete example or intent -> working name -> purpose or meaning -> placement in Forge -> operational details -> linked context.
59
+ - Use those same playbooks for action-heavy non-Psyche flows such as `work_adjustment`, `preference_judgment`, `preference_signal`, and specialized `movement`, `life_force`, or `workbench` requests so the conversation starts from what the user is trying to understand, change, add, update, link, or run before you choose the route.
58
60
  - For emotionally meaningful non-Psyche records such as goals, habits, and notes, reflect the meaning before you ask for structure.
59
61
  - When the user is vague, ask for one small concrete example, stake, or desired outcome before you ask them to name the record.
60
62
  - When the user is clear, say what the record seems to be becoming and ask only for the last missing detail.
@@ -64,9 +66,9 @@ Entity conversation rule:
64
66
 
65
67
  Forge data location rule:
66
68
 
67
- - by default, Forge stores data under the active runtime root at `data/forge.sqlite`
68
- - on a normal OpenClaw install, this usually means `~/.openclaw/extensions/forge-openclaw-plugin/data/forge.sqlite`
69
- - on a linked repo-local install, this usually means `<repo>/openclaw-plugin/data/forge.sqlite`
69
+ - by default, Forge stores data under the active runtime root at `forge.sqlite`
70
+ - on a normal OpenClaw install, this usually means `~/.openclaw/extensions/forge-openclaw-plugin/forge.sqlite`
71
+ - on a linked repo-local install, this usually means `<repo>/openclaw-plugin/forge.sqlite`
70
72
  - if the user wants the data somewhere else for persistence, backup, or manual control, tell them to set `plugins.entries["forge-openclaw-plugin"].config.dataRoot` and restart the OpenClaw gateway
71
73
  - if the user asks where the data is stored or how to move it, explain the current default plainly and show the exact config field
72
74
 
@@ -282,17 +284,33 @@ Use the batch entity tools for stored records:
282
284
  `forge_search_entities`, `forge_create_entities`, `forge_update_entities`, `forge_delete_entities`, `forge_restore_entities`
283
285
 
284
286
  These tools operate on:
285
- `goal`, `project`, `task`, `habit`, `note`, `calendar_event`, `work_block_template`, `task_timebox`, `psyche_value`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`, `mode_guide_session`, `trigger_report`, `event_type`, `emotion_definition`
287
+ `goal`, `project`, `strategy`, `task`, `habit`, `tag`, `note`, `insight`, `calendar_event`, `work_block_template`, `task_timebox`, `psyche_value`, `behavior_pattern`, `behavior`, `belief_entry`, `mode_profile`, `mode_guide_session`, `trigger_report`, `event_type`, `emotion_definition`, `preference_catalog`, `preference_catalog_item`, `preference_context`, `preference_item`, `questionnaire_instrument`, `sleep_session`, `workout_session`
286
288
 
287
289
  Use the wiki tools for file-first memory work:
288
290
  `forge_get_wiki_settings`, `forge_list_wiki_pages`, `forge_get_wiki_page`, `forge_search_wiki`, `forge_upsert_wiki_page`, `forge_get_wiki_health`, `forge_sync_wiki_vault`, `forge_reindex_wiki_embeddings`, `forge_ingest_wiki_source`
289
291
 
290
- Sleep and workout sessions are not batch entities. Use the health tools instead:
292
+ Use the health tools for review and reflective enrichment, not as the default CRUD architecture:
291
293
  `forge_get_sleep_overview`, `forge_get_sports_overview`, `forge_update_sleep_session`, `forge_update_workout_session`
292
294
 
295
+ Use the dedicated domain routes for specialized surfaces that are not simple batch entities:
296
+
297
+ - Movement lives under `/api/v1/movement/*`. Treat it as a dedicated timeline of `stays` and `trips`, not as generic batch CRUD. A `stay` means the user remained in the same place for a span of time. A `trip` means the user traveled between places. Use the movement routes when the user wants to understand time in place, travel behavior, specific stays or trips, known places, or selected-span aggregates such as "how long was I at home in the past 2 weeks?" or "when did I travel last month?".
298
+ - Movement user actions are: query movement behavior, add a place or manual stay/trip overlay, update an existing stay/trip/place, or link a specific movement item to another Forge entity. Keep the explanation user-facing: where they stayed, when they traveled, what changed, and what this movement should be linked to.
299
+ - When the user is filling a missing-data gap, the default write path is a user-defined overlay box, not a raw stay or trip patch. Use `POST /api/v1/movement/user-boxes/preflight` if you need to confirm overlap or snap to the nearest missing interval, then `POST /api/v1/movement/user-boxes` with `kind: "stay"` or `kind: "trip"`.
300
+ - Use `PATCH /api/v1/movement/stays/:id` or `PATCH /api/v1/movement/trips/:id` only when the user is editing an existing recorded stay or recorded trip. Do not use those routes to fill a missing span.
301
+ - If the user says something as explicit as "that missing block was me staying home", do not reopen broad intake. Confirm the interval or place only if it is still ambiguous, then create the overlay and read the timeline back.
302
+ - Life Force lives under `/api/v1/life-force*`. Use `GET /api/v1/life-force` for the current energy overview, `PATCH /api/v1/life-force/profile` for durable profile changes, `PUT /api/v1/life-force/templates/:weekday` for weekday curve edits, and `POST /api/v1/life-force/fatigue-signals` for real-time tired or recovered signals.
303
+ - Workbench lives under `/api/v1/workbench/*`. Use those dedicated routes for flow catalog reads, flow CRUD, runs, published outputs, node results, and latest-node-output reads instead of trying to force Workbench through the batch entity routes.
304
+ - If you are unsure which specialized route family applies, check `forge_get_agent_onboarding` and use its `entityRouteModel.specializedDomainSurfaces` section before guessing.
305
+
293
306
  Use live work tools for `task_run`:
294
307
  `forge_log_work`, `forge_start_task_run`, `forge_heartbeat_task_run`, `forge_focus_task_run`, `forge_complete_task_run`, `forge_release_task_run`
295
308
 
309
+ Use `forge_adjust_work_minutes` for `work_adjustment` when the user wants a truthful signed minute correction on an existing task or project rather than a fake live run or a retroactive new task.
310
+
311
+ Use the dedicated Preferences action tools for `preference_judgment` and `preference_signal`:
312
+ `forge_submit_preferences_judgment`, `forge_submit_preferences_signal`, `forge_update_preferences_score`
313
+
296
314
  Use `forge_post_insight` for `insight`.
297
315
  Use the calendar tools for provider sync and planning:
298
316
  `forge_get_calendar_overview`, `forge_connect_calendar_provider`, `forge_sync_calendar_connection`, `forge_create_work_block_template`, `forge_recommend_task_timeboxes`, `forge_create_task_timebox`
@@ -343,7 +361,7 @@ For project deletion and recovery, prefer the generic delete and restore tools:
343
361
 
344
362
  For restore operations, each item must include `entityType` and `id`.
345
363
 
346
- Batch tools do not create or control `task_run` or `insight`.
364
+ Batch tools do not create or control `task_run`.
347
365
 
348
366
  Use the exact route-facing field names. Do not invent friendlier aliases. If a field name is unclear, use `forge_get_agent_onboarding` as the schema source of truth.
349
367
 
@@ -376,10 +394,21 @@ Use the health tools when the request is about sleep or sports review:
376
394
 
377
395
  - `forge_get_sleep_overview` to inspect recent nights, averages, regularity, stage breakdown, and linked reflective context
378
396
  - `forge_get_sports_overview` to inspect training volume, workout types, effort trends, habit-generated sessions, and linked context
379
- - `forge_update_sleep_session` to add sleep-quality notes, tags, or links back to Forge entities
380
- - `forge_update_workout_session` to add subjective effort, mood, meaning, tags, or links on one workout
397
+ - `forge_update_sleep_session` to add sleep-quality notes, tags, or links back to Forge entities after review
398
+ - `forge_update_workout_session` to add subjective effort, mood, meaning, tags, or links on one workout after review
381
399
  - remember that the UI route is `/sports` while the backend overview route is `/api/v1/health/fitness`
382
400
 
401
+ Use these exact health batch payload shapes when the user is creating or editing the stored records themselves:
402
+
403
+ - create a manual sleep session:
404
+ `{"operations":[{"entityType":"sleep_session","data":{"startedAt":"2026-04-10T22:45:00.000Z","endedAt":"2026-04-11T06:45:00.000Z","qualitySummary":"Slept cleanly after a light evening.","links":[{"entityType":"habit","entityId":"habit_sleep_hygiene","relationshipType":"supports"}]}}]}`
405
+ - update a sleep session through batch CRUD:
406
+ `{"operations":[{"entityType":"sleep_session","id":"sleep_123","patch":{"notes":"Woke once around 03:00 but settled quickly.","tags":["travel","recovered"]}}]}`
407
+ - create a manual workout session:
408
+ `{"operations":[{"entityType":"workout_session","data":{"workoutType":"walk","startedAt":"2026-04-11T10:00:00.000Z","endedAt":"2026-04-11T10:45:00.000Z","subjectiveEffort":6,"meaningText":"Reset after a long planning block.","links":[{"entityType":"task","entityId":"task_123","relationshipType":"supports"}]}}]}`
409
+ - update a workout session through batch CRUD:
410
+ `{"operations":[{"entityType":"workout_session","id":"workout_123","patch":{"moodAfter":"clear","tags":["zone2"]}}]}`
411
+
383
412
  Work-block payload guidance:
384
413
 
385
414
  - `kind` must be one of `main_activity`, `secondary_activity`, `third_activity`, `rest`, `holiday`, or `custom`
@@ -476,7 +505,8 @@ Additional first-class surfaces:
476
505
 
477
506
  - Use the high-level batch routes for basic Preferences CRUD. `preference_catalog`, `preference_catalog_item`, `preference_context`, and `preference_item` all go through `forge_create_entities`, `forge_update_entities`, and `forge_delete_entities`.
478
507
  - Use the high-level batch routes for basic questionnaire CRUD too. `questionnaire_instrument` goes through `forge_create_entities`, `forge_update_entities`, and `forge_delete_entities`.
508
+ - Use the high-level batch routes for ordinary health-session CRUD too. `sleep_session` and `workout_session` go through `forge_search_entities`, `forge_create_entities`, `forge_update_entities`, and `forge_delete_entities` by default. Keep the dedicated health tools for review surfaces and reflective enrichment on one record.
479
509
  - Keep the dedicated Preferences tools only for real preference actions and read models: `forge_get_preferences_workspace`, `forge_start_preferences_game`, `forge_merge_preferences_contexts`, `forge_enqueue_preferences_item_from_entity`, `forge_submit_preferences_judgment`, `forge_submit_preferences_signal`, and `forge_update_preferences_score`.
480
510
  - Keep the dedicated questionnaire tools only for real flow actions and read models: `forge_list_questionnaires`, `forge_get_questionnaire`, `forge_clone_questionnaire`, `forge_ensure_questionnaire_draft`, `forge_publish_questionnaire_draft`, `forge_start_questionnaire_run`, `forge_get_questionnaire_run`, `forge_update_questionnaire_run`, and `forge_complete_questionnaire_run`.
481
511
  - Self-observation is note-backed. Read the calendar through `forge_get_self_observation_calendar`, but create or update the stored observation as a `note` tagged `Self-observation` with `frontmatter.observedAt` and links to the relevant `behavior_pattern`, `trigger_report`, or other Forge records.
482
- - `sleep_session` and `workout_session` are first-class health records. Review them through the dedicated health tools instead of treating them like loose notes.
512
+ - `sleep_session` and `workout_session` are first-class health records. Treat them like ordinary stored entities for CRUD, and use the dedicated health tools for read models or post-review enrichment rather than pretending they live on a special mutation island.