denchclaw 2.4.3 → 2.4.5

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 (128) hide show
  1. package/apps/web/.next/standalone/apps/web/.next/BUILD_ID +1 -1
  2. package/apps/web/.next/standalone/apps/web/.next/app-build-manifest.json +90 -90
  3. package/apps/web/.next/standalone/apps/web/.next/app-path-routes-manifest.json +25 -25
  4. package/apps/web/.next/standalone/apps/web/.next/build-manifest.json +2 -2
  5. package/apps/web/.next/standalone/apps/web/.next/cache/config.json +3 -3
  6. package/apps/web/.next/standalone/apps/web/.next/prerender-manifest.json +3 -3
  7. package/apps/web/.next/standalone/apps/web/.next/required-server-files.json +1 -1
  8. package/apps/web/.next/standalone/apps/web/.next/routes-manifest.json +1 -1
  9. package/apps/web/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  10. package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/cron/route_client-reference-manifest.js +1 -1
  11. package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/proxy/route_client-reference-manifest.js +1 -1
  12. package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/route_client-reference-manifest.js +1 -1
  13. package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/serve/[...path]/route_client-reference-manifest.js +1 -1
  14. package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/store/route_client-reference-manifest.js +1 -1
  15. package/apps/web/.next/standalone/apps/web/.next/server/app/api/apps/webhooks/[...path]/route_client-reference-manifest.js +1 -1
  16. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/active/route_client-reference-manifest.js +1 -1
  17. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/route.js +1 -1
  18. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/route_client-reference-manifest.js +1 -1
  19. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/runs/route_client-reference-manifest.js +1 -1
  20. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/stop/route.js +1 -1
  21. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/stop/route_client-reference-manifest.js +1 -1
  22. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/stream/route_client-reference-manifest.js +1 -1
  23. package/apps/web/.next/standalone/apps/web/.next/server/app/api/chat/subagents/route_client-reference-manifest.js +1 -1
  24. package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/jobs/[jobId]/runs/route_client-reference-manifest.js +1 -1
  25. package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/jobs/route_client-reference-manifest.js +1 -1
  26. package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/runs/[sessionId]/route_client-reference-manifest.js +1 -1
  27. package/apps/web/.next/standalone/apps/web/.next/server/app/api/cron/runs/search-transcript/route_client-reference-manifest.js +1 -1
  28. package/apps/web/.next/standalone/apps/web/.next/server/app/api/feedback/route.js +1 -1
  29. package/apps/web/.next/standalone/apps/web/.next/server/app/api/feedback/route_client-reference-manifest.js +1 -1
  30. package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/channels/route_client-reference-manifest.js +1 -1
  31. package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/chat/route_client-reference-manifest.js +1 -1
  32. package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/chat/stream/route_client-reference-manifest.js +1 -1
  33. package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/sessions/[id]/route_client-reference-manifest.js +1 -1
  34. package/apps/web/.next/standalone/apps/web/.next/server/app/api/gateway/sessions/route_client-reference-manifest.js +1 -1
  35. package/apps/web/.next/standalone/apps/web/.next/server/app/api/memories/route_client-reference-manifest.js +1 -1
  36. package/apps/web/.next/standalone/apps/web/.next/server/app/api/profiles/route_client-reference-manifest.js +1 -1
  37. package/apps/web/.next/standalone/apps/web/.next/server/app/api/profiles/switch/route_client-reference-manifest.js +1 -1
  38. package/apps/web/.next/standalone/apps/web/.next/server/app/api/sessions/[sessionId]/route_client-reference-manifest.js +1 -1
  39. package/apps/web/.next/standalone/apps/web/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
  40. package/apps/web/.next/standalone/apps/web/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  41. package/apps/web/.next/standalone/apps/web/.next/server/app/api/terminal/port/route_client-reference-manifest.js +1 -1
  42. package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/[id]/messages/route_client-reference-manifest.js +1 -1
  43. package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/[id]/route_client-reference-manifest.js +1 -1
  44. package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/route.js +1 -1
  45. package/apps/web/.next/standalone/apps/web/.next/server/app/api/web-sessions/route_client-reference-manifest.js +1 -1
  46. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/assets/[...path]/route_client-reference-manifest.js +1 -1
  47. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/browse/route_client-reference-manifest.js +1 -1
  48. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/browse-file/route_client-reference-manifest.js +1 -1
  49. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/context/route_client-reference-manifest.js +1 -1
  50. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/copy/route_client-reference-manifest.js +1 -1
  51. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/db/introspect/route_client-reference-manifest.js +1 -1
  52. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/db/query/route_client-reference-manifest.js +1 -1
  53. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/delete/route.js +1 -1
  54. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/delete/route_client-reference-manifest.js +1 -1
  55. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/execute/route_client-reference-manifest.js +1 -1
  56. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/file/route_client-reference-manifest.js +1 -1
  57. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/init/route.js +1 -1
  58. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/init/route_client-reference-manifest.js +1 -1
  59. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/link-preview/route_client-reference-manifest.js +1 -1
  60. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/list/route_client-reference-manifest.js +1 -1
  61. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/mkdir/route_client-reference-manifest.js +1 -1
  62. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/move/route_client-reference-manifest.js +1 -1
  63. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/route_client-reference-manifest.js +1 -1
  64. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/actions/runs/route_client-reference-manifest.js +1 -1
  65. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/display-field/route_client-reference-manifest.js +1 -1
  66. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/[id]/content/route_client-reference-manifest.js +1 -1
  67. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/[id]/route_client-reference-manifest.js +1 -1
  68. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/bulk-delete/route_client-reference-manifest.js +1 -1
  69. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/options/route_client-reference-manifest.js +1 -1
  70. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/route.js +1 -1
  71. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/entries/route_client-reference-manifest.js +1 -1
  72. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/[fieldId]/enum-rename/route_client-reference-manifest.js +1 -1
  73. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/[fieldId]/route_client-reference-manifest.js +1 -1
  74. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/reorder/route_client-reference-manifest.js +1 -1
  75. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/fields/route_client-reference-manifest.js +1 -1
  76. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/route.js +5 -5
  77. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/route_client-reference-manifest.js +1 -1
  78. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/objects/[name]/views/route_client-reference-manifest.js +1 -1
  79. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/open-file/route_client-reference-manifest.js +1 -1
  80. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/path-info/route_client-reference-manifest.js +1 -1
  81. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/query/route_client-reference-manifest.js +1 -1
  82. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/raw-file/route_client-reference-manifest.js +1 -1
  83. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/rename/route_client-reference-manifest.js +1 -1
  84. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/reports/execute/route.js +1 -1
  85. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/reports/execute/route_client-reference-manifest.js +1 -1
  86. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/search-index/route_client-reference-manifest.js +1 -1
  87. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/suggest-files/route_client-reference-manifest.js +1 -1
  88. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/switch/route.js +1 -1
  89. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/switch/route_client-reference-manifest.js +1 -1
  90. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/thumbnail/route_client-reference-manifest.js +1 -1
  91. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/tree/route_client-reference-manifest.js +1 -1
  92. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/upload/route.js +1 -1
  93. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/upload/route_client-reference-manifest.js +1 -1
  94. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/virtual-file/route_client-reference-manifest.js +1 -1
  95. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/watch/route_client-reference-manifest.js +1 -1
  96. package/apps/web/.next/standalone/apps/web/.next/server/app/api/workspace/write-binary/route_client-reference-manifest.js +1 -1
  97. package/apps/web/.next/standalone/apps/web/.next/server/app/page.js +8 -8
  98. package/apps/web/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  99. package/apps/web/.next/standalone/apps/web/.next/server/app/workspace/page_client-reference-manifest.js +1 -1
  100. package/apps/web/.next/standalone/apps/web/.next/server/app-paths-manifest.json +25 -25
  101. package/apps/web/.next/standalone/apps/web/.next/server/chunks/6787.js +2 -2
  102. package/apps/web/.next/standalone/apps/web/.next/server/chunks/687.js +7 -6
  103. package/apps/web/.next/standalone/apps/web/.next/server/chunks/8137.js +1 -1
  104. package/apps/web/.next/standalone/apps/web/.next/server/functions-config-manifest.json +8 -8
  105. package/apps/web/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
  106. package/apps/web/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -1
  107. package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/{layout-5b42eb12bc6891b1.js → layout-a597017db7df698d.js} +1 -1
  108. package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/page-6702f960a7cc2d6f.js +1 -0
  109. package/apps/web/.next/{static/css/fb279c912601f360.css → standalone/apps/web/.next/static/css/99b07ab2db5fe339.css} +1 -1
  110. package/apps/web/.next/standalone/apps/web/public/dench-workspace-icon.png +0 -0
  111. package/apps/web/.next/standalone/apps/web/server.js +1 -1
  112. package/apps/web/.next/standalone/package.json +1 -1
  113. package/apps/web/.next/static/chunks/app/{layout-5b42eb12bc6891b1.js → layout-a597017db7df698d.js} +1 -1
  114. package/apps/web/.next/static/chunks/app/page-6702f960a7cc2d6f.js +1 -0
  115. package/apps/web/.next/{standalone/apps/web/.next/static/css/fb279c912601f360.css → static/css/99b07ab2db5fe339.css} +1 -1
  116. package/apps/web/public/dench-workspace-icon.png +0 -0
  117. package/extensions/posthog-analytics/lib/build-env.js +1 -1
  118. package/package.json +1 -1
  119. package/skills/crm/SKILL.md +22 -9
  120. package/skills/crm/documents/SKILL.md +73 -7
  121. package/skills/crm/duckdb-operations/SKILL.md +17 -1
  122. package/skills/crm/object-builder/SKILL.md +28 -2
  123. package/apps/web/.next/standalone/apps/web/.next/static/chunks/app/page-4dfaa52589c03e51.js +0 -1
  124. package/apps/web/.next/static/chunks/app/page-4dfaa52589c03e51.js +0 -1
  125. /package/apps/web/.next/standalone/apps/web/.next/static/{yotM7sjmc2mLN7mGVWai0 → 6km2S2lfAi2PQ3TlStEAM}/_buildManifest.js +0 -0
  126. /package/apps/web/.next/standalone/apps/web/.next/static/{yotM7sjmc2mLN7mGVWai0 → 6km2S2lfAi2PQ3TlStEAM}/_ssgManifest.js +0 -0
  127. /package/apps/web/.next/static/{yotM7sjmc2mLN7mGVWai0 → 6km2S2lfAi2PQ3TlStEAM}/_buildManifest.js +0 -0
  128. /package/apps/web/.next/static/{yotM7sjmc2mLN7mGVWai0 → 6km2S2lfAi2PQ3TlStEAM}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: documents
3
- description: Document management with markdown files, cross-nesting between documents and objects, and human-readable entry detail pages linked through the documents table.
3
+ description: Document management with markdown files, always-on entry documents linked through the documents table, and mutation/edit logs for CRM entries. Use when creating or updating row notes, entry notes, detail pages, or document-linked CRM content.
4
4
  metadata: { "openclaw": { "inject": true, "always": true, "emoji": "📄" } }
5
5
  ---
6
6
 
@@ -14,6 +14,18 @@ This skill covers document management, cross-nesting, and entry detail pages. Fo
14
14
 
15
15
  Documents are markdown files in `{{WORKSPACE_PATH}}/**`. The DuckDB `documents` table tracks metadata only; the `.md` file IS the content.
16
16
 
17
+ ## Default Rule: Every Entry Needs a Connected Document
18
+
19
+ Treat the entry document as the default long-form companion to the row.
20
+
21
+ Mandatory defaults:
22
+
23
+ - Create or reuse a connected entry document whenever you create an entry and have enough information to derive a sane filename/title.
24
+ - When updating an entry, ensure a connected document exists before finishing the task. If it is missing, create it.
25
+ - Keep the document registered in DuckDB `documents` with `entry_id`, `parent_object_id`, and `file_path`.
26
+ - If the user asks to add or change anything on an entry, update the connected document too.
27
+ - Append a concise timestamped activity log entry for every meaningful mutation so the document acts as an edit log, not just a static page.
28
+
17
29
  ### Create Document
18
30
 
19
31
  1. Write the `.md` file: `write {{WORKSPACE_PATH}}/projects/roadmap.md`
@@ -41,12 +53,14 @@ These are **not the same thing**:
41
53
  When the user says:
42
54
 
43
55
  - "fill in notes for each entry"
56
+ - "add notes to this row"
57
+ - "add a note to this entry"
44
58
  - "write descriptions for all rows"
45
59
  - "add detailed writeups"
46
60
  - "put the outreach draft into each influencer notes page"
47
61
  - "create entry docs"
48
62
 
49
- default to **entry documents** unless they explicitly say "update the Notes column/field".
63
+ default to the **connected entry document**.
50
64
 
51
65
  If the user truly means the `Notes` field, they will usually talk about:
52
66
 
@@ -55,6 +69,8 @@ If the user truly means the `Notes` field, they will usually talk about:
55
69
  - filtering/sorting by Notes
56
70
  - SQL updates to `entry_fields`
57
71
 
72
+ If they explicitly ask to update the `Notes` field/column, update that DuckDB value **and** sync the connected entry document unless they clearly ask you not to.
73
+
58
74
  If they mean entry documents, they are talking about:
59
75
 
60
76
  - markdown pages
@@ -66,7 +82,7 @@ If they mean entry documents, they are talking about:
66
82
 
67
83
  ## Entry Detail Pages
68
84
 
69
- Each entry in an object can have an optional markdown file that acts as its detail page in the entry panel.
85
+ Each entry in an object should have a markdown file that acts as its detail page and running edit log in the entry panel.
70
86
 
71
87
  **CRITICAL:** New entry documents should use **human-readable filenames**, not raw UUID filenames. The file must also be registered in DuckDB `documents` with `entry_id`, `parent_object_id`, and `file_path`.
72
88
 
@@ -74,8 +90,20 @@ Each entry in an object can have an optional markdown file that acts as its deta
74
90
 
75
91
  For every entry document:
76
92
 
77
- 1. Write a human-readable markdown file inside the object directory
78
- 2. Insert/update a row in `documents` linking the entry to that file
93
+ 1. Reuse the existing linked document if one already exists for the entry
94
+ 2. Otherwise write a human-readable markdown file inside the object directory
95
+ 3. Insert/update a row in `documents` linking the entry to that file
96
+ 4. Update the markdown content and append the mutation log entry
97
+
98
+ Before creating a new file, resolve any existing document:
99
+
100
+ ```sql
101
+ SELECT id, title, file_path
102
+ FROM documents
103
+ WHERE entry_id = '<entry_id>'
104
+ ORDER BY updated_at DESC
105
+ LIMIT 1;
106
+ ```
79
107
 
80
108
  ```sql
81
109
  INSERT INTO documents (title, file_path, parent_object_id, entry_id)
@@ -127,6 +155,27 @@ Examples:
127
155
  - `Creator Name = Jane Smith` -> `jane-smith-001.md`
128
156
  - `Company Name = Acme Corp` -> `acme-corp-001.md`
129
157
 
158
+ ### Default content model
159
+
160
+ Keep the entry document readable for humans and useful as an audit trail. A good default shape is:
161
+
162
+ ```markdown
163
+ # Jane Smith
164
+
165
+ ## Summary
166
+ Current state of the entry in plain English.
167
+
168
+ ## Notes
169
+ User-facing notes, drafts, follow-ups, or other long-form details.
170
+
171
+ ## Activity Log
172
+ ### 2026-03-30T12:34:56Z - Entry updated
173
+ - Changed `Status`: `New` -> `Qualified`
174
+ - Added note: Follow up on Thursday about pricing
175
+ ```
176
+
177
+ Update the current sections in place and append new log items instead of rewriting history.
178
+
130
179
  ### NEVER do these
131
180
 
132
181
  - Do **NOT** default to `{entry_id}.md` for new documents
@@ -142,7 +191,7 @@ Older workspaces may still have legacy `{entry_id}.md` files. Those can continue
142
191
 
143
192
  ## Creating One Entry Document
144
193
 
145
- Only create entry `.md` files when the user wants detailed prose for a specific entry or group of entries.
194
+ Create or repair the connected entry `.md` file whenever the user creates an entry, mentions notes on the row/entry, or makes a mutation and no document exists yet.
146
195
 
147
196
  Example:
148
197
 
@@ -182,7 +231,7 @@ SET title = excluded.title,
182
231
 
183
232
  ## Batch Creating Entry Documents
184
233
 
185
- When the user asks for docs for many entries, do **not** update the `Notes` field in SQL. Create markdown files plus `documents` rows.
234
+ When the user asks for docs for many entries, or asks to add notes/details across many entries, create/update markdown files plus `documents` rows. Only update the `Notes` field in SQL when they explicitly want that field changed too.
186
235
 
187
236
  ### Workflow
188
237
 
@@ -190,6 +239,7 @@ When the user asks for docs for many entries, do **not** update the `Notes` fiel
190
239
  2. Derive a human-readable filename for each entry
191
240
  3. Write one `.md` file per entry under the object directory
192
241
  4. Insert/update one `documents` row per file
242
+ 5. Append or update each file's `## Notes` and `## Activity Log` sections to capture the requested changes
193
243
 
194
244
  ### Example: create docs for every influencer
195
245
 
@@ -253,3 +303,19 @@ Examples:
253
303
  - `marketing/influencer/outreach-playbook.md` with no `entry_id` -> standalone object-level document
254
304
 
255
305
  If a markdown file is meant to be the entry page, always register it in `documents`.
306
+
307
+ ## Sync on Entry Mutations
308
+
309
+ After **any** meaningful entry mutation:
310
+
311
+ 1. Resolve the linked entry document by `documents.entry_id`
312
+ 2. Create the document if it does not exist yet
313
+ 3. Update the relevant prose sections (`Summary`, `Notes`, drafts, follow-ups, etc.)
314
+ 4. Append a timestamped `Activity Log` entry describing the delta
315
+
316
+ This applies to:
317
+
318
+ - field value changes
319
+ - explicit `Notes` field updates
320
+ - status/owner/priority changes
321
+ - user requests to "add", "note", "log", "remember", or otherwise attach information to an entry
@@ -210,7 +210,7 @@ Important:
210
210
 
211
211
  **enum fields**: Field definition stores `enum_values` as JSON array. Entry stores the selected value string. `enum_multiple = true` for multi-select (value stored as JSON array string).
212
212
 
213
- **relation fields**: Field stores `related_object_id` (the ID of the target object) and `relationship_type` (`many_to_one` for single select, `many_to_many` for multi-select). Entry field value stores the related entry ID (or JSON array of IDs for many-to-many). Relation fields can only be created via direct DuckDB SQL (not the API). The UI renders them as a searchable dropdown of entries from the related object.
213
+ **relation fields**: Field stores `related_object_id` (the ID of the target object) and `relationship_type` (`many_to_one` for single select, `many_to_many` for multi-select). Entry field value stores the related entry ID (or JSON array of IDs for many-to-many). Relation fields can only be created via direct DuckDB SQL (not the API). The UI renders them as a searchable dropdown of entries from the related object. This is the default for foreign-table, lookup, linked-record, or "connect this column to another table" requests. Do **NOT** use `text`/`richtext` to store another object's label when a real linked object exists.
214
214
 
215
215
  Creating a relation field (SQL — the only way):
216
216
 
@@ -257,6 +257,8 @@ ON CONFLICT (name) DO NOTHING RETURNING *;
257
257
 
258
258
  ### Create Fields
259
259
 
260
+ Use this only for scalar fields. If the field is meant to reference another object/table, skip this section and use **Create Relation Field** instead.
261
+
260
262
  ```sql
261
263
  INSERT INTO fields (object_id, name, type, required, sort_order)
262
264
  VALUES
@@ -281,6 +283,16 @@ VALUES (
281
283
 
282
284
  Relation fields link entries across objects. **You MUST create these via SQL** — the API does not support `relation` type.
283
285
 
286
+ Use a relation field by default when:
287
+
288
+ - the user says the column should connect/link/reference another table or object
289
+ - the field name matches or strongly aliases an existing object
290
+ - the column is really a lookup/select field rather than free-form text
291
+
292
+ Do **NOT** create surrogate string columns like `Company Name`, `Client Name`, `Deal Name`, `Project Name`, or similar when the corresponding object already exists, unless the user explicitly wants denormalized snapshot text.
293
+
294
+ Default to `many_to_one`. Use `many_to_many` only for clearly plural or multi-select relationships.
295
+
284
296
  ```sql
285
297
  -- Link people → company (many people belong to one company)
286
298
  INSERT INTO fields (object_id, name, type, related_object_id, relationship_type, sort_order)
@@ -367,6 +379,8 @@ COMMIT;
367
379
  "
368
380
  ```
369
381
 
382
+ Entry creation is not complete until the connected entry document exists on disk and is registered in `documents`. After the SQL commit, follow the default sync workflow in `crm/documents/SKILL.md`.
383
+
370
384
  ### Search Entries (via view)
371
385
 
372
386
  ```sql
@@ -391,6 +405,8 @@ VALUES ('<entry_id>', (SELECT id FROM fields WHERE object_id = '<obj_id>' AND na
391
405
  ON CONFLICT (entry_id, field_id) DO UPDATE SET value = excluded.value, updated_at = now();
392
406
  ```
393
407
 
408
+ After updating `entry_fields`, immediately sync the connected entry document and append a timestamped activity log entry describing the change. This still applies when the user explicitly asks for the `Notes` field/column.
409
+
394
410
  ### Delete (with cascade)
395
411
 
396
412
  ```sql
@@ -197,7 +197,24 @@ EOF
197
197
 
198
198
  ## Proactive Relation Creation (IMPORTANT)
199
199
 
200
- **When creating multiple objects, ALWAYS create relation fields to link them — even if the user did not explicitly ask for it.** Real-world data is interconnected. If two objects are obviously related, link them. The user expects this; not linking them is a missed opportunity that forces manual work later.
200
+ **When creating multiple objects or adding fields to an existing object, ALWAYS create relation fields to link them — even if the user did not explicitly ask for it.** Real-world data is interconnected. If two objects are obviously related, link them. The user expects this; not linking them is a missed opportunity that forces manual work later.
201
+
202
+ ### Foreign-link default for new columns
203
+
204
+ Before you create any new field on an object:
205
+
206
+ 1. Run `SELECT name FROM objects ORDER BY name`
207
+ 2. Check whether the requested field is really a foreign link to one of those objects
208
+ 3. If yes, create a `relation` field via SQL instead of a scalar field via API/text defaults
209
+ 4. Regenerate the PIVOT view and update `.object.yaml` so the linked field is reflected everywhere
210
+
211
+ Aggressive defaults:
212
+
213
+ - If the user says the field should connect to another table/object, create a `relation` field.
214
+ - If the field name matches or strongly aliases an existing object, create a `relation` field.
215
+ - If the field refers to a workspace member, use `user`, not `text`.
216
+ - Do **NOT** create fallback text columns like `Company Name`, `Client Name`, `Project Name`, `Deal Name`, or `Owner Name` when the real object already exists, unless the user explicitly asks for a copied text snapshot.
217
+ - Default to `many_to_one`; switch to `many_to_many` only when the field is clearly plural or multi-select.
201
218
 
202
219
  ### When to create relations automatically
203
220
 
@@ -212,7 +229,7 @@ EOF
212
229
  - **Property + Agent** → add "Agent" relation on property (many_to_one → people)
213
230
  - **Any child object + parent object** → link child to parent
214
231
 
215
- **General rule**: If you're creating object B and object A already exists (or is being created alongside), ask yourself: "Would an entry in B logically belong to or reference an entry in A?" If yes, add a relation field.
232
+ **General rule**: If you're creating object B, or adding field F to object B, and object A already exists (or is being created alongside), ask yourself: "Would an entry in B logically belong to, reference, select, or connect to an entry in A?" If yes, add a relation field.
216
233
 
217
234
  ### Relation field SQL pattern
218
235
 
@@ -232,6 +249,15 @@ Use `many_to_one` when each entry links to exactly one entry in the other object
232
249
 
233
250
  **Relation fields must be created via SQL** — the API does not support the `relation` type.
234
251
 
252
+ ### Bad vs Good defaults
253
+
254
+ - Bad: add `Company Name` as `text` on `lead` when `company` already exists
255
+ - Good: add `Company` as `relation -> company`
256
+ - Bad: add `Project` as `text` on `task` when `project` already exists
257
+ - Good: add `Project` as `relation -> project`
258
+ - Bad: add `Owner Name` as `text` when the value should be a team member selector
259
+ - Good: add `Owner` / `Assigned To` as `user`
260
+
235
261
  ---
236
262
 
237
263
  ## CRM Patterns